You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.1KB

  1. package main
  2. // thanks to https://github.com/onrik/ethrpc/blob/master/ethrpc.go for
  3. // example
  4. import (
  5. "bytes"
  6. "encoding/json"
  7. "fmt"
  8. log "github.com/sirupsen/logrus"
  9. "io"
  10. "io/ioutil"
  11. "net/http"
  12. "time"
  13. )
  14. type httpRPCClient interface {
  15. Post(url string, contentType string, body io.Reader) (*http.Response, error)
  16. }
  17. type JSONRPCError struct {
  18. Code int `json:"code"`
  19. Message string `json:"message"`
  20. }
  21. func (err JSONRPCError) Error() string {
  22. return fmt.Sprintf("Error %d (%s)", err.Code, err.Message)
  23. }
  24. type JSONRPCResponse struct {
  25. ID string `json:"id"`
  26. JSONRPC string `json:"jsonrpc"`
  27. Result json.RawMessage `json:"result"`
  28. Error *JSONRPCError `json:"error"`
  29. }
  30. type JSONRPCRequest struct {
  31. ID string `json:"id"`
  32. JSONRPC string `json:"jsonrpc"`
  33. Method string `json:"method"`
  34. Params json.RawMessage `json:"params"`
  35. }
  36. type JSONRPC struct {
  37. url string
  38. client httpRPCClient
  39. }
  40. // New create new rpc client with given url
  41. func NewJSONRPC(url string, options ...func(rpc *JSONRPC)) *JSONRPC {
  42. netClient := &http.Client{
  43. Timeout: time.Second * 20,
  44. }
  45. rpc := &JSONRPC{
  46. url: url,
  47. client: netClient,
  48. }
  49. for _, option := range options {
  50. option(rpc)
  51. }
  52. return rpc
  53. }
  54. // Call returns raw response of method call
  55. func (rpc *JSONRPC) Call(method string, params json.RawMessage) (json.RawMessage, error) {
  56. request := JSONRPCRequest{
  57. ID: "1",
  58. JSONRPC: "2.0",
  59. Method: method,
  60. Params: params,
  61. }
  62. body, err := json.Marshal(request)
  63. if err != nil {
  64. return nil, err
  65. }
  66. response, err := rpc.client.Post(rpc.url, "application/json", bytes.NewBuffer(body))
  67. if response != nil {
  68. defer response.Body.Close()
  69. }
  70. if err != nil {
  71. log.Infof("jsonrpc error: %v", err)
  72. return nil, err
  73. }
  74. data, err := ioutil.ReadAll(response.Body)
  75. if err != nil {
  76. return nil, err
  77. }
  78. log.Debugf("%s", method)
  79. log.Debugf("Request: %s", body)
  80. log.Debugf("Response: %s", data)
  81. resp := new(JSONRPCResponse)
  82. if err := json.Unmarshal(data, resp); err != nil {
  83. return nil, err
  84. }
  85. if resp.Error != nil {
  86. return nil, *resp.Error
  87. }
  88. return resp.Result, nil
  89. }