Prerequisites
- Ensure you have a wallet created.
- API Key: Ensure you have an API key with the scopes:
wallets:transactions.create.
Swap Tokens
This guide explains how to swap tokens in Solana using the Jupiter advanced routing engine, which requires special configuration to work with smart wallets. If you’re using EVM chains, you can use 0x or 1inch directly. To perform a swap with the Jupiter Swap API and Crossmint wallets, follow these steps:- Request a quote from the Jupiter API.
- Build the swap transaction for that quote using the Jupiter API.
- Send the transaction using the Crossmint wallet.
For tokens with lower liquidity, the number of hops required to reach the destination token may be higher. This can
make the transaction size larger and increase the risk of failure. To minimize this risk, always set maxAccounts=33
when building the swap transaction. This ensures that even multi-hop swaps fit within Solana’s transaction account
limits and execute reliably.
- React
- Node.js
- React Native
- REST
Copy
Ask AI
import { useWallet, SolanaWallet } from '@crossmint/client-sdk-react-ui';
import { VersionedTransaction } from '@solana/web3.js';
export function SwapTokensComponent() {
const { wallet } = useWallet();
async function swapTokens(tokenIn: string, tokenOut: string, amount: number) {
// Get a quote from the Jupiter API
const queryParams = new URLSearchParams({
inputMint: tokenIn, // e.g "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
outputMint: tokenOut, // e.g "XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN"
amount: amount.toString(), // In lamports!
slippageBps: "50",
maxAccounts: "33", // This ensures that even multi-hop swaps fit within Solana's transaction account limits and execute reliably.
});
const response = await fetch(`https://lite-api.jup.ag/swap/v1/quote?${queryParams}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const quoteResponse = await response.json();
// Build the swap transaction
const swapResponse = await fetch("https://lite-api.jup.ag/swap/v1/swap", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userPublicKey: wallet.address,
quoteResponse: quoteResponse,
}),
});
const swapResponseData = await swapResponse.json();
// Send the transaction
const solanaWallet = SolanaWallet.from(wallet);
const versionedTransaction = VersionedTransaction.deserialize(
Buffer.from(swapResponseData.swapTransaction, "base64")
);
const tx = await solanaWallet.sendTransaction({
transaction: versionedTransaction,
});
console.log("Swap transaction sent successfully!");
}
return (
<div>
<button onClick={() => swapTokens("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN", 1)}>Swap Tokens</button>
</div>
);
}
Copy
Ask AI
import { CrossmintWallets, createCrossmint, SolanaWallet } from "@crossmint/wallets-sdk";
import { VersionedTransaction } from "@solana/web3.js";
const crossmint = createCrossmint({
apiKey: "<your-server-api-key>",
});
const crossmintWallets = CrossmintWallets.from(crossmint);
const wallet = await crossmintWallets.getWallet(
"email:[email protected]:solana",
{ chain: "solana", signer: { type: "email" } }
);
// Get a quote from the Jupiter API
const tokenIn = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
const tokenOut = "XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN";
const amount = 1000000000;
const queryParams = new URLSearchParams({
inputMint: tokenIn,
outputMint: tokenOut,
amount: amount.toString(), // In lamports!
slippageBps: "50",
maxAccounts: "33", // This ensures that even multi-hop swaps fit within Solana's transaction account limits and execute reliably.
});
const response = await fetch(`https://lite-api.jup.ag/swap/v1/quote?${queryParams}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const quoteResponse = await response.json();
// Build the swap transaction
const swapResponse = await fetch("https://lite-api.jup.ag/swap/v1/swap", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userPublicKey: wallet.address,
quoteResponse: quoteResponse,
}),
});
const swapResponseData = await swapResponse.json();
// Send the transaction
const solanaWallet = SolanaWallet.from(wallet);
const versionedTransaction = VersionedTransaction.deserialize(
Buffer.from(swapResponseData.swapTransaction, "base64")
);
const tx = await solanaWallet.sendTransaction({
transaction: versionedTransaction,
});
console.log("Swap transaction sent successfully!");
Copy
Ask AI
import { useWallet, SolanaWallet } from '@crossmint/client-sdk-react-native-ui';
import { View, Button } from 'react-native';
import { VersionedTransaction } from '@solana/web3.js';
export function SwapTokensComponent() {
const { wallet } = useWallet();
async function swapTokens(tokenIn: string, tokenOut: string, amount: number) {
// Get a quote from the Jupiter API
const queryParams = new URLSearchParams({
inputMint: tokenIn, // e.g "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
outputMint: tokenOut, // e.g "XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN"
amount: amount.toString(), // In lamports!
slippageBps: "50",
maxAccounts: "33", // This ensures that even multi-hop swaps fit within Solana's transaction account limits and execute reliably.
});
const response = await fetch(`https://lite-api.jup.ag/swap/v1/quote?${queryParams}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const quoteResponse = await response.json();
// Build the swap transaction
const swapResponse = await fetch("https://lite-api.jup.ag/swap/v1/swap", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userPublicKey: wallet.address,
quoteResponse: quoteResponse,
}),
});
const swapResponseData = await swapResponse.json();
// Send the transaction
const solanaWallet = SolanaWallet.from(wallet);
const versionedTransaction = VersionedTransaction.deserialize(
Buffer.from(swapResponseData.swapTransaction, "base64")
);
const tx = await solanaWallet.sendTransaction({
transaction: versionedTransaction,
});
console.log("Swap transaction sent successfully!");
}
return (
<View>
<Button onPress={() => swapTokens("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN", 1)}>Swap Tokens</Button>
</View>
);
}
Transactions must be approved by one of the wallet’s signers.
The SDK handles this automatically, but with the REST API you must approve the transaction to complete it.
1
Call the get quote endpoint
Call the get quote endpoint to get a quote for the swap.See the Jupiter API docs for more details.
Copy
Ask AI
curl --request POST \
--url https://lite-api.jup.ag/swap/v1/quote?inputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&outputMint=XsCPL9dNWBMvFtTmwcCA5v3xWPSMEBCszbQdiLLq6aN&amount=1000000000&slippageBps=50&maxAccounts=33 \
--header 'Content-Type: application/json'
2
Build the swap transaction
Build the swap transaction using the swap endpoint and pass in the quote response from the previous step.See the Jupiter API docs for more details.
Copy
Ask AI
curl --request POST \
--url https://lite-api.jup.ag/swap/v1/swap \
--header 'Content-Type: application/json' \
--data '{"userPublicKey": "<user-public-key>", "quoteResponse": <quote-response>}'
3
Send the transaction
Follow the steps in the Send a transaction guide to submit the returned transaction in the previous step.

