package main // thanks to https://github.com/onrik/ethrpc/blob/master/ethrpc.go for // example import ( "bytes" "encoding/json" "fmt" "io" "io/ioutil" "log" "net/http" "os" ) type logger interface { Println(v ...interface{}) } type httpClient 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 []interface{} `json:"params"` } // JsonRpc Client Object type JsonRpc struct { url string client httpClient log logger Debug bool } // New create new rpc client with given url func JsonRpcClient(url string, options ...func(rpc *JsonRpc)) *JsonRpc { rpc := &JsonRpc{ url: url, client: http.DefaultClient, log: log.New(os.Stderr, "", log.LstdFlags), } for _, option := range options { option(rpc) } return rpc } // Call returns raw response of method call func (rpc *JsonRpc) Call(method string, params ...interface{}) (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 { return nil, err } data, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err } if rpc.Debug { rpc.log.Println(fmt.Sprintf("%s\nRequest: %s\nResponse: %s\n", method, body, 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 }