-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclef_client.go
193 lines (164 loc) · 4.61 KB
/
clef_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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package clefclient
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
)
// rpcClient represents a client to interact with the clef JSON-RPC interface.
type rpcClient struct {
url string
}
// newRPCClient creates a new clef JSON-RPC client.
func newRPCClient(url string) *rpcClient {
return &rpcClient{url: url}
}
// rpcRequest represents a JSON-RPC request.
type rpcRequest struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params interface{} `json:"params"`
ID int `json:"id"`
}
// rpcResponse represents a JSON-RPC response.
type rpcResponse struct {
Jsonrpc string `json:"jsonrpc"`
Result json.RawMessage `json:"result"`
Error *rpcError `json:"error"`
ID int `json:"id"`
}
// rpcError represents a JSON-RPC error.
type rpcError struct {
Code int `json:"code"`
Message string `json:"message"`
}
// call sends a JSON-RPC request and returns the response.
func (c *rpcClient) call(method string, params interface{}) (*rpcResponse, error) {
reqBody, err := json.Marshal(rpcRequest{
Jsonrpc: "2.0",
Method: method,
Params: params,
ID: 1,
})
if err != nil {
return nil, err
}
resp, err := http.Post(c.url, "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
var rpcResp rpcResponse
if err := json.NewDecoder(resp.Body).Decode(&rpcResp); err != nil {
return nil, err
}
if rpcResp.Error != nil {
return nil, errors.New(rpcResp.Error.Message)
}
return &rpcResp, nil
}
// ClefClient represents a higher-level client to interact with clef.
type ClefClient struct {
transport transport
}
// NewHTTPClient creates a new ClefClient using HTTP transport
func NewHTTPClient(url string) *ClefClient {
return &ClefClient{transport: newHTTPTransport(url)}
}
// NewIPCClient creates a new ClefClient using IPC transport
func NewIPCClient(socketPath string) (*ClefClient, error) {
transport, err := newIPCTransport(socketPath)
if err != nil {
return nil, fmt.Errorf("failed to create IPC transport: %w", err)
}
return &ClefClient{transport: transport}, nil
}
// Close closes the underlying transport
func (cc *ClefClient) Close() error {
return cc.transport.close()
}
// NewAccount creates a new account
func (cc *ClefClient) NewAccount() (string, error) {
resp, err := cc.transport.call("account_new", nil)
if err != nil {
return "", err
}
var address string
if err := json.Unmarshal(resp.Result, &address); err != nil {
return "", err
}
return address, nil
}
// ListAccounts returns the list of available accounts
func (cc *ClefClient) ListAccounts() ([]string, error) {
resp, err := cc.transport.call("account_list", nil)
if err != nil {
return nil, err
}
var accounts []string
if err := json.Unmarshal(resp.Result, &accounts); err != nil {
return nil, err
}
return accounts, nil
}
// SignTransaction signs the given transaction
func (cc *ClefClient) SignTransaction(tx *Transaction) (*SignTxResponse, error) {
resp, err := cc.transport.call("account_signTransaction", tx)
if err != nil {
return nil, err
}
var result SignTxResponse
if err := json.Unmarshal(resp.Result, &result); err != nil {
return nil, err
}
return &result, nil
}
// SignData signs the given data
func (cc *ClefClient) SignData(req *SignDataRequest) (*SignDataResponse, error) {
resp, err := cc.transport.call("account_signData", req)
if err != nil {
return nil, err
}
var result SignDataResponse
if err := json.Unmarshal(resp.Result, &result); err != nil {
return nil, err
}
return &result, nil
}
// SignTypedData signs the given typed data
func (cc *ClefClient) SignTypedData(req *TypedDataRequest) (*SignDataResponse, error) {
resp, err := cc.transport.call("account_signTypedData", req)
if err != nil {
return nil, err
}
var result SignDataResponse
if err := json.Unmarshal(resp.Result, &result); err != nil {
return nil, err
}
return &result, nil
}
// EcRecover recovers the address from the given signature
func (cc *ClefClient) EcRecover(req *EcRecoverRequest) (*EcRecoverResponse, error) {
resp, err := cc.transport.call("account_ecRecover", req)
if err != nil {
return nil, err
}
var result EcRecoverResponse
if err := json.Unmarshal(resp.Result, &result); err != nil {
return nil, err
}
return &result, nil
}
// Version returns the version of the clef service
func (cc *ClefClient) Version() (*VersionResponse, error) {
resp, err := cc.transport.call("account_version", nil)
if err != nil {
return nil, err
}
var result VersionResponse
if err := json.Unmarshal(resp.Result, &result); err != nil {
return nil, err
}
return &result, nil
}