Automatically randomize CCIP-Read endpoints and conditionally choose to accept a response without terminating the request session. Calls will succeed as long as one endpoint produces a valid response.
foundryup
npm i
- Abstract Contract Base: OffchainNext.sol
- Test:
node test/test.js
- inherit
OffchainNext
- use
offchainLookup(...)
instead ofrevert OffchainLookup(...)
(same arguments) - use
revert OffchainTryNext()
during callback to reject responses and proceed to the next endpoint - will
revert OffchainLookupUnanswered()
if all endpoints attempted without success - override
_shouldTryNext(bytes)
to control which exceptions should retry
This approach works but cannot determine which endpoint failed so calls may take infinite time.
revert OffchainLookup(shuffled([a, b, c, ...]), ...)
- callback fires if any endpoint responds
- since we don't know which endpoint answered, must retry all endpoints again
- Abstract Contract Base: OffchainShuffle.sol
- Test:
node test/shuffle.js
- inherit
OffchainShuffle
- use
offchainLookup(...)
instead ofrevert OffchainLookup(...)
(same arguments) - on valid response, decode original
carry
usingextractCarry(carry)
- to reject response, call
offchainLookup(carry)
This approach is not allowed by EIP-3668, specifically: Client Lookup Protocol: Rule #5
If the
sender
field does not match the address of the contract that was called, return an error to the caller and stop.
- Singleton Contract: OffchainTrampoline.sol
- Interface: IOffchainTrampoline.sol
- Test:
node test/trampoline.js
- deploy
IOffchainTrampoline
- use:
IOffchainTrampoline().offchainLookup(...)
instead ofrevert OffchainLookup(...)
(same arguments)- minimal contract code
- avoids stack issues
- by default, any revert during callback will try next endpoint
- (optional) implement
IOffchainNext.isOffchainLookupRevertFatal(bytes)
to allow specific errors to terminate the request session- eg. invalid proof vs exclusion proof
- use
revert OffchainTryNext()
to always try next endpoint - will
revert OffchainLookupUnanswered()
if all endpoints attempted without success
- Library: FisherYates.sol
- Test:
node test/FisherYates.js