Skip to main content

Create game assets using the preset contract

Learn how to create Web3 assets for your game in the form of ERC721 tokens. This guide will teach you how to create, deploy and mint your first NFT collection.

create game assetscreate game assets

This is intended to be a beginner guide - we'll take you through the process step-by-step so don't worry if you're new to this. If you'd like to familiarise yourself further with the concepts of minting, ERC721 smart contracts and gas fees, see our section on Minting.

💡Type of smart contract deployed in this tutorial
The type of smart contract you will be deploying in this tutorial is a basic NFT smart contract from zkevm-boilerplate repository. This repository serves as a starting point for developers looking to build their first smart contract on the Immutable zkEVM.

In general, when deploying contracts on Immutable zkEVM, we strongly recommend users deploy our recommend contract presets.

Install developer tools

There are a few tools required for this tutorial:

(For macOS users) Homebrew

Homebrew is a package manager allows you to easily install the packages needed for this tutorial. Go to the Homebrew website for instructions on how to install and use it.

Node.js

Node.js allows us to use JavaScript to build and run applications.

Ensure you have the latest LTS version

...or you may experience issues following this tutorial.

For Windows users, you can verify that Node.js is properly installed and working by opening PowerShell or the Command Prompt and running:

npm -v

Visual Studio Code

Visual Studio Code is a code editor we will be using for this tutorial. It is known for its user-friendly interface and extensive extension library.

Get a wallet that supports Ethereum-based assets

As our Minting article explains, minting NFTs on zkEVM requires gas. Test $IMX will be used as gas on Immutable zkEVM Testnet in this example. Content creaters are required to hold Test $IMX in a wallet in order to mint an NFT (and to deploy the smart contract).

For this tutorial, we will use Metamask as our wallet. Other wallets can be used for this purpose.

💡How to verify if a wallet is compatible with a certain chain?
You can check the wallet's settings or preferences and look for options to add or select the desired chain. Additionally, you can examine the wallet's documentation or visit the official website of the chain to determine if the wallet supports it and follow any provided instructions for integration.

Download Metamask wallet and store seed phrase safely

  1. Download the Metamask browser wallet
  2. Follow the steps in the plugin to create a new wallet, then record and store your seed phrase in a safe location

Connect to Immutable's zkEVM testnet

  1. Once you have installed the Metamask browser extension, click on it to open.
  2. Click on the network dropdown:
    Network Section
  3. Select Add network:
    NetworkAdd
  4. Select Add a network manually at the bottom of the screen and fill in the following details:
  5. Save this and ensure that your selected network is the Immutable zkEVM Testnet

Fork the boilerplate repository

Immutable's zkevm-boilerplate repository provides a standard set of libraries and uses Immutable's pre-set contracts. It is your starting point for deploying Immutable's recommended ERC721 Preset contract and familiarising yourself with the zkEVM blockchain.

Follow these Github guides on how to clone a repository:

At the end of this process you should have a copy of the repository installed locally on your machine with the path ../{YOUR_GITHUB_USERNAME}/zkevm-boilerplate

Once you have the repository downloaded onto your local machine, run the following command from the root directory:

npm install

Configure Hardhat

Update your project's hardhat.config.js/ts file with the following code. This file is located in your smart contract repository.

