Skip to main content

Overview

GweAI’s Swap page enables direct token-to-token exchanges without intermediate steps. Swap any supported token for another using real-time market prices and automated routing.

Direct Swaps

Trade tokens directly without selling to USDC first

Real-Time Quotes

Live pricing from smart contract router

Automatic Routing

Optimal paths via USDC when needed

Transaction History

Complete record of all your swaps

Accessing Swap

1

Navigate to Swap

Click Swap in the main navigation menu
2

Connect Your Wallet

Click Connect Wallet to enable swapping
3

Select Tokens

Choose the token to swap FROM and the token to receive
4

Enter Amount & Execute

Input amount and click Swap Tokens
Network: All swaps execute on Base Sepolia Testnet with USDC gas fees.

Swap Interface

Token Selection

Swap token selection
The swap interface has two main panels:

From Token (Sell)

  • Input: Amount to swap
  • Selector: Click to choose token
  • Balance: Shows available balance
  • USD Value: Calculated from input amount

To Token (Buy)

  • Output: Estimated amount you’ll receive
  • Selector: Click to choose token
  • Balance: Shows current holdings
  • USD Value: Calculated from output amount

Swap Button

The center button between panels:
  • Swap Direction: Click 🔄 to reverse FROM/TO tokens
  • Quick Toggle: Instantly flips your swap

Executing a Swap

1

Choose FROM Token

Click the FROM token dropdownSelect the token you want to swap (e.g., BTC)Your Balance: Shows how much you have
2

Choose TO Token

Click the TO token dropdownSelect the token you want to receive (e.g., SOL)Cannot be same as FROM token
3

Enter Amount

Type the amount of FROM token to swapExample: 0.5 (for 0.5 BTC)Auto-Calculation: TO amount updates automatically
4

Review Quote

Check the swap details card:
Rate: 1 BTC ≈ 324.67 SOL
Protocol Fee: 0.973 SOL
Slippage: 0.5%
Network Fee: ~$0.50
5

Execute Swap

Click Swap Tokens buttonApprove the transaction in your wallet
6

Confirmation

Wait for blockchain confirmation (2-5 seconds)Success toast appears with transaction hash

Smart Contract Integration

Router Contract

Swaps execute through the verified Router smart contract:
// From useSwapContract.ts
const ROUTER_ADDRESS = '0x...'  // Verified on BaseScan

const executeSwap = async ({
  tokenInAddress,   // FROM token contract
  tokenOutAddress,  // TO token contract
  amountIn,         // Amount to swap
  tokenInDecimals,  // Token decimals (6, 8, or 18)
  tokenOutDecimals, // Output token decimals
  slippageBps       // 50 = 0.5%
}) => {
  // Step 1: Get quote from router
  const quote = await getSwapQuote(params);
  
  // Step 2: Approve token spending (if first time)
  if (currentAllowance < amountIn) {
    await approveRouter();
  }
  
  // Step 3: Execute swap
  const txHash = await router.swap(
    tokenInAddress,
    tokenOutAddress,
    amountIn,
    minAmountOut  // Protected by slippage
  );
  
  return txHash;
};

Approval Flow

Why Needed:ERC-20 tokens require explicit permission for contracts to transfer them.Process:
// Check current allowance
const allowance = await token.allowance(userAddress, routerAddress);

if (allowance < amountToSwap) {
  // Request unlimited approval (better UX)
  await token.approve(routerAddress, maxUint256);
}
Benefit: You only approve once, then future swaps skip this step.
After Approval:The actual swap transaction:
const swapData = `0xfe029156${  // swap() selector
  tokenInAddress.slice(2).padStart(64, '0')  // FROM token
}${
  tokenOutAddress.slice(2).padStart(64, '0') // TO token
}${
  amountIn.toString(16).padStart(64, '0')    // Amount in
}${
  minAmountOut.toString(16).padStart(64, '0') // Min out
}`;

await walletClient.sendTransaction({
  to: ROUTER_ADDRESS,
  data: swapData
});
Post-Swap:
// Wait for blockchain confirmation
await publicClient.waitForTransactionReceipt({
  hash: txHash,
  confirmations: 1
});

