LFJ Developer Docs
  • Liquidity Book
  • Introduction
  • LB V2.2 Key Changes
  • Guides
    • Swap Tokens
    • Add/Remove Liquidity
    • Tracking Volume
    • Tracking Pool Balances
    • Finding The Best Quote
    • Byte32 Decoding
    • Price From Bin Id
    • Bin Id From Price
    • Finding Liquidity Depth
    • User Balances
  • Concepts
    • Concentrated Liquidity
    • Bin Math
    • Bin Liquidity
    • Swaps
    • Fees
    • Oracle
  • Contracts
    • Interfaces
      • ILBLegacyFactory
      • ILBLegacyToken
      • ILBLegacyPair
      • ILBLegacyRouter
      • ILBFlashLoanCallback
      • IPendingOwnable
      • IJoeFactory
      • IJoePair
      • IJoeRouter01
      • IJoeRouter02
      • IWNATIVE
      • ILBFactory
      • ILBHooks
      • ILBPair
      • ILBRouter
      • ILBToken
    • Libraries
      • Math
        • BitMath
        • Encoded
        • LiquidityConfigurations
        • PackedUint128Math
        • SafeCast
        • SampleMath
        • TreeMath
        • Uint128x128Math
        • Uint256x256Math
      • BinHelper
      • Clone
      • Constants
      • FeeHelper
      • Hooks
      • ImmutableClone
      • JoeLibrary
      • OracleHelper
      • PairParameterHelper
      • PriceHelper
      • ReentrancyGuardUpgradeable
      • TokenHelper
    • LBBaseHooks
    • LBFactory
    • LBPair
    • LBQuoter
    • LBRouter
    • LBToken
  • Deployment Addresses
    • Avalanche C-Chain
    • Fuji Testnet
    • Arbitrum One
    • Binance Smart Chain
    • Binance Smart Chain Testnet
    • Ethereum Mainnet
    • Monad Testnet
  • SDK
    • Introduction
    • Making a Trade
    • Adding Liquidity
    • Removing Liquidity
  • Audits
  • AMM
    • Joe V1 Contracts
    • Joe V1 Audits
  • LFJ DEX API
    • Dex Analytics
    • Pools
    • Rewards
    • User
    • User Lifetime Stats
    • Vaults
    • Models
  • LFJ Aggregator API
    • Default
    • Models
Powered by GitBook
On this page
  • 1. Required imports for this guide
  • 2. Declare required constants
  • 3. Create Viem clients
  • 4. Declare user inputs and initialize TokenAmount
  • 5. Use PairV2 and RouteV2 functions to generate all possible routes
  • 6. Generate TradeV2 instances and get the best trade
  • 7. Check trade information
  • 8. Declare slippage tolerance and swap method/parameters
  • 9. Execute trade using Viem
  1. SDK

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

// 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}`);
PreviousIntroductionNextAdding Liquidity

Last updated 8 days ago

Note that in your project, you most likely will not hardcode the private key at any time. You would be using libraries like or to connect to a wallet, sign messages, interact with contracts, and get the above constants.

web3react
wagmi