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);
| Recipients | ||
|---|---|---|
Recipient #1 | ||
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: assetAsset, 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: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e', quantity: '1', }; tx.burnAsset(forgingScript, asset1); const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
| Assets | Quantity to burn |
|---|---|
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);
| Recipients | ||
|---|---|---|
Recipient #1 | ||
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 a label `777` token with `rate` and `addr`