Skip to main content
Learn how to create your first token on Spark. This guide covers token creation, parameter configuration, and best practices for launching tokens on the Spark network.
Create a Token

Token Creation Flow

The complete process for creating a token on Spark:
1

Initialize Issuer Wallet

Set up your issuer wallet to manage token operations.
import { IssuerSparkWallet } from "@buildonspark/issuer-sdk";

const { wallet } = await IssuerSparkWallet.initialize({
  options: { network: "REGTEST" }
});
console.log("Issuer wallet ready for token creation");
2

Define Token Parameters

Configure your token’s core metadata and properties.
const tokenParams = {
  tokenName: "My Token",
  tokenTicker: "MTK",
  decimals: 8,
  maxSupply: BigInt(1000000),
  isFreezable: true
};
3

Create Token

Deploy your token to the Spark network instantly.
const tokenCreationTx = await wallet.createToken(tokenParams);
console.log("Token created! Transaction ID:", tokenCreationTx);
4

Verify Creation

Confirm your token was created successfully.
const metadata = await wallet.getIssuerTokenMetadata();
console.log("Token Name:", metadata.tokenName);
console.log("Token Symbol:", metadata.tokenSymbol);
console.log("Max Supply:", metadata.maxSupply);

Create Token

Creating a token on Spark is instant and free. This is the moment where you define its core parameters and commit them to chain. createToken(params) Creates a new token directly on Spark using Spark Native Tokens (recommended).
const tokenCreationTx = await wallet.createToken({
  tokenName: "Test Token",
  tokenTicker: "TEST",
  decimals: 8,
  maxSupply: BigInt(10000000),
  isFreezable: true
});

console.log("Token Creation TX:", tokenCreationTx);

What You Need to Know

One Token Per Wallet

Token creation is limited to one token per issuer wallet

No L1 Funding Required

No Bitcoin L1 funding needed for token creation

Instant Creation

Tokens are created instantly on the Spark network

Immutable Metadata

Token metadata cannot be changed once set

Immediate Minting

Minting can begin immediately after creation

Free Creation

Token creation is completely free on Spark

Token Supply Options

Unlimited Supply Tokens

Create tokens with no maximum supply limit:
const unlimitedToken = await wallet.createToken({
  tokenName: "USD Coin",
  tokenTicker: "USDC",
  maxSupply: BigInt(0), // 0n = unlimited supply
  decimals: 6, // 1 USDC = 1_000_000 base units
  isFreezable: true
});

console.log("Unlimited supply token created:", unlimitedToken);

Fixed Supply Tokens

Create tokens with a predetermined maximum supply:
// Create a token with max supply of 1 million
const fixedToken = await wallet.createToken({
  tokenName: "My Fixed Token",
  tokenTicker: "MFT",
  maxSupply: BigInt(1000000000000), // 1,000,000.000000 tokens
  decimals: 6,
  isFreezable: false
});

console.log("Fixed supply token created:", fixedToken);

Bitcoin-Style Token

Create a token with Bitcoin-like characteristics:
// Create a token with max 21 million supply and minimum denomination of 0.00000001
const bitcoinToken = await wallet.createToken({
  tokenName: "Example Bitcoin",
  tokenTicker: "ExBTC",
  maxSupply: BigInt(2100000000000000), // 21,000,000.00000000 tokens
  decimals: 8,
  isFreezable: false
});

console.log("Bitcoin-style token created:", bitcoinToken);

Decimal Precision

Understanding how decimals work in token creation:

6 Decimals

Example: USDC
Base Units: 1,000,000
Display: 1.000000 USDC

8 Decimals

Example: Bitcoin
Base Units: 100,000,000
Display: 1.00000000 BTC

18 Decimals

Example: Ethereum
Base Units: 1,000,000,000,000,000,000
Display: 1.000000000000000000 ETH

Decimal Examples

// 6 decimal token (like USDC)
const usdcToken = await wallet.createToken({
  tokenName: "USD Coin",
  tokenTicker: "USDC",
  decimals: 6,
  maxSupply: BigInt(1000000000000), // 1,000,000 USDC
  isFreezable: true
});

// 8 decimal token (like Bitcoin)
const btcToken = await wallet.createToken({
  tokenName: "Bitcoin Token",
  tokenTicker: "BTC",
  decimals: 8,
  maxSupply: BigInt(2100000000000000), // 21,000,000 BTC
  isFreezable: false
});

