Skip to content

Commit

Permalink
client: add go client package for service api
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Nov 16, 2018
1 parent 99a3388 commit d74986a
Show file tree
Hide file tree
Showing 7 changed files with 373 additions and 59 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -8,6 +8,7 @@

# dependencies
/node_modules
vendor/

# IDEs and editors
/.idea
Expand Down
53 changes: 30 additions & 23 deletions server/Gopkg.lock → Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions Gopkg.toml
@@ -0,0 +1,61 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true


[[constraint]]
name = "github.com/go-chi/chi"
version = "3.3.3"

[[constraint]]
name = "github.com/go-chi/cors"
version = "1.0.0"

[[constraint]]
name = "github.com/gochain-io/gochain"
version = "2.1.43"

[[constraint]]
name = "github.com/rs/zerolog"
version = "1.10.3"

[[constraint]]
name = "github.com/urfave/cli"
version = "1.20.0"

[[constraint]]
branch = "v2"
name = "gopkg.in/mgo.v2"

[[override]]
version = "0.1.0"
name = "gopkg.in/fatih/set.v0"

[prune]
go-tests = true
unused-packages = true
[[prune.project]]
name = "github.com/gochain-io/gochain"
unused-packages = false
151 changes: 151 additions & 0 deletions client/client.go
@@ -0,0 +1,151 @@
package client

import (
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"net/http"
"net/url"
"strconv"

"github.com/gochain-io/explorer/server/models"
)

const (
MainnetURL = "https://explorer.gochain.io"
TestnetURL = "https://testnet-explorer.gochain.io"
)

var (
Mainnet = NewClient(MainnetURL)
Testnet = NewClient(TestnetURL)
wei, _ = new(big.Int).SetString("1000000000000000000", 10)
)

type Client struct {
url string
}

func NewClient(url string) *Client {
return &Client{url: url}
}

func (c *Client) Address(addr string) (*models.Address, error) {
var data models.Address
err := c.get("/api/address/"+addr, nil, &data)
if err != nil {
return nil, err
}
return &data, nil
}

func (c *Client) AddressTransactions(addr string, skip, limit int) (*models.TransactionList, error) {
vals := make(url.Values)
vals.Add("skip", strconv.Itoa(skip))
vals.Add("limit", strconv.Itoa(limit))
var data models.TransactionList
err := c.get(fmt.Sprintf("/api/address/%s/transactions", addr), vals, &data)
if err != nil {
return nil, err
}
return &data, nil
}

func (c *Client) AddressHolders(addr string, skip, limit int) (*models.TokenHolderList, error) {
vals := make(url.Values)
vals.Add("skip", strconv.Itoa(skip))
vals.Add("limit", strconv.Itoa(limit))
var data models.TokenHolderList
err := c.get(fmt.Sprintf("/api/address/%s/holders", addr), vals, &data)
if err != nil {
return nil, err
}
return &data, nil
}

func (c *Client) AddressInternalTransactions(addr string, skip, limit int) (*models.TokenHolderList, error) {
vals := make(url.Values)
vals.Add("skip", strconv.Itoa(skip))
vals.Add("limit", strconv.Itoa(limit))
var data models.TokenHolderList
err := c.get(fmt.Sprintf("/api/address/%s/internal_transactions", addr), vals, &data)
if err != nil {
return nil, err
}
return &data, nil
}

func (c *Client) CirculatingSupply() (string, error) {
return c.getStr("/circulatingSupply")
}

func (c *Client) CirculatingSupplyWei() (*big.Int, error) {
s, err := c.CirculatingSupply()
if err != nil {
return nil, err
}
r, ok := new(big.Rat).SetString(s)
if !ok {
return nil, fmt.Errorf("failed to set string: %q", s)
}
r = r.Mul(r, new(big.Rat).SetInt(wei))
if !r.IsInt() {
return nil, fmt.Errorf("not an int: %s", r)
}
return r.Num(), nil
}

func (c *Client) TotalSupply() (string, error) {
return c.getStr("/totalSupply")
}

func (c *Client) TotalSupplyWei() (*big.Int, error) {
s, err := c.TotalSupply()
if err != nil {
return nil, err
}
r, ok := new(big.Rat).SetString(s)
if !ok {
return nil, fmt.Errorf("failed to set string: %q", s)
}
r = r.Mul(r, new(big.Rat).SetInt(wei))
if !r.IsInt() {
return nil, fmt.Errorf("not an int: %s", r)
}
return r.Num(), nil
}

func (c *Client) RichList(skip, limit int) (*models.Richlist, error) {
vals := make(url.Values)
vals.Add("skip", strconv.Itoa(skip))
vals.Add("limit", strconv.Itoa(limit))
var data models.Richlist
err := c.get("/api/richlist", vals, &data)
if err != nil {
return nil, err
}
return &data, nil
}

func (c *Client) get(servicePath string, vals url.Values, data interface{}) error {
resp, err := http.Get(c.url + fmt.Sprintf("%s?%s", servicePath, vals.Encode()))
if err != nil {
return err
}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return err
}
resp.Body.Close()
return nil
}

func (c *Client) getStr(servicePath string) (string, error) {
resp, err := http.Get(c.url + servicePath)
if err != nil {
return "", err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
return string(b), err
}

0 comments on commit d74986a

Please sign in to comment.