Making a Trade
This guide demonstrates how to execute a swap. In this example, we will be swapping 20 USDC for AVAX.
1. Required imports for this guide
import {
ChainId,
WNATIVE,
Token,
TokenAmount,
Percent,
} from "@traderjoe-xyz/sdk-core";
import {
PairV2,
RouteV2,
TradeV2,
TradeOptions,
LB_ROUTER_V22_ADDRESS,
jsonAbis,
} from "@traderjoe-xyz/sdk-v2";
import {
createPublicClient,
createWalletClient,
http,
parseUnits,
BaseError,
ContractFunctionRevertedError,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { avalanche } from "viem/chains";
import { config } from "dotenv";
2. Declare required constants
config();
const privateKey = process.env.PRIVATE_KEY;
const { LBRouterV22ABI } = jsonAbis;
const CHAIN_ID = ChainId.AVALANCHE;
const router = LB_ROUTER_V22_ADDRESS[CHAIN_ID];
const account = privateKeyToAccount(`0x${privateKey}`);
// initialize tokens
const WAVAX = WNATIVE[CHAIN_ID]; // Token instance of WAVAX
const USDC = new Token(
CHAIN_ID,
"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
6,
"USDC",
"USD Coin"
);
const USDT = new Token(
CHAIN_ID,
"0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
6,
"USDT",
"Tether USD"
);
// declare bases used to generate trade routes
const BASES = [WAVAX, USDC, USDT];
3. Create Viem clients
const publicClient = createPublicClient({
chain: avalanche,
transport: http(),
});
const walletClient = createWalletClient({
account,
chain: avalanche,
transport: http(),
});
4. Declare user inputs and initialize TokenAmount
TokenAmount
// the input token in the trade
const inputToken = USDC;
// the output token in the trade
const outputToken = WAVAX;
// specify whether user gave an exact inputToken or outputToken value for the trade
const isExactIn = true;
// user string input; in this case representing 20 USDC
const typedValueIn = "20";
// parse user input into inputToken's decimal precision, which is 6 for USDC
const typedValueInParsed = parseUnits(typedValueIn, inputToken.decimals);
// wrap into TokenAmount
const amountIn = new TokenAmount(inputToken, typedValueInParsed);
5. Use PairV2 and RouteV2 functions to generate all possible routes
// get all [Token, Token] combinations
const allTokenPairs = PairV2.createAllTokenPairs(
inputToken,
outputToken,
BASES
);
// init PairV2 instances for the [Token, Token] pairs
const allPairs = PairV2.initPairs(allTokenPairs);
// generates all possible routes to consider
const allRoutes = RouteV2.createAllRoutes(allPairs, inputToken, outputToken);
6. Generate TradeV2 instances and get the best trade
const isNativeIn = false; // set to 'true' if swapping from Native; otherwise, 'false'
const isNativeOut = true; // set to 'true' if swapping to Native; otherwise, 'false'
// generates all possible TradeV2 instances
const trades = await TradeV2.getTradesExactIn(
allRoutes,
amountIn,
outputToken,
isNativeIn,
isNativeOut,
publicClient,
CHAIN_ID
);
// chooses the best trade
const bestTrade: TradeV2 = TradeV2.chooseBestTrade(trades, isExactIn);
7. Check trade information
// print useful information about the trade, such as the quote, executionPrice, fees, etc
console.log(bestTrade.toLog());
// get trade fee information
const { totalFeePct, feeAmountIn } = await bestTrade.getTradeFee();
console.log("Total fees percentage", totalFeePct.toSignificant(6), "%");
console.log(`Fee: ${feeAmountIn.toSignificant(6)} ${feeAmountIn.token.symbol}`);
8. Declare slippage tolerance and swap method/parameters
// set slippage tolerance
const userSlippageTolerance = new Percent("50", "10000"); // 0.5%
// set swap options
const swapOptions: TradeOptions = {
allowedSlippage: userSlippageTolerance,
ttl: 3600,
recipient: account.address,
feeOnTransfer: false, // or true
};
// generate swap method and parameters for contract call
const {
methodName, // e.g. swapExactTokensForNATIVE,
args, // e.g.[amountIn, amountOut, (pairBinSteps, versions, tokenPath) to, deadline]
value, // e.g. 0x0
} = bestTrade.swapCallParameters(swapOptions);
9. Execute trade using Viem
Remember to approve spending ERC20 tokens by router before execution
const { request } = await publicClient.simulateContract({
address: router,
abi: LBRouterV22ABI,
functionName: methodName,
args: args,
account,
value: BigInt(value),
});
const hash = await walletClient.writeContract(request);
console.log(`Transaction sent with hash ${hash}`);
Last updated