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.
foundryupnpm 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
carryusingextractCarry(carry) - to reject response, call
offchainLookup(carry)
This approach is not allowed by EIP-3668, specifically: Client Lookup Protocol: Rule #5
If the
senderfield 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