const config = {
solidity: {
version: '0.8.17',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
};

Create a project and install the Immutable SDK

Create project

Create a folder for your project and go to the root directory:

mkdir myproject && cd myproject

Initialize a JavaScript project:

npm init

# After running `npm init`, it will ask you for a bunch of values.
# You can leave the fields empty or run the following which uses the defaults:
npm init -y

Prerequisites

Node version

The Immutable SDK requires Node v18 (Active LTS version) or higher. Node v18 can be installed via nvm which allows to quickly install and use different versions of node via the command line.

The installation steps for nvm for Linux, Mac, and Windows Install & Update Script. You are now ready to install the Node LTS version:

nvm install --lts

Install the Immutable SDK

Run the following command in your project root directory.

npm install -D @imtbl/sdk
Troubleshooting

The Immutable SDK is still in early development. Should complications arise during the installation, please use the following commands to ensure the most recent release of the SDK is correctly installed:

rm -Rf node_modules
npm cache clean --force
npm i

Dependencies

npm install -D typescript ts-node

Add metadata

Set up a metadata hosting service

The contract we are able to deploy will specify the location of where the collection's metadata is hosted. If you are unsure as to what metadata is, or why we recommend it to be hosted off-chain, please see our section on Metadata.

💡Hosting service
For this example, we will use Pinata, which is a service built on the InterPlanetary File System (IPFS). You can use the free version for this tutorial.

When using Pinata, you should be aware of the following:
  • Hosting images on IPFS means that they will be publicly accessible on a decentralized network, enabling anyone to view and access them
  • Pinata is a public gateway to IPFS and it may be slower to respond because of increased network congestion and limited resources on the publicly accessible server
  • Immutable's requests are built to time out after 5 seconds. As such, it is not advisable to use Pinata in production.
  • For better performance, we recommend using services like AWS S3.

Pinata is just one of several providers that allows users to host files on IPFS. Metadata is often hosted on IPFS networks, however there are pros and cons depending on your project's needs.

One of the pros of IPFS storage is that the integrity (immutability) of the file can be verified as each image is represented by a unique content ID (CID). Additionally, as it is a decentralized network, your image is hosted by several nodes, further ensuring its availability.

Follow the steps below to prepare and upload your collection's metadata to Pinata:

  1. Sign up for Pinata
  2. Prepare one image for your NFT and another image to represent the entire collection
  3. Upload the images by pressing Add Files and selecting File
Upload File
  1. Note down the URL for the files by clicking on the eye icon
Upload File

Your URL should have the format: https://peach-dear-wildfowl-698.mypinata.cloud/ipfs/{UNIQUE_HASH}

💡Metadata URLs
Different IPFS providers will have different URL formats than above. Provided the URL is a valid link, the format of the URL will be supported.

Create metadata

We will now be creating metadata for your collection.

Please note the following distinction:

  • Contract metadata is information about the entire NFT collection, such as its description and name. A collection can have many NFTs.
  • NFT metadata is characteristics and properties of the specific NFT you intend to mint. They represent the unique attributes of a particular token.

Define and upload your collection and NFT metadata to Pinata with the following steps:

  1. Create folders and files by running these commands in your terminal:
mkdir -p myproject/contract-metadata
touch myproject/contract-metadata/contract.json

mkdir -p myproject/nft-metadata
touch myproject/nft-metadata/1
touch myproject/nft-metadata/42
touch myproject/nft-metadata/340282366920938463463374607431768211456

This will create files in following tree structure:

myproject
├── contract-metadata
│   └── contract.json
└── nft-metadata
└── 1
└── 42
└── 340282366920938463463374607431768211456
💡Metadata URLs
All NFT metadata filenames should be in the format of [int].

The collection metadata file can contain any values as long as it is in JSON format.
  1. In the folder nft-metadata populate the 1 file with the metadata for the corresponding NFT, using the following example. Make sure to replace each image with the URLs that you created earlier to host your NFT images.
{
"id": 1,
"image": "<replace this with your own IPFS link from step #1>",
"token_id": "1",
"background_color": null,
"animation_url": null,
"youtube_url": null,
"name": "Test zkEVM NFT",
"description": "This NFT is my first zkEVM NFT created on Immutable",
"external_url": null,
"attributes": [
{
"trait_type": "Hat",
"value": "Top Hat"
},
{
"trait_type": "Coat",
"value": "Tails"
},
{
"trait_type": "Neck",
"value": "Bow Tie"
}
]
}
  1. Copy the contents of the 1 file into the 42 and 340282366920938463463374607431768211456 files, changing the values of "id" to match.

  2. In the folder contract-metadata populate the contract.json file with the metadata for the collection, using the following example. Replace image with the URL for the specific NFT image you uploaded when you created your collection metadata.

{
"name": "My collection",
"description": "Some description",
"image": "<replace this with your own IPFS link from step #1>",
"external_link": "https://some-url"
}
  1. Ensure files are saved before uploading both folders into Pinata. Double check this by closing the file and re opening - make sure that the values have been saved. Then upload myproject directory to Pinata by selecting Add Files and Folder. Name your folder myproject in Pinata.
Upload Folder
  1. Click on the folder myproject and then the nft-metadata folder to obtain your collections baseURI. This is used by Immutable's Blockchain Data APIs to fetch the NFT metadata from your hosting service when you mint your NFTs. Note down this URL, which should have the following format: https://peach-dear-wildfowl-698.mypinata.cloud/ipfs/QmVhfy6QYWBzwUZfDSJGvScLScaWKHEyUKBax8AmYqd4Sr/nft-metadata/

  2. Go back and click on the contract-metadata followed by contract.json and note down the URL. This will be used to fill external_link in the contract. This will have this format: https://peach-dear-wildfowl-698.mypinata.cloud/ipfs/QmVhfy6QYWBzwUZfDSJGvScLScaWKHEyUKBax8AmYqd4Sr/contract-metadata/contract.json

To get a better understanding, dive deeper into our metadata guides:

Set up minting wallet

Obtain test $IMX tokens to pay for gas fees

To deploy our smart contract to the test network, we’ll need some test $IMX.

To get test $IMX you will need to create a Immutable Hub account and go to this faucet. Enter your wallet's address in the text field requesting it and then click the Receive Test-IMX button. It may take a few minutes for the test $IMX to arrive.

Your test $IMX balance will be visible in your wallet:

IMX balance
💡Ensure that your wallet is set to the zkEVM network
If you cannot see your balance, your wallet may not be set to the zkEVM-testnet network. To add this network please see this guide.

Locate your wallet's private key

💡Protect your private key
The script needs your wallet's private key, obtainable from Metamask by following these steps. Be cautious not to expose it in public or production code to safeguard your wallet's security.
  1. Open Metamask
  2. Make sure the network at the top of the screen is the test network you wish to deploy to
  3. Open Account details by clicking on the following button and selecting Account Details
Upload File
  1. Select Export Private Key and enter your password
  2. Copy the long string provided (your private key) as this will be needed in the next step.

Configure the private key

We now need to configure the application with your private key in order to grant it the requisite authorisation to deploy your contract.

  1. Open the .env.example file located in your project's (forked zkEVM-boilerplate) root directory.
  2. Update the PRIVATE_KEY variable with your private key string that you obtained in the previous step.
  3. Save the file
  4. Rename the file from .env.example to .env
💡You don't need ETHERSCAN_API_URL and GOERLI_URL
You can ignore these variables in the .env.example file as they are not needed for this tutorial.

Set royalty fees (optional)

💡Learn more about NFT royalties
For more details information regarding royalties and how they are enforced at Immutable, see our Royalty guide.

Royalties will be paid to a specified wallet each time the NFT is sold on a 3rd party marketplace. This is an optional step if you wish to learn how to incorporate royalties in your project.

  1. Go to the root directory of your contract deployment environment that you created during the project setup process. This should be something like ../{YOUR_GITHUB_USERNAME}/zkevm-boilerplate
  2. Go to the ../zkevm-boilerplate/scripts/ directory
  3. Open the deploy.ts file in your code editor
  4. Update the following variables with the correct details in the deploy.ts file:
    • DEPLOYER_ADDRESS - The owner of the contract's wallet, i.e. you
    • ROYALTY_PAYMENT_ADDRESS - The wallet that will receive the royalty fees
    • COLLECTION_NAME - The name of your collection
    • COLLECTION_SYMBOL - The symbol of your collection - typically 2-3 characters long
    • baseURI - The baseURI from step 2
    • contractURI - The contractURI from step 2
    • FEE - The royalty fee % to a factor of x1000. e.g. 2000 is 2%

This is what your deploy.ts file should look like:

deploy.ts
const contract: MyERC721 = await MyERC721.connect(deployer).deploy(
`[DEPLOYER_ADDRESS]`, // owner
`[COLLECTION_NAME]`, // name
`[COLLECTION_SYMBOL]`, // symbol
`[baseURI]`, // baseURI
`[contractURI]`, // contractURI
operatorAllowlist, // operator allowlist contract address
`[ROYALTY_PAYMENT_ADDRESS]`, // royalty recipient
ethers.BigNumber.from(`[FEE]`) // royalty fee
);
  1. Run the following command to commit your changes:
npx hardhat compile

Contract deployment

Deploy the contract

Fill in the values in scripts/deploy.ts as appropriate, and then run the following command from your project's root directory:

# Deploy to Immutable zkEVM Testnet
npx hardhat run --network immutableZkevmTestnet scripts/deploy.ts
🎉Congratulations on deploying your first contract on Immutable zkEVM!
Take a moment to pat yourself on the back for coming this far. 😌

Make sure you copy the CONTRACT_ADDRESS which is returned after the successful deployment:

MyERC721 contract deployed to 0x6A4C106A6571533dE17d60D171a2747F549ae3C9

Verify the contract has been deployed

Immutable's testnet explorer can be used to verify your contract has been deployed to the network.

Entering the CONTRACT_ADDRESS returned from the previous step in the search bar should return a record if it has been successfully deployed.

Mint tokens

Enable Minter role for yourself

We will now be using the Immutable SDK that you installed earlier.

Before you can mint from your newly deployed collection, you need to assign yourself the role of being an eligible minter. The following steps will enable this:

  1. Go to the myproject directory that you set up earlier

  2. Create a file called grantMinterRole.ts at the root directory

  3. Add the following code to your file, with the following variables updated:

    • CONTRACT_ADDRESS - The address you received after deploying the contract
    • PRIVATE_KEY - Your wallet's private key
grantMinterRole.ts
import { getDefaultProvider, Wallet } from 'ethers'; // ethers v5
import { Provider, TransactionResponse } from '@ethersproject/providers'; // ethers v5
import { ERC721Client } from '@imtbl/zkevm-contracts';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]';
const PRIVATE_KEY = '[PRIVATE_KEY]';
const provider = getDefaultProvider('https://rpc.testnet.immutable.com');

