github.com/gagliardetto/solana-go@v1.11.0/rpc/client-with-ratelimit2.go (about) 1 package rpc 2 3 import ( 4 "context" 5 "io" 6 "net/http" 7 8 "github.com/gagliardetto/solana-go/rpc/jsonrpc" 9 "golang.org/x/time/rate" 10 ) 11 12 var _ JSONRPCClient = &clientWithLimiter{} 13 14 type clientWithLimiter struct { 15 rpcClient jsonrpc.RPCClient 16 limiter *rate.Limiter 17 } 18 19 // NewWithLimiter creates a new rate-limitted Solana RPC client. 20 // Example: NewWithLimiter(URL, rate.Every(time.Second), 1) 21 func NewWithLimiter( 22 rpcEndpoint string, 23 every rate.Limit, // time frame 24 b int, // number of requests per time frame 25 ) JSONRPCClient { 26 opts := &jsonrpc.RPCClientOpts{ 27 HTTPClient: newHTTP(), 28 } 29 30 rpcClient := jsonrpc.NewClientWithOpts(rpcEndpoint, opts) 31 rater := rate.NewLimiter(every, b) 32 33 return &clientWithLimiter{ 34 rpcClient: rpcClient, 35 limiter: rater, 36 } 37 } 38 39 func (wr *clientWithLimiter) CallForInto(ctx context.Context, out interface{}, method string, params []interface{}) error { 40 err := wr.limiter.Wait(ctx) 41 if err != nil { 42 return err 43 } 44 return wr.rpcClient.CallForInto(ctx, &out, method, params) 45 } 46 47 func (wr *clientWithLimiter) CallWithCallback( 48 ctx context.Context, 49 method string, 50 params []interface{}, 51 callback func(*http.Request, *http.Response) error, 52 ) error { 53 err := wr.limiter.Wait(ctx) 54 if err != nil { 55 return err 56 } 57 return wr.rpcClient.CallWithCallback(ctx, method, params, callback) 58 } 59 60 func (wr *clientWithLimiter) CallBatch( 61 ctx context.Context, 62 requests jsonrpc.RPCRequests, 63 ) (jsonrpc.RPCResponses, error) { 64 err := wr.limiter.Wait(ctx) 65 if err != nil { 66 return nil, err 67 } 68 return wr.rpcClient.CallBatch(ctx, requests) 69 } 70 71 // Close closes clientWithLimiter. 72 func (cl *clientWithLimiter) Close() error { 73 if c, ok := cl.rpcClient.(io.Closer); ok { 74 return c.Close() 75 } 76 return nil 77 }