Learn how to perform and monitor swap operations with AaveKit.
Alongside the Position Swaps feature, AaveKit provides the following tools for swapping:
Swap Tokens: exchange tokens instantly at market price or set conditions with a limit order.
Monitor Swap Status: track the status of a swap.
User Swaps: list and filter user swaps.
Cancel a Swap: cancel a swap in progress.
Swaps are implemented using a modular provider architecture. Currently, CoW Protocol is the swap provider, offering MEV protection and optimal execution through batch auctions.
Review the fees section to understand the swap costs.
Swap Tokens
Token swaps can be executed in two ways:
Intent-based: The swap is signed off-chain and submitted as an intent, which is then executed by a solver. This is the preferred method as it is gasless for users.
Transaction-based: The swap is executed directly on-chain via a transaction. This method is used when intent-based execution is not available.
Native token swaps are always transaction-based since users must send funds directly.
Swapping tokens involves the following steps:
Select the token to swap from
Select the token to swap to
Choose between market order and limit order
Execute the swap operation
Source Token
Fetch user token balances that can be swapped. This allows you to display only tokens the user owns that are swappable, making source token selection easier.
- React
- TypeScript
- GraphQL
Use the useUserBalances hook with the swappable filter to list user tokens that can be swapped.
You can query for swappable token balances as follows:
For more details on filtering and sorting user balances, see the User Balances documentation.
Destination Token
Once you've selected a source token, fetch the tokens you can swap TO. This ensures you only display valid swap destinations for the selected source token.
- React
- TypeScript
- GraphQL
Use useSwappableTokens to list destination tokens based on your selected source token.
You can query for a list of swappable tokens as follows:
Market or Limit Order
Once you've identified the tokens to swap, the next step is choosing an order type. Market orders execute immediately at the current rate, while limit orders wait until your specified price conditions are met.
- Market
- Limit
To place a market order, specify the token pair, amount, and swap direction.
The request takes the following parameters:
chainId — The target chain
sell — The token to sell (native or erc20)
buy — The token to receive (native or erc20)
amount — The swap amount, interpreted based on kind
kind — Sell (default) or Buy, determines how amount is interpreted
user — The sender address
receiver — The recipient address (defaults to user)
selectedSlippage — Optional slippage tolerance to use instead of the suggested slippage
Since only one amount is provided, the swap kind determines what gets calculated:
| Swap Kind | User inputs… | System calculates… | |
|---|---|---|---|
| Sell | How much of the token to sell and which token to buy | The amount of the buy token you'll receive | |
| Buy | How much of the token to buy and which token to sell | The amount of the sell token you need to provide |
Depending on the token pair, swaps can be performed in different ways:
Execute Swaps
- React
- TypeScript
- GraphQL
To execute the swap operation with AaveKit React, follow these steps.
First, use the useTokenSwapQuote hook (or the imperative useTokenSwapQuoteAction variant) to get a swap quote.
The useTokenSwapQuoteAction hook does not watch for updates. Use it when you need on-demand, fresh data (e.g., in an event handler).
You can specify a different currency to return fiat amounts in.
The SwapQuote object provides detailed pricing information for swap operations.
Where:
accuracy — quote accuracy level (QuoteAccuracy.Fast or QuoteAccuracy.Accurate)
quoteId — a unique quote identifier required for executing the swap
buy and sell — current prices before fees
finalBuy and finalSell — amounts you'll receive/pay after fees and slippage
costs — a breakdown of all fees (partner fee, provider fee, flash loan fee, network costs)
suggestedSlippage — recommended slippage tolerance
selectedSlippage — the slippage tolerance selected when requesting a market quote (if provided)
For limit orders, consider fetching a market quote first to get current buy and sell values. Use these as a baseline to repeat the swap quote with a limit order request.
Then, instantiate the hooks for the wallet library of your choice:
useSendTransaction — used to send ERC-20 approval and swap transactions when needed
useSignTypedData — used to sign ERC-20 permits and swap order typed data
Viem
import { useWalletClient } from "wagmi";import { useSendTransaction, useSignTypedData } from "@aave/react/viem";
// …
const { data: wallet } = useWalletClient();const [sendTransaction] = useSendTransaction(wallet);const [signTypedData] = useSignTypedData(wallet);Then, execute the swap. The approach differs based on order type: market orders execute immediately at current prices, while limit orders let you set specific price conditions.
- Market Order
- Limit Order
For market orders, call swap with the quoteId from the last market order quote.
Basic Usage
const execute = async (quote: SwapQuote) => { const result = await swap({ fromQuote: { quoteId: quote.quoteId, }, });
if (result.isErr()) { console.error(result.error); return; }
// result.value: SwapReceipt console.log("Swap order placed:", result.value);};Finally, handle the result.
Handle Result
if (result.isErr()) { switch (result.error.name) { case "CancelError": // The user cancelled the operation return;
case "SigningError": console.error(`Failed to sign: ${result.error.message}`); break;
case "TimeoutError": console.error(`Transaction timed out: ${result.error.message}`); break;
case "TransactionError": console.error(`Transaction failed: ${result.error.message}`); break;
case "ValidationError": switch (result.error.cause.__typename) { case "InsufficientBalanceError": console.error( `Insufficient balance: ${result.error.cause.required.value.toDisplayString(2)} required.`, ); break; case "InsufficientLiquidityError": console.error(`Insufficient liquidity: ${result.error.cause.reason}`); break; } break;
case "UnexpectedError": console.error(result.error.message); break; } return;}// result.value: SwapReceiptconsole.log("Swap order placed:", result.value);That's it—you placed your first swap order. Keep track of its status in the Monitor Swap Status section.
Monitor Swap Status
Once the swap is executed, a SwapReceipt object is returned with an id field. Use this id to track the swap status. For more details, see the Execute Swaps section.
- React
- TypeScript
- GraphQL
Use the useSwapStatus hook to monitor the status of a swap in real-time.
The hook automatically polls for status updates until the swap reaches a terminal state: fulfilled, cancelled, or expired.
User Swaps
List and filter user swaps with built-in pagination support.
- React
- TypeScript
- GraphQL
Use the useUserSwaps hook to list user swaps.
The hook automatically polls for status updates until all listed swaps reach a terminal state: fulfilled, cancelled, or expired.
You can filter swaps as follows:
Cancel a Swap
Before cancelling, identify the swap by its status.
Only swaps with status Open can be cancelled.
User Swaps
const swapsItems: SwapStatus[] = [ { __typename: "SwapOpen", swapId: "adb123…", // … }, { __typename: "SwapPendingSignature", // … }, { __typename: "SwapCancelled", // … }, { __typename: "SwapExpired", // … }, { __typename: "SwapFulfilled", // … },];After identifying the swap, follow the steps below to cancel it with AaveKit.
- React
- TypeScript
- GraphQL
To cancel a swap with AaveKit React:
First, instantiate the useSendTransaction and useSignTypedData hooks for the wallet library of your choice.
Viem
import { useWalletClient } from "wagmi";import { useSendTransaction, useSignTypedData } from "@aave/react/viem";
// …
const { data: wallet } = useWalletClient();const [sendTransaction] = useSendTransaction(wallet);const [signTypedData, signing] = useSignTypedData(wallet);Then, execute the cancel swap operation.
Cancel Swap
const execute = async () => { const result = await cancelSwap({ id: swapReceipt.id, });};Finally, handle the result.
Handle Result
if (result.isErr()) { switch (result.error.name) { case "CancelError": // The user cancelled the operation return;
case "SigningError": console.error(`Failed to sign the transaction: ${result.error.message}`); break;
case "TimeoutError": console.error(`Transaction timed out: ${result.error.message}`); break;
case "TransactionError": console.error(`Transaction failed: ${result.error.message}`); break;
case "UnexpectedError": console.error(result.error.message); break; } return;}
// result.value: SwapCancelledResultconsole.log("Swap cancelled:", result.value.cancelledAt);That's it—you cancelled your first swap. Keep track of its status in the Monitor Swap Status section.
Fees
Swaps include a network fee, partner fee, provider fee, and in the case of Position Swaps a flash loan fee.
Network Fee
The network fee covers gas costs for executing the swap transaction on-chain. This fee varies based on current network congestion and is paid in the chain's native token (e.g., ETH on Ethereum).
Partner Fee
Aave Labs applies a fee to swaps done through the Aave Labs API. The fee depends on the swap operation and token pair:
Borrow Swap: 0% fee across all pairs.
All other swap operations: a discounted fee of 0.15% is applied to swaps between correlated assets (e.g., ETH/wstETH), while 0.25% is applied to all other pairs.
Correlated assets are tokens that maintain a stable price relationship, typically pegged to the same underlying asset or index. Swaps between correlated assets receive a discounted fee because they carry lower price risk.
The following asset groups are considered correlated (list reviewed and updated periodically):
Stablecoins: USDC, USDT, DAI, GHO, EURC, USDbC, USDe, USDS, sUSDe, RLUSD, PYUSD, LUSD, sDAI, crvUSD, USD₮0, USDC.e, EURe, xDAI, wxDAI
ETH correlated: weETH, ETH, WETH, wstETH, cbETH, ezETH, wrsETH, osETH, rETH, ETHx
BTC correlated: cbBTC, WBTC, LBTC, tBTC, eBTC
Provider Fee
CoW Protocol charges a fee for swap execution: 0.02% for most pairs, reduced to 0.003% for tokens in their Reduced Fee Tokens list (a dynamic registry of major stablecoins and RWAs based on price volatility). The fee is included in the swap quote.
Flash Loan Fee
Some of the Position Swaps require flash loans to execute atomically. When applicable, a flash loan fee of 0.05% of the flash-loaned amount is charged. This fee is collected by the protocol treasury and controlled by the DAO through governance.
Flash loan fees apply to operations that require borrowing assets temporarily (e.g., Swap Borrow Asset). Operations that use existing positions (e.g., Withdraw and Swap) typically do not incur flash loan fees.