// Refresh wallet balances
await refreshBalance();

// Show success notification
showSuccessToast('Swap Complete!', 'Tokens swapped successfully');

Pricing & Quotes

Real-Time Quote Fetching

Quotes are fetched from the router contract:
// From useSwapContract.ts
const getSwapQuote = async (params) => {
  const [amountOut, protocolFee] = await publicClient.readContract({
    address: ROUTER_ADDRESS,
    abi: routerAbi,
    functionName: 'getQuote',
    args: [
      tokenInAddress,
      tokenOutAddress,
      amountInWei
    ]
  });
  
  return {
    amountOut: formatUnits(amountOut, tokenOutDecimals),
    protocolFee: formatUnits(protocolFee, tokenOutDecimals),
    route: tokenInAddress === USDC || tokenOutAddress === USDC 
      ? 'Direct' 
      : 'Via USDC'
  };
};

Slippage Protection

All swaps include automatic slippage protection:
// Calculate minimum output with 0.5% slippage
const expectedOut = parseUnits(quote.amountOut, tokenOutDecimals);
const minAmountOut = (expectedOut * BigInt(9950)) / BigInt(10000);
// 9950/10000 = 99.5% of expected = 0.5% slippage tolerance
Slippage Failure: If the actual output falls below minAmountOut, the transaction reverts. This protects you from unfavorable price movements.

Price Updates

Prices refresh automatically:
  • On Amount Change: New quote fetched with 500ms debounce
  • Every 30 Seconds: Background price refresh
  • Manual Refresh: Click the 🔄 button

Supported Tokens

You can swap between these tokens:
TokenSymbolDecimalsNotes
BitcoinBTC8Wrapped BTC
EthereumETH18Display only
SolanaSOL9
BNB ChainBNB18
RippleXRP6
ToncoinTON9
AvalancheAVAX18
TRONTRX6
CardanoADA6
DogecoinDOGE8
USD CoinUSDC6Stablecoin
ETH Status: Ethereum is currently display-only and cannot be traded. If you select ETH, you’ll see an error message.

Routing Logic

Direct Swaps

Some pairs swap directly:
  • BTC ↔ USDC - Direct pool
  • SOL ↔ USDC - Direct pool
  • Any Token ↔ USDC - Direct pool

Routed Swaps

Other pairs route through USDC:
BTC → SOL

BTC → USDC → SOL
  (swap 1)  (swap 2)
Example:
  • Swap 0.5 BTC for SOL
  • Router converts: 0.5 BTC → 22,500 USDC → 161.87 SOL
  • You receive: ~161.87 SOL (minus fees)

Transaction History

Your Swap Records

The Swap page shows your complete transaction history:
Swap transaction history
Columns:
  • Pair: Token symbols with direction arrow
  • Amount In: Tokens you swapped
  • Amount Out: Tokens you received
  • Time: Transaction timestamp
  • Tx Hash: Link to blockchain explorer

Fetching History

History is fetched directly from the blockchain:
// From useSwapTransactions.ts
const { transactions, loading } = useSwapTransactions(
  userAddress,  // Only your swaps
  connected     // Only when wallet connected
);

// Fetches Swap events from Router contract
const logs = await publicClient.getLogs({
  address: ROUTER_ADDRESS,
  event: {
    name: 'Swap',
    inputs: [
      { name: 'user', type: 'address', indexed: true },
      { name: 'tokenIn', type: 'address' },
      { name: 'tokenOut', type: 'address' },
      { name: 'amountIn', type: 'uint256' },
      { name: 'amountOut', type: 'uint256' }
    ]
  },
  args: {
    user: userAddress  // Filter to your address
  },
  fromBlock: 'earliest'
});

Pagination

  • 10 swaps per page
  • Previous/Next navigation
  • Total count displayed

Fees & Costs

Fee Breakdown

