import axios from 'axios' ; import { BigNumberish , BigNumber , providers } from 'ethers' ; import { getAddress } from 'ethers/lib/utils' ; import { DAPP_LIST_BASE_URL , TRUSTWALLET_BASE_URL } from './constants' ; import { TokenFromList , TokenMapping , TokenStandard } from './interfaces' ; export function isRegistered ( tokenAddress , tokenMapping ? ) { if ( ! tokenMapping ) return true ; return tokenMapping [ getAddress ( tokenAddress ) ] !== undefined ; } export function shortenAddress ( address ) { return `${ address . substr ( 0 , 6 ) }...${ address . substr ( address . length - 4 , 4 ) }` ; } export function compareBN ( a , b ) { a = BigNumber . from ( a ) ; b = BigNumber . from ( b ) ; const diff = a . sub ( b ) ; return diff . isZero ( ) ? 0 : diff . lt ( 0 ) ? - 1 : 1 ; } export async function addressToAppName ( address , networkName ? ) { if ( ! networkName ) return undefined ; try { const { data } = await axios . get ( `${ DAPP_LIST_BASE_URL }/${ networkName }/${ getAddress ( address ) }.json` ) ; return data . appName ; } catch { return undefined ; } } export async function lookupEnsName ( address , provider ) { try { return await provider . lookupAddress ( address ) ; } catch { return undefined ; } } export function getExplorerUrl ( chainId ) { const mapping = { 1 : 'https://etherscan.io/address' , 3 : 'https://ropsten.etherscan.io/address' , 4 : 'https://rinkeby.etherscan.io/address' , 5 : 'https://goerli.etherscan.io/address' , 6 : 'https://blockscout.com/etc/kotti/address' , 10 : 'https://optimistic.etherscan.io/address' , 30 : 'https://blockscout.com/rsk/mainnet/address' , 42 : 'https://kovan.etherscan.io/address' , 56 : 'https://bscscan.com/address' , 61 : 'https://blockscout.com/etc/mainnet/address' , 63 : 'https://blockscout.com/etc/mordor/address' , 77 : 'https://blockscout.com/poa/sokol/address' , 97 : 'https://testnet.bscscan.com/address' , 99 : 'https://blockscout.com/poa/core/address' , 100 : 'https://blockscout.com/poa/xdai/address' , 137 : 'https://explorer-mainnet.maticvigil.com/address' , 10000 : 'https://smartscan.cash/address' , 42161 : 'https://arbiscan.io/address' , 43113 : 'https://cchain.explorer.avax-test.network/address' , 43114 : 'https://cchain.explorer.avax.network/address' , 80001 : 'https://explorer-mumbai.maticvigil.com/address' } ; return mapping [ chainId ] ; } export function getTrustWalletName ( chainId ) { const mapping = { 1 : 'ethereum' , 56 : 'smartchain' , 61 : 'classic' , } ; return mapping [ chainId ] ; } export function getDappListName ( chainId ) { const mapping = { 1 : 'ethereum' , 56 : 'smartchain' , 100 : 'xdai' , 137 : 'matic' , 10000 : 'smartbch' , 42161 : 'arbitrum' , 43114 : 'avalanche' , } ; return mapping [ chainId ] ; } export function isSupportedNetwork ( chainId ) { const supportedNetworks = [ 1 , 3 , 4 , 5 , 42 , 100 , 10000 , 42161 , 43113 , 43114 ] ; return supportedNetworks . includes ( chainId ) ; } export async function getFullTokenMapping ( chainId ) { const erc20Mapping = await getTokenMapping ( chainId , 'ERC20' ) ; const erc721Mapping = await getTokenMapping ( chainId , 'ERC721' ) ; if ( erc20Mapping === undefined && erc721Mapping === undefined ) return undefined ; const fullMapping = { ... erc721Mapping , ... erc20Mapping } ; return fullMapping ; } async function getTokenMapping ( chainId , standard = 'ERC20' ) { const url = getTokenListUrl ( chainId , standard ) ; if ( ! url ) return undefined ; try { const res = await axios . get ( url ) ; const tokens = res . data . tokens ; const tokenMapping = { } ; for ( const token of tokens ) { tokenMapping [ getAddress ( token . address ) ] = token ; } return tokenMapping ; } catch { return undefined ; } } function getTokenListUrl ( chainId , standard = 'ERC20' ) { const mapping = { ERC20 : { 1 : 'https://tokens.1inch.eth.link/' , 10 : 'https://static.optimism.io/optimism.tokenlist.json' , 56 : 'https://raw.githubusercontent.com/pancakeswap/pancake-swap-interface/master/src/constants/token/pancakeswap.json' , 100 : 'https://tokens.honeyswap.org' , 137 : 'https://unpkg.com/quickswap-default-token-list@1.0.28/build/quickswap-default.tokenlist.json' , 42161 : 'https://bridge.arbitrum.io/token-list-42161.json' , 43114 : 'https://raw.githubusercontent.com/pangolindex/tokenlists/main/aeb.tokenlist.json' } , ERC721 : { 1 : 'https://raw.githubusercontent.com/vasa-develop/nft-tokenlist/master/mainnet_curated_tokens.json' } } ; return mapping [ standard ] [ chainId ] ; } export async function getTokenIcon ( tokenAddress , chainId , tokenMapping = { } ) { const normalisedAddress = getAddress ( tokenAddress ) ; const tokenData = tokenMapping [ normalisedAddress ] ; const iconFromMapping = ! tokenData ?. logoURI ?. startsWith ( '/' ) && tokenData ?. logoURI ; const networkName = getTrustWalletName ( chainId ) ; const iconFromTrust = networkName && `${ TRUSTWALLET_BASE_URL }/${ networkName }/assets/${ normalisedAddress }/logo.png` ; const icon = iconFromMapping || iconFromTrust || 'erc20.png' ; return icon ; } export function toFloat ( n , decimals ) { return ( n / ( 10 ** decimals ) ) . toFixed ( 3 ) ; } export function fromFloat ( floatString , decimals ) { const sides = floatString . split ( '.' ) ; if ( sides . length === 1 ) return floatString . padEnd ( decimals + floatString . length , '0' ) ; if ( sides . length > 2 ) return '0' ; return sides [ 1 ] . length > decimals ? sides [ 0 ] + sides [ 1 ] . slice ( 0 , decimals ) : sides [ 0 ] + sides [ 1 ] . padEnd ( decimals , '0' ) ; } export const unpackResult = async ( promise ) => ( await promise ) [ 0 ] ; export const withFallback = async ( promise , fallback ) => { try { return await promise ; } catch { return fallback ; } } ; export const emitAnalyticsEvent = ( eventName ) => { if ( window && ( window as any ) . sa_event ) { ( window as any ) . sa_event ( eventName ) ; } } ;