How can we help? 👋

Minting and Burning Tokens.

How to mint and burn tokens.

This tutorial explains how to interact with tokens on the SEI network using JavaScript/TypeScript and the viem library. We'll cover fetching token list, minting, checking ERC20 balances, and burning tokens.

💡
You can check the full source code in this github repository. https://github.com/seiyan-fun

0. Prerequisites

  • Node.js

1. Fetching Tokens

The getTokens function retrieves a list of token addresses based on a specified sort type:

import axios from "axios";

type SortType = "order-by-bump" | "order-by-created" | "order-by-marketcap";

async function getTokens(sortType: SortType) {
  const baseUrl = "https://seiyan.fun/api/public/v1/tokens/";
  const url = baseUrl + sortType;

  try {
    const response = await axios.get<string[]>(url);
    return response.data;
  } catch (error) {
    console.error("Error fetching tokens:", error);
    return [];
  }
}

This function allows you to fetch tokens sorted by different criteria.

  • "order-by-bump"
  • "order-by-created"
  • "order-by-marketcap"

2. Minting Tokens

The mint function allows you to mint tokens:

async function mint(
  creatorPrivateKey: `0x${string}`,
  tokenContractAddress: `0x${string}`,
  seiAmount: bigint,
  slippage: bigint,
) {
  const account = privateKeyToAccount(creatorPrivateKey);
  const publicClient = createPublicClient({
    chain: sei,
    transport: http(),
  });
  const walletClient = createWalletClient({
    account,
    chain: sei,
    transport: http(),
  });

  const [estimatedAmountOut] = await publicClient.readContract({
    address: BOND_CONTRACT_ADDRESS,
    abi: BOND_CONTRACT_ABI,
    functionName: "getMintAmountOut",
    args: [tokenContractAddress, account.address, seiAmount],
  });
  const minimumTokenAmount = (estimatedAmountOut * (100n - slippage)) / 100n;

  const tx = {
    to: BOND_CONTRACT_ADDRESS,
    value: seiAmount,
    data: encodeFunctionData({
      abi: BOND_CONTRACT_ABI,
      functionName: "mint",
      args: [tokenContractAddress, minimumTokenAmount, account.address],
    }),
  };

  const txHash = await walletClient.sendTransaction({
    ...tx,
    type: "legacy",
    gas: 5_000_000n, // expected gas limit
    gasPrice: parseEther("1", "gwei"),
    nonce: await publicClient.getTransactionCount({
      address: account.address,
    }),
    account,
  });
  const receipt = await publicClient.waitForTransactionReceipt({
    hash: txHash,
    timeout: 30000,
  });
  console.log(`Mint transactionHash: ${txHash}, Status: ${receipt.status}`);
}

This function:

  1. Sets up the wallet and public clients.
  1. Estimates the amount of tokens to be received.
  1. Prepares and sends a transaction to mint tokens.
  1. Waits for the transaction receipt and logs the result.
 

3. Checking Token Balance

The getERC20Balance function checks the balance of a specific token for an account:

async function getERC20Balance(
  tokenAddress: `0x${string}`,
  accountAddress: `0x${string}`,
) {
  const publicClient = createPublicClient({
    chain: sei,
    transport: http(),
  });

  const balance = await publicClient.readContract({
    address: tokenAddress,
    abi: parseAbi([
      "function balanceOf(address account) view returns (uint256)",
    ]),
    functionName: "balanceOf",
    args: [accountAddress],
  });

  return balance;
}

This function uses the balanceOf method of the ERC20 contract to retrieve the balance.

4. Burning Tokens

The burn function allows you to burn tokens:

async function burn(
  creatorPrivateKey: `0x${string}`,
  tokenContractAddress: `0x${string}`,
  tokenAmount: bigint,
  slippage: bigint,
) {
  const account = privateKeyToAccount(creatorPrivateKey);
  const publicClient = createPublicClient({
    chain: sei,
    transport: http(),
  });
  const walletClient = createWalletClient({
    account,
    chain: sei,
    transport: http(),
  });

  const [estimatedAmountOut] = await publicClient.readContract({
    address: BOND_CONTRACT_ADDRESS,
    abi: BOND_CONTRACT_ABI,
    functionName: "getBurnAmountOut",
    args: [tokenContractAddress, account.address, tokenAmount],
  });
  const minimumSeiAmount = (estimatedAmountOut * (100n - slippage)) / 100n;

  const tx = {
    to: BOND_CONTRACT_ADDRESS,
    value: 0n,
    data: encodeFunctionData({
      abi: BOND_CONTRACT_ABI,
      functionName: "burn",
      args: [
        tokenContractAddress,
        tokenAmount,
        minimumSeiAmount,
        account.address,
      ],
    }),
  };

  const txHash = await walletClient.sendTransaction({
    ...tx,
    type: "legacy",
    gas: 5_000_000n, // expected gas limit
    gasPrice: parseEther("1", "gwei"),
    nonce: await publicClient.getTransactionCount({
      address: account.address,
    }),
    account,
  });
  const receipt = await publicClient.waitForTransactionReceipt({
    hash: txHash,
    timeout: 30000,
  });
  console.log(`Burn transactionHash: ${txHash}, Status: ${receipt.status}`);
}

This function:

  1. Estimates the amount of SEI to be received from burning tokens.
  1. Prepares and sends a transaction to burn tokens.
  1. Waits for the transaction receipt and logs the result.
 

5. Execution

The script concludes by demonstrating how to use these functions:


// TODO: enter your private key.
// get token list
const tokens = await getTokens("order-by-created");
const token = tokens[0];
console.log("Token Address: ", token);

// mint tokens
await mint(
  "0xYOUR_PRIVATE_KEY",
  getAddress(token),
  parseEther("0.1"),
  1n,
);

// get ERC20 balance
const account = privateKeyToAccount(
  "0xYOUR_PRIVATE_KEY",
);
const balance = await getERC20Balance(getAddress(token), account.address);

// burn all tokens
await burn(
  "0xYOUR_PRIVATE_KEY",
  getAddress(token),
  balance,
  1n,
);
  1. Fetches the most recently created token.
  1. Mints some of that token.
  1. Checks the balance of the minted token.
  1. Burns the entire balance of the token.