|
- package main
-
- // thanks to https://github.com/onrik/ethrpc/blob/master/ethrpc.go for
- // example
-
- import (
- "bytes"
- "encoding/json"
- "fmt"
- log "github.com/sirupsen/logrus"
- "io"
- "io/ioutil"
- "net/http"
- "time"
- )
-
- type httpRPCClient interface {
- Post(url string, contentType string, body io.Reader) (*http.Response, error)
- }
-
- type JSONRPCError struct {
- Code int `json:"code"`
- Message string `json:"message"`
- }
-
- func (err JSONRPCError) Error() string {
- return fmt.Sprintf("Error %d (%s)", err.Code, err.Message)
- }
-
- type JSONRPCResponse struct {
- ID string `json:"id"`
- JSONRPC string `json:"jsonrpc"`
- Result json.RawMessage `json:"result"`
- Error *JSONRPCError `json:"error"`
- }
-
- type JSONRPCRequest struct {
- ID string `json:"id"`
- JSONRPC string `json:"jsonrpc"`
- Method string `json:"method"`
- Params json.RawMessage `json:"params"`
- }
-
- type JSONRPC struct {
- url string
- client httpRPCClient
- }
-
- // New create new rpc client with given url
- func NewJSONRPC(url string, options ...func(rpc *JSONRPC)) *JSONRPC {
-
- netClient := &http.Client{
- Timeout: time.Second * 20,
- }
-
- rpc := &JSONRPC{
- url: url,
- client: netClient,
- }
- for _, option := range options {
- option(rpc)
- }
-
- return rpc
- }
-
- // Call returns raw response of method call
- func (rpc *JSONRPC) Call(method string, params json.RawMessage) (json.RawMessage, error) {
- request := JSONRPCRequest{
- ID: "1",
- JSONRPC: "2.0",
- Method: method,
- Params: params,
- }
-
- body, err := json.Marshal(request)
- if err != nil {
- return nil, err
- }
-
- response, err := rpc.client.Post(rpc.url, "application/json", bytes.NewBuffer(body))
- if response != nil {
- defer response.Body.Close()
- }
- if err != nil {
- log.Infof("jsonrpc error: %v", err)
- return nil, err
- }
-
- data, err := ioutil.ReadAll(response.Body)
- if err != nil {
- return nil, err
- }
-
- log.Debugf("%s", method)
- log.Debugf("Request: %s", body)
- log.Debugf("Response: %s", data)
-
- resp := new(JSONRPCResponse)
- if err := json.Unmarshal(data, resp); err != nil {
- return nil, err
- }
-
- if resp.Error != nil {
- return nil, *resp.Error
- }
-
- return resp.Result, nil
-
- }
|