Skip to content

Free Gas Tracker Endpoints #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions gas_tracker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2022 Avi Misra
*
* Use of this work is governed by a MIT License.
* You may find a license copy in project root.
*/

package etherscan

import "time"

// GasEstiamte gets estiamted confirmation time (in seconds) at the given gas price
func (c *Client) GasEstimate(gasPrice int) (confirmationTimeInSec time.Duration, err error) {
params := M{"gasPrice": gasPrice}
var confTime string
err = c.call("gastracker", "gasestimate", params, &confTime)
if err != nil {
return
}
return time.ParseDuration(confTime + "s")
}

// GasOracle gets suggested gas prices (in Gwei)
func (c *Client) GasOracle() (gasPrices GasPrices, err error) {
err = c.call("gastracker", "gasoracle", M{}, &gasPrices)
return
}
29 changes: 29 additions & 0 deletions gas_tracker_e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018 LI Zhennan
*
* Use of this work is governed by a MIT License.
* You may find a license copy in project root.
*/

package etherscan

import (
"testing"
)

//GasEstiamte generates dynamic data. Best we can do is ensure all fields are populated
func TestClient_GasEstimate(t *testing.T) {
_, err := api.GasEstimate(20000000)
noError(t, err, "api.GasEstimate")
}

//GasOracle generates dynamic data. Best we can do is ensure all fields are populated
func TestClient_GasOracle(t *testing.T) {
gasPrice, err := api.GasOracle()
noError(t, err, "api.GasOrcale")

if 0 == len(gasPrice.GasUsedRatio) {
t.Errorf("gasPrice.GasUsedRatio empty")
}

}
69 changes: 68 additions & 1 deletion response.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@

package etherscan

import "encoding/json"
import (
"encoding/json"
"fmt"
"strconv"
"strings"
)

// Envelope is the carrier of nearly every response
type Envelope struct {
Expand Down Expand Up @@ -175,3 +180,65 @@ type Log struct {
Removed bool `json:"removed"`
}

//GasPrices holds info for Gas Oracle queries
//Gas Prices are returned in Gwei
type GasPrices struct {
LastBlock int
SafeGasPrice float64
ProposeGasPrice float64
FastGasPrice float64
SuggestBaseFeeInGwei float64 `json:"suggestBaseFee"`
GasUsedRatio []float64 `json:"gasUsedRatio"`
}

func (gp *GasPrices) UnmarshalJSON(data []byte) error {
_gp := struct {
LastBlock string
SafeGasPrice string
ProposeGasPrice string
FastGasPrice string
SuggestBaseFeeInGwei string `json:"suggestBaseFee"`
GasUsedRatio string `json:"gasUsedRatio"`
}{}

err := json.Unmarshal(data, &_gp)
if err != nil {
return err
}

gp.LastBlock, err = strconv.Atoi(_gp.LastBlock)
if err != nil {
return fmt.Errorf("Unable to convert LastBlock %s to int: %w", _gp.LastBlock, err)
}

gp.SafeGasPrice, err = strconv.ParseFloat(_gp.SafeGasPrice, 64)
if err != nil {
return fmt.Errorf("Unable to convert SafeGasPrice %s to float64: %w", _gp.SafeGasPrice, err)
}

gp.ProposeGasPrice, err = strconv.ParseFloat(_gp.ProposeGasPrice, 64)
if err != nil {
return fmt.Errorf("Unable to convert ProposeGasPrice %s to float64: %w", _gp.ProposeGasPrice, err)
}

gp.FastGasPrice, err = strconv.ParseFloat(_gp.FastGasPrice, 64)
if err != nil {
return fmt.Errorf("Unable to convert FastGasPrice %s to float64: %w", _gp.FastGasPrice, err)
}

gp.SuggestBaseFeeInGwei, err = strconv.ParseFloat(_gp.SuggestBaseFeeInGwei, 64)
if err != nil {
return fmt.Errorf("Unable to convert SuggestBaseFeeInGwei %s to float64: %w", _gp.SuggestBaseFeeInGwei, err)
}

gasRatios := strings.Split(_gp.GasUsedRatio, ",")
gp.GasUsedRatio = make([]float64, len(gasRatios))
for i, gasRatio := range gasRatios {
gp.GasUsedRatio[i], err = strconv.ParseFloat(gasRatio, 64)
if err != nil {
return fmt.Errorf("Unable to convert gasRatio %s to float64: %w", gasRatio, err)
}
}

return nil
}