Signed Intents
Signed intents separate authorization from transaction submission. A payer signs EIP-712 data; an executor submits multiswapWithSignature to the Dispatcher.
Domain
name: CavalRe Multiswap
version: 1
chainId: current chain
verifyingContract: Dispatcher
Types
const types = {
Amount: [
{ name: "tokenAddress", type: "address" },
{ name: "amount", type: "uint256" },
],
Allocation: [
{ name: "tokenAddress", type: "address" },
{ name: "allocation", type: "uint256" },
{ name: "minAmount", type: "uint256" },
],
MultiswapIntent: [
{ name: "pool", type: "address" },
{ name: "payer", type: "address" },
{ name: "recipient", type: "address" },
{ name: "executor", type: "address" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
{ name: "payReserveAssetsHash", type: "bytes32" },
{ name: "recReserveAssetsHash", type: "bytes32" },
],
};
The contract hashes each Amount and Allocation, concatenates the element hashes in array order, and signs the resulting two array hashes inside MultiswapIntent.
Use the onchain helpers hashAmounts, hashAllocations, and hashMultiswapIntent to test an implementation before requesting a user signature.
Payer, recipient, and executor
payersupplies ERC-20 pay assets and must have approved the Dispatcher.recipientreceives output assets and cannot be the zero address.executorcan restrict submission to one address.executor = address(0)permits any submitter holding the signature.
For native pay assets, the executor supplies msg.value even though the signed payer remains the accounting payer.
Nonces and deadlines
Read the payer’s current sequential nonce:
nonces(payer)
Successful execution increments it by one. A stale or future nonce reverts.
The current module exposes no standalone nonce-cancellation or invalidation function. Treat a signed intent as usable until its deadline expires or its nonce is consumed.
Smart contract wallets
Signature validation uses OpenZeppelin SignatureChecker, so EOAs and ERC-1271 contract wallets are supported.
Execution
await walletClient.writeContract({
account: executor,
address: dispatcher,
abi: intentAbi,
functionName: "multiswapWithSignature",
args: [intent, signature],
value: nativePayValue,
});
The signed payload binds the pool, parties, nonce, deadline, ordered pay amounts, ordered receive allocations, and minimum receive amounts. Settlement then uses the same accounting path as a direct trade.