Skip to main content
Learn how to manage your tokens on Spark after creation. This guide covers minting new tokens, freezing/unfreezing addresses, burning tokens, and monitoring token activity.
Manage Tokens

Token Management Overview

Once you’ve created your token, you can perform various management operations to control its supply, distribution, and behavior on the Spark network.

Mint Tokens

Create new tokens to increase supply

Freeze/Unfreeze

Control token transfers for specific addresses

Burn Tokens

Permanently remove tokens from circulation

Mint Tokens

Minting on Spark is available immediately after your token is created. The mintTokens function lets you create new tokens, either to set the initial supply or to mint more over time as needed. mintTokens(tokenAmount) Mints new tokens directly to the issuer’s Spark address.
const transactionId = await wallet.mintTokens(BigInt(1000000));
console.log("Spark Transaction ID:", transactionId);

What You Need to Know

Only Creator Can Mint

Only the creator wallet can mint tokens

Minted to Creator

Tokens are minted directly to the creator’s Spark address

Base Units Required

Amount must be specified in base units

Instant Transaction

Minting is a single, instant transaction

Minting Examples

Initial Supply Minting

// Mint initial supply of 1,000,000 tokens (6 decimals)
const initialSupply = BigInt(1000000000000); // 1,000,000.000000 tokens
const mintTx = await wallet.mintTokens(initialSupply);
console.log("Initial supply minted:", mintTx);

Ongoing Minting

// Mint additional tokens as needed
const additionalTokens = BigInt(100000000); // 100,000.000000 tokens
const mintTx = await wallet.mintTokens(additionalTokens);
console.log("Additional tokens minted:", mintTx);

Where Are Tokens Minted?

When you mint tokens on Spark, they’re credited directly to your issuer’s Spark address derived from:
sp + <token_public_key>
This address is bech32m-encoded and generated automatically when you create your wallet. All minted supply is sent here by default. You can’t specify a different destination when minting. Transfers must happen in a separate step.

Freeze & Unfreeze Tokens

The freeze functionality allows token issuers to freeze and unfreeze tokens at specific Spark Addresses, only available for tokens created with isFreezable: true.

Freeze Tokens

freezeTokens(sparkAddress) Freezes tokens for a specific Spark address, preventing them from sending or receiving your token.
const freezeResult = await wallet.freezeTokens("spark1...");
console.log("Freeze result:", freezeResult);

Unfreeze Tokens

unfreezeTokens(sparkAddress) Unfreezes tokens for a specific Spark address, restoring their ability to send and receive your token.
const unfreezeResult = await wallet.unfreezeTokens("spark1...");
console.log("Unfreeze result:", unfreezeResult);

Freeze Requirements

Token Must Be Freezable

Token must be created with isFreezable: true

Only Issuer Can Freeze

Only the issuer can freeze or unfreeze addresses

Issuer Cannot Be Frozen

Issuer’s own address cannot be frozen

Instant Effect

Freeze takes effect instantly across the network

Freeze Examples

// Freeze tokens for a specific address
const targetAddress = "spark1s2h8nvdh4h7h43tcwjdcysf7v0fprz5uh6vshs4n0tvhgzz2xgcqpg8yqv7";
const freezeResult = await wallet.freezeTokens(targetAddress);

console.log("Frozen outputs:", freezeResult.impactedOutputIds);
console.log("Frozen amount:", freezeResult.impactedTokenAmount);

// Later, unfreeze the same address
const unfreezeResult = await wallet.unfreezeTokens(targetAddress);
console.log("Unfrozen successfully:", unfreezeResult);

Burn Tokens

The burnTokens function permanently removes tokens from circulation, reducing total supply. Burned tokens are sent to an inaccessible dead address, making them unrecoverable. burnTokens(tokenAmount) Burns existing tokens, permanently removing them from circulation.
const transactionId = await wallet.burnTokens(BigInt(100000));
console.log("Spark Transaction ID:", transactionId);

What You Need to Know

Irreversible Action

Burning is irreversible. Tokens cannot be recovered

Only Own Tokens

You can only burn tokens from your own wallet

Base Units Required

Amount must be specified in base units

Reduces Supply

Burned tokens permanently reduce total supply

Burning Examples

Burn Excess Supply

// Burn excess tokens to reduce supply
const excessAmount = BigInt(500000000); // 500,000.000000 tokens
const burnTx = await wallet.burnTokens(excessAmount);
console.log("Excess tokens burned:", burnTx);

Deflationary Token

// Implement deflationary mechanics
const burnAmount = BigInt(1000000); // 1,000,000.000000 tokens
const burnTx = await wallet.burnTokens(burnAmount);
console.log("Deflationary burn completed:", burnTx);

