From 6540bcf902a12e1c6f9c11b37f35afc69ed50835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 14 Jul 2022 00:18:57 +0200 Subject: [PATCH 1/9] ci: new env variable, cron change --- .github/workflows/ci.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 From c67b16f39bca58dcfe030d0a3f1f99fd450fc18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 14 Jul 2022 00:29:23 +0200 Subject: [PATCH 2/9] fix: changing package name in readme files --- README.md | 16 ++++++++-------- README_ZH.md | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) 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 +请自由享受开源,欢迎贡献开源。 From b2c73079eea5676771d80911486f02d750ce780e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 14 Jul 2022 00:30:34 +0200 Subject: [PATCH 3/9] feat: adding native token to network definition --- network.go | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/network.go b/network.go index dbd61fb..2edca6f 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,41 @@ 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?"} // 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?"} // 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?"} // 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?"} // 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?"} // 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?"} // 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?"} // 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", "C:\\Users\\lukas\\InfinityForceProjects\\etherscan-api\\network.go", "https://api-testnet.polygonscan.com/api?"} // 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?"} // 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?"} // 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?"} // AvaxTestnet Avalanche testnet for development - AvaxTestnet Network = Network{"Avax test", "avax_test", "test", "https://api-testnet.snowtrace.io/api?"} + AvaxTestnet Network = Network{"Avax test", "avax_test", "AVAX", "https://api-testnet.snowtrace.io/api?"} // Fantom mainnet for production - FantomMainnet Network = Network{"Fantom", "fantom", "main", "https://api.ftmscan.com/api?"} + FantomMainnet Network = Network{"Fantom", "fantom", "FTM", "https://api.ftmscan.com/api?"} // FantomTestNet - FantomTestnet Network = Network{"Fantom test", "fantom_test", "test", "https://api-testnet.ftmscan.com/api?"} + FantomTestnet Network = Network{"Fantom test", "fantom_test", "FTM", "https://api-testnet.ftmscan.com/api?"} // 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?"} // 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?"} // 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?"} // 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/"} networks = map[string]*Network{ EthMainnet.Name: &EthMainnet, @@ -137,7 +138,7 @@ 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 } From 77c08f26cd982101bd8d031174eb137f5a78c759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 14 Jul 2022 02:48:23 +0200 Subject: [PATCH 4/9] test(block): testing all available networks --- block_e2e_test.go | 81 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 19 deletions(-) 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) + }) + } } } From fb9d13c704d9dbd91bdcde5daf568b83f606f0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 22 Sep 2022 00:54:13 +0200 Subject: [PATCH 5/9] fix: unhandled network in client creation --- client.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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, From f0adf38eb88f0af91742cbe3438988766b99d20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 22 Sep 2022 01:26:04 +0200 Subject: [PATCH 6/9] fix: incorrect token name for polygon mumbai --- network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network.go b/network.go index 2edca6f..3cb796e 100644 --- a/network.go +++ b/network.go @@ -29,7 +29,7 @@ var ( // MaticMainnet Matic mainnet for production MaticMainnet Network = Network{"Polygon", "polygon", "MATIC", "https://api.polygonscan.com/api?"} // MaticTestnet Matic testnet for development - MaticTestnet Network = Network{"Polygon Mumbai", "polygon_mumbai", "C:\\Users\\lukas\\InfinityForceProjects\\etherscan-api\\network.go", "https://api-testnet.polygonscan.com/api?"} + MaticTestnet Network = Network{"Polygon Mumbai", "polygon_mumbai", "MATIC", "https://api-testnet.polygonscan.com/api?"} // BscMainnet Bsc mainnet for production BscMainnet Network = Network{"Binance", "bsc", "BNB", "https://api.bscscan.com/api?"} // BscTestnet Bsc testnet for development From a7f7b2921c7a102a401cd6d725500cef1209256b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Thu, 13 Oct 2022 03:14:25 +0200 Subject: [PATCH 7/9] feat: adding network id by hex and int --- network.go | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/network.go b/network.go index 3cb796e..d5ff18b 100644 --- a/network.go +++ b/network.go @@ -15,41 +15,41 @@ import ( var ( // EthMainnet Ethereum mainnet for production - EthMainnet Network = Network{"Ethereum", "eth_main", "ETH", "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", "ETH", "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", "ETH", "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", "ETH", "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", "ETH", "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", "ETH", "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", "MATIC", "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", "MATIC", "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", "BNB", "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", "BNB", "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", "AVAX", "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", "AVAX", "https://api-testnet.snowtrace.io/api?"} + AvaxTestnet Network = Network{"Avax test", "avax_test", "AVAX", "https://api-testnet.snowtrace.io/api?", "0xa869", 43113} // Fantom mainnet for production - FantomMainnet Network = Network{"Fantom", "fantom", "FTM", "https://api.ftmscan.com/api?"} + FantomMainnet Network = Network{"Fantom", "fantom", "FTM", "https://api.ftmscan.com/api?", "0xfa", 250} // FantomTestNet - FantomTestnet Network = Network{"Fantom test", "fantom_test", "FTM", "https://api-testnet.ftmscan.com/api?"} + 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", "CRO", "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", "CRO", "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", "ETH", "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", "ETH", "https://api-testnet.arbiscan.io/"} + ArbitrumTestnet Network = Network{"Arbitrum test", "arbitrum_test", "ETH", "https://api-testnet.arbiscan.io/", "0x0", 0} networks = map[string]*Network{ EthMainnet.Name: &EthMainnet, @@ -140,6 +140,8 @@ type Network struct { CommonName string // CommonName of the network or chain 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. From 48ce92c9ac165488d2dcd0858c6ce258229ae675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Tue, 13 Dec 2022 14:02:59 +0100 Subject: [PATCH 8/9] feat: adding Optimism --- go.mod | 11 ++++++++++- go.sum | 15 +++++++++++++++ network.go | 14 +++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) 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 d5ff18b..04780dd 100644 --- a/network.go +++ b/network.go @@ -50,6 +50,10 @@ var ( ArbitrumMainnet Network = Network{"Arbitrum", "arbitrum", "ETH", "https://api.arbiscan.io/api?", "0x0", 0} // Arbitrum test net 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, @@ -123,6 +127,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 @@ -153,7 +165,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 } From 233e7e6104ea0ff8a0530f9ec43e9b40d27f1bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20R=C5=BCanek?= Date: Tue, 31 Jan 2023 08:36:01 +0100 Subject: [PATCH 9/9] feat: additional names to reflect coingecko naming --- network.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/network.go b/network.go index 04780dd..b90c91a 100644 --- a/network.go +++ b/network.go @@ -38,9 +38,9 @@ var ( 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", "AVAX", "https://api-testnet.snowtrace.io/api?", "0xa869", 43113} - // Fantom mainnet for production - FantomMainnet Network = Network{"Fantom", "fantom", "FTM", "https://api.ftmscan.com/api?", "0xfa", 250} - // FantomTestNet + // 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", "CRO", "https://api.cronoscan.com/api?", "0x19", 25} @@ -81,6 +81,7 @@ var ( MaticMainnet.CommonName: &MaticMainnet, "maticmainnet": &MaticMainnet, "polygon": &MaticMainnet, + "polygon-pos": &MaticMainnet, "matic": &MaticMainnet, MaticTestnet.Name: &MaticTestnet, MaticTestnet.CommonName: &MaticTestnet, @@ -90,6 +91,7 @@ var ( BscMainnet.CommonName: &BscMainnet, "bscmainnet": &BscMainnet, "binance": &BscMainnet, + "binance-smart-chain": &BscMainnet, BscTestnet.Name: &BscTestnet, BscTestnet.CommonName: &BscTestnet, "bsctestnet": &BscTestnet,