github.com/gagliardetto/solana-go@v1.11.0/rpc/client-with-ratelimit.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 "go.uber.org/ratelimit" 10 ) 11 12 var _ JSONRPCClient = &clientWithRateLimiting{} 13 14 type clientWithRateLimiting struct { 15 rpcClient jsonrpc.RPCClient 16 rateLimiter ratelimit.Limiter 17 } 18 19 // NewWithRateLimit creates a new rate-limitted Solana RPC client. 20 func NewWithRateLimit( 21 rpcEndpoint string, 22 rps int, // requests per second 23 ) JSONRPCClient { 24 opts := &jsonrpc.RPCClientOpts{ 25 HTTPClient: newHTTP(), 26 } 27 28 rpcClient := jsonrpc.NewClientWithOpts(rpcEndpoint, opts) 29 30 return &clientWithRateLimiting{ 31 rpcClient: rpcClient, 32 rateLimiter: ratelimit.New(rps), 33 } 34 } 35 36 func (wr *clientWithRateLimiting) CallForInto(ctx context.Context, out interface{}, method string, params []interface{}) error { 37 wr.rateLimiter.Take() 38 return wr.rpcClient.CallForInto(ctx, &out, method, params) 39 } 40 41 func (wr *clientWithRateLimiting) CallWithCallback( 42 ctx context.Context, 43 method string, 44 params []interface{}, 45 callback func(*http.Request, *http.Response) error, 46 ) error { 47 wr.rateLimiter.Take() 48 return wr.rpcClient.CallWithCallback(ctx, method, params, callback) 49 } 50 51 func (wr *clientWithRateLimiting) CallBatch( 52 ctx context.Context, 53 requests jsonrpc.RPCRequests, 54 ) (jsonrpc.RPCResponses, error) { 55 wr.rateLimiter.Take() 56 return wr.rpcClient.CallBatch(ctx, requests) 57 } 58 59 // Close closes clientWithRateLimiting. 60 func (cl *clientWithRateLimiting) Close() error { 61 if c, ok := cl.rpcClient.(io.Closer); ok { 62 return c.Close() 63 } 64 return nil 65 }