// 1. Choose input/output mints and amount.
const inputMint = NATIVE_MINT; // wSOL
const outputMint = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC
const inputAmount = "8000000"; // 0.008 SOL (lamports)
// 2. Fetch all pool basic info. Cache this aggressively — it's a large RPC fan-out.
const poolData = await raydium.tradeV2.fetchRoutePoolBasicInfo();
// 3. Enumerate every viable route across AMM v4, CPMM, CLMM, and Stable AMM.
const routes = raydium.tradeV2.getAllRoute({
inputMint,
outputMint,
...poolData,
});
// 4. Hydrate routes with the live RPC state (reserves, ticks, mint info).
const {
routePathDict,
mintInfos,
ammPoolsRpcInfo,
ammSimulateCache,
clmmPoolsRpcInfo,
computeClmmPoolInfo,
computePoolTickData,
computeCpmmData,
} = await raydium.tradeV2.fetchSwapRoutesData({
routes,
inputMint,
outputMint,
});
// 5. Compute output amounts for every candidate route. Result is sorted descending by output.
const swapRoutes = raydium.tradeV2.getAllRouteComputeAmountOut({
inputTokenAmount: new TokenAmount(
new Token({
mint: inputMint.toBase58(),
decimals: mintInfos[inputMint.toBase58()].decimals,
isToken2022: mintInfos[inputMint.toBase58()].programId.equals(TOKEN_2022_PROGRAM_ID),
}),
inputAmount,
),
directPath: routes.directPath.map(
(p) =>
ammSimulateCache[p.id.toBase58()] ||
computeClmmPoolInfo[p.id.toBase58()] ||
computeCpmmData[p.id.toBase58()],
),
routePathDict,
simulateCache: ammSimulateCache,
tickCache: computePoolTickData,
mintInfos,
outputToken: toApiV3Token({
...mintInfos[outputMint.toBase58()],
programId: mintInfos[outputMint.toBase58()].programId.toBase58(),
address: outputMint.toBase58(),
freezeAuthority: undefined,
mintAuthority: undefined,
extensions: { feeConfig: toFeeConfig(mintInfos[outputMint.toBase58()].feeConfig) },
}),
chainTime: Math.floor(raydium.chainTimeData?.chainTime ?? Date.now() / 1000),
slippage: 0.005, // 0.5%
epochInfo: await raydium.connection.getEpochInfo(),
});
const targetRoute = swapRoutes[0];
if (!targetRoute) throw new Error("no swap routes were found");
// 6. Resolve the pool keys for the chosen route.
const poolKeys = await raydium.tradeV2.computePoolToPoolKeys({
pools: targetRoute.poolInfoList,
ammRpcData: ammPoolsRpcInfo,
clmmRpcData: clmmPoolsRpcInfo,
});
// 7. Build, sign, and execute the swap transaction(s).
const { execute, transactions } = await raydium.tradeV2.swap({
routeProgram: Router,
txVersion: TxVersion.V0,
swapInfo: targetRoute,
swapPoolKeys: poolKeys,
ownerInfo: {
associatedOnly: true,
checkCreateATAOwner: true,
},
computeBudgetConfig: {
units: 600_000,
microLamports: 465_915,
},
});
// `sequentially: true` is important — the first transaction may need to create
// intermediate ATAs that subsequent transactions rely on.
const { txIds } = await execute({ sequentially: true });
console.log("txIds:", txIds);