const grantMinterRole = async (
provider: Provider
): Promise<TransactionResponse> => {
// Bound contract instance
const contract = new ERC721Client(CONTRACT_ADDRESS);
// The wallet of the intended signer of the mint request
const wallet = new Wallet(PRIVATE_KEY, provider);

// Give the wallet minter role access
const populatedTransaction = await contract.populateGrantMinterRole(
wallet.address
);
const result = await wallet.sendTransaction(populatedTransaction);
return result;
};

grantMinterRole(provider);
  1. Run the following script:
 ./node_modules/.bin/ts-node grantMinterRole.ts

Mint Option 1: Mint a single NFTs by specifying the token ID

Do the following to mint a single NFT using the Immutable SDK, specifying the ID of the token that requires minting:

caution

If using Immutable's recommended ERC721 preset contract the Token IDs of the desired NFT must be unique to a collection and below 2^128, the mintBatchByQuantityThreshold (i.e. 340,282,366,920,938,463,463,374,607,431,768,211,455 or lower).

  1. Create a file called mintNFT.ts
  2. Add the following code to your file with the following variables:
    • CONTRACT_ADDRESS - The address of the deployed ERC721 contract
    • PRIVATE_KEY - The private key of the account used for signing the mint request
    • ACCOUNT_ADDRESS - The second address of the wallet that will own the NFTs being minted in the batch
    • TOKEN_ID - A free token ID in the collection that is less than 340,282,366,920,938,463,463,374,607,431,768,211,456
