# NFT minting tutorial

NFT minting tutorial

*Estimated completion time: 15 mins*

This tutorial provides a step by step guide on how to mint an NFT on XpansionChain. It is designed for developers building on Web3 for the first time, so anyone can follow along regardless of prior experience. This has been simplified for educational purposes and we are working on expanding the content.

By the end of this tutorial you will have:

* Prepared an NFT collection
* Deployed a smart contract for your NFT collection
* Minted and listed an NFT

If you get stuck at any point, reach out on the dev-faq and dev-discussion channels in our <mark style="color:blue;">Discord</mark>. Click <mark style="color:blue;">here</mark> to provide feedback on the tutorial or let us know what topics you'd like to see in our documentation.

### Step 1: Prerequisites[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-1-prerequisites) <a href="#step-1-prerequisites" id="step-1-prerequisites"></a>

There are a few tools required for this tutorial:

<mark style="color:blue;">**Homebrew**</mark>

INFO

Homebrew is only needed for Mac OS.

Homebrew installs the packages needed for this tutorial. Copy the command on the <mark style="color:blue;">Homebrew website</mark>, then run in the terminal.

<mark style="color:blue;">**Node.js**</mark>

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

NODE.JS VERSION

Ensure that you get the latest LTS version or you may experience issues following the turorial.

* Windows
* macOS

For **Windows** users, check that NodeJS is working by opening powershell or command line and executing the command:

```
npm -v
```

**Yarn**

Yarn is an open source package manager. Follow the steps below to install:

Run the following command in powershell.

```
npm install yarn -g
```

<mark style="color:blue;">**Visual Studio Code**</mark>

Visual Studio Code is the code editor we will be using for this tutorial.

### Step 2: Setup MetaMask[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-2-setup-metamask) <a href="#step-2-setup-metamask" id="step-2-setup-metamask"></a>

To trade cryptocurrencies and NFTs, we need a wallet. For this tutorial, we will use Metamask.

1. Open <mark style="color:blue;">metamask.io</mark> to install the browser extension
2. Follow the steps in the plugin to create a new wallet, then record and store your seed phrase in a safe location
3. Ensure you display test networks
4. Change the network selection from **Ethereum Mainnet** to **Goerli Test Network**
5. Note down your <mark style="color:blue;">private key</mark> and <mark style="color:blue;">public key</mark>

Changing the network enables us to deploy on a testnet where we can experiment using test Eth. To learn more about transactions on Ethereum work, check out <mark style="color:blue;">this page</mark> from the Ethereum foundation.

### Step 3: Obtain GoerliETH[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-3-obtain-goerlieth) <a href="#step-3-obtain-goerlieth" id="step-3-obtain-goerlieth"></a>

To deploy our smart contract to the Goerli test network, we’ll need some test Eth. To get test Eth you can go to the <mark style="color:blue;">Goerli faucet</mark> and enter your Goerli account address, then click “Send Me ETH.” It may take a few minutes for the goerliETH to arrive.

If this faucet doesn't work, try these alternative faucets:

* <mark style="color:blue;">Faucet 1</mark>
* <mark style="color:blue;">Faucet 2</mark>

### Step 4: Setup Pinata[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-4-setup-pinata) <a href="#step-4-setup-pinata" id="step-4-setup-pinata"></a>

Pinata is a service that allows users to host files on the <mark style="color:blue;">InterPlanetary File System</mark> (IPFS) network. We use Pinata to store our NFT metadata as it ensures the authenticity of the file will be verifiable and the file will always be accessible. Follow the steps below to prepare your collection:

INFO

You can use the free version for this tutorial, however consider creating a paid account for your real collection to ensure your images can be loaded. Be aware that your images will be publicly hosted on IPFS.

CAUTION

We don't suggest using Pinata in production. Our systems will timeout after 5 seconds if your server does not respond; ensure your providers respond faster. For better performance, use services like AWS S3 to host metadata in production.

1. Sign up to <mark style="color:blue;">Pinata</mark>
2. Prepare 3 images for your NFTs
3. Upload an image by pressing Upload and selecting the file
4. Upload the remaining 2 images
5. Note down the URL for each file

