Skip to main content

Tokens

Mintlayer supports on-chain fungible tokens (MLS-01) and NFTs (Data NFTs). The SDK's Client exposes the full lifecycle through one-call methods, each also available as a buildX variant; see Transactions.


Fungible tokens

Supply policies

When issuing a token you choose one of three supply policies:

PolicyDescription
UnlimitedMinting is always allowed with no cap
LockableUnlimited minting until lockTokenSupply is called, after which the supply is frozen permanently
FixedA hard cap is set at issuance; supply cannot exceed it

Issuing a token

const signedTx = await client.issueToken({
token_ticker: 'MYTOKEN',
number_of_decimals: 8,
metadata_uri: 'https://example.com/token-metadata.json',
is_freezable: true,
supply_type: 'Lockable',
authority: 'tmt1q...', // token authority address (must be one of your addresses)
// supply_amount: 1000000, // required for supply_type: 'Fixed'
});

The authority address becomes the token authority: the key that controls future operations (minting, freezing, authority transfer). Keep it secure; the full lifecycle walkthrough lives in Issue a Token (SDK), and the metadata URI should follow the Token Metadata Standards.

Minting and unminting

await client.mintToken({
token_id: 'tmltk1...',
amount: 1000,
destination: 'tmt1q...',
});

await client.unmintToken({ token_id: 'tmltk1...', amount: 500 }); // burns tokens

mintToken mints new units to destination; unmintToken removes units from circulation. Both require the token authority key.

Locking supply

For Lockable tokens, lock the supply permanently:

await client.lockTokenSupply({ token_id: 'tmltk1...' });

After this call no further minting is possible for the token.

Freezing

If the token was issued with is_freezable: true, the authority can freeze and unfreeze it. freezeToken also takes is_unfreezable, which decides whether the freeze can ever be lifted:

await client.freezeToken({ token_id: 'tmltk1...', is_unfreezable: false });
await client.unfreezeToken({ token_id: 'tmltk1...' });

Authority and metadata management

await client.changeTokenAuthority({
token_id: 'tmltk1...',
new_authority: 'tmt1q...', // destination for the authority
});

await client.changeMetadataUri({
token_id: 'tmltk1...',
new_metadata_uri: 'https://example.com/new-metadata.json',
});

changeTokenAuthority hands control of the token to another address; changeMetadataUri updates where the token's metadata is published.

Burning and transferring

await client.burn({ token_id: 'tmltk1...', amount: 25 });

await client.transfer({
to: 'tmt1q...',
amount: 10,
token_id: 'tmltk1...', // omit to transfer the base coin instead
});

Tokens owned by the connected addresses are listed by client.getTokensOwned(); per-token balances via client.getBalances().


NFTs

Issuing an NFT

const signedTx = await client.issueNft({
ticker: 'MYNFT',
name: 'My First NFT',
description: 'Issued with @mintlayer/sdk',
creator: 'tmt1q...', // optional
media_uri: 'https://example.com/media.png',
media_hash: '<content hash of the media>',
icon_uri: 'https://example.com/icon.png',
additional_metadata_uri: 'https://example.com/metadata.json',
destination: 'tmt1q...', // where the NFT is minted
});

The metadata fields follow the Data NFT standard; see Issue an NFT (SDK) for a walkthrough and the MLS-03 metadata schema for the off-chain metadata.

Transferring an NFT

await client.transferNft({
to: 'tmt1q...',
token_id: 'tmltk1...',
});

Units and decimals

All amount values are human-readable; the SDK converts them to atoms using the token's number_of_decimals. For display conversions use the exported helpers:

import { atomsToDecimal, decimalsToAtoms } from '@mintlayer/sdk';

atomsToDecimal('100000000', 8); // '1'
decimalsToAtoms(1, 8); // 100000000n