mintNFT.ts
import { getDefaultProvider, Wallet } from 'ethers'; // ethers v5
import { Provider, TransactionResponse } from '@ethersproject/providers'; // ethers v5
import { ERC721MintByIDClient } from '@imtbl/zkevm-contracts';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]';
const PRIVATE_KEY = '[PRIVATE_KEY]';

// Specify who we want to receive the minted token
const RECIPIENT = 'ACCOUNT_ADDRESS';

// Choose an ID for the new token
const TOKEN_ID = 0;

const provider = getDefaultProvider('https://rpc.testnet.immutable.com');

const mint = async (provider: Provider): Promise<TransactionResponse> => {
// Bound contract instance
const contract = new ERC721MintByIDClient(CONTRACT_ADDRESS);
// The wallet of the intended signer of the mint request
const wallet = new Wallet(PRIVATE_KEY, provider);
// We can use the read function hasRole to check if the intended signer
// has sufficient permissions to mint before we send the transaction
const minterRole = await contract.MINTER_ROLE(provider);
const hasMinterRole = await contract.hasRole(
provider,
minterRole,
wallet.address
);

if (!hasMinterRole) {
// Handle scenario without permissions...
console.log('Account doesnt have permissions to mint.');
return Promise.reject(
new Error('Account doesnt have permissions to mint.')
);
}

// Rather than be executed directly, contract write functions on the SDK client are returned
// as populated transactions so that users can implement their own transaction signing logic.
const populatedTransaction = await contract.populateMint(RECIPIENT, TOKEN_ID);
const result = await wallet.sendTransaction(populatedTransaction);
console.log(result); // To get the TransactionResponse value
return result;
};

