Swaps enable users to instantly trade between assets in a pool. Users can use the SDK to both simulate the outcome of a swap before executing it, and to execute the swap.

Simulating a Swap

Always simulate a swap before executing to check the expected output and slippage:
async function simulateSwap() {
  try {
    const simulation = await client.simulateSwap({
      poolId: "pool-public-key",
      assetInAddress: "bitcoin-pubkey",
      assetOutAddress: "usdb-pubkey",
      amountIn: "100000000", // 1 BTC in satoshis
    });

    console.log('Expected output:', simulation.amountOut);
    console.log('Execution price:', simulation.executionPrice);
    console.log('Price impact %:', simulation.priceImpactPct);
    
    return simulation;
  } catch (error) {
    console.error('Simulation failed:', error);
  }
}

Executing a Swap

After simulating, execute the swap with slippage protection:
async function executeSwap() {
  try {
    // First simulate to get expected output
    const simulation = await client.simulateSwap({
      poolId: "pool-public-key",
      assetInAddress: "bitcoin-pubkey",
      assetOutAddress: "usdb-pubkey",
      amountIn: "100000000", // 1 BTC
    });

    // Calculate minimum output with slippage tolerance
    const minAmountOut = BigInt(simulation.amountOut) * 99n / 100n; // 1% slippage

    // Execute the swap
    const swap = await client.executeSwap({
      poolId: "pool-public-key",
      assetInAddress: "bitcoin-pubkey",
      assetOutAddress: "usdb-pubkey",
      amountIn: "100000000", // 1 BTC
      minAmountOut: minAmountOut.toString(),
      maxSlippageBps: 100, // 1% max slippage
    });

    console.log('Swap successful!');
    console.log('Amount out:', swap.amountOut);
    console.log('Outbound transfer:', swap.outboundTransferId);
    
    return swap;
  } catch (error) {
    console.error('Swap failed:', error);
  }
}

Advanced Swap Examples

Note on integrator fees:
  • If you set integratorFeeRateBps up to 30 BPS, none of the integrator fee is shared with Flashnet
  • If you set integratorFeeRateBps above 30 BPS, 30% of the integrator fee is shared with Flashnet
All host and integrator fees are assessed and distributed in Asset B only. Displayed amountOut values from the API are post‑fee.

Token-to-Token Swap

async function swapTokenToToken() {
  const swap = await client.executeSwap({
    poolId: "pool-id",
    assetInAddress: "token-a-pubkey",
    assetOutAddress: "token-b-pubkey",
    amountIn: "1000000", // Amount in token A's smallest units
    minAmountOut: "950000", // Minimum acceptable output
    maxSlippageBps: 50, // 0.5% max slippage
  });
  
  console.log('Swapped', swap.amountIn, 'for', swap.amountOut);
}

Bitcoin-to-Token Swap

async function swapBTCToToken() {
  const BTC_PUBKEY = "020202020202020202020202020202020202020202020202020202020202020202";
  
  const swap = await client.executeSwap({
    poolId: "pool-id",
    assetInAddress: BTC_PUBKEY,
    assetOutAddress: "usdb-pubkey",
    amountIn: "10000000", // 0.1 BTC in satoshis
    minAmountOut: "9900000000", // Minimum 99,000 USDB (with 6 decimals)
    maxSlippageBps: 100, // 1% max slippage
  });
  
  console.log('Swapped BTC for USDB:', swap);
}

Swap with Price Checks

async function swapWithPriceValidation() {
  const poolId = "pool-id";
  const amountIn = 100000000n; // 1 BTC
  
  // Get current pool state
  const pool = await client.getPool(poolId);
  
  // Calculate spot price
  const spotPrice = Number(pool.assetBReserve) / Number(pool.assetAReserve);
  console.log('Current spot price:', spotPrice);
  
  // Simulate swap
  const simulation = await client.simulateSwap({
    poolId: poolId,
    assetInAddress: pool.assetAAddress,
    assetOutAddress: pool.assetBAddress,
    amountIn: amountIn.toString(),
  });
  
  // Calculate effective price
  const effectivePrice = Number(simulation.amountOut) / Number(amountIn);
  const priceImpact = ((spotPrice - effectivePrice) / spotPrice) * 100;
  
  console.log('Effective price:', effectivePrice);
  console.log('Price impact:', priceImpact.toFixed(2), '%');
  
  // Only proceed if price impact is acceptable
  if (priceImpact < 2) { // Less than 2% impact
    const swap = await client.executeSwap({
      poolId: poolId,
      assetInAddress: pool.assetAAddress,
      assetOutAddress: pool.assetBAddress,
      amountIn: amountIn.toString(),
      minAmountOut: (BigInt(simulation.amountOut) * 98n / 100n).toString(), // 2% slippage
      maxSlippageBps: 200,
    });
    
    console.log('Swap executed:', swap);
  } else {
    console.log('Price impact too high, swap cancelled');
  }
}

Error Handling

async function swapWithErrorHandling() {
  try {
    const swap = await client.executeSwap({
      poolId: "pool-id",
      assetInAddress: "bitcoin-pubkey",
      assetOutAddress: "usdb-pubkey",
      amountIn: "100000000",
      minAmountOut: "99000000000",
      maxSlippageBps: 100,
    });
    
    console.log('Success:', swap);
  } catch (error) {
    if (error.message.includes('Insufficient balance')) {
      console.error('Not enough funds to execute swap');
    } else if (error.message.includes('Slippage exceeded')) {
      console.error('Price moved too much during execution');
    } else if (error.message.includes('Pool inactive')) {
      console.error('Pool is currently inactive');
    } else {
      console.error('Swap failed:', error);
    }
  }
}

Next Steps