-
Notifications
You must be signed in to change notification settings - Fork 431
Expand file tree
/
Copy pathclient2.go
More file actions
130 lines (113 loc) · 2.91 KB
/
client2.go
File metadata and controls
130 lines (113 loc) · 2.91 KB
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
package rpc
import (
"context"
"io"
"net/http"
"github.com/gagliardetto/solana-go/rpc/jsonrpc"
"golang.org/x/time/rate"
)
type OptionFuncs []func(*RPCClientOpts)
type RPCClientOpts struct {
*jsonrpc.RPCClientOpts
limiter *rate.Limiter
}
// New creates a new Solana JSON RPC client.
// Client is safe for concurrent use by multiple goroutines.
//
// Use WithHTTPClient to set a custom HTTP client on the client.
// Use WithCustomHeaders to set custom headers on the client.
// Use WithLimiter to set a rate limiter on the client.
//
// Examples:
//
// client := rpc.New2("https://api.mainnet-beta.solana.com")
// client := rpc.New2("https://api.mainnet-beta.solana.com", rpc.WithHTTPClient(http.DefaultClient))
// client := rpc.New2("https://api.mainnet-beta.solana.com", rpc.WithHTTPClient(http.DefaultClient), rpc.WithLimiter(rate.Every(time.Second), 1))
func New2(rpcEndpoint string, fns OptionFuncs) *Client2 {
opts := &RPCClientOpts{
RPCClientOpts: &jsonrpc.RPCClientOpts{
HTTPClient: newHTTP(),
},
}
for _, f := range fns {
f(opts)
}
rpcClient := jsonrpc.NewClientWithOpts(rpcEndpoint, opts.RPCClientOpts)
return &Client2{
rpcClient: rpcClient,
limiter: opts.limiter,
}
}
func WithHTTPClient(
client *http.Client,
) func(*RPCClientOpts) {
return func(opts *RPCClientOpts) {
opts.HTTPClient = client
}
}
func WithCustomHeader(
customHeader http.Header,
) func(*RPCClientOpts) {
return func(opts *RPCClientOpts) {
opts.CustomHeader = customHeader
}
}
func WithLimiter(
every rate.Limit, // requests per second; use rate.Every(d) to convert a duration
b int, // number of requests per time frame
) func(*RPCClientOpts) {
return func(opts *RPCClientOpts) {
opts.limiter = rate.NewLimiter(every, b)
}
}
type Client2 struct {
rpcClient jsonrpc.RPCClient
limiter *rate.Limiter
}
func (cl *Client2) CallForInto(
ctx context.Context,
out any,
method string,
params []any,
) error {
if cl.limiter == nil {
return cl.rpcClient.CallForInto(ctx, out, method, params)
}
if err := cl.limiter.Wait(ctx); err != nil {
return err
}
return cl.rpcClient.CallForInto(ctx, out, method, params)
}
func (cl *Client2) CallWithCallback(
ctx context.Context,
method string,
params []any,
callback func(*http.Request, *http.Response) error,
) error {
if cl.limiter == nil {
return cl.rpcClient.CallWithCallback(ctx, method, params, callback)
}
if err := cl.limiter.Wait(ctx); err != nil {
return err
}
return cl.rpcClient.CallWithCallback(ctx, method, params, callback)
}
func (cl *Client2) CallBatch(
ctx context.Context,
requests jsonrpc.RPCRequests,
) (jsonrpc.RPCResponses, error) {
if cl.limiter == nil {
return cl.rpcClient.CallBatch(ctx, requests)
}
if err := cl.limiter.Wait(ctx); err != nil {
return nil, err
}
return cl.rpcClient.CallBatch(ctx, requests)
}
// Close closes.
func (cl *Client2) Close() error {
if c, ok := cl.rpcClient.(io.Closer); ok {
return c.Close()
}
return nil
}