Getting Started

This guide will help you quickly understand how to use JAMM DEX for token swaps and liquidity management.

Prerequisites

Before you begin, please ensure you have the following:

  1. JuChain Wallet: A Web3 wallet that supports the JuChain network.

  2. JU Token: The native token used to pay for transaction fees.

  3. Test Tokens: ERC-20 tokens for swapping.

Contract Addresses

Mainnet Addresses

  • JAMMFactory: 0x6b5d54E6F73e96Ca960DBA71D778b98221939aa6

  • JAMMRouter: 0x3F26fb54C28Eab026e908A9A9357a456F3c8Dc87

  • WJU: 0x4d1B49B424afd7075d3c063adDf97D5575E1c7E2

  • USDT: 0xc8e19C19479a866142B42fB390F2ea1Ff082E0D2

  • ETH: 0x80077F108Dd73B709C43A1a13F0EEF25e48f7D0e

  • BNB: 0x151b6F646Ac02Ed9877884ed9637A84f2FD8FaA6

Testnet Addresses

  • JAMMFactory: 0xbddd716a9d6325700d1c29562c819987e5b1f6a8

  • JAMMRouter: 0x3f8b0038023393009712D0051D192a8825dd02B9

  • WJU: 0xb8cdb16bc2b64d42638e285a691973ff10078d8e

Your First Token Swap

1. Setup

First, you need to connect to the JuChain network and prepare the tokens for swapping.

// Connect to the JuChain network
const provider = new ethers.providers.JsonRpcProvider('https://rpc.juchain.org');
const signer = new ethers.Wallet(privateKey, provider);

// JAMMRouter contract instance
const routerAddress = '0x3F26fb54C28Eab026e908A9A9357a456F3c8Dc87';
const routerABI = ['...']; // Add router ABI
const router = new ethers.Contract(routerAddress, routerABI, signer);

2. Executing a Swap

The following example shows how to swap TokenA for TokenB:

// Swap parameters
const amountIn = ethers.utils.parseEther("1.0"); // 1 TokenA
const amountOutMin = ethers.utils.parseEther("0.9"); // Minimum 0.9 TokenB to receive
const path = [tokenA_address, tokenB_address]; // Swap path
const fees = [100]; // Fee tier for the pair (1%)
const to = signer.address; // Recipient address
const referrer = ethers.constants.AddressZero; // No referrer
const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 minutes from now

// Execute the swap
const tx = await router.swapExactTokensForTokens(
    amountIn,
    amountOutMin,
    path,
    fees,
    to,
    referrer,
    deadline
);

await tx.wait();
console.log("Swap completed!");

3. Swapping with JU

If you want to swap with the native JU token, use the ETH-related functions:

// Buy tokens with JU
const tx = await router.swapExactETHForTokens(
    amountOutMin,
    [WJU_address, tokenB_address], // Path must start with WJU
    [100], // Fee tier
    to,
    referrer,
    deadline,
    { value: ethers.utils.parseEther("1.0") } // Send 1 JU
);

Providing Liquidity for the First Time

1. Adding Liquidity

// Liquidity parameters
const tokenA = "TOKEN_A_ADDRESS";
const tokenB = "TOKEN_B_ADDRESS";
const fee = 100; // 1% fee tier
const amountADesired = ethers.utils.parseEther("10");
const amountBDesired = ethers.utils.parseEther("10");
const amountAMin = ethers.utils.parseEther("9"); // Minimum amount of TokenA
const amountBMin = ethers.utils.parseEther("9"); // Minimum amount of TokenB
const to = signer.address;
const deadline = Math.floor(Date.now() / 1000) + 60 * 20;

// Approve the router to spend your tokens first
const tokenAContract = new ethers.Contract(tokenA, erc20ABI, signer);
const tokenBContract = new ethers.Contract(tokenB, erc20ABI, signer);

await tokenAContract.approve(routerAddress, amountADesired);
await tokenBContract.approve(routerAddress, amountBDesired);

// Add liquidity
const tx = await router.addLiquidity(
    tokenA,
    tokenB,
    fee,
    amountADesired,
    amountBDesired,
    amountAMin,
    amountBMin,
    to,
    deadline
);

const receipt = await tx.wait();
console.log("Liquidity added successfully!");

2. Removing Liquidity

// Get LP token balance
const pairAddress = await factory.getPair(tokenA, tokenB, fee);
const pairContract = new ethers.Contract(pairAddress, pairABI, signer);
const lpBalance = await pairContract.balanceOf(signer.address);

