Build a Token Swap App (AllowanceHolder)

View as Markdown

This guide walks through building a token swap app in Next.js using the 0x Swap API (AllowanceHolder).

It highlights the core concepts used in production apps like Matcha.xyz and can be adapted to any swap interface.

Try it Out

What We’re Building

This example demonstrates:

  • Fetching indicative prices via /swap/allowance-holder/price
  • Fetching firm executable quotes via /swap/allowance-holder/quote
  • Approving ERC20 allowances for AllowanceHolder
  • Submitting swap transactions on-chain

Video tutorial version here:

Pre-requisites

You should be familiar with:

This demo uses Base, but works on all supported chains.

Core Concepts

You’ll build:

  • 🌈 RainbowKit for wallet connection
  • 🏷 PriceView (indicative pricing)
  • 💸 QuoteView (firm quotes + submit transaction)
  • 🪙 Token list management

These components form the foundation of most swap apps:

Swap v2 App Core Concepts

🌈 RainbowKit

What is it?

RainbowKit is a React library that makes it easy to add wallet connection to your app. We are using their Next.js App Router example in our app.

Check out their installation instructions to understand the configurations. You can configure your desired chains and generate the required connectors.

Code

Setup WalletConnect projectId in providers.tsx

RainbowKit relies on WalletConnect. Obtain a free projectId from WalletConnect Cloud and replace the key in the .env file.

1// Inside /swap-v2-next-app/.env
2# To get a RainbowKit relies on WalletConnect, get a free projectId here:
3# https://cloud.walletconnect.com/app
4NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID="ADD_YOUR_KEY"
1// Inside /app/providers/tsx
2const projectId = process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID as string; // Uses your free key setup in .env

🏷 PriceView

What is it?

PriceView displays indicative pricing using/swap/allowance-holder/price. Indicative pricing is for users to browse for a price without committing to a trade.

Indicative prices:

  • Do not reserve liquidity
  • Are ideal for browsing or real-time updates
  • Avoid unnecessary /quote calls, which should only be used when the user intends to trade

Firm quotes are fetched later in QuoteView.

UX flow

  1. Select tokens
  2. Enter amount → triggers indicative price fetch
  3. Connect wallet (RainbowKit handles network switching)
  4. Approve allowance for AllowanceHolder
  5. Review trade → proceed to QuoteView

Code

Fetch Indicative Price

Token Allowances & Approvals

Important: Read Before Using 0x API

  • NEVER set an allowance on the Settler contract. Doing so may result in unintended consequences, including potential loss of tokens or exposure to security risks. The Settler contract does not support or require token allowances for its operation. Setting an allowance on the Settler contract will lead to misuse by other parties.

  • ONLY set allowances on AllowanceHolder or Permit2 contracts, as indicated by the API responses.

  • The correct allowance target is returned in issues.allowance.spender or allowanceTarget.

Before placing a trade on the PageView, users must set allowances on all tokens involved. A token allowance lets a third party move funds on your behalf. Essentially, you permit them to move your tokens.

In our case, we want to approve an allowance for AllowanceHolder contract to trade our ERC20 tokens for us. To do this, we need to approve a specific allowance, allowing this contract to move a certain amount of our ERC20 tokens on our behalf. Read more about token allowances.

token allowance ui

The logic to check if the user has approved a token allowance the selected sell token is setup in /app/components/price.ts.

  1. Read existing allowance with useReadContract
  2. If insufficient → simulate + write approval (useSimulateContract, useWriteContract)
  3. Wait for confirmation using useWaitForTransactionReceipt

Be aware that approvals cost gas. Looking for a gasless approach? Check out Gasless API.

Need to quickly revoke an allowance while testing? To revoke an allowance, you can set the allowance to 0. This can be done programmatically or through a UI such as https://revoke.cash/ .

💸 QuoteView

What is it?

QuoteView displays a firm, executable quote returned from /swap/allowance-holder/quote.

Firm quotes:

  • Reserve liquidity from market makers
  • Contain a fully executable order

swap demo quoteview

UX Flow

  • Shows final sell and buy amounts
  • Metadata (symbols, decimals) comes from the token list
  • User clicks “Place Order” to sign and broadcast the transaction

Code

Fetch Firm Quote

Submit Transaction

The last step is to submit the transaction with all the required parameters using your preferred web3 library (e.g. wagmi, viem, ethers.js, web3.js). In this example, we use wagmi’s useSendTransaction.

Pass the required params we get from the quote response to sendTransaction. Code here.

1sendTransaction({
2 account: walletClient?.account.address,
3 gas: !!quote?.transaction.gas ? BigInt(quote?.transaction.gas) : undefined,
4 to: quote?.transaction.to,
5 data: quote?.transaction.data,
6 chainId: chainId,
7});

🪙 Token lists

What is it?

Token Lists provide curated sets of ERC20 tokens—along with their associated metadata—that applications can use when enabling asset selection (e.g., choosing tokens to swap). These lists typically include:

  • Name (e.g., Wrapped Ether)
  • Symbol (e.g., ETH)
  • Contract address
  • logoURI

Developers can either consume an existing list in full or create a customized list derived from one or more established sources.

Commonly Used Token List Sources

Code

The demo uses a curated a token list in /src/constants.ts. In production level apps, it’s common practice to maintain a token list since some apps don’t support all available tokens.

Monetize Your Swap Integration

Swap API provides two built-in ways to monetize your swap integration—available on both free and paid plan:

  • Affiliate fees: Earn a commission on each trade (demonstrated in this example app).
  • Trade surplus: trade surplus (i.e. positive slippage) 1

For implementation details and pricing considerations, see the how to monetize your app using 0x Swap API.

1 Trade surplus is available only to select integrators on a custom plan. Contact support for access.

Conclusion

By following the best practices outlined in this blog post, you can create a user-friendly and effective app that enables trustless token swapping on our supported chains.

You now have a fully functional swap workflow that demonstrates:

  • Indicative pricing
  • Firm quotes
  • Setting token allowances
  • Submitting transactions on-chain

This pattern works across all supported chains..

Happy swapping!