forked from okx/xlayer-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.go
139 lines (113 loc) · 3.01 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package client
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
)
const jsonRPCVersion = "2.0"
// Client defines typed wrappers for the zkEVM RPC API.
type Client struct {
url string
}
// NewClient creates an instance of client
func NewClient(url string) *Client {
return &Client{
url: url,
}
}
// JSONRPCCall executes a 2.0 JSON RPC HTTP Post Request to the provided URL with
// the provided method and parameters, which is compatible with the Ethereum
// JSON RPC Server.
func JSONRPCCall(url, method string, parameters ...interface{}) (types.Response, error) {
params, err := json.Marshal(parameters)
if err != nil {
return types.Response{}, err
}
request := types.Request{
JSONRPC: jsonRPCVersion,
ID: float64(1),
Method: method,
Params: params,
}
httpRes, err := sendJSONRPC_HTTPRequest(url, request)
if err != nil {
return types.Response{}, err
}
resBody, err := io.ReadAll(httpRes.Body)
if err != nil {
return types.Response{}, err
}
defer httpRes.Body.Close()
if httpRes.StatusCode != http.StatusOK {
return types.Response{}, fmt.Errorf("%v - %v", httpRes.StatusCode, string(resBody))
}
var res types.Response
err = json.Unmarshal(resBody, &res)
if err != nil {
return types.Response{}, err
}
return res, nil
}
// BatchCall used in batch requests to send multiple methods and parameters at once
type BatchCall struct {
Method string
Parameters []interface{}
}
// JSONRPCBatchCall executes a 2.0 JSON RPC HTTP Post Batch Request to the provided URL with
// the provided method and parameters groups, which is compatible with the Ethereum
// JSON RPC Server.
func JSONRPCBatchCall(url string, calls ...BatchCall) ([]types.Response, error) {
requests := []types.Request{}
for i, call := range calls {
params, err := json.Marshal(call.Parameters)
if err != nil {
return nil, err
}
req := types.Request{
JSONRPC: jsonRPCVersion,
ID: float64(i),
Method: call.Method,
Params: params,
}
requests = append(requests, req)
}
httpRes, err := sendJSONRPC_HTTPRequest(url, requests)
if err != nil {
return nil, err
}
resBody, err := io.ReadAll(httpRes.Body)
if err != nil {
return nil, err
}
defer httpRes.Body.Close()
if httpRes.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%v - %v", httpRes.StatusCode, string(resBody))
}
var res []types.Response
err = json.Unmarshal(resBody, &res)
if err != nil {
errorMessage := string(resBody)
return nil, fmt.Errorf(errorMessage)
}
return res, nil
}
func sendJSONRPC_HTTPRequest(url string, payload interface{}) (*http.Response, error) {
reqBody, err := json.Marshal(payload)
if err != nil {
return nil, err
}
reqBodyReader := bytes.NewReader(reqBody)
httpReq, err := http.NewRequest(http.MethodPost, url, reqBodyReader)
if err != nil {
return nil, err
}
httpReq.Header.Add("Content-type", "application/json")
httpRes, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, err
}
return httpRes, nil
}