diff --git a/caller.go b/caller.go index 67cb935..eb2e10d 100644 --- a/caller.go +++ b/caller.go @@ -3,6 +3,7 @@ package multicall import ( "context" "fmt" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -77,9 +78,14 @@ func (caller *Caller) Call(opts *bind.CallOpts, calls ...*Call) ([]*Call, error) } // CallChunked makes multiple multicalls by chunking given calls. -func (caller *Caller) CallChunked(opts *bind.CallOpts, chunkSize int, calls ...*Call) ([]*Call, error) { +// Cooldown is helpful for sleeping between chunks and avoiding rate limits. +func (caller *Caller) CallChunked(opts *bind.CallOpts, chunkSize int, cooldown time.Duration, calls ...*Call) ([]*Call, error) { var allCalls []*Call for i, chunk := range chunkInputs(chunkSize, calls) { + if i > 0 && cooldown > 0 { + time.Sleep(cooldown) + } + chunk, err := caller.Call(opts, chunk...) if err != nil { return calls, fmt.Errorf("call chunk [%d] failed: %v", i, err) diff --git a/caller_test.go b/caller_test.go index 0fcc08b..9d82367 100644 --- a/caller_test.go +++ b/caller_test.go @@ -152,7 +152,7 @@ func TestCaller_TwoCalls(t *testing.T) { }, } - calls, err := caller.CallChunked(nil, 1, call1, call2) + calls, err := caller.CallChunked(nil, 1, 0, call1, call2) r.NoError(err) call1Out := calls[0].Outputs.(*testType) @@ -206,7 +206,7 @@ func TestCaller_EmptyCall(t *testing.T) { }, } - calls, err := caller.CallChunked(nil, 1, call) + calls, err := caller.CallChunked(nil, 1, 0, call) r.NoError(err) r.Len(calls, 1) }