Skip to main content

Basic Swap

This guide walks through a complete swap using the TypeScript SDK — from client setup to execution.

Full Example

import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
import { EvixClient } from "@inductiv/evix-sdk";

// 1. Setup
const PRIVATE_KEY = "0x..." as `0x${string}`;
const EVIX_ADDRESS = "0x..." as `0x${string}`;

const account = privateKeyToAccount(PRIVATE_KEY);

const publicClient = createPublicClient({
chain: base,
transport: http(),
});

const walletClient = createWalletClient({
account,
chain: base,
transport: http(),
});

const evix = new EvixClient({
chainId: base.id,
contractAddress: EVIX_ADDRESS,
publicClient,
walletClient,
});

// 2. Define swap parameters
const TOKEN_IN = "0x..." as `0x${string}`;
const TOKEN_OUT = "0x..." as `0x${string}`;
const AMOUNT_IN = 1_000_000n;

async function main() {
// 3. Simulate to get expected output
const expectedOut = await evix.simulateSwap({
tokenIn: TOKEN_IN,
tokenOut: TOKEN_OUT,
amountIn: AMOUNT_IN,
deadline: BigInt(Math.floor(Date.now() / 1000) + 120),
minAmountOut: 0n,
recipient: account.address,
});

console.log("Simulated output:", expectedOut.toString());

// 4. Compute minimum output with slippage tolerance
const slippageBps = 50n; // 0.5%
const minOut = expectedOut - (expectedOut * slippageBps) / 10_000n;

// 5. Execute the swap
const result = await evix.swap({
tokenIn: TOKEN_IN,
tokenOut: TOKEN_OUT,
amountIn: AMOUNT_IN,
deadline: BigInt(Math.floor(Date.now() / 1000) + 120),
minAmountOut: minOut,
recipient: account.address,
});

console.log("Swap executed:", {
amountOut: result.amountOut.toString(),
tx: result.transactionHash,
});
}

main().catch(console.error);

Step-by-Step Breakdown

1. Client Setup

The EvixClient requires:

  • chainId — The chain ID for your deployment (e.g. 8453 for Base)
  • contractAddress — Your provisioned Evix deployment address
  • publicClient — A viem PublicClient for simulations and reads
  • walletClient — A viem WalletClient for transaction execution (optional for simulation-only)

2. Simulation

simulateSwap() uses eth_call to preview the output without submitting a transaction. Use minAmountOut: 0n during simulation to avoid artificial reverts.

tip

Simulation is not just for previewing — it validates that the pair is supported, the amount is valid, and the deadline hasn't passed.

3. Slippage Calculation

Compute minAmountOut as a percentage below the simulated output:

// 0.5% slippage = 50 basis points
const slippageBps = 50n;
const minOut = expectedOut - (expectedOut * slippageBps) / 10_000n;
SlippageBasis PointsMultiplier
0.1%109990 / 10000
0.3%309970 / 10000
0.5%509950 / 10000
1.0%1009900 / 10000

4. Execution

swap() simulates first, then submits the transaction. It returns the actual output amount and the transaction hash.

caution

Ensure the wallet has sufficient token balance and that the Evix contract has been approved to spend tokenIn via ERC20.approve().

Token Approval

Before your first swap, approve the Evix contract to spend your input token:

import { erc20Abi } from "viem";

const approveTx = await walletClient.writeContract({
address: TOKEN_IN,
abi: erc20Abi,
functionName: "approve",
args: [EVIX_ADDRESS, AMOUNT_IN],
});

Error Handling

try {
const result = await evix.swap(params);
} catch (error) {
// Common revert reasons:
// - DeadlineExceeded: Transaction landed after deadline
// - InsufficientOutput: Market moved beyond slippage tolerance
// - UnsupportedPair: Pair not allowlisted on this deployment
// - InvalidAmountIn: Zero input amount
// - InvalidRecipient: Zero address recipient
console.error("Swap failed:", error);
}