Freezable vs Non-Freezable Tokens

Freezable Tokens

Tokens that can be frozen by the issuer after creation:
const freezableToken = await wallet.createToken({
  tokenName: "Regulated Token",
  tokenTicker: "REG",
  decimals: 8,
  maxSupply: BigInt(1000000),
  isFreezable: true // Can be frozen by issuer
});

// Later, issuer can freeze tokens for specific addresses
await wallet.freezeTokens("spark1...");
Use cases:
  • Regulatory compliance
  • Security tokens
  • Tokens requiring issuer control

Non-Freezable Tokens

Tokens that cannot be frozen once created:
const nonFreezableToken = await wallet.createToken({
  tokenName: "Decentralized Token",
  tokenTicker: "DCT",
  decimals: 8,
  maxSupply: BigInt(1000000),
  isFreezable: false // Cannot be frozen
});
Use cases:
  • Decentralized tokens
  • Utility tokens
  • Community tokens

Verify Token Creation

After creating your token, verify it was created successfully: getIssuerTokenMetadata() Gets the metadata about the issuer’s token.
const metadata = await wallet.getIssuerTokenMetadata();
console.log("Token Name:", metadata.tokenName);
console.log("Token Symbol:", metadata.tokenSymbol);
console.log("Token Decimals:", metadata.tokenDecimals);
console.log("Max Supply:", metadata.maxSupply);
console.log("Is Freezable:", metadata.isFreezable);
console.log("Token Identifier:", metadata.bech32mTokenIdentifier);

Legacy L1 Announcements

Deprecated: L1 token announcements via announceTokenL1() are being phased out. While existing tokens announced on-chain will continue to function normally, we recommend using Spark Native Tokens (createToken()) for all new token launches. The L1 announcement flow will be removed from the SDK in upcoming releases.

Why Use Spark Native Tokens?

Instant Creation

No waiting for Bitcoin L1 confirmations

No L1 Fees

No Bitcoin transaction fees required

Better UX

Seamless user experience

Future-Proof

Recommended approach for new tokens
Existing tokens that were announced on Bitcoin L1 continue to work exactly as before. From Spark’s perspective, there is no difference in functionality between L1-announced tokens and Spark Native Tokens.

Best Practices

Token Naming

  • Clear and Descriptive: Use names that clearly describe the token’s purpose
  • Avoid Confusion: Don’t use names that could be confused with existing tokens
  • Professional: Use proper capitalization and avoid special characters

Ticker Symbols

  • Short and Memorable: Keep tickers to 3-5 characters
  • Uppercase: Use all uppercase letters
  • Unique: Ensure your ticker is not already in use

Decimal Precision

  • Match Use Case: Choose decimals that match your token’s intended use
  • Consider UX: More decimals can complicate user interfaces
  • Standard Practices: Follow industry standards (6 for stablecoins, 8 for Bitcoin-like tokens)

Supply Strategy

  • Plan Ahead: Consider your token’s economic model before setting max supply
  • Unlimited vs Fixed: Decide based on your token’s purpose
  • Future Flexibility: Remember that metadata is immutable once set

Complete Example

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

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

    console.log("Issuer wallet initialized");

    // 2. Create token with specific parameters
    const tokenCreationTx = await wallet.createToken({
      tokenName: "My Awesome Token",
      tokenTicker: "MAT",
      decimals: 8,
      maxSupply: BigInt(1000000000000), // 1,000,000.00000000 tokens
      isFreezable: true
    });

    console.log("Token created successfully!");
    console.log("Transaction ID:", tokenCreationTx);

    // 3. Verify token creation
    const metadata = await wallet.getIssuerTokenMetadata();
    console.log("Token Details:");
    console.log("- Name:", metadata.tokenName);
    console.log("- Symbol:", metadata.tokenSymbol);
    console.log("- Decimals:", metadata.tokenDecimals);
    console.log("- Max Supply:", metadata.maxSupply);
    console.log("- Is Freezable:", metadata.isFreezable);
    console.log("- Token ID:", metadata.bech32mTokenIdentifier);

    // 4. Start minting tokens
    const mintTx = await wallet.mintTokens(BigInt(100000000)); // 1.00000000 tokens
    console.log("Initial tokens minted:", mintTx);

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

createMyToken().catch(console.error);