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 }