How to mint an NFT via CLI
Tags: blockchain, solidity, script, web3
Published: 2021-09-20 10:26:34

### Introduction

In this article we will create a script with NodeJS to create an NFT via CLI, passing in its private address and a URL containing the NFT metadata.

To do this tutorial, I recommend looking at our series to understand the previous steps and see how we got here

> [How to create a Smart Contract to mint an NFT
](https://dev.to/emanuelferreira/how-to-create-a-smart-contract-to-mint-a-nft-2bbn)

> [How to deploy a Smart Contract to Rinkeby Testnet using Infura and Hardhat](https://dev.to/emanuelferreira/how-to-deploy-smart-contract-to-rinkeby-testnet-using-infura-and-hardhat-5ddj)

### Boilerplate
To be faster, I will provide a boilerplate containing the babel, typescript, file structure, packages, scripts, environment variables...

[Click here to go to the GitHub with boilerplate](https://github.com/EmanuelCampos/mint-nft-script/tree/boilerplate)

Our boilerplate contains the following packages to run the script:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f70vp4jg92gyjyl0svjk.png)

### Taking the Provider
Our application provider will help us interact with our contract by defining the network we want to access as mainnet or testnet.

> Note: To get the provider we are going to use Infura, you can see my previous article on how to use Infura: [How to deploy a Smart Contract to Rinkeby Testnet using Infura and Hardhat](https://dev.to/emanuelferreira/how-to-deploy-smart-contract-to-rinkeby-testnet-using-infura-and-hardhat-5ddj)

Going into the `getProvider` file in the `src/getProvider.ts` directory we will take the code below and edit it to get our provider.

*getProvider.ts*
```js
import { ethers } from "ethers"; //Library to connect to the ethereum
import dotenv from 'dotenv' // Library to get the enviroment variables

dotenv.config() // starting the dotenv

export const getProvider = () => {
}; // function to get provider
```

Now we are going to edit our file and leave it the same as below(I will explain in the code what each line does).

*getProvider.ts*
```js
import { ethers } from "ethers";
import dotenv from 'dotenv'

dotenv.config()

export const getProvider = () => {
  const infuraProvider = new ethers.providers.InfuraProvider(
    process.env.NETWORK, // Our enviroment variable with network (rinkeby, mainnet, ropsten)
    process.env.PROJECT_ID // Our environment variable with the id of our project in infura
  ); // Function in ethers to connect to Infura

  return infuraProvider; // returning the provider
};
```

Ready, we finished our first function!

### Contract Addresses
In the `contractAddresses.ts` file in `src/contractAddresses.ts` we have an export of the environment variable which is the address of the contract we deployed in the previous article.

*contractAddresses.ts*
```js
import dotenv from 'dotenv'

dotenv.config()

export const FactoryNFTAddress = process.env.CONTRACT_ADDRESS;
```

### Creating the Mint Script
Now finally let's create our script to mint an NFT using only 1 command.

We have some basic settings to run our script:

In the `mintNFT.ts` file in `src/mintNFT.ts` we have some basic settings to run our script, let's complete by adding the desired functions.

*mintNFT.ts*
```js
import { ethers } from "ethers";

const run = async () => {
};

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```

#### Getting the args
Let's start by getting the two arguments that are `privateKey` and `tokenURI` and validating if at least 2 arguments were sent.

*mintNFT.ts*
```js
import { ethers } from "ethers";

const run = async () => {
  const [, , ...unsanitizedArgs] = process.argv; // getting the args

  if (unsanitizedArgs.length !== 2) {
    // eslint-disable-next-line
    console.log("yarn es ./src/mintNft <privatekey> <tokenuri>");
    return;
  } // validating whether the 2 arguments were sent

  const [privateKey, tokenUri] = unsanitizedArgs; // destructuring to get the arguments


};

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```

#### Getting the Provider
After we get the arguments we need to know which address is being used to mint the NFT and sign the contract.

*mintNFT.ts*
```js
import { ethers } from "ethers";

const run = async () => {
  const [, , ...unsanitizedArgs] = process.argv; // getting the args

  if (unsanitizedArgs.length !== 2) {
    // eslint-disable-next-line
    console.log("yarn es ./src/mintNft <privatekey> <tokenuri>");
    return;
  } // validating whether the 2 arguments were sent

  const [privateKey, tokenUri] = unsanitizedArgs; // destructuring to get the arguments
};

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```

#### Connecting with the wallet and the contract
First, we need to import some things which are the ABI of our contract that we got after compiling it, the address of our contract, and our getProvider

*mintNFT.ts*
```js
import { ethers } from "ethers";
import { getProvider } from "./getProvider";

import FactoryNFT from "../artifacts/contracts/factoryNFT.sol/FactoryNFT.json";
import { FactoryNFTAddress } from "./contractAddresses";


const run = async () => {
  const [, , ...unsanitizedArgs] = process.argv; // getting the args

  if (unsanitizedArgs.length !== 2) {
    // eslint-disable-next-line
    console.log("yarn es ./src/mintNft <privatekey> <tokenuri>");
    return;
  } // validating whether the 2 arguments were sent

  const [privateKey, tokenUri] = unsanitizedArgs; // destructuring to get the arguments
};

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```

You can get your ABI contract after compiling your contract, just dragging the artifacts folder to the root folder. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1873w7fdsovon9w2u93v.png)
 
Now we need to pass the wallet that we are using for our transaction to our contract, for that we will use ethers on both occasions.

*mintNFT.ts*
```js
import { ethers } from "ethers";

const run = async () => {
  const [, , ...unsanitizedArgs] = process.argv; // getting the args

  if (unsanitizedArgs.length !== 2) {
    // eslint-disable-next-line
    console.log("yarn es ./src/mintNft <privatekey> <tokenuri>");
    return;
  } // validating whether the 2 arguments were sent

  const [privateKey, tokenUri] = unsanitizedArgs; // destructuring to get the arguments

  const wallet = new ethers.Wallet(privateKey, provider); // getting your wallet

  const factoryNFTContract = new ethers.Contract(
    FactoryNFTAddress, // your contract address
    FactoryNFT.abi, // your contract ABI
    wallet // your wallet
  ); // getting the contract
};

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```
#### Making the transaction
And now the last step is to use our contract to make our transaction.

*mintNFT.ts*
```js
import { ethers } from "ethers";

const run = async () => {
  const [, , ...unsanitizedArgs] = process.argv; // getting the args

  if (unsanitizedArgs.length !== 2) {
    // eslint-disable-next-line
    console.log("yarn es ./src/mintNft <privatekey> <tokenuri>");
    return;
  } // validating whether the 2 arguments were sent

  const [privateKey, tokenUri] = unsanitizedArgs; // destructuring to get the arguments

  const wallet = new ethers.Wallet(privateKey, provider); // getting your wallet

  const factoryNFTContract = new ethers.Contract(
    FactoryNFTAddress, // your contract address
    FactoryNFT.abi, // your contract ABI
    wallet // your wallet
  ); // getting the contract
};

  console.log("minting");
  const transaction = await factoryNFTContract.createToken(tokenUri); // interacting with the contract
  const tx = await transaction.wait(); // waiting the minting of the block
  const event = tx.events[0];
  const value = event.args[2];
  const tokenId = value.toNumber(); // getting the created tokenId

  console.log({
    transaction,
    tx,
    tokenId,
  }); // returns

(async () => {
  try {
    await run();
  } catch (err) {
    // eslint-disable-next-line
    console.log("err: ", err);
    process.exit(1);
  }
  process.exit(0);
})();
```

Now you can run the command below and see the result in the console.

```bash
yarn es ./src/mintNft <privatekey> <tokenuri>
```

Result:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqiz2hd2447vt355joie.png)

The script is done, now you can get your tokenID and consult the contract that will return your metadata.

> thanks [Sibelius](https://twitter.com/sseraphini) for helping with the script.

Now you can Follow me on [Twitter](https://twitter.com/manelferreira_)

Project Repository(Complete): https://github.com/EmanuelCampos/mint-nft-script/tree/master

Project Repository(Blank Template): https://github.com/EmanuelCampos/mint-nft-script/tree/boilerplate