|
1 | 1 | package rpccalls |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "fmt" |
5 | 6 | "io" |
6 | 7 | "net/http" |
7 | | - "strings" |
8 | 8 |
|
9 | 9 | "encoding/json" |
10 | | - |
11 | | - "github.com/san-lab/go4337/userop" |
12 | 10 | ) |
13 | 11 |
|
14 | | -const StdBundlerCallTemplate = `curl -X GET %s/%s --header 'accept: application/json' --header 'content-type: application/json' -d ' |
15 | | -{ |
16 | | - "jsonrpc": "2.0", |
17 | | - "id": 1, |
18 | | - "method": "eth_supportedEntryPoints", |
19 | | - "params": [] |
20 | | -} |
21 | | -' |
22 | | -` |
23 | | - |
24 | | -func ApiCall(url, key string, methodTemplate string, usop *userop.UserOperation) ([]byte, error) { |
| 12 | +func POSTCall(url, key string, data []byte) (result []byte, aerr *APIError, err error) { |
25 | 13 | client := http.Client{} |
26 | 14 | url = url + "/" + key |
27 | | - ausop := usop.ToUserOpForApi() |
28 | | - data, err := json.Marshal(ausop) |
29 | | - if err != nil { |
30 | | - return nil, fmt.Errorf("could not marshal userop: %v", err) |
31 | | - } |
32 | | - |
33 | | - methodCall := fmt.Sprintf(methodTemplate, string(data)) |
34 | | - //fmt.Println("methodCall:", methodCall) |
35 | | - buf := strings.NewReader(methodCall) |
| 15 | + buf := bytes.NewBuffer(data) |
| 16 | + //fmt.Println("POSTing", url, "with", string(data)) |
36 | 17 | req, err := http.NewRequest("POST", url, nil) |
37 | 18 | if err != nil { |
38 | | - //fmt.Println(err) |
39 | | - return nil, err |
| 19 | + return nil, nil, err |
40 | 20 | } |
41 | 21 | req.Header.Set("accept", "application/json") |
42 | 22 | req.Header.Set("content-type", "application/json") |
43 | 23 | req.Body = io.NopCloser(buf) |
44 | 24 | resp, err := client.Do(req) |
45 | 25 | if err != nil { |
46 | | - return nil, fmt.Errorf("could not do request: %v", err) |
| 26 | + return nil, nil, fmt.Errorf("could not do request: %v", err) |
| 27 | + } |
| 28 | + defer resp.Body.Close() |
| 29 | + resbts, err := io.ReadAll(resp.Body) |
| 30 | + if err != nil { |
| 31 | + return nil, nil, fmt.Errorf("could not read response: %v", err) |
| 32 | + } |
| 33 | + aresp := &APIRPCResponse{} |
| 34 | + err = json.Unmarshal(resbts, aresp) |
| 35 | + if err != nil { |
| 36 | + return nil, nil, fmt.Errorf("could not unmarshal response: %v", err, string(resbts)) |
| 37 | + } |
| 38 | + if aresp.Error.Code != 0 { |
| 39 | + return nil, &aresp.Error, nil |
| 40 | + } |
| 41 | + return aresp.Result, nil, nil |
| 42 | +} |
| 43 | + |
| 44 | +func ApiFreeHandCall(url, key, methodTemplate string, params ...interface{}) (result []byte, aerr *APIError, err error) { |
| 45 | + sparams := make([]any, len(params)) |
| 46 | + for i, p := range params { |
| 47 | + sparams[i], err = json.Marshal(p) |
| 48 | + if err != nil { |
| 49 | + return nil, nil, fmt.Errorf("could not marshal param: %v", err) |
| 50 | + } |
| 51 | + } |
| 52 | + calldat := fmt.Sprintf(methodTemplate, sparams...) |
| 53 | + return POSTCall(url, key, []byte(calldat)) |
| 54 | + |
| 55 | +} |
| 56 | + |
| 57 | +// Returns unparsed "Result" if successful, otherwise nil and either *APIError or error |
| 58 | +func ApiCall(url, key string, ar *APIRequest) ([]byte, *APIError, error) { |
| 59 | + data, err := ar.ToJSON() |
| 60 | + if err != nil { |
| 61 | + return nil, nil, fmt.Errorf("could not marshal APIRequest: %v", err, ar) |
47 | 62 | } |
48 | | - return io.ReadAll(resp.Body) |
49 | 63 |
|
| 64 | + return POSTCall(url, key, data) |
| 65 | + |
| 66 | +} |
| 67 | + |
| 68 | +type APIRequest struct { |
| 69 | + ID int `json:"id"` |
| 70 | + Jsonrpc string `json:"jsonrpc"` |
| 71 | + Method string `json:"method"` |
| 72 | + Params []interface{} `json:"params"` |
| 73 | +} |
| 74 | + |
| 75 | +func (ar *APIRequest) ToJSON() ([]byte, error) { |
| 76 | + return json.Marshal(ar) |
| 77 | +} |
| 78 | + |
| 79 | +type APIRPCResponse struct { |
| 80 | + ID int `json:"id"` |
| 81 | + Jsonrpc string `json:"jsonrpc"` |
| 82 | + Result json.RawMessage `json:"result,omitempty"` |
| 83 | + Error APIError `json:"error,omitempty"` |
| 84 | +} |
| 85 | + |
| 86 | +type APIError struct { |
| 87 | + Code int `json:"code"` |
| 88 | + Data json.RawMessage `json:"data"` |
| 89 | + Message string `json:"message"` |
50 | 90 | } |
0 commit comments