Skip to main content

Overview

This guide shows you how to execute same-chain token swaps using the deBridge API. You’ll see examples for both EVM chains and Solana.

EVM chain swap example

This example demonstrates swapping USDC to MATIC on Polygon.

Setup

First, import the required dependencies and set up your wallet:
import { ethers, Wallet, Contract } from "ethers";
import { SameChainSwapInput } from './types';
import { createDeBridgeSameChainSwap } from './utils/deBridge/sameChainSwap';
import { EVM_NATIVE_TOKEN, USDC } from './utils/tokens';
import { CHAIN_IDS } from './utils/chains';

const wallet = new Wallet(privateKey);
const signer = wallet.connect(polygonProvider);
const senderAddress = await signer.getAddress();

Create the swap parameters

Define your swap parameters with token addresses and amounts:
const usdcDecimals = 6;
const amountToSend = "0.2";
const amountInAtomicUnit = ethers.parseUnits(amountToSend, usdcDecimals);

const sameChainSwapInput: SameChainSwapInput = {
  chainId: CHAIN_IDS.Polygon.toString(),
  tokenIn: USDC.POLYGON,
  tokenInAmount: amountInAtomicUnit.toString(),
  tokenOut: EVM_NATIVE_TOKEN.address, // 0x0000... for native MATIC
  tokenOutRecipient: senderAddress,
  senderAddress: senderAddress,
};
Token amounts must be in the token’s smallest unit (atomic units). For USDC with 6 decimals, use parseUnits() to convert.

Get the swap transaction

Call the deBridge API to generate the transaction:
const swap = await createDeBridgeSameChainSwap(sameChainSwapInput);

if (!swap || !swap.tx || !swap.tx.to || !swap.tx.data) {
  throw new Error("Invalid transaction request from API");
}

console.log("Order Estimation:", swap);
const transactionRequest = swap.tx;
The response includes:
  • tx - The transaction object to sign and send
  • tokenIn - Details about the input token and amount
  • tokenOut - Expected output token amount and minimum amount
  • slippage - Applied and recommended slippage values
  • estimatedTransactionFee - Gas fee estimates

Approve token spending

For ERC-20 tokens, you need to approve the deBridge contract:
const tokenContract = new Contract(sameChainSwapInput.tokenIn, erc20Abi, signer);
const spenderAddress = transactionRequest.to;
const requiredAmount = BigInt(swap.tokenIn.amount);

// Check current allowance
const currentAllowance = await tokenContract.allowance(
  senderAddress,
  spenderAddress
);

if (currentAllowance < requiredAmount) {
  console.log("Approving token spending...");
  const approveTx = await tokenContract.approve(spenderAddress, requiredAmount);
  await approveTx.wait();
  console.log("Approval confirmed");
}
Always verify the current allowance before approving to avoid unnecessary transactions.

Execute the swap

Send the transaction to complete the swap:
const txResponse = await signer.sendTransaction(transactionRequest);
console.log(`Transaction Hash: ${txResponse.hash}`);
console.log(`View on Polygonscan: https://polygonscan.com/tx/${txResponse.hash}`);

const txReceipt = await txResponse.wait();
if (txReceipt && txReceipt.status === 1) {
  console.log("Swap completed successfully!");
  console.log(`Block number: ${txReceipt.blockNumber}`);
  console.log(`Gas used: ${txReceipt.gasUsed.toString()}`);
}

Solana swap example

This example demonstrates swapping USDC to SOL on Solana.

Setup for Solana

Import Solana-specific dependencies:
import { Connection, Keypair } from "@solana/web3.js";
import bs58 from 'bs58';
import { prepareSolanaTransaction } from './utils/solana';
import { SOL, USDC } from './utils/tokens';

const solWallet = Keypair.fromSecretKey(bs58.decode(solPrivateKey));
const connection = new Connection(solRpcUrl, { commitment: "confirmed" });

Create Solana swap parameters

const usdcDecimals = 6;
const amountToSend = "0.2";
const amountInAtomicUnit = ethers.parseUnits(amountToSend, usdcDecimals);

const sameChainSwapInput: SameChainSwapInput = {
  chainId: CHAIN_IDS.Solana.toString(), // 7565164
  tokenIn: USDC.SOLANA,
  tokenInAmount: amountInAtomicUnit.toString(),
  tokenOut: SOL.nativeSol,
  tokenOutRecipient: solWallet.publicKey.toBase58(),
  senderAddress: solWallet.publicKey.toBase58(),
};

Execute Solana swap

Generate and send the Solana transaction:
const swap = await createDeBridgeSameChainSwap(sameChainSwapInput);

if (!swap || !swap.tx || !swap.tx.data) {
  throw new Error("Invalid transaction request from API");
}

// Prepare and sign the transaction
const signedTx = await prepareSolanaTransaction(
  solRpcUrl,
  swap.tx.data,
  solWallet
);

// Send the transaction
const raw = signedTx.serialize();
const signature = await connection.sendRawTransaction(raw, {
  skipPreflight: false
});

console.log(`Transaction Signature: ${signature}`);
console.log(`View on Solscan: https://solscan.io/tx/${signature}`);
Solana transactions don’t require separate token approval. The approval is handled within the transaction itself.

Complete examples

View the complete, runnable examples in the source repository:
  • Polygon USDC to MATIC: src/scripts/same-chain/poly-usdc-to-matic.ts:1
  • Solana USDC to SOL: src/scripts/same-chain/sol-usdc-to-sol.ts:1
  • MegaETH USDM to ETH: src/scripts/same-chain/megaEth-usdm-to-eth.ts:1

Error handling

Implement proper error handling for production use:
try {
  const swap = await createDeBridgeSameChainSwap(sameChainSwapInput);
  // ... execute swap
} catch (error) {
  if (error instanceof Error) {
    console.error(`Swap failed: ${error.message}`);
  }
  // Handle specific error cases:
  // - Insufficient balance
  // - Slippage too high
  // - Network errors
}

Next steps

Get swap estimations

Learn how to get detailed swap estimations before executing transactions

Build docs developers (and LLMs) love