Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 881be9b

Browse filesBrowse files
committed
add Client
1 parent 2d033f3 commit 881be9b
Copy full SHA for 881be9b

File tree

Expand file treeCollapse file tree

3 files changed

+137
-0
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+137
-0
lines changed

‎client.go

Copy file name to clipboard
+96Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package etherscan
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
)
9+
10+
type httpClient interface {
11+
Get(url string) (resp *http.Response, err error)
12+
}
13+
14+
type NetworkID = int
15+
16+
const (
17+
Mainnet = 1
18+
Rinkeby = 3
19+
20+
baseUrlMainnet = "https://api.etherscan.io/api"
21+
baseUrlRinkeby = "https://api-rinkeby.etherscan.io/api"
22+
)
23+
24+
type Client struct {
25+
c httpClient
26+
baseURL string
27+
apiKey string
28+
}
29+
30+
func NewClient(networkID NetworkID, apiKey string) (*Client, error) {
31+
url, err := urlByNetworkID(networkID)
32+
if err != nil {
33+
return nil, err
34+
}
35+
36+
return &Client{
37+
c: http.DefaultClient,
38+
baseURL: url,
39+
apiKey: apiKey,
40+
}, nil
41+
}
42+
43+
func (c *Client) Account(address string) (*AccountResponse, error) {
44+
params := map[string]string{
45+
"module": "account",
46+
"action": "balance",
47+
"address": address,
48+
"tag": "latest",
49+
}
50+
51+
resp, err := c.get(params)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
defer resp.Body.Close()
57+
58+
var accountResp AccountResponse
59+
60+
decoder := json.NewDecoder(resp.Body)
61+
err = decoder.Decode(&accountResp)
62+
63+
return &accountResp, err
64+
}
65+
66+
func (c *Client) get(params map[string]string) (*http.Response, error) {
67+
query := c.buildQuery(params)
68+
url, err := url.Parse(c.baseURL)
69+
if err != nil {
70+
return nil, err
71+
}
72+
73+
url.RawQuery = query
74+
resp, err := c.c.Get(url.String())
75+
if err != nil {
76+
return resp, err
77+
}
78+
79+
if resp.StatusCode < 200 || resp.StatusCode > 299 {
80+
resp.Body.Close()
81+
return resp, fmt.Errorf("bad status code %d", resp.StatusCode)
82+
}
83+
84+
return resp, nil
85+
}
86+
87+
func (c *Client) buildQuery(params map[string]string) string {
88+
v := url.Values{}
89+
for key, value := range params {
90+
v.Set(key, value)
91+
}
92+
93+
v.Set("apikey", c.apiKey)
94+
95+
return v.Encode()
96+
}

‎types.go

Copy file name to clipboard
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package etherscan
2+
3+
type AccountResponse struct {
4+
Status string `json:"status"`
5+
Message string `json:"message"`
6+
Result *BigInt `json:"result"`
7+
}

‎utils.go

Copy file name to clipboard
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package etherscan
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"math/big"
7+
)
8+
9+
type BigInt struct {
10+
big.Int
11+
}
12+
13+
func (bigint *BigInt) UnmarshalJSON(b []byte) error {
14+
var s string
15+
err := json.Unmarshal(b, &s)
16+
if err != nil {
17+
return err
18+
}
19+
20+
bigint.SetString(s, 10)
21+
22+
return nil
23+
}
24+
25+
func urlByNetworkID(id NetworkID) (string, error) {
26+
switch id {
27+
case Mainnet:
28+
return baseUrlMainnet, nil
29+
case Rinkeby:
30+
return baseUrlRinkeby, nil
31+
}
32+
33+
return "", fmt.Errorf("unknown network id %d", id)
34+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.