This document introduces how to use the FT SDK to issue tokens, transfer tokens, burn tokens, and query tokens.
Before using this guide, ensure you have completed the environment setup and received test coins. Please refer to Setting Up an MVC Project.
This guide is based on the previously configured environment and keys.
Code Example
Replace the src/index.ts file with the following content:
import {Address, Mnemonic} from"meta-contract/dist/mvc";import {promises as fs} from'fs';import {API_NET, API_TARGET, FtManager, Wallet} from"meta-contract";import {BURN_ADDRESS} from"meta-contract/dist/mcp02/constants";constFILE_PATH='mnemonic-seed.txt'constWALLET_PATH="m/44'/10001'/0'/0/0"let seed ='';constgenerateMnemonic=async ():Promise<string> => { console.log("Generating random mnemonic seed: <%s>, use your own if you already have it", Mnemonic.fromRandom().toString())
constmnemonic=Mnemonic.fromRandom().toString();awaitfs.writeFile(FILE_PATH, mnemonic,'utf8');return mnemonic;};constreadMnemonic=async ():Promise<string> => {returnawaitfs.readFile(FILE_PATH,'utf8');};// Detect if the mnemonic seed file exists, if not, generate a new one// Then create a wallet with the seed with path WALLET_PATHconstsetupMyWalletAndOperateFt=async ():Promise<void> => {try {awaitfs.access(FILE_PATH);constmnemonic=awaitreadMnemonic();console.log('Mnemonic seed exists: <%s>, will use this one.', mnemonic); seed = mnemonic; } catch (error) {constmnemonic=awaitgenerateMnemonic(); console.log('Mnemonic seed not detected, generating new one. <%s> , please keep it safe for future use.', mnemonic);
seed = mnemonic; }console.log('Creating wallet with seed: <%s> and path <%s>', seed,WALLET_PATH);let mnemonicParsed =Mnemonic.fromString(seed);let privateKey =mnemonicParsed.toHDPrivateKey("",API_NET.TEST).deriveChild(WALLET_PATH);let wallet =newWallet(privateKey.privateKey.toWIF(),API_NET.TEST,1);console.log("Your private key %s",privateKey.privateKey.toWIF());console.log("Your address %s",privateKey.privateKey.toAddress(API_NET.TEST).toString());console.log("Your balance %s satoshis",awaitwallet.getBalance());// create a FtManager instance and generate a new token// codehash, genesis, sensibleId, genesisTxId are the results of the genesis operationlet ftManager =newFtManager({ network:API_NET.TEST, apiTarget:API_TARGET.MVC, purse:privateKey.privateKey.toWIF(), feeb:1, debug:true, })let codehash:stringlet genesis:stringlet sensibleId:stringlet genesisTxId:string// use time as token name so that it's unique// you can change it to any name you likeconstcurrentDate=newDate().getHours() +':'+newDate().getMinutes()consttokenName='MintTest - '+ currentDateconsttokenSymbol='MVCTest'constdecimalNum=8constreceiverAddress=wallet.address// create a new token(Genesis)console.log("Creating token with name: <%s>, symbol: <%s>, decimal: <%s>", tokenName, tokenSymbol, decimalNum);constgenesisResult=awaitftManager.genesis({ tokenName: tokenName, tokenSymbol: tokenSymbol, decimalNum: decimalNum, genesisWif:privateKey.privateKey.toWIF(), }) codehash =genesisResult.codehash genesis =genesisResult.genesis genesisTxId =genesisResult.txid sensibleId =genesisResult.sensibleId console.log("Token created with codehash: <%s>, genesis: <%s>, genesisTxId: <%s>, sensibleId: <%s>", codehash, genesis, genesisTxId, sensibleId);
// sleep for 1 second to wait for the token to be createdawaitnewPromise(resolve =>setTimeout(resolve,1000));// split utxo for fee preparationconstreceivers= []for (let i =0; i <4; i++) {receivers.push({ amount:10000, address:wallet.address.toString(), }) }constfeeTxid= (awaitwallet.sendArray(receivers)).txIdconsole.log('Created fee providing txid ', feeTxid)// sleep for 1 second to wait for the fee tx to be createdawaitnewPromise(resolve =>setTimeout(resolve,1000));// mint some token to burnlet {txid} =awaitftManager.mint({ sensibleId, genesisWif:privateKey.privateKey.toWIF(), receiverAddress, tokenAmount:'10000000000', })console.log('Minted %d %s tokens by txid %s ',10000000000, tokenSymbol, txid)// sleep for 1 second to wait for the token to be mintedawaitnewPromise(resolve =>setTimeout(resolve,1000));// transfer and burn tokenconstburnTokenAmount="100000"// transfer to zero address in order to burn, you can use this method to transfer to any addresslet transfer =awaitftManager.transfer({ genesis: genesis, codehash: codehash, receivers: [ { amount: burnTokenAmount, address:Address.fromPublicKeyHash(BURN_ADDRESS,API_NET.TEST).toString(), }, ], senderWif:privateKey.privateKey.toWIF() })console.log('Sent %s %s tokens to zero address by txid %s', burnTokenAmount, tokenSymbol,transfer.txid)awaitnewPromise(resolve =>setTimeout(resolve,1000));// transfer to zero address in order to burnlet transfer2 =awaitftManager.transfer({ genesis, codehash, receivers: [ { amount: burnTokenAmount, address:Address.fromPublicKeyHash(BURN_ADDRESS,API_NET.TEST).toString(), }, ], senderWif:privateKey.privateKey.toWIF() })console.log('Sent %s %s tokens again to zero address by txid2 %s', burnTokenAmount, tokenSymbol,transfer.txid)awaitnewPromise(resolve =>setTimeout(resolve,1000));// burn the tokensconstftUtxos= [ { txId:transfer.txid, outputIndex:0, tokenAddress:Address.fromPublicKeyHash(BURN_ADDRESS,API_NET.TEST).toString(), tokenAmount: burnTokenAmount, }, { txId:transfer2.txid, outputIndex:0, tokenAddress:Address.fromPublicKeyHash(BURN_ADDRESS,API_NET.TEST).toString(), tokenAmount: burnTokenAmount, }, ]// burnconstburnResult=awaitftManager.burn({ genesis: genesis, codehash: codehash, ftUtxos: ftUtxos, })console.log('Burned %s tokens by txid %s', tokenSymbol,burnResult.txid)// check token balanceconsole.log('Your token balance is %s %s tokens',awaitftManager.getBalance({ codehash: codehash, genesis: genesis, address:receiverAddress.toString() }), tokenSymbol)};setupMyWalletAndOperateFt().catch(console.error);
The above example code demonstrates how to create a new token, transfer tokens (to a burn address), burn tokens, and query token balances. The waiting operations are to prevent access frequency from being too high and causing program exceptions due to the indexer not indexing correctly.
Program Functionality
Initialize the wallet and print out the address and balance.
Create an FtManager instance and generate (Genesis) a new token. The token name can be specified as desired. The token creation process will return information such as codehash, genesis, sensibleId, and genesisTxId.
Wait for 1 second to allow the token creation to complete.
Prepare some UTXOs for subsequent fee payments.
Mint 10,000,000,000 tokens.
Wait for 1 second to allow the token minting to complete.
Transfer 100,000 tokens twice to the burn address (zero address) to burn them.
Wait for 1 second to allow the token transfers to complete.
Burn the tokens.
Query the token balance to confirm the token burn was successful.
Running the Program
Run the following commands to execute the program:
npxtscnodesrc/index.js
If everything runs correctly, you will see an output similar to the following:
Your balance 9701713 satoshis
Creating token with name: <MintTest - 14:23>, symbol: <MVCTest>, decimal: <8>
Token created with codehash: <c9cc7bbd1010b44873959a8b1a2bcedeb62302b7>, genesis: <a5ec