Skip to main content

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

  • payer supplies ERC-20 pay assets and must have approved the Dispatcher.
  • recipient receives output assets and cannot be the zero address.
  • executor can 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.