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.
Did this answer your question?
😞
😐
🤩