Swap Tokens (Uniswap V4)
Swap ERC20 tokens on Uniswap V4 at the best available price on a single chain. Auto-routes through a direct pool or a hub token (up to 2 hops), enforces an on-chain slippage floor, uses Permit2 for approvals, and supports native ETH. Returns the transaction hash, output amount, and executed route. Ideal for: same-chain token swaps on Uniswap V4, native-ETH swaps, buying and selling ERC20s.
Catalog action EVM Onchain wallet Gas swap
Swap ERC20 tokens on Uniswap V4 at the best available price on a single chain. Auto-routes through a direct pool or a hub token (up to 2 hops), enforces an on-chain slippage floor, uses Permit2 for approvals, and supports native ETH. Returns the transaction hash, output amount, and executed route. Ideal for: same-chain token swaps on Uniswap V4, native-ETH swaps, buying and selling ERC20s.
This action can require a wallet connector, gas, token movement, or an external side effect. Test with simulation or a controlled amount before using it in a live workflow.
At a Glance
| Field | Value |
|---|---|
| Action ID | v4-swap |
| Category | EVM Onchain |
| Connector | wallet |
| Requires gas | Yes |
| Funds movement | swap |
| Tags | blockchain, evm, dex, swap, sell, buy, token, erc20, trade, uniswap, v4, defi |
Payload Schema
| Field | Type | Required | Description |
|---|---|---|---|
tokenIn | string | Yes | Input token address to sell. Use 0x0000000000000000000000000000000000000000 for native ETH. |
tokenOut | string | Yes | Output token address to receive. Use 0x0000000000000000000000000000000000000000 for native ETH. |
amountIn | string | Yes | Exact input amount to sell, in the token's smallest unit (wei). |
chainId | number | Yes | Chain to swap on. V4 swaps are single-chain only. |
recipient | string | No | Output tokens are always delivered to the swapping wallet — V4 TAKE_ALL routes to the transaction sender and there is no recipient word on-chain. If provided, this MUST equal the swapping wallet address; a different address is rejected. Leave empty to use the swapping wallet. |
slippageBps | number | No | Slippage tolerance in basis points (100 = 1%). Default is 300 (3%). Max 8000 (80%). |
deadlineMinutes | number | No | Transaction deadline in minutes from now. Default: 20. |
maxHops | number | No | Maximum number of pool hops the auto-router may use. Default: 2. Capped at 2 for v1. |
maxPriceImpactBps | number | No | Aborts the swap if fill-vs-spot price impact exceeds this many basis points (1000 = 10%). Default is 1000 (10%). Higher tolerates more impact. |
Result Schema
| Field | Type | Required | Description |
|---|---|---|---|
transactionHash | string | Yes | The Universal Router swap transaction hash. |
amountIn | string | Yes | Input amount that was swapped, in the token's smallest unit (wei). |
amountInFormatted | string | null | No | Full-precision, human-readable input amount (e.g. "1.5"). Null when tokenIn's decimals could not be resolved. |
amountOut | string | Yes | Actual output amount received, in the token's smallest unit. Parsed from the transaction receipt's ERC20 Transfer logs for ERC20 output; falls back to the routing quote for native-ETH output or when the receipt can't be reliably decoded. The guaranteed on-chain floor is amountOutMinimum. |
amountOutFormatted | string | null | No | Full-precision, human-readable output amount. Null when tokenOut's decimals could not be resolved. |
amountOutMinimum | string | Yes | Minimum output amount enforced on-chain (TAKE_ALL minAmount), computed from the quote and slippageBps. |
route | array | Yes | The executed route: 1 entry for a direct swap, 2 entries for a hub-token hop. |
tokenIn | string | Yes | Input token address that was sold. |
tokenOut | string | Yes | Output token address that was received. |
chainId | number | Yes | Chain the swap executed on. |
tokenInDecimals | number | null | No | Decimal places of tokenIn, used to format amountInFormatted. Null if on-chain lookup failed. |
tokenOutDecimals | number | null | No | Decimal places of tokenOut, used to format amountOutFormatted. Null if on-chain lookup failed. |
tokenInSymbol | string | null | No | Symbol of the input token (e.g. 'WETH'). Null if on-chain lookup failed. |
tokenOutSymbol | string | null | No | Symbol of the output token (e.g. 'USDC'). Null if on-chain lookup failed. |
Examples
json{ "type": "v4-swap", "payload": { "tokenIn": "ETH", "tokenOut": "ETH", "amountIn": "1000000", "chainId": 1 }, "children": [], "connector": { "type": "wallet", "id": "conn_wallet" }}
bashcurl -X POST "https://api.b3os.org/v1/actions/v4-swap/test" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "inputs": { "tokenIn": "ETH", "tokenOut": "ETH", "amountIn": "1000000", "chainId": 1 }}'
Payload fields can use workflow expressions such as {{$trigger.body.amount}}, {{$nodes.fetch.result.price}}, and {{$props.asset}} when the value should come from a trigger, prior node, or reusable workflow prop.
