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 }