decred.org/dcrdex@v1.0.5/client/webserver/site/src/js/coinexplorers.ts (about) 1 import { 2 app, 3 PageElement 4 } from './registry' 5 import * as intl from './locales' 6 7 export const Mainnet = 0 8 export const Testnet = 1 9 export const Simnet = 2 10 11 const coinIDTakerFoundMakerRedemption = 'TakerFoundMakerRedemption:' 12 13 /* ethBasedExplorerArg returns the explorer argument for ETH, ERC20 and EVM 14 Compatible assets and whether the return value is an address. */ 15 function ethBasedExplorerArg (cid: string): [string, boolean] { 16 if (cid.startsWith(coinIDTakerFoundMakerRedemption)) return [cid.substring(coinIDTakerFoundMakerRedemption.length), true] 17 else if (cid.length === 42) return [cid, true] 18 else return [cid, false] 19 } 20 21 const ethExplorers: Record<number, (cid: string) => string> = { 22 [Mainnet]: (cid: string) => { 23 const [arg, isAddr] = ethBasedExplorerArg(cid) 24 return isAddr ? `https://etherscan.io/address/${arg}` : `https://etherscan.io/tx/${arg}` 25 }, 26 [Testnet]: (cid: string) => { 27 const [arg, isAddr] = ethBasedExplorerArg(cid) 28 return isAddr ? `https://sepolia.etherscan.io/address/${arg}` : `https://sepolia.etherscan.io/tx/${arg}` 29 }, 30 [Simnet]: (cid: string) => { 31 const [arg, isAddr] = ethBasedExplorerArg(cid) 32 return isAddr ? `https://etherscan.io/address/${arg}` : `https://etherscan.io/tx/${arg}` 33 } 34 } 35 36 const polygonExplorers: Record<number, (cid: string) => string> = { 37 [Mainnet]: (cid: string) => { 38 const [arg, isAddr] = ethBasedExplorerArg(cid) 39 return isAddr ? `https://polygonscan.com/address/${arg}` : `https://polygonscan.com/tx/${arg}` 40 }, 41 [Testnet]: (cid: string) => { 42 const [arg, isAddr] = ethBasedExplorerArg(cid) 43 return isAddr ? `https://amoy.polygonscan.com/address/${arg}` : `https://amoy.polygonscan.com/tx/${arg}` 44 }, 45 [Simnet]: (cid: string) => { 46 const [arg, isAddr] = ethBasedExplorerArg(cid) 47 return isAddr ? `https://polygonscan.com/address/${arg}` : `https://polygonscan.com/tx/${arg}` 48 } 49 } 50 51 export const CoinExplorers: Record<number, Record<number, (cid: string) => string>> = { 52 42: { // dcr 53 [Mainnet]: (cid: string) => { 54 const [txid, vout] = cid.split(':') 55 if (vout !== undefined) return `https://explorer.dcrdata.org/tx/${txid}/out/${vout}` 56 return `https://explorer.dcrdata.org/tx/${txid}` 57 }, 58 [Testnet]: (cid: string) => { 59 const [txid, vout] = cid.split(':') 60 if (vout !== undefined) return `https://testnet.dcrdata.org/tx/${txid}/out/${vout}` 61 return `https://testnet.dcrdata.org/tx/${txid}` 62 }, 63 [Simnet]: (cid: string) => { 64 const [txid, vout] = cid.split(':') 65 if (vout !== undefined) return `http://127.0.0.1:17779/tx/${txid}/out/${vout}` 66 return `https://127.0.0.1:17779/tx/${txid}` 67 } 68 }, 69 0: { // btc 70 [Mainnet]: (cid: string) => `https://mempool.space/tx/${cid.split(':')[0]}`, 71 [Testnet]: (cid: string) => `https://mempool.space/testnet/tx/${cid.split(':')[0]}`, 72 [Simnet]: (cid: string) => `https://mempool.space/tx/${cid.split(':')[0]}` 73 }, 74 2: { // ltc 75 [Mainnet]: (cid: string) => `https://ltc.bitaps.com/${cid.split(':')[0]}`, 76 [Testnet]: (cid: string) => `https://sochain.com/tx/LTCTEST/${cid.split(':')[0]}`, 77 [Simnet]: (cid: string) => `https://ltc.bitaps.com/${cid.split(':')[0]}` 78 }, 79 20: { // dgb 80 [Mainnet]: (cid: string) => `https://digiexplorer.info/tx/${cid.split(':')[0]}`, 81 [Testnet]: (cid: string) => `https://testnetexplorer.digibyteservers.io/tx/${cid.split(':')[0]}`, 82 [Simnet]: (cid: string) => `https://digiexplorer.info/tx/${cid.split(':')[0]}` 83 }, 84 60: ethExplorers, 85 60001: ethExplorers, 86 60002: ethExplorers, 87 3: { // doge 88 [Mainnet]: (cid: string) => `https://dogeblocks.com/tx/${cid.split(':')[0]}`, 89 [Testnet]: (cid: string) => `https://blockexplorer.one/dogecoin/testnet/tx/${cid.split(':')[0]}`, 90 [Simnet]: (cid: string) => `https://dogeblocks.com/tx/${cid.split(':')[0]}` 91 }, 92 5: { // dash 93 [Mainnet]: (cid: string) => `https://blockexplorer.one/dash/mainnet/tx/${cid.split(':')[0]}`, 94 [Testnet]: (cid: string) => `https://blockexplorer.one/dash/testnet/tx/${cid.split(':')[0]}`, 95 [Simnet]: (cid: string) => `https://blockexplorer.one/dash/mainnet/tx/${cid.split(':')[0]}` 96 }, 97 133: { // zec 98 [Mainnet]: (cid: string) => `https://zcashblockexplorer.com/transactions/${cid.split(':')[0]}`, 99 [Testnet]: (cid: string) => `https://blockexplorer.one/zcash/testnet/tx/${cid.split(':')[0]}`, 100 [Simnet]: (cid: string) => `https://zcashblockexplorer.com/transactions/${cid.split(':')[0]}` 101 }, 102 147: { // zcl 103 [Mainnet]: (cid: string) => `https://explorer.zcl.zelcore.io/tx/${cid.split(':')[0]}`, 104 [Simnet]: (cid: string) => `https://explorer.zcl.zelcore.io/tx/${cid.split(':')[0]}` 105 }, 106 136: { // firo 107 [Mainnet]: (cid: string) => `https://explorer.firo.org/tx/${cid.split(':')[0]}`, 108 [Testnet]: (cid: string) => `https://testexplorer.firo.org/tx/${cid.split(':')[0]}`, 109 [Simnet]: (cid: string) => `https://explorer.firo.org/tx/${cid.split(':')[0]}` 110 }, 111 145: { // bch 112 [Mainnet]: (cid: string) => `https://bch.loping.net/tx/${cid.split(':')[0]}`, 113 [Testnet]: (cid: string) => `https://tbch4.loping.net/tx/${cid.split(':')[0]}`, 114 [Simnet]: (cid: string) => `https://bch.loping.net/tx/${cid.split(':')[0]}` 115 }, 116 966: polygonExplorers, 117 966001: polygonExplorers, 118 966002: polygonExplorers, 119 966003: polygonExplorers, 120 966004: polygonExplorers 121 } 122 123 export function formatCoinID (cid: string) { 124 if (cid.startsWith(coinIDTakerFoundMakerRedemption)) { 125 const makerAddr = cid.substring(coinIDTakerFoundMakerRedemption.length) 126 return intl.prep(intl.ID_TAKER_FOUND_MAKER_REDEMPTION, { makerAddr: makerAddr }) 127 } 128 return cid 129 } 130 131 /* 132 * baseChainID returns the asset ID for the asset's parent if the asset is a 133 * token, otherwise the ID for the asset itself. 134 */ 135 function baseChainID (assetID: number) { 136 const asset = app().user.assets[assetID] 137 return asset.token ? asset.token.parentID : assetID 138 } 139 140 /* 141 * setCoinHref sets the hyperlink element's href attribute based on provided 142 * assetID and data-explorer-coin value present on supplied link element. 143 */ 144 export function setCoinHref (assetID: number, link: PageElement) { 145 const net = app().user.net 146 const assetExplorer = CoinExplorers[baseChainID(assetID)] 147 if (!assetExplorer) return 148 const formatter = assetExplorer[net] 149 if (!formatter) return 150 link.classList.remove('plainlink') 151 link.classList.add('subtlelink') 152 link.href = formatter(link.dataset.explorerCoin || '') 153 }