Fee TypeAmountDescription
Protocol Fee0.3%Taken from output amount
Gas Fee~$0.01-0.50Paid in USDC
SlippageUp to 0.5%Price protection buffer
Example Swap:
Swapping: 100 USDC → SOL
Expected Out: 0.7194 SOL
Protocol Fee: 0.0022 SOL (0.3%)
Actual Received: 0.7172 SOL
Gas Fee: 0.15 USDC

Fee Optimization

Unlimited Approvals

Approve once, swap forever - saves gas

Batch Swaps

Combine multiple small swaps into larger ones

Direct Routes

Token ↔ USDC swaps are cheapest

Off-Peak Trading

Lower gas during low network activity

Buy USDC Modal

If you don’t have USDC for swaps or gas:
1

Click 'Buy' Tab

Switch from Swap to Buy tab in the interface
2

Buy USDC Modal Opens

Shows options to acquire USDC:
  • On-ramp providers (MoonPay, Transak)
  • Exchange transfers
  • Faucets (testnet only)
3

Follow Instructions

Complete USDC purchase through selected method
4

Return to Swap

Once USDC arrives, return to Swap tab

Security Features

Verified Contracts

All token and router contracts verified on BaseScan

Token Whitelist

Only approved tokens can be swapped

Slippage Guards

Transactions revert if price moves unfavorably

Non-Custodial

You always control your private keys

Contract Validation

// From useSwapContract.ts
if (!isVerifiedToken(tokenInAddress)) {
  throw new Error('Input token not in whitelist');
}

if (!isVerifiedToken(tokenOutAddress)) {
  throw new Error('Output token not in whitelist');
}

const validation = await validateTransaction({
  contractAddress: ROUTER_ADDRESS,
  contractType: 'ROUTER',
  userAddress: address
});

if (!validation.valid) {
  throw new Error(validation.error);
}

Troubleshooting

”Insufficient Balance” Error

Cause: Not enough of the FROM token Solution:
  1. Check balance shown under FROM token
  2. Reduce swap amount
  3. Buy or deposit more tokens

”ETH Trading Disabled” Error

Cause: ETH is currently not supported for swaps Solution:
  • Choose a different token (BTC, SOL, etc.)
  • Use the Trading page for ETH (view-only)

“Swap Failed” - Slippage Error

Cause: Price moved beyond 0.5% tolerance Solution:
  1. Wait a few seconds and retry
  2. Reduce swap amount
  3. If persistent, market is highly volatile

Quote Not Updating

Cause: Network or API issue Solution:
  1. Click the refresh 🔄 button
  2. Change amount slightly to trigger recalculation
  3. Check internet connection

Best Practices

Always review the estimated output before swappingCompare with current market prices
Test with small amounts firstVerify the swap process works as expected
Protocol fees add up on frequent swapsBatch swaps when possible
Direct swaps (to/from USDC) are cheaperToken → Token may cost more due to routing
Keep records for tax purposesDownload or screenshot swap confirmations

Advanced Features

Token Logos & Metadata

All tokens use centralized configuration:
// From tokens.ts
export const TOKENS = {
  BTC: {
    symbol: 'BTC',
    name: 'Bitcoin',
    logo: 'https://s2.coinmarketcap.com/static/img/coins/64x64/1.png',
    decimals: 8,
    coinGeckoId: 'bitcoin'
  },
  // ... other tokens
};

Amount Formatting

Amounts are formatted based on token decimals:
// From SwapPage.tsx
const formatTokenAmount = (amount: string, symbol: string): string => {
  const decimals = TOKENS[symbol]?.decimals || 18;
  const formatted = formatUnits(BigInt(amount), decimals);
  return parseFloat(formatted).toFixed(
    decimals === 6 ? 2 :   // USDC: 2 decimals
    decimals === 8 ? 8 :   // BTC: 8 decimals
    4                      // Others: 4 decimals
  );
};

Next Steps

Trading

Advanced trading with charts

Portfolio

Track your holdings

AI Chat

Swap using natural language

Vault Staking

Earn yield on swapped tokens

Build docs developers (and LLMs) love