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`