Swap

The Fusion AMM SDK enables swaps in a FusionPool by specifying either the input token amount (tokens to send) or the output token amount (tokens to receive). Use the mint address parameter to define the token being swapped. Additionally users can also request swap quotes to estimate output (for input-specified swaps) or input (for output-specified swaps).

  • Input-Specified Swap: The input includes fees, so only the remaining amount is swapped. Example: 1000 USDC input with 0.3% fees (3 USDC) swaps 997 USDC.

  • Output-Specified Swap: The required input includes fees on top of the base amount. Example: 10 SOL output at 150 USDC/SOL requires 1,500 USDC + 0.3% fees (4.5 USDC), totaling 1504.5 USDC.

See swapInstructions function of the high-level SDK package.

Additionally users can also request swap quotes to estimate output (for input-specified swaps) or input (for output-specified swaps), accounting for fees and pool liquidity.

Swap examples:

1. Input-Specific Swap

In the example below we are swapping SOL tokens as input, thus selling SOL.

import { SLIPPAGE_TOLERANCE_BPS, swapInstructions } 
  from "@crypticdot/fusionamm-sdk";
import { sendTransaction } from "@crypticdot/fusionamm-tx-sender";
import { address, createSolanaRpc } from "@solana/kit";

export const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
export const signer = await loadKeypair(); // Load your wallet

let poolAddress = address("7VuKeevbvbQQcxz6N4SNLmuq6PYy4AcGQRDssoqo4t65");
let mintAddress = address("So11111111111111111111111111111111111111112");
let inputAmount = 1_000_000_000n;

const swap = await swapInstructions(
  rpc,
  {
    inputAmount: inputAmount,
    mint: mintAddress,
  },
  poolAddress,
  SLIPPAGE_TOLERANCE_BPS, // 1% slippage
  signer,
);

const signature = await sendTransaction(rpc, swap.instructions, signer);
console.log("Transaction ID:", signature);

2. Output-Specific Swap

In the example below we are swapping SOL tokens as output, thus buying SOL.

import { SLIPPAGE_TOLERANCE_BPS, swapInstructions } 
  from "@crypticdot/fusionamm-sdk";
import { sendTransaction } from "@crypticdot/fusionamm-tx-sender";
import { address, createSolanaRpc } from "@solana/kit";

export const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
export const signer = await loadKeypair(); // Load your wallet

let poolAddress = address("7VuKeevbvbQQcxz6N4SNLmuq6PYy4AcGQRDssoqo4t65");
let mintAddress = address("So11111111111111111111111111111111111111112");
let outputAmount = 1_000_000_000n;

const swap = await swapInstructions(
  rpc,
  {
    outputAmount: outputAmount,
    mint: mintAddress,
  },
  poolAddress,
  SLIPPAGE_TOLERANCE_BPS, // 1% slippage
  signer,
);

const signature = await sendTransaction(rpc, swap.instructions, signer);
console.log("Transaction ID:", signature);

3. Swap Quote

In the example below, we compute the output of a swap: the amount we get, the price impact, fees, etc. The full source code: https://github.com/DefiTuna/fusionamm-sdk/blob/main/ts-sdk/cli/src/commands/swap_quote.ts

const fusionPool = await fetchFusionPool(rpc, args.pool);
const mintA = await fetchMint(rpc, fusionPool.data.tokenMintA);
const mintB = await fetchMint(rpc, fusionPool.data.tokenMintB);

const currPrice = sqrtPriceToPrice(fusionPool.data.sqrtPrice, mintA.data.decimals, mintB.data.decimals);
console.log("Current pool price:", currPrice);

// Fetch 5 tick arrays around the current prices.
const tickArrays = await fetchTickArrayOrDefault(rpc, fusionPool);

const swapQuoteParams = [
  flags.amountIn ?? flags.amountOut!,
  aToB,
  SLIPPAGE_TOLERANCE_BPS,
  fusionPool.data,
  tickArrays.map(x => x.data),
] as const;

const swapQuote = flags.amountIn
  ? swapQuoteByInputToken(...swapQuoteParams)
  : swapQuoteByOutputToken(...swapQuoteParams);

const swapQuoteAmount =
  flags.amountIn !== undefined
    ? (swapQuote as ExactInSwapQuote).tokenEstOut
    : (swapQuote as ExactOutSwapQuote).tokenEstIn;

const nextPrice = sqrtPriceToPrice(swapQuote.nextSqrtPrice, mintA.data.decimals, mintB.data.decimals);
console.log("Next pool price:", nextPrice);

if (flags.amountIn !== undefined) {
  console.log("Output amount of the swap:", swapQuoteAmount);
} else {
  console.log("Input amount required for the swap:", swapQuoteAmount);
}

const priceImpact = Math.abs(nextPrice / currPrice - 1) * 100;
console.log(`Price impact: ${priceImpact}%`);
console.log(`Trade fee:`, swapQuote.tradeFee);

Last updated