Prerequisites
- A Crossmint production client-side API key with wallet permissions enabled (create in Console → API Keys)
- USDC on Base mainnet in your Crossmint wallet
- ETH on Base for gas fees (not required if gas sponsorship is enabled)
- Node.js 18+
How It Works
- The user signs in with email via Crossmint Auth
- Crossmint provisions an EVM smart wallet
- The app fetches a bridge quote from the LI.FI API (server-side)
- The user approves the USDC spend and signs the swap transaction (client-side)
- The app polls LI.FI for the bridge status until completion
Step-by-Step
Create the Project
Scaffold a new Next.js app:Install the Crossmint SDK and viem:Create a Replace
.env.local file in the project root:.env.local
<your-client-api-key> with the client-side API key from the Crossmint Console.Set Up Crossmint Providers
Wrap the app in Crossmint’s auth and wallet providers. This configures wallet creation on Base with an email signer, giving users a non-custodial wallet they fully control.Then import this in your root layout:
app/providers.tsx
app/layout.tsx
Create the LI.FI Server Actions
These Next.js Server Actions call the LI.FI API to fetch quotes and poll the bridge status.
app/actions/swap.ts
getSwapQuote returns a quote object that includes the transaction calldata and an estimated output amount. getSwapStatus polls the bridge status by transaction hash.Build the Swap Page
The main page handles three responsibilities: authentication, fetching a quote, and executing the swap. The swap flow has two on-chain transactions:
- Approve — grant the LI.FI router permission to spend USDC
- Swap — execute the bridge transaction using calldata from the quote
Because the wallet uses an email signer (non-custodial), a signing prompt appears the first time the user sends a transaction in a session. Subsequent transactions in the same session do not require additional approval.
app/page.tsx
Swap Flow Summary
| Step | Where | What happens |
|---|---|---|
| Get Quote | Server | Calls LI.FI /quote with token addresses and amount |
| Approve | Client | Signs an ERC-20 approve transaction for the LI.FI router |
| Execute Swap | Client | Signs the swap transaction using calldata from the quote |
| Poll Status | Server | Calls LI.FI /status every five seconds until DONE or FAILED |
Customizing the Swap
You can bridge any token pair that LI.FI supports by changing the constants at the top ofpage.tsx:

