Skip to content

Complete Example

This example demonstrates a complete bridge flow using the Core SDK in a Node.js backend environment.

Setup

import { 
  getBridgeQuote,
  convertQuoteResultToQuote,
  executeBridgeTransaction,
  getBridgeStatus,
  type BridgeProvider,
  type BridgeStatus,
} from '@silentswap/sdk';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { ethereum, avalanche } from 'viem/chains';
 
// Create wallet client
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({
  account,
  chain: ethereum,
  transport: http(),
});
 
// Simple connector implementation for chain switching
const connector = {
  switchChain: async ({ chainId }: { chainId: number }) => {
    // For production, you'd want to create a new client for the target chain
    // This is a simplified example
    console.log(`Switching to chain ${chainId}`);
  },
};

Complete Bridge Flow

async function bridgeTokens(
  srcChainId: number,
  srcToken: string,
  srcAmount: string,
  dstChainId: number,
  dstToken: string,
  userAddress: `0x${string}`
) {
  try {
    // Step 1: Get quote (compares providers and selects best)
    console.log('Fetching bridge quote...');
    const quoteResult = await getBridgeQuote(
      srcChainId,
      srcToken,
      srcAmount,
      dstChainId,
      dstToken,
      userAddress
    );
 
    console.log('Quote received:');
    console.log(`  Provider: ${quoteResult.provider}`);
    console.log(`  Output Amount: ${quoteResult.outputAmount}`);
    console.log(`  Fee (USD): ${quoteResult.feeUsd.toFixed(2)}`);
    console.log(`  Slippage: ${quoteResult.slippage.toFixed(2)}%`);
    console.log(`  Retention Rate: ${(quoteResult.retentionRate * 100).toFixed(2)}%`);
    console.log(`  Estimated Time: ${quoteResult.estimatedTime}s`);
 
    // Step 2: Convert to executable quote with transactions
    console.log('\nConverting to executable quote...');
    const quote = convertQuoteResultToQuote(quoteResult, srcChainId);
 
    // Step 3: Execute transaction
    console.log('\nExecuting bridge transaction...');
    const status = await executeBridgeTransaction(
      quote,
      walletClient,
      connector,
      (step) => {
        console.log(`  → ${step}`);
      }
    );
 
    if (status.status !== 'pending') {
      throw new Error(`Unexpected status: ${status.status}`);
    }
 
    console.log('\nTransaction submitted:');
    console.log(`  Transaction Hashes: ${status.txHashes?.join(', ')}`);
    console.log(`  Request ID: ${status.requestId}`);
 
    // Step 3: Monitor status
    if (status.requestId) {
      console.log('\nMonitoring bridge status...');
      const finalStatus = await pollBridgeStatus(
        status.requestId,
        quote.provider
      );
 
      console.log('\nFinal status:', finalStatus.status);
      if (finalStatus.txHashes) {
        console.log('Transaction Hashes:', finalStatus.txHashes);
      }
 
      return finalStatus;
    }
 
    return status;
  } catch (err) {
    console.error('Bridge error:', err);
    throw err;
  }
}
 
// Helper function to poll status
async function pollBridgeStatus(
  requestId: string,
  provider: BridgeProvider,
  maxAttempts: number = 60,
  intervalMs: number = 5000
): Promise<BridgeStatus> {
  for (let i = 0; i < maxAttempts; i++) {
    const status = await getBridgeStatus(requestId, provider);
    
    if (status.status === 'success') {
      return status;
    }
    
    if (status.status === 'failed' || status.status === 'refund') {
      return status;
    }
    
    console.log(`  Attempt ${i + 1}/${maxAttempts}: ${status.status}...`);
    await new Promise(resolve => setTimeout(resolve, intervalMs));
  }
  
  throw new Error('Bridge status polling timeout');
}

Usage Example

// Bridge USDC from Ethereum to Avalanche
const result = await bridgeTokens(
  1, // Ethereum
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
  '1000000', // 1 USDC (6 decimals)
  43114, // Avalanche
  '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', // USDC.e
  account.address
);
 
console.log('Bridge completed:', result);

Example with Optimal USDC Solving

import { 
  getBridgeQuote,
  convertQuoteResultToQuote,
  solveOptimalUsdcAmount,
  executeBridgeTransaction,
} from '@silentswap/sdk';
 
async function bridgeToUsdcWithDeposit(
  srcChainId: number,
  srcToken: string,
  srcAmount: string,
  userAddress: `0x${string}`,
  depositCalldata: string
) {
  // Step 1: Solve for optimal USDC amount
  console.log('Solving for optimal USDC amount...');
  const solveResult = await solveOptimalUsdcAmount(
    srcChainId,
    srcToken,
    srcAmount,
    userAddress,
    depositCalldata
  );
 
  console.log('Solve result:');
  console.log(`  USDC Out: ${solveResult.usdcAmountOut.toString()}`);
  console.log(`  Amount In: ${solveResult.actualAmountIn.toString()}`);
  console.log(`  Provider: ${solveResult.provider}`);
  console.log(`  Allowance Target: ${solveResult.allowanceTarget}`);
 
    // Step 2: Get quote with the solved amount
    const quoteResult = await getBridgeQuote(
      srcChainId,
      srcToken,
      solveResult.actualAmountIn.toString(),
      43114, // Avalanche
      '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', // USDC on Avalanche
      userAddress
    );
 
    // Convert to executable quote
    const quote = convertQuoteResultToQuote(quoteResult, srcChainId);
 
  // Step 3: Execute transaction
  const status = await executeBridgeTransaction(
    quote,
    walletClient,
    connector,
    (step) => console.log(`  → ${step}`)
  );
 
  return { solveResult, quote, status };
}

Error Handling Example

async function safeBridgeTokens(...args: Parameters<typeof bridgeTokens>) {
  try {
    return await bridgeTokens(...args);
  } catch (err) {
    if (err instanceof AggregateError) {
      console.error('All providers failed:');
      err.errors.forEach((error, i) => {
        console.error(`  Provider ${i + 1}:`, error.message);
      });
    } else if (err.message.includes('Price impact too high')) {
      console.error('Price impact exceeded maximum. Try a smaller amount.');
    } else if (err.message.includes('Failed to switch to chain')) {
      console.error('Chain switching failed. Ensure the chain is supported.');
    } else if (err.message.includes('AbortError')) {
      console.error('Request was cancelled or timed out.');
    } else {
      console.error('Unexpected error:', err);
    }
    throw err;
  }
}

Telegram Bot Example

import { Telegraf } from 'telegraf';
import { getBridgeQuote } from '@silentswap/sdk';
 
const bot = new Telegraf(process.env.BOT_TOKEN!);
 
bot.command('quote', async (ctx) => {
  try {
    const quote = await getBridgeQuote(
      1, // Ethereum
      '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
      '1000000', // 1 USDC
      43114, // Avalanche
      '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', // USDC.e
      ctx.from.id.toString() // Use user ID as identifier
    );
 
    await ctx.reply(
      `Bridge Quote:\n` +
      `Provider: ${quote.provider}\n` +
      `Output: ${quote.outputAmount}\n` +
      `Fee: ${quote.feeUsd.toFixed(2)}\n` +
      `Slippage: ${quote.slippage.toFixed(2)}%`
    );
  } catch (err) {
    await ctx.reply(`Error: ${err.message}`);
  }
});
 
bot.launch();

Next Steps