github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/etherman/etherscan/etherscan.go (about) 1 package etherscan 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "math/big" 9 "net/http" 10 11 "github.com/0xPolygon/supernets2-node/encoding" 12 ) 13 14 type etherscanResponse struct { 15 Status string `json:"status"` 16 Message string `json:"message"` 17 Result gasPriceEtherscan `json:"result"` 18 } 19 20 // gasPriceEtherscan definition 21 type gasPriceEtherscan struct { 22 LastBlock string `json:"LastBlock"` 23 SafeGasPrice string `json:"SafeGasPrice"` 24 ProposeGasPrice string `json:"ProposeGasPrice"` 25 FastGasPrice string `json:"FastGasPrice"` 26 } 27 28 // Config structure 29 type Config struct { 30 ApiKey string `mapstructure:"ApiKey"` 31 Url string 32 } 33 34 // Client for etherscan 35 type Client struct { 36 config Config 37 Http http.Client 38 } 39 40 // NewEtherscanService is the constructor that creates an etherscanService 41 func NewEtherscanService(apikey string) *Client { 42 const url = "https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=" 43 return &Client{ 44 config: Config{ 45 Url: url, 46 ApiKey: apikey, 47 }, 48 Http: http.Client{}, 49 } 50 } 51 52 // SuggestGasPrice retrieves the gas price estimation from etherscan 53 func (e *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) { 54 var resBody etherscanResponse 55 url := e.config.Url + e.config.ApiKey 56 res, err := e.Http.Get(url) 57 if err != nil { 58 return big.NewInt(0), err 59 } 60 defer res.Body.Close() 61 body, err := io.ReadAll(res.Body) 62 if err != nil { 63 return big.NewInt(0), err 64 } 65 if res.StatusCode != http.StatusOK { 66 return big.NewInt(0), fmt.Errorf("http response is %d", res.StatusCode) 67 } 68 // Unmarshal result 69 err = json.Unmarshal(body, &resBody) 70 if err != nil { 71 return big.NewInt(0), fmt.Errorf("Reading body failed: %w", err) 72 } 73 fgp, _ := big.NewInt(0).SetString(resBody.Result.FastGasPrice, encoding.Base10) 74 return new(big.Int).Mul(fgp, big.NewInt(encoding.Gwei)), nil 75 }