github.com/ethereum-optimism/optimism@v1.7.2/packages/core-utils/src/etherscan.ts (about)

     1  import fetch from 'node-fetch'
     2  
     3  interface NetworkData {
     4    chainId: number
     5    names: string[]
     6    etherscanApiUrl: string
     7  }
     8  
     9  const networks: {
    10    [id: number]: NetworkData
    11  } = {
    12    1: {
    13      chainId: 1,
    14      names: ['mainnet', 'main', 'eth', 'ethereum'],
    15      etherscanApiUrl: 'https://api.etherscan.io',
    16    },
    17    3: {
    18      chainId: 3,
    19      names: ['ropsten'],
    20      etherscanApiUrl: 'https://api-ropsten.etherscan.io',
    21    },
    22    4: {
    23      chainId: 4,
    24      names: ['rinkeby'],
    25      etherscanApiUrl: 'https://api-rinkeby.etherscan.io',
    26    },
    27    5: {
    28      chainId: 5,
    29      names: ['goerli'],
    30      etherscanApiUrl: 'https://api-goerli.etherscan.io',
    31    },
    32    10: {
    33      chainId: 10,
    34      names: ['optimism'],
    35      etherscanApiUrl: 'https://api-optimistic.etherscan.io',
    36    },
    37    42: {
    38      chainId: 42,
    39      names: ['kovan'],
    40      etherscanApiUrl: 'https://api-kovan.etherscan.io',
    41    },
    42    69: {
    43      chainId: 69,
    44      names: ['opkovan', 'kovan-optimism', 'optimistic-kovan'],
    45      etherscanApiUrl: 'https://api-kovan-optimistic.etherscan.io',
    46    },
    47  }
    48  
    49  export class Etherscan {
    50    net: NetworkData
    51  
    52    constructor(
    53      private readonly apiKey: string,
    54      private readonly network: string | number
    55    ) {
    56      if (typeof network === 'string') {
    57        this.net = Object.values(networks).find((net) => {
    58          return net.names.includes(network)
    59        })
    60      } else {
    61        this.net = networks[this.network]
    62      }
    63    }
    64  
    65    public async getContractSource(address: string): Promise<any> {
    66      const url = new URL(`${this.net.etherscanApiUrl}/api`)
    67      url.searchParams.append('module', 'contract')
    68      url.searchParams.append('action', 'getsourcecode')
    69      url.searchParams.append('address', address)
    70      url.searchParams.append('apikey', this.apiKey)
    71      const response = await fetch(url)
    72      const result = await response.json()
    73      return (result as { result: number[] }).result[0]
    74    }
    75  
    76    public async getContractABI(address: string): Promise<any> {
    77      const source = await this.getContractSource(address)
    78      if (source.Proxy === '1') {
    79        const impl = await this.getContractSource(source.Implementation)
    80        return impl.ABI
    81      } else {
    82        return source.ABI
    83      }
    84    }
    85  }