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  }