Minting Transactions

Learn to use ForgeScript to create minting transactions for minting and burning native assets.

Minting Assets

In this section, we will see how to mint native assets with a ForgeScript. For minting assets with smart contract, visit Transaction - Smart Contract - Minting Assets with Smart Contract.

Firstly, we need to define the forgingScript with ForgeScript. We use the first wallet address as the "minting address" (you can use other addresses).

// use browser wallet to get address
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
// use app wallet to get address
const address = wallet.getPaymentAddress();

// create forgingScript
const forgingScript = ForgeScript.withOneSignature(address);

Then, we define the metadata.

const assetMetadata: AssetMetadata = {
  "name": "Mesh Token",
  "image": "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
  "mediaType": "image/jpg",
  "description": "This NFT was minted by Mesh (https://meshjs.dev/)."
};
const asset: Mint = {
  assetName: 'MeshToken',
  assetQuantity: '1',
  metadata: assetMetadata,
  label: '721',
  recipient: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr' 
};
tx.mintAsset(
  forgingScript,
  asset,
);

Here is the full code:

import { Transaction, ForgeScript } from '@meshsdk/core';
import type { Mint, AssetMetadata } from '@meshsdk/core';

// prepare forgingScript
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
const forgingScript = ForgeScript.withOneSignature(address);

const tx = new Transaction({ initiator: wallet });

// define asset#1 metadata
const assetMetadata1: AssetMetadata = {
  "name": "Mesh Token",
  "image": "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
  "mediaType": "image/jpg",
  "description": "This NFT was minted by Mesh (https://meshjs.dev/)."
};
const asset1: Mint = {
  assetName: 'MeshToken',
  assetQuantity: '1',
  metadata: assetMetadata1,
  label: '721',
  recipient: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr',
};
tx.mintAsset(
  forgingScript,
  asset1,
);

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
Mint assets and send to recipients

Add or remove recipients, input the address and define the asset metadata before minting and sending.

Recipients
Recipient #1
No wallets installed

Burning Assets

Like minting assets, we need to define the forgingScript with ForgeScript. We use the first wallet address as the "minting address". Note that, assets can only be burned by its minting address.

const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
const forgingScript = ForgeScript.withOneSignature(address);

Then, we define Asset and set tx.burnAsset()

const asset: Asset = {
  unit: '64af286e2ad0df4de2e7de15f8ff5b3d27faecf4ab2757056d860a424d657368546f6b656e',
  quantity: '1',
};
tx.burnAsset(forgingScript, asset);

Here is the full code:

import { Transaction, ForgeScript } from '@meshsdk/core';
import type { Asset } from '@meshsdk/core';

// prepare forgingScript
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
const forgingScript = ForgeScript.withOneSignature(address);

const tx = new Transaction({ initiator: wallet });

// burn asset#1
const asset1: Asset = {
  unit: '64af286e2ad0df4de2e7de15f8ff5b3d27faecf4ab2757056d860a424d657368546f6b656e',
  quantity: '1',
};
tx.burnAsset(forgingScript, asset1);

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
Select assets to burn

Select the assets and input the quantity you wish to burn. Note this demo we only selects up to 9 random assets.

AssetsQuantity to burn
No wallets installed

Minting Assets with Native Script

Additionally, you can define the forging script with NativeScript. For example if you want to have a policy locking script, you can create a new ForgeScript with NativeScript:

import type { NativeScript } from '@meshsdk/core';

const nativeScript: NativeScript = {
  type: 'all',
  scripts:
  [
    {
      type: 'before',
      slot: '<insert slot here>'
    },
    {
      type: 'sig',
      keyHash: '<insert keyHash here>'
    }
  ]
};

const forgingScript = ForgeScript.fromNativeScript(nativeScript);

To get the keyHash, use the resolvePaymentKeyHash(). To get the slot, use the resolveSlotNo(). Check out Resolvers on how to use these functions.

Important: if you are using a policy locking script, you must define setTimeToExpire before the expiry; otherwise, you will catch the ScriptWitnessNotValidatingUTXOW error. See Transaction - setTimeLimit.

You can get the policy ID for this Native Script with resolveNativeScriptHash:

const policyId = resolveNativeScriptHash(nativeScript);

Here is the full code:

import { Transaction, ForgeScript, Mint, AssetMetadata, resolvePaymentKeyHash } from '@meshsdk/core';

// prepare forgingScript
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];

const keyHash = resolvePaymentKeyHash(address);

const nativeScript: NativeScript = {
  type: 'all',
  scripts: [
    {
      type: 'before',
      slot: '99999999',
    },
    {
      type: 'sig',
      keyHash: keyHash,
    },
  ],
};

const forgingScript = ForgeScript.fromNativeScript(nativeScript);

const tx = new Transaction({ initiator: wallet });

// define asset#1 metadata
const assetMetadata1: AssetMetadata = {
  "name": "Mesh Token",
  "image": "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
  "mediaType": "image/jpg",
  "description": "This NFT was minted by Mesh (https://meshjs.dev/)."
};
const asset1: Mint = {
  assetName: 'MeshToken',
  assetQuantity: '1',
  metadata: assetMetadata1,
  label: '721',
  recipient: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr',
};
tx.mintAsset(
  forgingScript,
  asset1,
);

tx.setTimeToExpire('99999999');

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
Mint assets Native Script

Add or remove recipients, input the address and define the asset metadata before minting and sending.

Recipients
Recipient #1
No wallets installed

Minting Assets with Plutus Script

For minting assets with a Plutus Script, you need to define the PlutusScript:

const script: PlutusScript = {
  code: '<plutusScript.compiledCode.cborHex>',
  version: "V2",
};

You also need to define the Redeemer:

const redeemer = {
  data: { alternative: 0, fields: ["mesh"] },
  tag: "MINT",
};

Then you can create the transaction with the Transaction class:

const tx = new Transaction({ initiator: wallet })
  .mintAsset(script, asset, redeemer)
  .setRequiredSigners([address]);

Here is the full code:

const address = (await wallet.getUsedAddresses())[0];

const script: PlutusScript = {
  code: '<plutusScript.compiledCode.cborHex>',
  version: "V2",
};

const redeemer = {
  data: { alternative: 0, fields: [] },
  tag: "MINT",
};

const asset: Mint = {
  assetName: "MeshToken",
  assetQuantity: "1",
  metadata: assetMetadata,
  label: "721",
  recipient: address,
};

const tx = new Transaction({ initiator: wallet })
  .mintAsset(script, asset, redeemer)
  .setRequiredSigners([address]);

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);

Minting Royalty Token

Royalty tokens is a special type of token that allows the creator to collect a royalty fee, this proposed standard will allow for uniform royalties' distributions across the secondary market space. Read CIP-27 for more information.

The implementation of royalty tokens is very simple, minting a token with 777 label, with "rate" and "addr" in the metadata.

Here is the full code:

const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];

// create forgingScript, you can also use native script here
const forgingScript = ForgeScript.withOneSignature(address);

const tx = new Transaction({ initiator: wallet });

const _assetMetadata = {
  rate: '0.2',
  addr: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr'
};
const asset: Mint = {
  assetName: '',
  assetQuantity: '1',
  metadata: _assetMetadata,
  label: '777',
  recipient: address,
};

tx.mintAsset(forgingScript, asset);

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
Minting Royalty Token

Minting a label `777` token with `rate` and `addr`

No wallets installed