Learn how to create and initialize an Issuer Wallet for token management on Spark. This guide covers wallet creation, initialization options, and essential issuer operations.
Initialize Issuer Wallet
The initialize method is the primary way to create or restore an Issuer Wallet. Leave mnemonicOrSeed blank to generate a new wallet, or provide an existing mnemonic seed phrase to import an existing wallet.
initialize(params)
Creates and initializes a new IssuerSparkWallet instance.
import { IssuerSparkWallet } from "@buildonspark/issuer-sdk" ;
// Create a new issuer wallet
const { wallet , mnemonic } = await IssuerSparkWallet . initialize ({
options: {
network: "REGTEST" // or "MAINNET"
}
});
console . log ( "New issuer wallet created!" );
console . log ( "Mnemonic:" , mnemonic );
console . log ( "Address:" , wallet . getSparkAddress ());
BIP-39 mnemonic phrase or raw seed. Leave blank to generate a new wallet.
Account index for generating multiple identity keys from the same mnemonic (default: 1)
Custom signer implementation for advanced use cases
Wallet configuration options including network selection
wallet
IssuerSparkWallet
required
The initialized IssuerSparkWallet instance
The 12-word mnemonic seed phrase for wallet recovery (undefined for raw seed)
Essential Issuer Operations
After creating your issuer wallet, you can perform these essential operations
getIdentityPublicKey()
Gets the identity public key of the issuer wallet
const identityKey = await wallet . getIdentityPublicKey ();
console . log ( "Identity Public Key:" , identityKey );
The identity public key as a hex string
getSparkAddress()
Gets the Spark address of the issuer wallet
const sparkAddress = await wallet . getSparkAddress ();
console . log ( "Spark Address:" , sparkAddress );
sparkAddress
SparkAddressFormat
required
The Spark address for receiving Bitcoin and tokens
getBalance()
Gets the current balance of the wallet including token balances.
const balance = await wallet . getBalance ();
console . log ( "Bitcoin Balance:" , balance . balance , "sats" );
console . log ( "Token Balances:" , balance . tokenBalances );
The wallet’s current Bitcoin balance in satoshis
tokenBalances
Map<string, { balance: bigint, tokenInfo: TokenInfo, bech32mTokenIdentifier: string }>
required
Map of token public keys to token balances with token information and Bech32m identifiers
cleanupConnections()
Properly closes all network connections and cleans up resources when you’re done using the wallet.
await wallet . cleanupConnections ();
console . log ( "Issuer wallet connections cleaned up" );
No return value - cleans up connections and aborts active streams
Token Management Operations
createToken(params)
Creates a new token directly on Spark using Spark Native Tokens (recommended).
const tokenId = await wallet . createToken ({
tokenName: "My Token" ,
tokenTicker: "MTK" ,
decimals: 8 ,
maxSupply: BigInt ( 1000000 ), // Use 0n for unlimited supply
isFreezable: true
});
console . log ( "Token created with ID:" , tokenId );
Name of the token (e.g., “SparkCoin”)
Token ticker symbol (e.g., “SPARKC”)
The precision the token supports (e.g., 8 for BTC)
The maximum supply for this token (use 0n for unlimited supply)
Whether the issuer can freeze this token
Spark Transaction ID as string
mintTokens(tokenAmount)
Mints new tokens to the issuer’s balance.
const txId = await wallet . mintTokens ( BigInt ( 1000 ));
console . log ( "Tokens minted. Transaction ID:" , txId );
The amount to mint (e.g., 1000n)
transferTokens(params)
Transfers tokens to another Spark Address.
const txId = await wallet . transferTokens ({
tokenIdentifier: "btkn1..." , // Bech32m token identifier
tokenAmount: BigInt ( 100 ),
receiverSparkAddress: "spark1..."
});
console . log ( "Tokens transferred. Transaction ID:" , txId );
Bech32m token identifier (e.g., btkn1…) of the token to transfer
Amount of tokens to transfer
Recipient’s Spark Address
selectedOutputs
OutputWithPreviousTransactionData[]
(Optional) Specific outputs to use for transfer
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 ( "Max Supply:" , metadata . maxSupply );
console . log ( "Is Freezable:" , metadata . isFreezable );
metadata
IssuerTokenMetadata
required
Object containing token metadata including public key, name, symbol, decimals, max supply, freezable status, and Bech32m identifier
getIssuerTokenIdentifier()
Gets the Bech32m token identifier for the issuer’s token.
const tokenIdentifier = await wallet . getIssuerTokenIdentifier ();
console . log ( "Token Identifier:" , tokenIdentifier );
Bech32m token identifier (e.g., btkn1…)
getIssuerTokenBalance(sparkAddress?)
Gets the token balance of a specific wallet or the issuer wallet.
// Get issuer's own token balance
const issuerBalance = await wallet . getIssuerTokenBalance ();
console . log ( "Issuer token balance:" , issuerBalance . balance );
// Get another wallet's token balance
const otherBalance = await wallet . getIssuerTokenBalance ( "spark1..." );
console . log ( "Other wallet balance:" , otherBalance . balance );
(Optional) Spark Address of the wallet to get the balance of. If no address is provided, returns the issuer wallet’s token balance.
Object containing balance and Bech32m token identifier
Advanced Token Operations
batchTransferTokens(params)
Transfers tokens to multiple recipients in a single transaction.
const txId = await wallet . batchTransferTokens ({
tokenIdentifier: "btkn1..." ,
transfers: [
{ tokenAmount: BigInt ( 100 ), receiverSparkAddress: "spark1..." },
{ tokenAmount: BigInt ( 200 ), receiverSparkAddress: "spark1..." },
{ tokenAmount: BigInt ( 50 ), receiverSparkAddress: "spark1..." }
]
});
console . log ( "Batch transfer completed. Transaction ID:" , txId );
Bech32m token identifier of the token to transfer
transfers
Array<{tokenAmount: bigint, receiverSparkAddress: string}>
required
Array of transfer objects containing recipient addresses and amounts
selectedOutputs
OutputWithPreviousTransactionData[]
(Optional) Specific outputs to use for transfer
burnTokens(tokenAmount)
Burns existing tokens, reducing the total supply.
const txId = await wallet . burnTokens ( BigInt ( 500 ));
console . log ( "Tokens burned. Transaction ID:" , txId );
The amount to burn (e.g., 500n)
freezeTokens(sparkAddress)
Freezes issuer’s tokens for a specific wallet.
const result = await wallet . freezeTokens ( "spark1..." );
console . log ( "Tokens frozen for address" );
console . log ( "Impacted outputs:" , result . impactedOutputIds );
console . log ( "Impacted amount:" , result . impactedTokenAmount );
The Spark Address to freeze
Object containing impacted output IDs and token amount
unfreezeTokens(sparkAddress)
Unfreezes issuer’s tokens for a specific wallet.
const result = await wallet . unfreezeTokens ( "spark1..." );
console . log ( "Tokens unfrozen for address" );
console . log ( "Impacted outputs:" , result . impactedOutputIds );
console . log ( "Impacted amount:" , result . impactedTokenAmount );
The Spark Address to unfreeze
Object containing impacted output IDs and token amount
Network Configuration
Issuer wallets support both mainnet and regtest networks:
const { wallet } = await IssuerSparkWallet . initialize ({
options: {
network: "MAINNET"
}
});
// Use for production token issuance
Always use REGTEST for development and testing. Only use MAINNET for production token issuance with real Bitcoin.
Account Derivation
You can create multiple issuer accounts from the same mnemonic by specifying different account numbers:
const { wallet : issuer1 } = await IssuerSparkWallet . initialize ({
mnemonicOrSeed: "your-mnemonic-phrase" ,
accountNumber: 0 , // First issuer account
options: { network: "REGTEST" }
});
const { wallet : issuer2 } = await IssuerSparkWallet . initialize ({
mnemonicOrSeed: "your-mnemonic-phrase" ,
accountNumber: 1 , // Second issuer account
options: { network: "REGTEST" }
});
console . log ( "Issuer 1 Address:" , issuer1 . getSparkAddress ());
console . log ( "Issuer 2 Address:" , issuer2 . getSparkAddress ());
Security Best Practices
Protect your mnemonic : Never share your 12-word mnemonic phrase. Store it securely offline.
Use strong randomness : Ensure your environment uses cryptographically secure random number generation.
Network selection : Always use REGTEST for development and testing. Only use MAINNET for production.
Regular backups : Back up your wallet’s mnemonic phrase regularly.
Token security : Consider the implications of making tokens freezable vs non-freezable.
Complete Example
import { IssuerSparkWallet } from "@buildonspark/issuer-sdk" ;
async function demonstrateIssuerWallet () {
try {
// 1. Initialize issuer wallet
const { wallet , mnemonic } = await IssuerSparkWallet . initialize ({
options: { network: "REGTEST" }
});
console . log ( "Issuer wallet initialized!" );
console . log ( "Mnemonic:" , mnemonic );
console . log ( "Address:" , wallet . getSparkAddress ());
// 2. Create a token
const tokenId = await wallet . createToken ({
tokenName: "Demo Token" ,
tokenTicker: "DEMO" ,
decimals: 8 ,
maxSupply: BigInt ( 1000000 ),
isFreezable: true
});
console . log ( "Token created:" , tokenId );
// 3. Get token metadata
const metadata = await wallet . getIssuerTokenMetadata ();
console . log ( "Token metadata:" , metadata );
// 4. Mint some tokens
const mintTxId = await wallet . mintTokens ( BigInt ( 10000 ));
console . log ( "Tokens minted:" , mintTxId );
// 5. Get token balance
const balance = await wallet . getIssuerTokenBalance ();
console . log ( "Token balance:" , balance . balance );
// 6. Transfer tokens
const transferTxId = await wallet . transferTokens ({
tokenIdentifier: metadata . bech32mTokenIdentifier ,
tokenAmount: BigInt ( 1000 ),
receiverSparkAddress: "spark1..."
});
console . log ( "Tokens transferred:" , transferTxId );
} catch ( error ) {
console . error ( "Issuer wallet operation failed:" , error );
}
}
demonstrateIssuerWallet (). catch ( console . error );