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  }