diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fc72752..c697d73 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,7 +6,7 @@ on: pull_request: branches: [ master ] schedule: - - cron: "42 6 * * 0" + - cron: "41 6 * * 0" jobs: build: @@ -23,10 +23,11 @@ jobs: - name: Test env: ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} + NETWORKS: ${{ secrets.NETWORKS }} run: go test -v -coverprofile=coverage.txt -covermode=count ./... - name: Codecov uses: codecov/codecov-action@v2.1.0 - name: golangci-lint - uses: golangci/golangci-lint-action@v2 \ No newline at end of file + uses: golangci/golangci-lint-action@v2 diff --git a/README.md b/README.md index 56acd1f..17163a8 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ -**English** | [中文](https://github.com/nanmu42/etherscan-api/blob/master/README_ZH.md) +**English** | [中文](https://github.com/uded/etherscan-api/blob/master/README_ZH.md) # etherscan-api -[![GoDoc](https://godoc.org/github.com/nanmu42/etherscan-api?status.svg)](https://godoc.org/github.com/nanmu42/etherscan-api) -[![CI status](https://github.com/nanmu42/etherscan-api/actions/workflows/ci.yaml/badge.svg)](https://github.com/nanmu42/etherscan-api/actions) -[![codecov](https://codecov.io/gh/nanmu42/etherscan-api/branch/master/graph/badge.svg)](https://codecov.io/gh/nanmu42/etherscan-api) -[![Go Report Card](https://goreportcard.com/badge/github.com/nanmu42/etherscan-api)](https://goreportcard.com/report/github.com/nanmu42/etherscan-api) +[![GoDoc](https://godoc.org/github.com/uded/etherscan-api?status.svg)](https://godoc.org/github.com/uded/etherscan-api) +[![CI status](https://github.com/uded/etherscan-api/actions/workflows/ci.yaml/badge.svg)](https://github.com/uded/etherscan-api/actions) +[![codecov](https://codecov.io/gh/uded/etherscan-api/branch/master/graph/badge.svg?token=2OFgDXhVM0)](https://codecov.io/gh/uded/etherscan-api) +[![Go Report Card](https://goreportcard.com/badge/github.com/uded/etherscan-api)](https://goreportcard.com/report/github.com/uded/etherscan-api) Golang client for the Etherscan.io API(and its families like BscScan), with nearly full implementation(accounts, transactions, tokens, contracts, blocks, stats), full network support(Mainnet, Ropsten, Kovan, Rinkby, Goerli, Tobalaba), and only depending on standard library. :wink: # Usage ```bash -go get github.com/nanmu42/etherscan-api +go get github.com/uded/etherscan-api ``` Create an API instance and off you go. :rocket: ```go import ( - "github.com/nanmu42/etherscan-api" + "github.com/uded/etherscan-api" "fmt" ) @@ -61,7 +61,7 @@ func main() { } ``` -You may find full method list at [GoDoc](https://godoc.org/github.com/nanmu42/etherscan-api). +You may find full method list at [GoDoc](https://godoc.org/github.com/uded/etherscan-api). # Etherscan API Key diff --git a/README_ZH.md b/README_ZH.md index 905a770..0a9fd0b 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -2,10 +2,10 @@ # etherscan-api -[![GoDoc](https://godoc.org/github.com/nanmu42/etherscan-api?status.svg)](https://godoc.org/github.com/nanmu42/etherscan-api) -[![CI status](https://github.com/nanmu42/etherscan-api/actions/workflows/ci.yaml/badge.svg)](https://github.com/nanmu42/etherscan-api/actions) -[![codecov](https://codecov.io/gh/nanmu42/etherscan-api/branch/master/graph/badge.svg)](https://codecov.io/gh/nanmu42/etherscan-api) -[![Go Report Card](https://goreportcard.com/badge/github.com/nanmu42/etherscan-api)](https://goreportcard.com/report/github.com/nanmu42/etherscan-api) +[![GoDoc](https://godoc.org/github.com/uded/etherscan-api?status.svg)](https://godoc.org/github.com/uded/etherscan-api) +[![CI status](https://github.com/uded/etherscan-api/actions/workflows/ci.yaml/badge.svg)](https://github.com/uded/etherscan-api/actions) +[![codecov](https://codecov.io/gh/uded/etherscan-api/branch/master/graph/badge.svg?token=2OFgDXhVM0)](https://codecov.io/gh/uded/etherscan-api) +[![Go Report Card](https://goreportcard.com/badge/github.com/uded/etherscan-api)](https://goreportcard.com/report/github.com/uded/etherscan-api) Etherscan API的Golang客户端, 支持几乎所有功能(accounts, transactions, tokens, contracts, blocks, stats), @@ -15,14 +15,14 @@ Etherscan API的Golang客户端, # 使用方法 ```bash -go get github.com/nanmu42/etherscan-api +go get github.com/uded/etherscan-api ``` 填入网络选项和API Key即可开始使用。 :rocket: ```go import ( - "github.com/nanmu42/etherscan-api" + "github.com/uded/etherscan-api" "fmt" ) @@ -63,7 +63,7 @@ func main() { } ``` -客户端方法列表可在[GoDoc](https://godoc.org/github.com/nanmu42/etherscan-api)查询。 +客户端方法列表可在[GoDoc](https://godoc.org/github.com/uded/etherscan-api)查询。 # Etherscan API Key @@ -80,4 +80,4 @@ API的调用速率不能高于5次/秒,否则会遭到封禁。 MIT -请自由享受开源,欢迎贡献开源。 \ No newline at end of file +请自由享受开源,欢迎贡献开源。 diff --git a/block_e2e_test.go b/block_e2e_test.go index c49a8ac..f907748 100644 --- a/block_e2e_test.go +++ b/block_e2e_test.go @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 LI Zhennan + * Copyright (c) 2022 Łukasz Rżanek * * Use of this work is governed by a MIT License. * You may find a license copy in project root. @@ -10,37 +11,79 @@ package etherscan import ( "encoding/json" "testing" + + "github.com/stretchr/testify/assert" ) func TestClient_BlockReward(t *testing.T) { - const ans = `{"blockNumber":"2165403","timeStamp":"1472533979","blockMiner":"0x13a06d3dfe21e0db5c016c03ea7d2509f7f8d1e3","blockReward":"5314181600000000000","uncles":[{"miner":"0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1","unclePosition":"0","blockreward":"3750000000000000000"},{"miner":"0x0d0c9855c722ff0c78f21e43aa275a5b8ea60dce","unclePosition":"1","blockreward":"3750000000000000000"}],"uncleInclusionReward":"312500000000000000"}` + const ( + ethAns = `{"blockNumber":"2165403","timeStamp":"1472533979","blockMiner":"0x13a06d3dfe21e0db5c016c03ea7d2509f7f8d1e3","blockReward":"5314181600000000000","uncles":[{"miner":"0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1","unclePosition":"0","blockreward":"3750000000000000000"},{"miner":"0x0d0c9855c722ff0c78f21e43aa275a5b8ea60dce","unclePosition":"1","blockreward":"3750000000000000000"}],"uncleInclusionReward":"312500000000000000"}` + maticAns = `{"blockNumber":"2165403","timeStamp":"1595322344","blockMiner":"0x0375b2fc7140977c9c76d45421564e354ed42277","blockReward":"0","uncles":[],"uncleInclusionReward":"0"}` + bscAns = `{"blockNumber":"2165403","timeStamp":"1605169045","blockMiner":"0x78f3adfc719c99674c072166708589033e2d9afe","blockReward":"0","uncles":[],"uncleInclusionReward":"0"}` + avaxAns = `{"blockNumber":"2165403","timeStamp":"1622557183","blockMiner":"0x0100000000000000000000000000000000000000","blockReward":"7963290000000000","uncles":[],"uncleInclusionReward":"0"}` + ftmAns = `{"blockNumber":"2165403","timeStamp":"1612983193","blockMiner":"0x0000000000000000000000000000000000000000","blockReward":"5225066000000000","uncles":[],"uncleInclusionReward":"0"}` + cronosAns = `{"blockNumber":"2165403","timeStamp":"1648843458","blockMiner":"0x4f87a3f99bd1e58d01de1c38b7f83cb967e816c2","blockReward":"49532402000000000000","uncles":[],"uncleInclusionReward":"0"}` + arbitrumAns = `{"blockNumber":"2165403","timeStamp":"1634069963","blockMiner":"0x0000000000000000000000000000000000000000","blockReward":"2065103660121552","uncles":[],"uncleInclusionReward":"0"}` + ) - reward, err := api.BlockReward(2165403) - noError(t, err, "api.BlockReward") + type Data struct { + BlockNumber int + Ans string + } - j, err := json.Marshal(reward) - noError(t, err, "json.Marshal") - if string(j) != ans { - t.Errorf("api.BlockReward not working, got %s, want %s", j, ans) + testData := map[string]Data{ + EthMainnet.CommonName: {2165403, ethAns}, + MaticMainnet.CommonName: {2165403, maticAns}, + BscMainnet.CommonName: {2165403, bscAns}, + AvaxMainnet.CommonName: {2165403, avaxAns}, + FantomMainnet.CommonName: {2165403, ftmAns}, + CronosMainnet.CommonName: {2165403, cronosAns}, + ArbitrumMainnet.CommonName: {2165403, arbitrumAns}, + } + + for _, network := range TestNetworks { + if td, ok := testData[network.Network.CommonName]; ok { + t.Run(network.Network.Name, func(t *testing.T) { + reward, err := network.client.BlockReward(td.BlockNumber) + assert.NoError(t, err) + + j, err := json.Marshal(reward) + assert.NoError(t, err) + assert.Equalf(t, td.Ans, string(j), "api.BlockReward not working, got %s, want %s", j, ethAns) + }) + } } } func TestClient_BlockNumber(t *testing.T) { - // Note: All values taken from docs.etherscan.io/api-endpoints/blocks - const ansBefore = 9251482 - const ansAfter = 9251483 - - blockNumber, err := api.BlockNumber(1578638524, "before") - noError(t, err, "api.BlockNumber") + type Data struct { + Timestamp int64 + AnsBefore int + AnsAfter int + } - if blockNumber != ansBefore { - t.Errorf(`api.BlockNumber(1578638524, "before") not working, got %d, want %d`, blockNumber, ansBefore) + testData := map[string]Data{ + // Note: All values taken from docs.etherscan.io/api-endpoints/blocks + EthMainnet.CommonName: {1578638524, 9251482, 9251483}, + MaticMainnet.CommonName: {1601510400, 5164199, 5164200}, + BscMainnet.CommonName: {1601510400, 946206, 946207}, + AvaxMainnet.CommonName: {1609455600, 18960, 18961}, + FantomMainnet.CommonName: {1609455600, 1632921, 1632921}, // it is the same! + CronosMainnet.CommonName: {1654034400, 3023556, 3023557}, + ArbitrumMainnet.CommonName: {1656626400, 16655953, 16655954}, } - blockNumber, err = api.BlockNumber(1578638524, "after") - noError(t, err, "api.BlockNumber") + for _, network := range TestNetworks { + if td, ok := testData[network.Network.CommonName]; ok { + t.Run(network.Network.Name, func(t *testing.T) { + blockNumber, err := network.client.BlockNumber(td.Timestamp, "before") + assert.NoError(t, err) + assert.Equalf(t, td.AnsBefore, blockNumber, `api.BlockNumber(%d, "before") not working, got %d, want %d`, td.Timestamp, blockNumber, td.AnsBefore) - if blockNumber != ansAfter { - t.Errorf(`api.BlockNumber(1578638524,"after") not working, got %d, want %d`, blockNumber, ansAfter) + blockNumber, err = network.client.BlockNumber(td.Timestamp, "after") + assert.NoError(t, err) + assert.Equalf(t, td.AnsAfter, blockNumber, `api.BlockNumber(%d, "after") not working, got %d, want %d`, td.Timestamp, blockNumber, td.AnsAfter) + }) + } } } diff --git a/client.go b/client.go index 950c532..5e95a68 100644 --- a/client.go +++ b/client.go @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 LI Zhennan + * Copyright (c) 2022 Łukasz Rżanek * * Use of this work is governed by a MIT License. * You may find a license copy in project root. @@ -48,7 +49,7 @@ func New(network Network, APIKey string) *Client { return NewCustomized(Customization{ Timeout: 30 * time.Second, Key: APIKey, - BaseURL: network.Domain(), + Network: &network, }) } @@ -60,6 +61,8 @@ type Customization struct { Key string // Base URL like `https://api.etherscan.io/api?` BaseURL string + // Network + Network *Network // When true, talks a lot Verbose bool // HTTP Client to be used. Specifying this value will ignore the Timeout value set @@ -86,8 +89,12 @@ func NewCustomized(config Customization) *Client { Timeout: config.Timeout, } } + if config.Network != nil { + config.BaseURL = config.Network.baseURL + } return &Client{ coon: httpClient, + network: *config.Network, key: config.Key, baseURL: config.BaseURL, Verbose: config.Verbose, diff --git a/go.mod b/go.mod index d00d41d..8defbc1 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,13 @@ module github.com/uded/etherscan-api go 1.18 -require github.com/google/go-cmp v0.5.7 +require ( + github.com/google/go-cmp v0.5.7 + github.com/stretchr/testify v1.8.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index a6ca3a4..e51298d 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,19 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/network.go b/network.go index dbd61fb..b90c91a 100644 --- a/network.go +++ b/network.go @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 LI Zhennan + * Copyright (c) 2022 Łukasz Rżanek * * Use of this work is governed by a MIT License. * You may find a license copy in project root. @@ -14,41 +15,45 @@ import ( var ( // EthMainnet Ethereum mainnet for production - EthMainnet Network = Network{"Ethereum", "eth_main", "main", "https://api.etherscan.io/api?"} + EthMainnet Network = Network{"Ethereum", "eth_main", "ETH", "https://api.etherscan.io/api?", "0x1", 1} // EthRopsten Testnet(POW) - EthRopsten Network = Network{"Ethereum Ropsten", "eth_ropsten", "test", "https://api-ropsten.etherscan.io/api?"} + EthRopsten Network = Network{"Ethereum Ropsten", "eth_ropsten", "ETH", "https://api-ropsten.etherscan.io/api?", "0x3", 3} // EthKovan Testnet(POA) - EthKovan Network = Network{"Ethereum Kovan", "eth_kovan", "test", "https://api-kovan.etherscan.io/api?"} + EthKovan Network = Network{"Ethereum Kovan", "eth_kovan", "ETH", "https://api-kovan.etherscan.io/api?", "0x2a", 42} // EthRinkby Testnet(CLIQUE) - EthRinkby Network = Network{"Ethereum Rinkby", "eth_rinkeby", "test", "https://api-rinkeby.etherscan.io/api?"} + EthRinkby Network = Network{"Ethereum Rinkby", "eth_rinkeby", "ETH", "https://api-rinkeby.etherscan.io/api?", "0x4", 4} // EthGoerli Testnet(CLIQUE) - EthGoerli Network = Network{"Ethereum Goerli", "eth_goerli", "test", "https://api-goerli.etherscan.io/api?"} + EthGoerli Network = Network{"Ethereum Goerli", "eth_goerli", "ETH", "https://api-goerli.etherscan.io/api?", "0x5", 5} // EthTobalaba Testnet - EthTobalaba Network = Network{"Ethereum Tobalaba", "eth_tobalaba", "test", "https://api-tobalaba.etherscan.io/api?"} + EthTobalaba Network = Network{"Ethereum Tobalaba", "eth_tobalaba", "ETH", "https://api-tobalaba.etherscan.io/api?", "0x0", 0} // MaticMainnet Matic mainnet for production - MaticMainnet Network = Network{"Polygon", "polygon", "main", "https://api.polygonscan.com/api?"} + MaticMainnet Network = Network{"Polygon", "polygon", "MATIC", "https://api.polygonscan.com/api?", "0x89", 137} // MaticTestnet Matic testnet for development - MaticTestnet Network = Network{"Polygon Mumbai", "polygon_mumbai", "test", "https://api-testnet.polygonscan.com/api?"} + MaticTestnet Network = Network{"Polygon Mumbai", "polygon_mumbai", "MATIC", "https://api-testnet.polygonscan.com/api?", "0x13881", 80001} // BscMainnet Bsc mainnet for production - BscMainnet Network = Network{"Binance", "bsc", "main", "https://api.bscscan.com/api?"} + BscMainnet Network = Network{"Binance", "bsc", "BNB", "https://api.bscscan.com/api?", "0x38", 56} // BscTestnet Bsc testnet for development - BscTestnet Network = Network{"Binance test", "bsc_test", "test", "https://api-testnet.bscscan.com/api?"} + BscTestnet Network = Network{"Binance test", "bsc_test", "BNB", "https://api-testnet.bscscan.com/api?", "0x61", 97} // AvaxMainnet Avalanche mainnet for production - AvaxMainnet Network = Network{"Avax", "avax", "main", "https://api.snowtrace.io/api?"} + AvaxMainnet Network = Network{"Avax", "avax", "AVAX", "https://api.snowtrace.io/api?", "0xa86a", 43114} // AvaxTestnet Avalanche testnet for development - AvaxTestnet Network = Network{"Avax test", "avax_test", "test", "https://api-testnet.snowtrace.io/api?"} - // Fantom mainnet for production - FantomMainnet Network = Network{"Fantom", "fantom", "main", "https://api.ftmscan.com/api?"} - // FantomTestNet - FantomTestnet Network = Network{"Fantom test", "fantom_test", "test", "https://api-testnet.ftmscan.com/api?"} + AvaxTestnet Network = Network{"Avax test", "avax_test", "AVAX", "https://api-testnet.snowtrace.io/api?", "0xa869", 43113} + // FantomMainnet for production + FantomMainnet Network = Network{"Fantom", "fantom", "FTM", "htstps://api.ftmscan.com/api?", "0xfa", 250} + // FantomTestnet + FantomTestnet Network = Network{"Fantom test", "fantom_test", "FTM", "https://api-testnet.ftmscan.com/api?", "0x0", 0} // Cronos mainnet for production - CronosMainnet Network = Network{"Cronos", "cronos", "main", "https://api.cronoscan.com/api?"} + CronosMainnet Network = Network{"Cronos", "cronos", "CRO", "https://api.cronoscan.com/api?", "0x19", 25} // Cronos test net - CronosTestnet Network = Network{"Cronos test", "cronos_test", "test", "https://api-testnet.cronoscan.com/api?"} + CronosTestnet Network = Network{"Cronos test", "cronos_test", "CRO", "https://api-testnet.cronoscan.com/api?", "0x152", 338} // Arbitrum mainnet for production - ArbitrumMainnet Network = Network{"Arbitrum", "arbitrum", "main", "https://api.arbiscan.io/api?"} + ArbitrumMainnet Network = Network{"Arbitrum", "arbitrum", "ETH", "https://api.arbiscan.io/api?", "0x0", 0} // Arbitrum test net - ArbitrumTestnet Network = Network{"Arbitrum test", "arbitrum_test", "test", "https://api-testnet.arbiscan.io/"} + ArbitrumTestnet Network = Network{"Arbitrum test", "arbitrum_test", "ETH", "https://api-testnet.arbiscan.io/", "0x0", 0} + // Optimism mainnet for production + OptimismMainnet Network = Network{"Optimsm", "optimism", "ETH", "https://api-optimistic.etherscan.io/", "0xa", 10} + // Optimism test net + OptimismTestnet Network = Network{"Optimism Goerli", "optimism_test", "ETH", "https://api-goerli-optimistic.etherscan.io/", "", 420} networks = map[string]*Network{ EthMainnet.Name: &EthMainnet, @@ -76,6 +81,7 @@ var ( MaticMainnet.CommonName: &MaticMainnet, "maticmainnet": &MaticMainnet, "polygon": &MaticMainnet, + "polygon-pos": &MaticMainnet, "matic": &MaticMainnet, MaticTestnet.Name: &MaticTestnet, MaticTestnet.CommonName: &MaticTestnet, @@ -85,6 +91,7 @@ var ( BscMainnet.CommonName: &BscMainnet, "bscmainnet": &BscMainnet, "binance": &BscMainnet, + "binance-smart-chain": &BscMainnet, BscTestnet.Name: &BscTestnet, BscTestnet.CommonName: &BscTestnet, "bsctestnet": &BscTestnet, @@ -122,6 +129,14 @@ var ( "arbitrumtest": &ArbitrumTestnet, "arbitrumtestnet": &ArbitrumTestnet, "arbitrum_rinkeby": &ArbitrumTestnet, + OptimismMainnet.Name: &OptimismMainnet, + OptimismMainnet.CommonName: &OptimismMainnet, + OptimismTestnet.Name: &OptimismTestnet, + OptimismTestnet.CommonName: &OptimismTestnet, + "optimismtest": &OptimismTestnet, + "optimismtestnet": &OptimismTestnet, + "optimism_goerli": &OptimismTestnet, + "optimismgoerli": &OptimismTestnet, } networkNames []string @@ -137,8 +152,10 @@ func init() { type Network struct { Name string // Name of the network or chain CommonName string // CommonName of the network or chain - Type string // Type of the network, either main or test + TokenName string // TokenName of the network baseURL string // baseURL for the API client + ChainIDHex string // ChainIDHex for identifing the chain + ChainID int // ChainID for identyfing the chain } // Domain returns the subdomain of etherscan API via n provided. @@ -150,7 +167,7 @@ func ParseNetworkName(network string) (Network, error) { if x, ok := networks[network]; ok { return *x, nil } - // Case insensitive parse, do a separate lookup to prevent unnecessary cost of lowercasing a string if we don't need to. + // Case-insensitive parse, do a separate lookup to prevent unnecessary cost of lowercasing a string if we don't need to. if x, ok := networks[strings.ToLower(network)]; ok { return *x, nil }