import { Account , EthereumProvider , ChainInformation } from './types' ; import { getChainInformation , getKnownChainsIds } from './chains' ; function isUnwrappedRpcResult ( response ) { return ( typeof response === 'object' && response !== null && 'jsonrpc' in response ) ; } const EXPLORER_URL_TYPES = new Map ( [ [ 'block' , 'block' ] , [ 'transaction' , 'tx' ] , [ 'address' , 'address' ] , [ 'token' , 'token' ] , ] ) ; export const blockExplorerUrl = ( type , value , chainId ) => { if ( ! getKnownChainsIds ( ) . includes ( chainId ) ) { return '' ; } if ( ! EXPLORER_URL_TYPES . has ( type ) ) { throw new Error ( 'type not supported.' ) ; } const domain = ( getChainInformation ( chainId ) as ChainInformation ) . explorerUrl ; const typePart = EXPLORER_URL_TYPES . get ( type ) ; return `${ domain }/${ typePart }/${ value }` ; } ; export function rpcResult ( response ) { if ( isUnwrappedRpcResult ( response ) ) { if ( response . error ) { throw new Error ( response . error ) ; } return response . result || null ; } return response || null ; } async function ethereumRequest ( ethereum , method , params ) { if ( ethereum . request ) { return ethereum . request ( { method , params } ) . then ( rpcResult ) ; } if ( ethereum . sendAsync && ethereum . selectedAddress ) { return new Promise ( ( resolve , reject ) => { ethereum . sendAsync ( { method , params , from : ethereum . selectedAddress , jsonrpc : '2.0' , id : 0 } , ( err , result ) => { if ( err ) { reject ( err ) ; } else { resolve ( result ) ; } } ) ; } ) . then ( rpcResult ) ; } if ( ethereum . send ) { return ethereum . send ( method , params ) . then ( rpcResult ) ; } throw new Error ( 'The Ethereum provider doesn’t seem to provide a request method.' ) ; } export async function getAccountIsContract ( ethereum , account ) { try { const code = await ethereumRequest ( ethereum , 'eth_getCode' , [ account ] ) ; return code !== '0x' ; } catch ( err ) { return false ; } } export async function getAccountBalance ( ethereum , account ) { return ethereumRequest ( ethereum , 'eth_getBalance' , [ account , 'latest' ] ) ; } export async function getBlockNumber ( ethereum ) { return ethereumRequest ( ethereum , 'eth_blockNumber' , [ ] ) ; } export function pollEvery < R , T > ( fn , delay ) { let timer ; let stop = false ; const poll = async ( request , onResult ) => { const result = await request ( ) ; if ( ! stop ) { onResult ( result ) ; timer = setTimeout ( poll . bind ( null , request , onResult ) , delay ) ; } } ; return ( ... params ) => { const { request , onResult } = fn ( ... params ) ; stop = false ; poll ( request , onResult ) ; return ( ) => { stop = true ; clearTimeout ( timer ) ; } ; } ; } const ACCOUNT_KEY = 'LAST_ACTIVE_ACCOUNT' ; const CONNECTOR_KEY = 'LAST_WALLET_CONNECTOR' ; export const setLastActiveAccount = ( account ) => { localStorage ?. setItem ( ACCOUNT_KEY , account ) ; } ; export const clearLastActiveAccount = ( ) => { localStorage ?. removeItem ( ACCOUNT_KEY ) ; } ; export const getLastActiveAccount = ( ) : Account | null => { return localStorage ?. getItem ( ACCOUNT_KEY ) ; } ; export const setLastConnector = ( connector ) => { localStorage ?. setItem ( CONNECTOR_KEY , connector ) ; } ; export const getLastConnector = ( ) : string | null => { return localStorage ?. getItem ( CONNECTOR_KEY ) ; } ;