// Remove 50% of your liquidity
const liquidity = lpBalance.div(2);

// Approve the router to spend your LP tokens
await pairContract.approve(routerAddress, liquidity);

// Calculate minimum amounts to receive with 1% slippage tolerance
const { reserve0, reserve1 } = await pairContract.getReserves();
const totalSupply = await pairContract.totalSupply();
const amount0 = liquidity.mul(reserve0).div(totalSupply);
const amount1 = liquidity.mul(reserve1).div(totalSupply);
const amount0Min = amount0.mul(99).div(100);
const amount1Min = amount1.mul(99).div(100);

// Remove liquidity
const tx = await router.removeLiquidity(
    tokenA,
    tokenB,
    fee,
    liquidity,
    amount0Min,
    amount1Min,
    to,
    deadline
);

await tx.wait();
console.log("Liquidity removed successfully!");

Using the permit Function

JAMM DEX supports EIP-2612 permit, allowing you to approve token spending with a signature, avoiding a separate approve transaction.

// Generate permit signature
const domain = {
    name: 'JAMM LPs',
    version: '1',
    chainId: await signer.getChainId(),
    verifyingContract: pairAddress
};

const types = {
    Permit: [
        { name: 'owner', type: 'address' },
        { name: 'spender', type: 'address' },
        { name: 'value', type: 'uint256' },
        { name: 'nonce', type: 'uint256' },
        { name: 'deadline', type: 'uint256' }
    ]
};

const nonce = await pairContract.nonces(signer.address);
const value = {
    owner: signer.address,
    spender: routerAddress,
    value: liquidity,
    nonce: nonce,
    deadline: deadline
};

const signature = await signer._signTypedData(domain, types, value);
const { v, r, s } = ethers.utils.splitSignature(signature);

// Remove liquidity using permit
const tx = await router.removeLiquidityWithPermit(
    tokenA,
    tokenB,
    fee,
    liquidity,
    amount0Min, // Use calculated min amounts
    amount1Min,
    to,
    deadline,
    false, // approveMax
    v,
    r,
    s
);

Querying Information

Getting Pair Information

// Check if a pair exists
const pairAddress = await factory.getPair(tokenA, tokenB, fee);
if (pairAddress === ethers.constants.AddressZero) {
    console.log("Pair does not exist.");
} else {
    console.log("Pair address:", pairAddress);
}

// Get reserves
const pair = new ethers.Contract(pairAddress, pairABI, provider);
const { reserve0, reserve1 } = await pair.getReserves();
console.log("Reserves:", reserve0.toString(), reserve1.toString());

Calculating Swap Amounts

// Calculate output amount
const amountOut = await router.getAmountOut(
    amountIn,
    reserves.reserve0,
    reserves.reserve1,
    fee
);
console.log("Expected output:", ethers.utils.formatEther(amountOut));

// Calculate amounts for a multi-hop swap
const amounts = await router.getAmountsOut(amountIn, path, fees);
console.log("Multi-hop swap path amounts:", amounts.map(a => ethers.utils.formatEther(a)));

Common Error Handling

Common Reasons for Transaction Failure

  1. "JAMMRouter: EXPIRED": The transaction deadline has passed.

  2. "JAMMRouter: INSUFFICIENT_OUTPUT_AMOUNT": Slippage is too high, and the output amount is less than the minimum required.

  3. "JAMM: INSUFFICIENT_LIQUIDITY": Not enough liquidity in the pair for the swap.

  4. "JAMMFactory: INVALID_FEE": An unsupported fee tier was used.

Error Handling Example

try {
    const tx = await router.swapExactTokensForTokens(...);
    await tx.wait();
} catch (error) {
    if (error.message.includes("INSUFFICIENT_OUTPUT_AMOUNT")) {
        console.log("Slippage too high. Please increase your slippage tolerance.");
    } else if (error.message.includes("EXPIRED")) {
        console.log("Transaction expired. Please try again.");
    } else {
        console.log("Transaction failed:", error.message);
    }
}

Next Steps

Now that you understand the basics of using JAMM DEX, you can continue learning about:

  • Fee Structure - Understand the fee system.

  • Referral System - Learn how to earn referral rewards.

  • Integration Guides - Integrate JAMM DEX into your application.

Getting Help

If you encounter any issues, you can get help through the following channels:

  • Technical Docs: Check the detailed technical reference.

  • Community Support: https://t.me/jammfun

Last updated