When TRANSFER_REQUIRE_CONFIRMATION=true (default), Uniswap swaps follow the same human-in-the-loop pattern as native transfers: the agent prepares an unsigned quote, the user reviews details in chat, then Confirm or Cancel.
The env var name is shared with transfers (TRANSFER_REQUIRE_CONFIRMATION). Set it to false only when you want auto-sign for both transfers and swaps.

Flow

Chat UI

The sample web app renders a Swap confirmation card with:
FieldExample
Sell0.1 ETH
Buy~250 USDC
Networkbase
RoutingCLASSIC
ApprovalRequired or not required
Buttons: Confirm (sign + broadcast) and Cancel (discard pending swap). Pending swaps expire after PENDING_SWAP_TTL_MINUTES (default 15, max 60).

REST API

Base path: your agentic-ai API (sample: /agents).
MethodPathDescription
GET/agents/:agentId/swaps/:pendingIdFetch pending swap details
POST/agents/:agentId/swaps/:pendingId/confirmSign approval (if needed) and swap
POST/agents/:agentId/swaps/:pendingId/cancelCancel without broadcasting
Confirm response (success):
{
  "status": "submitted",
  "swapTxHash": "0x…",
  "approvalTxHash": "0x…",
  "chainId": 8453
}

SSE events

During chat streaming, the backend emits:
EventPurpose
swap_pendingStructured rows + pendingSwapId for the UI
swap_confirmation_uiSame UI payload for dedicated listeners
Message metadata persists swapPending so history reloads the card without re-parsing markdown.

Environment variables

VariableDefaultEffect
TRANSFER_REQUIRE_CONFIRMATIONtrueEnable swap confirmation UI
PENDING_SWAP_TTL_MINUTES15Pending swap expiry
TRANSFER_WAIT_FOR_RECEIPTtrueWait for receipt after broadcast

Implementing in your app

Mirror the sample web app:
  1. Parse swapPending from assistant message metadata (or markdown fallback).
  2. Render a confirmation card with sell/buy/network rows.
  3. On Confirm, POST …/swaps/:pendingId/confirm with the user JWT.
  4. Show swapTxHash with a block explorer link.
Transfer confirmation uses the same pattern — see Full-stack integration.