Your URLs should have the format `https://gateway.pinata.cloud/ipfs/QmWfjs6CVu4ENgXGNfdPhgaSdzEhCsCfB5XEFUosPFGsNV`

### Step 5: Create Metadata[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-5-create-metadata) <a href="#step-5-create-metadata" id="step-5-create-metadata"></a>

<mark style="color:blue;">NFT Metadata</mark> contains information about the characteristics and properties of an NFT.

1. Open Visual Studio Code
2. Create New Folder (Open Folder --> New Folder)
3. Press the page icon 3x to create 3 files
4. Name the files **1,2 & 3**. These are our Token IDs.

![FileCreation](https://docs.x.immutable.com/assets/images/step5_filecreation-9e3a44025cc27223f3531c2fb4853e6e.png)

DANGER

Ensure the files are named **1, 2 & 3** or you may run into errors later.

Populate each file with the metadata for the corresponding NFT. You can use the following metadata for your test collection, however make sure to replace each `image_URL` with the URLs that you created earlier to host your NFT images.

```
{
  "name": "1st NFT",
  "description": "This is your 1st nft",
  "image_url": "<replace this with your own IPFS picture link>",
  "attack": 123,
  "collectable": true,
  "class": "EnumValue1"
}
```

```
{
  "name": "2nd NFT",
  "description": "This is your 2nd nft",
  "image_url": "<replace this with your own IPFS picture link>",
  "attack": 223,
  "collectable": true,
  "class": "EnumValue2"
}
```

```
{
  "name": "3rd NFT",
  "description": "This is your 3rd nft",
  "image_url": "<replace this with your own IPFS picture  link>",
  "attack": 323,
  "collectable": true,
  "class": "EnumValue3"
}
```

Ensure you press **save** before uploading the folder into Pinata. Double check this by closing the file and re opening - make sure that the values have saved.

![Upload Folder](https://docs.x.immutable.com/assets/images/pinata3-folder-95525f293e614c69defcd18b43f4525f.png)

Click on the folder name to obtain your **metadata API URL**. This endpoint is used by the metadata crawler to add metadata to your NFTs when they are minted. Note this down.

![Folder Appearance](https://docs.x.immutable.com/assets/images/Step5_Metadata-0584388f8026db9ff4f73d073dfaf7d3.png)

The resulting URL should have the format `https://gateway.pinata.cloud/ipfs/QmWfKt2pXLnQ2AB5jfS2KYB9K2hxFtgcMNxyndkSGT3yuj`.

CHECK YOUR WORK

Click on your metadata API URL and ensure that there are 3 files named 1,2 & 3. Click into each file and confirm the data is correct. If any of them are empty, you will need to reupload your folder.

### Step 6: Create Etherscan API Key[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-6-create-etherscan-api-key) <a href="#step-6-create-etherscan-api-key" id="step-6-create-etherscan-api-key"></a>

An Etherscan API Key is necessary to verify that you're the owner of the smart contract that you're trying to publish. Follow the steps below:

1. Navigate to <mark style="color:blue;">Etherscan</mark>
2. Sign in (or create a new account)
3. Navigate to `API-KEYS` and add a new key
4. Note down the generated API key

![Etherscan API Key](https://docs.x.immutable.com/assets/images/Etherscan1-no-arrow-cbf188bd3082d700f9f3601b48694b57.png) ![Etherscan API Key2](https://docs.x.immutable.com/assets/images/Etherscan2-68258ece1893f4024dd8507b998cbd8f.png)

### Step 7: Create NFT contract[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-7-create-nft-contract) <a href="#step-7-create-nft-contract" id="step-7-create-nft-contract"></a>

Next we will need to update the variables for our smart contract.

1. Clone or download the <mark style="color:blue;">imx-contracts</mark> code from github.
2. Unzip the file and open it in Visual Studio Code (File--> Open Folder)
3. Rename the `.env.example` to `.env`

![Env file](https://3017072639-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7a6afyDwSEkvWtt1UhmH%2Fuploads%2FKQW0wmHHG34rryoQIuvf%2F1%20%E5%8F%B3%E8%BE%B9%E6%9C%80%E9%A1%B6%E4%B8%8A%E5%92%8C%E4%B8%8B%E9%9D%A2%E7%AC%AC%E4%B8%80%E8%A1%8C%20%E8%BF%98%E6%9C%89%E6%9C%80%E5%B7%A6%E8%BE%B9%20IMX%E6%94%B9%E4%B8%BAXPC.png?alt=media\&token=fd3c67a7-7d42-4ae4-89d0-b9919ca2ff56)

4. Fill in the following details:

| Field Name                                                  | Description                                                   |
| ----------------------------------------------------------- | ------------------------------------------------------------- |
| `Etherscan API Key`                                         | Etherscan API Key from previous step                          |
| `CONTRACT_OWNER_ADDRESS`                                    | Metamask wallet address also known as public key              |
| `DEPLOYER_TESTNET_PRIVATE_KEY DEPLOYER_MAINNET_PRIVATE_KEY` | Metamask wallet private key                                   |
| `CONTRACT_NAME`                                             | Name of your NFT collection eg "Spaghetti Adventures"         |
| `CONTRACT_SYMBOL`                                           | This is a shortened version of your collection name eg "SPAG" |

ALCHEMY API KEY

Note down the `ALCHEMY_API_KEY`. We do not need to update this value now, but we will use this value later.

### Step 8: Install Dev library[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-8-install-dev-library) <a href="#step-8-install-dev-library" id="step-8-install-dev-library"></a>

Next we will need to install packages needed for deploying our smart contract.

1. Right click on any file in the explorer
2. Select 'Open in Integrated Terminal'

![Open the integrated terminal](https://3017072639-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7a6afyDwSEkvWtt1UhmH%2Fuploads%2FHIYiXMh3jX4gpW5HyL56%2F2%E6%9C%80%E5%B7%A6%E8%BE%B9%20%E5%8F%B3%E8%BE%B9%E7%AC%AC%E4%B8%80%E8%A1%8C%20IMX%E6%94%B9%E4%B8%BAXPC.png?alt=media\&token=b87f15bc-ceb2-447b-b583-198fdfd3d8cb)

3. Run `npm install --include=dev` and wait until the installation is completed
4. Save your work

### Step 9: Deploy Contract[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-9-deploy-contract) <a href="#step-9-deploy-contract" id="step-9-deploy-contract"></a>

Before we can mint on Layer 2, we need to deploy a smart contract on Layer 1 to ensure assets can be withdrawn to Layer 1. Click <mark style="color:blue;">here</mark> to learn more about the differences between Layer 1 and Layer 2.

1. Run `yarn hardhat run deploy/asset.ts --network sandbox`
2. It will take \~5 minutes to deploy your contract to Goerli Etherscan
3. Copy the deployed contract address

![Step9\_Deploying the contract](https://docs.x.immutable.com/assets/images/Step9DeployContract-a6dc46e2417dba73bdf5f2806d861d25.png)

CHECK YOUR WORK

Paste your contract address into <mark style="color:blue;">Goerli Etherscan</mark>. It should say **contract** in the upper left. If this says address, ensure you are on the correct network

### Step 10: Add your NFT Collection to XpansionChain[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-10-add-your-nft-collection-to-immutable-x) <a href="#step-10-add-your-nft-collection-to-immutable-x" id="step-10-add-your-nft-collection-to-immutable-x"></a>

After deploying your contract to Layer 1, you will need to <mark style="color:blue;">register</mark> it with XpansionChain by creating a project and a collection.

1. Download the <mark style="color:blue;">imx-examples repo</mark>
2. Open the folder in Visual Studio Code
3. Rename `.env.example` to `.env` and save
4. Fill in the following:

| Field Name                    | Description                                  |
| ----------------------------- | -------------------------------------------- |
| `ALCHEMY_API_KEY`             | `AlCHEMY_API_KEY` from step 7                |
| `OWNER_ACCOUNT_PRIVATE_KEY`   | Metamask private key from step 2             |
| `COLLECTION_CONTRACT_ADDRESS` | Deployed contract address from previous step |

![Step10\_1](https://3017072639-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7a6afyDwSEkvWtt1UhmH%2Fuploads%2FbJ9vhkWF5fmdRbS2BJF4%2F3%E6%9C%80%E5%B7%A6%E8%BE%B9IMX%E6%94%B9%E4%B8%BAXPC.png?alt=media\&token=5b58e382-bf4a-4e3a-94c7-a4879b729e4e)

1. Save
2. Run `npm install`

### Step 11: Register as a User[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-11-register-as-a-user) <a href="#step-11-register-as-a-user" id="step-11-register-as-a-user"></a>

Before you can create a project, you will need to register as a user. Registering as a user creates a Layer 2 wallet and enables us to make transactions on Layer 2.

1. Navigate to the <mark style="color:blue;">Sandbox Test Marketplace</mark>
2. Press `Connect Wallet`
3. Follow the prompts

### Step 12: Register your Email Address[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-12-register-your-email-address) <a href="#step-12-register-your-email-address" id="step-12-register-your-email-address"></a>

Register with your email address at the XpansionChain <mark style="color:blue;">Developer Hub</mark> to access the ability to create projects on XpansionChain via the <mark style="color:blue;">Public API</mark> or the CLI in the <mark style="color:blue;">imx-examples repo.</mark>

You must first have a project in order to create collections that you can mint assets from on XpansionChain (L2).

### Step 13: Create Project[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-13-create-project) <a href="#step-13-create-project" id="step-13-create-project"></a>

A <mark style="color:blue;">project</mark> is an admin level entity associatied with an owner wallet address. This address is needed to make changes like creating or updating collections. Begin by navigating to **src/onboarding/2-create-project.ts**.

![Onboarding Project](https://3017072639-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7a6afyDwSEkvWtt1UhmH%2Fuploads%2FYHbyMI2mtCZaoQaZNptG%2F4%E6%9C%80%E5%B7%A6%E8%BE%B9IMX%E6%94%B9%E4%B8%BAXPC.png?alt=media\&token=65189ecb-d826-4a76-9690-3e0c41883a89)

1. Fill in `name`, `company_name` and `contact_email`
2. Press save
3. Run `npm run onboarding:create-project`
4. Copy the Project ID from the output
5. Use this to populate the `COLLECTION_PROJECT_ID` in the .env file and press save

![Step12](https://docs.x.immutable.com/assets/images/Step12_2-6b3701cba37b53980a346e1b311bfbb2.png)

### Step 14: Register Collection[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-14-register-collection) <a href="#step-14-register-collection" id="step-14-register-collection"></a>

A <mark style="color:blue;">collection</mark> is a group of NFTs that share a smart contract and each collection belongs to a project. Collections are displayed on the marketplace to end users, eg Gods Unchained.

Navigate to the ***src/onboarding/3-create-collections.ts*** file and populate the following values:

| Field Name             | Description                                                                 |
| ---------------------- | --------------------------------------------------------------------------- |
| `name`                 | Name of your collection on the marketplace                                  |
| `description`          | The description for your collection                                         |
| `icon_url`             | Icon that displays for your collection                                      |
| `metadata_api_url`     | Metadata API URL that we generated earlier (ensure there is no trailing /s) |
| `collection_image_url` | Image of your collection that displays on the marketplace                   |

To register the collection, run the command `npm run onboarding:create-collection`.

INFO

Remember to remove the prepending double slashes ”//” in relation to the fields described below as these comment out the code.

### Step 15: Create Metadata Schema[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-15-create-metadata-schema) <a href="#step-15-create-metadata-schema" id="step-15-create-metadata-schema"></a>

A collection's metadata schema describes the properties of the NFTs it can mint, as well as the potential values and types of those properties. These fields can be used as filters in the marketplace later on. Click <mark style="color:blue;">here</mark> to learn more about Metadata Schema.

Navigate to **src/onboarding/4-add-metadata-schema.ts** and update metadata on line 43:

![Add Metadata](https://3017072639-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7a6afyDwSEkvWtt1UhmH%2Fuploads%2FFtViqFzve2E0En75nGru%2F1.png?alt=media\&token=e2dcb1a4-ddee-47a3-b173-842c4e6ed991)

You can use the example metadata schema provided here, or use your own. Copy and paste the code below into line 43, as shown in the above image.

Example Metadata Schema

```
{
  name :  'name' ,
  type :  MetadataTypes.Text
},
{
  name :  'description' ,
  type :  MetadataTypes.Text
},
{
  name :  'image_url' ,
  type :  MetadataTypes.Text
},
{
  name :  'attack' ,
  type :  MetadataTypes.Discrete,
  filterable : true
},
{
  name :  'collectable' ,
  type :  MetadataTypes.Boolean,
  filterable : true
},
{
  name : 'class' ,
  type :  MetadataTypes.Enum ,
  filterable : true
}
```

To add metadata schema to the collection, run the command `npm run onboarding:add-metadata-schema` in the integrated terminal.

### Step 16: Mint NFT[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-16-mint-nft) <a href="#step-16-mint-nft" id="step-16-mint-nft"></a>

Now that we have added our contract to XpansionChain, the final step is to add our assets to the blockchain by minting them.

1. Navigate to the .env file
2. Fill in the follow under the 'Bulk Minting' section

![Specify Metadata](https://docs.x.immutable.com/assets/images/Step15_1-b0bfbe302c703dadb300fe57cbce8293.png)

| Field name      | Description                                                                                                                                                                                                              |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PRIVATE_KEY1`  | MetaMask Private Key - Copy from 'Onboarding' section.                                                                                                                                                                   |
| `TOKEN_ID`      | Enter 1 as the `TOKEN_ID` if this is the first time you’re minting from your collection. If you have already minted a few NFTs, then take the TOKEN\_ID of the last minted NFT, and increment it by 1 and enter it here. |
| `TOKEN_ADDRESS` | Same as `COLLECTION_CONTRACT_ADDRESS` - Copy from 'Onboarding' section.                                                                                                                                                  |
| `BULK_MINT_MAX` | Enter 50 for this tutorial. This allows us to configure the maximum number of NFTs that can be minted in bulk in one go.                                                                                                 |

SAVE

Don't forget to press save after updating the values

**To Mint**

1. Run `npm run bulk-mint -- -n <number of tokens to mint> -w <your wallet address>` where

* `<number of tokens to mint>` is the number of NFTs you wish to mint. In this tutorial, this number is 3.
* `<your wallet address>` is the MetaMask wallet you’re minting your NFTs to. For each contract (in other words, for each TOKEN\_ADDRESS) you are minting tokens for, remember to set the TOKEN\_ID in .env to the latest incremented index.

### Step 17: List your NFT[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#step-17-list-your-nft) <a href="#step-17-list-your-nft" id="step-17-list-your-nft"></a>

Our assets will now be accessible in our Goerli Wallet. However, for other users to see them we will need to list them on the marketplace.

1. Visit the <mark style="color:blue;">Sandbox IMX Marketplace</mark>
2. Click Connet Wallet and follow the prompts
3. Click My Assets --> Select an NFT
4. Press List for Sale

### Conclusion[​](https://docs.x.immutable.com/docs/x/zero-to-hero-nft-minting#conclusion) <a href="#conclusion" id="conclusion"></a>

Congratulations on minting and listing an NFT on the Goerli test network!

FEEDBACK

This tutorial covered the simplest implementation of minting, however we are continuing to build out the workflow. Feel free to leave any feedback <mark style="color:blue;">here</mark>.

If you'd like to reuse these steps for a mainnet launch, note the following changes:

| Step     | Change                                                                                                                             |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Step 2   | Metamask Network should use Ethereum Mainnet                                                                                       |
| Step 9.1 | `yarn hardhat run deploy/asset.ts --network mainnet`                                                                               |
| Step 10  | Set `ETH_NETWORK` to mainnet in the .env file                                                                                      |
| Step 10  | Remove \`sandbox\` from the URL in `PUBLIC_API_URL` in the .env file                                                               |
| N/A      | Set `STARK_CONTRACT_ADDRESS` and `REGISTRATION_ADDRESS` to the <mark style="color:blue;">mainnet addresses</mark> in the .env file |
