Skip to content

This page describes the client path: deploy the owner’s UserProxyV6, approve that proxy for each input token, sign the unchanged 12-field flat Order on IntentSettlerV3, then publish the authorization envelope with announce.

There is no AgentSwap SDK to install. The examples below are self-contained, and any EIP-712 signer can produce the owner signature.

The order uses ERC-20 tokens on one chain. Before signing, the owner must give their proxy an allowance for tokenIn:

tokenIn.approve(userProxy, allowance)

The approval is the on-chain gate for the later proxy pull and is separate from the order signature. The proxy pulls exactly amountIn from owner to the settler only when a solver calls fill.

See signing and authorization for the domain and authorization model, and the order reference for the frozen 12-field struct.

The client helper derives raw integer amounts and Unix-second timestamps. Its recipient is set explicitly; it is not inferred by the settler.

// Amounts are integer strings in the token's own decimals; times are Unix seconds.
const order = {
owner, // the proxy owner and order signer
recipient, // where the output lands; need not be the owner
tokenIn,
amountIn, // exact, not a ceiling
tokenOut,
startAmountOut, // the floor at startTime
endAmountOut, // the floor the curve rests at
startTime, // decay begins
decayEndTime, // decay ends; the floor rests from here
endTime, // the last timestamp at which the order lives
appData, // bytes32 attribution tag, or 32 zero bytes
nonce, // an unused owner-proxy nonce
};

The invariants the settler enforces on these values are on the curve page; an order that violates one reverts at announce, at fill and at resolve alike.

startAmountOut == endAmountOut represents a fixed-price limit order. startAmountOut > endAmountOut represents a descending Dutch auction. The owner signs the nonce as one of the 12 fields in the flat Order.

The primary type is Order, under the IntentSettlerV3 EIP-712 domain.

const typedData = {
primaryType: 'Order',
domain: {
name: 'AgentSwap IntentSettler',
version: '3',
chainId,
verifyingContract: intentSettlerV3,
},
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
],
Order: [
{ name: 'owner', type: 'address' },
{ name: 'recipient', type: 'address' },
{ name: 'tokenIn', type: 'address' },
{ name: 'amountIn', type: 'uint256' },
{ name: 'tokenOut', type: 'address' },
{ name: 'startAmountOut', type: 'uint256' },
{ name: 'endAmountOut', type: 'uint256' },
{ name: 'startTime', type: 'uint256' },
{ name: 'decayEndTime', type: 'uint256' },
{ name: 'endTime', type: 'uint256' },
{ name: 'appData', type: 'bytes32' },
{ name: 'nonce', type: 'uint256' },
],
},
message: order,
};
const ownerSignature = await provider.request({
method: 'eth_signTypedData_v4',
params: [owner, JSON.stringify(typedData)],
});

The Order type includes all 12 order fields, including nonce. The signature is over the settler’s domain.

The typed data must contain the following bindings:

Binding Value
domain.name AgentSwap IntentSettler
domain.version 3
domain.verifyingContract the deployed IntentSettlerV3 address
primaryType Order
message all 12 fields of order

Wrap the owner signature for announce as the V6 owner authorization:

abi.encode(AuthKind.Owner, abi.encode(bytes(ownerSignature)))

AuthKind.Owner is 0. orderDigest(order) returns the digest that the proxy recomputes when it authorizes the pull.

announce(order, auth) is permissionless and optional. The owner can self-submit it, or another broadcaster can publish the same authorization. The envelope is carried in IntentAnnounced; it is checked again and consumed by fill.

// announce((O),bytes) — selector 0x294470ec. Any account may send it.
await provider.request({
method: 'eth_sendTransaction',
params: [{ from: account, to: intentSettlerV3, data: encodeAnnounce(order, auth) }],
});

Verify what you built before you rely on it: orderDigest(order) returns the exact V6 digest, and orderHash(order) (0xd94a1dc6) returns the id the events are keyed by. Both are eth_calls against the settler.

The announcement verifies the signature, but it does not make the order fillable. A spent proxy nonce, a missing proxy allowance, a changed ERC-1271 wallet configuration, or an unusable route can still prevent settlement. A solver must screen the order and eth_call-dry-run fill immediately before submitting it; see fill an order.