Transfer Tokens

Transfer tokens to other Spark addresses for distribution or trading. transferTokens(params) Transfers tokens to another Spark Address.
const transferTx = await wallet.transferTokens({
  tokenIdentifier: "btkn1...",
  tokenAmount: BigInt(1000000),
  receiverSparkAddress: "spark1..."
});
console.log("Transfer transaction ID:", transferTx);

Batch Transfer Tokens

batchTransferTokens(params) Transfers tokens to multiple recipients in a single transaction.
const batchTx = await wallet.batchTransferTokens({
  tokenIdentifier: "btkn1...",
  transfers: [
    { tokenAmount: BigInt(1000000), receiverSparkAddress: "spark1..." },
    { tokenAmount: BigInt(2000000), receiverSparkAddress: "spark1..." }
  ]
});
console.log("Batch transfer transaction ID:", batchTx);

Monitor Token Activity

Get Token Balance

getIssuerTokenBalance(sparkAddress?) Gets the token balance of a specific wallet or the issuer wallet.
// Get issuer's token balance
const issuerBalance = await wallet.getIssuerTokenBalance();
console.log("Issuer balance:", issuerBalance.balance);

// Get balance for specific address
const userBalance = await wallet.getIssuerTokenBalance("spark1...");
console.log("User balance:", userBalance.balance);

Query Token Transactions

queryTokenTransactions(params) Retrieves token transactions from the network with flexible filtering options.
const transactions = await wallet.queryTokenTransactions({
  ownerPublicKeys: ["spark1..."],
  tokenIdentifiers: ["btkn1..."],
  issuerPublicKeys: ["spark1..."]
});
console.log("Token transactions:", transactions);

Token Management Best Practices

Supply Management

  • Plan Your Supply: Decide on initial supply and future minting strategy before creating your token
  • Monitor Max Supply: Keep track of your token’s max supply to avoid minting beyond limits
  • Consider Deflation: Implement burning mechanisms to create deflationary pressure if desired

Freeze Management

  • Use Sparingly: Only freeze addresses when absolutely necessary for compliance or security
  • Document Reasons: Keep records of why addresses were frozen
  • Regular Review: Periodically review frozen addresses and unfreeze when appropriate

Transfer Management

  • Verify Addresses: Always double-check recipient addresses before transferring
  • Use Batch Transfers: For multiple recipients, use batch transfers to save on fees
  • Monitor Transactions: Track all transfers for accounting and compliance purposes

Security Considerations

  • Protect Private Keys: Keep your issuer wallet’s private keys secure
  • Test on Regtest: Always test token management operations on regtest first
  • Backup Metadata: Keep records of your token’s metadata and configuration

Complete Example

import { IssuerSparkWallet } from "@buildonspark/issuer-sdk";

async function manageMyToken() {
  try {
    // 1. Initialize issuer wallet
    const { wallet } = await IssuerSparkWallet.initialize({
      options: { network: "REGTEST" }
    });

    console.log("Issuer wallet initialized for token management");

    // 2. Get token metadata
    const metadata = await wallet.getIssuerTokenMetadata();
    console.log("Token:", metadata.tokenName, "(", metadata.tokenSymbol, ")");

    // 3. Mint initial supply
    const initialSupply = BigInt(1000000000000); // 1,000,000.000000 tokens
    const mintTx = await wallet.mintTokens(initialSupply);
    console.log("Initial supply minted:", mintTx);

    // 4. Check balance
    const balance = await wallet.getIssuerTokenBalance();
    console.log("Current balance:", balance.balance, "base units");

    // 5. Transfer tokens to users
    const transferTx = await wallet.transferTokens({
      tokenIdentifier: metadata.bech32mTokenIdentifier,
      tokenAmount: BigInt(100000000), // 100.000000 tokens
      receiverSparkAddress: "spark1..." // Replace with actual address
    });
    console.log("Tokens transferred:", transferTx);

    // 6. Freeze an address (if token is freezable)
    if (metadata.isFreezable) {
      const freezeResult = await wallet.freezeTokens("spark1...");
      console.log("Address frozen:", freezeResult);
    }

    // 7. Burn some tokens
    const burnAmount = BigInt(10000000); // 10.000000 tokens
    const burnTx = await wallet.burnTokens(burnAmount);
    console.log("Tokens burned:", burnTx);

    // 8. Query recent transactions
    const transactions = await wallet.queryTokenTransactions({
      issuerPublicKeys: [metadata.tokenPublicKey]
    });
    console.log("Recent transactions:", transactions.length);

  } catch (error) {
    console.error("Token management error:", error);
  }
}

manageMyToken().catch(console.error);