mint(provider);
  1. Run the following script:
 ./node_modules/.bin/ts-node mintNFT.ts
🎉Congratulations on minting your first NFTs on Immutable zkEVM!
Pat yourself on the back for minting your first NFTs (with metadata!) 😌

Mint Option 2: Mint a batch of NFTs by specifying token IDs

Do the following to mint NFTs using the Immutable SDK, where you are able to specify the ID of each token to be minted. Minting in batches is more gas efficent than single mint requests.

caution

If using Immutable's recommended ERC721 preset contract the Token IDs of the batch must be unique to a collection and below the mintBatchByQuantityThreshold.

Immutable's recommended ERC721 preset contract has multiple batch minting strategies tailored for different minting scenarios. Significant gas savings can be realised if minting multiple NFTs to a single wallet using the mintBatchByQuantity() function. This function will assign Token IDs of the mintBatchByQuantityThreshold and above to the NFTs minted with this function.

For more information on batch minting check out the batch minting product page.

  1. Create a file called mintNFTsByID.ts
  2. Add the following code to your file with the following variables:
    • CONTRACT_ADDRESS - The address of the deployed ERC721 contract
    • PRIVATE_KEY - The private key of the account used for signing the mint request
    • ACCOUNT_ADDRESS1 - The first address of the wallet that will own the NFTs being minted in the batch
    • ACCOUNT_ADDRESS2 - The second address of the wallet that will own the NFTs being minted in the batch
    • TOKEN_ID1 - A free token ID in the collection that is less than 340,282,366,920,938,463,463,374,607,431,768,211,456
    • TOKEN_ID2 - A free token ID in the collection that is less than 340,282,366,920,938,463,463,374,607,431,768,211,456
    • TOKEN_ID3 - A free token ID in the collection that is less than 340,282,366,920,938,463,463,374,607,431,768,211,456
    • TOKEN_ID4 - A free token ID in the collection that is less than 340,282,366,920,938,463,463,374,607,431,768,211,456
mintNFTsByID.ts
import { getDefaultProvider, Wallet } from 'ethers'; // ethers v5
import { Provider, TransactionResponse } from '@ethersproject/providers'; // ethers v5
import { ERC721Client } from '@imtbl/zkevm-contracts';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]';
const PRIVATE_KEY = '[PRIVATE_KEY]';
const TOKEN_ID1 = 0;
const TOKEN_ID2 = 0;
const TOKEN_ID3 = 0;
const TOKEN_ID4 = 0;
const provider = getDefaultProvider('https://rpc.testnet.immutable.com');

const mint = async (provider: Provider): Promise<TransactionResponse> => {
// Bound contract instance
const contract = new ERC721Client(CONTRACT_ADDRESS);
// The wallet of the intended signer of the mint request
const wallet = new Wallet(PRIVATE_KEY, provider);
// We can use the read function hasRole to check if the intended signer
// has sufficient permissions to mint before we send the transaction
const minterRole = await contract.MINTER_ROLE(provider);
const hasMinterRole = await contract.hasRole(
provider,
minterRole,
wallet.address
);

if (!hasMinterRole) {
// Handle scenario without permissions...
console.log('Account doesnt have permissions to mint.');
return Promise.reject(
new Error('Account doesnt have permissions to mint.')
);
}

// Construct the mint requests
const requests = [
{
to: '[ACCOUNT_ADDRESS1]',
tokenIds: [TOKEN_ID1, TOKEN_ID2],
},
{
to: '[ACCOUNT_ADDRESS2]',
tokenIds: [TOKEN_ID3, TOKEN_ID4],
},
];

// Rather than be executed directly, contract write functions on the SDK client are returned
// as populated transactions so that users can implement their own transaction signing logic.
const populatedTransaction = await contract.populateMintBatch(requests);
const result = await wallet.sendTransaction(populatedTransaction);
console.log(result); // To get the TransactionResponse value
return result;
};

mint(provider);
  1. Run the following script:
 ./node_modules/.bin/ts-node mintNFTsByID.ts
🎉Congratulations on minting your first NFTs on Immutable zkEVM!
Pat yourself on the back for minting your first batch of NFTs (with metadata!) 😌

Mint Option 3: Mint a batch of NFTs without specifying token ID (gas efficent)

Do the following to mint NFTs using the Immutable SDK in the most gas optimised method available. This method is more gas efficient than mintBatch() however the ID of each token is system generated. For more information on how this is achieved check out our mintBatchByQuantity() function on the batch minting product page.

caution

If using Immutable's recommended ERC721 preset contract the Token IDs of the batch must be unique to a collection and equal or above the mintBatchByQuantityThreshold.

  1. Create a file called mintNFTsByQuantity.ts
  2. Add the following code to your file with the following variables:
    • CONTRACT_ADDRESS - The address of the deployed ERC721 contract
    • PRIVATE_KEY - The private key of the account used for signing the mint request
    • ACCOUNT_ADDRESS1 - The first address of the wallet that will own the NFTs being minted in the batch
    • ACCOUNT_ADDRESS2 - The second address of the wallet that will own the NFTs being minted in the batch
mintNFTsByQuantity.ts
import { getDefaultProvider, Wallet } from 'ethers'; // ethers v5
import { Provider, TransactionResponse } from '@ethersproject/providers'; // ethers v5
import { ERC721Client } from '@imtbl/zkevm-contracts';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]';
const PRIVATE_KEY = '[PRIVATE_KEY]';

// Specify who we want to receive the minted token
const provider = getDefaultProvider('https://rpc.testnet.immutable.com');

const mint = async (provider: Provider): Promise<TransactionResponse> => {
// Bound contract instance
const contract = new ERC721Client(CONTRACT_ADDRESS);
// The wallet of the intended signer of the mint request
const wallet = new Wallet(PRIVATE_KEY, provider);
// We can use the read function hasRole to check if the intended signer
// has sufficient permissions to mint before we send the transaction
const minterRole = await contract.MINTER_ROLE(provider);
const hasMinterRole = await contract.hasRole(
provider,
minterRole,
wallet.address
);

if (!hasMinterRole) {
// Handle scenario without permissions...
console.log('Account doesnt have permissions to mint.');
return Promise.reject(
new Error('Account doesnt have permissions to mint.')
);
}

const mints = [
{
to: '[ACCOUNT_ADDRESS1]',
quantity: 3,
},
{
to: '[ACCOUNT_ADDRESS2]',
quantity: 3,
},
];

// Rather than be executed directly, contract write functions on the SDK client are returned
// as populated transactions so that users can implement their own transaction signing logic.
const populatedTransaction = await contract.populateMintBatchByQuantity(
mints
);
const result = await wallet.sendTransaction(populatedTransaction);
console.log(result); // To get the TransactionResponse value
return result;
};

mint(provider);
  1. Run the following script:
 ./node_modules/.bin/ts-node mintNFTsByQuantity.ts
🎉Congratulations on minting your first NFTs on Immutable zkEVM!
Pat yourself on the back for minting your first batch of NFTs (with metadata!) 😌

Verify successful mints

tip

Blockscout's Immutable zkEVM testnet explorer can be used to verify your contract has been deployed to the network.

Entering the CONTRACT_ADDRESS in the search bar will allow you to view transactions by collection. The mint request you just generated will produce a Contract Call record.

Using the below script you can verify the minting request was successful.

  1. Create a file called reviewTransaction.ts
  2. Add the following code to your file with the following variable:
    • CONTRACT_ADDRESS - The address of the deployed ERC721 contract
reviewTransaction.ts
import { config as immutableConfig, blockchainData } from '@imtbl/sdk';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]'; // The address of the contract you deployed

const config: blockchainData.BlockchainDataModuleConfiguration = {
baseConfig: new immutableConfig.ImmutableConfiguration({
environment: immutableConfig.Environment.SANDBOX,
}),
};

const client = new blockchainData.BlockchainData(config);

async function getData() {
try {
const response = await client.listActivities({
chainName: 'imtbl-zkevm-testnet',
contractAddress: CONTRACT_ADDRESS,
});

for (const result in response.result) {
console.log(result);
}
return response.result;
} catch (error) {
console.error(error);
}
}

getData();
  1. Run the following script:
 ./node_modules/.bin/ts-node reviewTransaction.ts

View minted NFT

To validate that a mint was successful, you can view an NFT using the getNFT method, which will show the NFT with metadata details via Immutable's indexer:

  1. Create a file called getNFT.ts
  2. Add the following code to your file with the following variable populated:
    • CONTRACT_ADDRESS - The address of the deployed ERC721 contract
    • TOKEN_ID - The ID of the token. Minted token IDs can be retrieved from the output of the previous step.
getNFT.ts
import { config as immutableConfig, blockchainData } from '@imtbl/sdk';

const CONTRACT_ADDRESS = '[CONTRACT_ADDRESS]'; // The address of the deployed collection contract
const TOKEN_ID = ''; // The ID of the minted token

const config: blockchainData.BlockchainDataModuleConfiguration = {
baseConfig: new immutableConfig.ImmutableConfiguration({
environment: immutableConfig.Environment.SANDBOX,
}),
};

const client = new blockchainData.BlockchainData(config);

async function getData() {
try {
const response = await client.getNFT({
chainName: 'imtbl-zkevm-testnet',
contractAddress: CONTRACT_ADDRESS,
tokenId: TOKEN_ID,
});

console.log(response.result);
return response.result;
} catch (error) {
console.error(error);
}
}

getData();
  1. Run the following script:
 ./node_modules/.bin/ts-node getNFT.ts

Next steps

Now that you've created game assets, you can perform a primary sale.