Easily Create An NFT App Using The New Infura NFT SDK TypeScript

If you know TypeScript, adding the ability to create, mint, and manage non-fungible tokens (NFTs) to your app is easy. The Infura NFT SDK wraps REST calls to Ethereum nodes, abstracting away the technical compilations and making it possible to work with NFTs with just an Infura account, some configuration, and a few lines of code. The Infura NFT SDK also doesn't require the overhead of learning Solidity, importing ABIs, etc. Whether new to Web3 or highly experienced, Infura NFT SDK makes NFTs easy.

Let's jump in, build, and deploy an ERC721 NFT to see how it works.

D_D Newsletter CTA

What is the Infura NFT SDK?

The Infura NFT SDK is an SDK that allows you to build and interact with NFTs easily. It's implemented in TypeScript, a programming language that is a strict superset of JavaScript. The SDK includes creating, minting, and managing NFTs and query information about them.

The significant part is that it abstracts away the technical details so you can focus on the core functionality of your DApp instead of the (often tricky) details. It's all about ease of use with Infura SDKs!

Supported chains include:

Write

  • Ethereum: Mainnet, Goerli, Sepolia

  • Polygon: Mainnet, Mumbai

Read

  • Ethereum: Mainnet, Goerli, Sepolia

  • Polygon: Mainnet, Mumbai

  • BSC: Mainnet

By using the Infura NFT SDK, you also get access to Infura's core functionality and infrastructure, which provides access to Ethereum (and other blockchains) without requiring you to run a full node. With the SDK, you can leverage many capabilities, making it easier to build and scale your DApps.

So let's build an NFT and see what the SDK can do.

Building and Deploying ERC721 NFT

We will build a DApp and smart contract on Ethereum and use the SDK to create a new NFT. We'll do all this on the Ethereum Goerli testnet, so we don't have to worry about defects or the cost of deploying to the mainnet.

Prerequisite

Before getting started, you need the following prerequisites:

  • Node.js and its package manager NPM. Verify you have Node.js installed by using the following terminal command: node -v && npm -v

  • TypeScript installed

  • An Infura account

  • A basic understanding of TypeScript and JavaScript

  • MetaMask

Infura

The Infura NFT SDK is straightforward to use. Most of this tutorial is just the setup and configuration needed to create a DApp. Let's start by logging in to your Infura account. You should land on your dashboard, where you can create a new key, as shown below. We'll create a new key for this project.

Click the "Create a New Key" button and fill in the required information.

After creating your key, your project ID will be visible on your dashboard under the "API KEY" section, as shown below. Copy and keep it somewhere; you'll need it later in this tutorial.

Set up an IPFS project on Infura Dashboard

Now, let's create an IPFS project. IPFS is a P2P distributed file system for storing and accessing files (and other data). It works well with blockchain. We'll need IPFS (and these credentials) to upload and store the metadata of our NFT project.

Head to your dashboard and create another new key by clicking "Create a Key", as shown below.

This time we'll choose IPFS as the network. This project will work on the mainnet and (what we will use it for) testnet.

After creating your key, you'll see your project ID and API key secret under your dashboard's "API KEY" section. You'll need this later as well, so copy it and keep it somewhere safe.

Project Setup and Installation

Next, we'll set up and initialize a Node.js Typescript project. Use the following commands in your console:

mkdir typescript-nft-demo && cd typescript-nft-demo

npm init -y

npm install -D typescript ts-node

npx tsc --init

Open the project in your preferred development environment. For example, if you are using Visual Studio Code, use the following command to open the project automatically:

code .

Install the Project Libraries

Next, we need to install the Infura SDK and dotenv library for reading the environment variables.

Use the following command:

npm install @infura/sdk dotenv

Your project look similar to the following image.

Create a .env file at your project's root and add the following variables to it:

INFURA_PROJECT_ID=<YOUR-INFURA-PROJECT-ID>

INFURA_PROJECT_SECRET=<YOUR-INFURA-PROJECT-API-KEY>

WALLET_PRIVATE_KEY=<YOUR-WALLET-MNEMONIC/PRIVATE-KEY>

EVM_RPC_URL=https://goerli.infura.io/v3/<YOUR-PROJECT-API-KEY>

INFURA_IPFS_PROJECT_ID=<YOUR-INFURA-IPFS-PROJECT-ID>

INFURA_IPFS_PROJECT_SECRET=<YOUR-INFURA-IPFS-PROJECT-SECRET-KEY>

WALLET_PUBLIC_ADDRESS=<YOUR-WALLET-ADDRESS>
  • Replace <YOUR-INFURA-PROJECT-ID> and <YOUR-INFURA-PROJECT-API-KEY> with the ID and API key from the Infura project created earlier in this tutorial.

  • Replace <YOUR-INFURA-IPFS-PROJECT-ID> and <YOUR-INFURA-IPFS-PROJECT-SECRET-KEY> with the ID and API key from the IPFS project created earlier in this tutorial.

  • On the line starting with EVM_RPC_URL, replace <YOUR-PROJECT-API-KEY> with your Infura API key.

  • <YOUR-WALLET-ADDRESS> should be replaced with your public blockchain address.

  • <YOUR-WALLET-MNEMONIC/PRIVATE-KEY> is your wallet's private key.

Note: Never share your private keys or seed phrase with anyone! Keep them secure.

You can find your wallet address and private key to your wallet on MetaMask in the following steps:

  • Open MetaMask by clicking on the browser extension icon or visiting the MetaMask website.

  • Click on the three dots in the top right corner of the MetaMask window.

  • Select "Account Details" from the drop-down menu, and click on the "Export Private Key" button.

  • A pop-up window will appear, asking you to enter your password. Enter your password and click on the "Unlock" button.

  • Once your account is unlocked, you can see your private key.

Now that we've successfully configured our project create a new TypeScript file, nft.ts, at the root level.

Your project structure should look similar to the one below.

Setup Infura Authentication

Authentication from inside our DApp requires our PROJECT\_ID and PROJECT\_SECRET. We'll load these from our new .env file.

Create an auth object inside the nft.ts using the following code snippet:

import { config as loadEnv } from "dotenv";
import { SDK, Auth, Metadata, TEMPLATES } from "@infura/sdk";

// load environment variables from .env file
loadEnv();

// Create an instance of the Auth class 
const auth = new Auth({

  // set the projectId taken from the INFURA_PROJECT_ID environment variable 
  projectId: process.env.INFURA_PROJECT_ID,

  // set the secretId taken from the INFURA_PROJECT_SECRET environment variable 
  secretId: process.env.INFURA_PROJECT_SECRET,

  // set the private key taken from the WALLET_PRIVATE_KEY environment variable 
  privateKey: process.env.WALLET_PRIVATE_KEY,

  // set the rpcUrl taken from the EVM_RPC_URL environment variable 
  rpcUrl: process.env.EVM_RPC_URL,

  // set the chainId for the Goerli testnet
  chainId: 5, // Goerli

  // set the options for IPFS
  ipfs: {

    // set the project Id taken from the INFURA_IPFS_PROJECT_ID environment variable
    projectId: process.env.INFURA_IPFS_PROJECT_ID,

    // set the API key secret taken from the INFURA_IPFS_PROJECT_SECRET environment variable
    apiKeySecret: process.env.INFURA_IPFS_PROJECT_SECRET,
  },
});

// Instantiate the SDK
const sdk = new SDK(auth);

Configure the tsconfig.json file as shown. (You might get an error but keep going.) tsconfig.json is a configuration file for TypeScript projects. It's used to specify the compiler options and files that you should include in the project.

Configure your tsconfig.json with the following code snippet:

{
        "compilerOptions": {

          "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

          "module": "ES2022", /* Specify what module code is generated. */

          // "rootDir": "./",                                  /* Specify the root folder within your source files. */

          "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */

          "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */

          "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */

          /* Type Checking */

          "strict": true, /* Enable all strict type-checking options. */

          "skipLibCheck": true /* Skip type checking all .d.ts files. */
      }
}

Next, add the type module to the package.json file using the following code snippet:

//...

"type": "module",
"scripts": {},

//...

Create Token Metadata

Now we're done configuring. Let's get to the exciting stuff!

First, we'll create the token metadata.

Token metadata refers to additional information or data associated with a token (typically an ERC-721 or ERC-1155 token on the Ethereum blockchain). This metadata can include information such as the token's name, symbol, image, and other attributes that describe the token or give it context.

The metadata is stored on-chain and typically represented as URI or URL that points to a JSON file containing the metadata.

Inside the nft.ts file, add the following code snippet. It will create and store the token metadata. The metadata class is from the Infura NFT SDK.

(Note: The consensys.net external\_url is just for demo purposes here, you can replace it.)

// Define the properties of the token, including its description, external URL, image, name, and attributes
const tokenMetadata = Metadata.openSeaTokenLevelStandard({

  description: "Fantastic creature of different emojis",

  external_url: "https://consensys.net/",

  image: await sdk.storeFile({

    // Store the image from the given URL
    metadata: "https://res.cloudinary.com/olanetsoft/image/upload/c_pad,b_auto:predominant,fl_preserve_transparency/v1672327921/demo.jpg",

  }),
  name: "Kandy Jane",
  attributes: [],
});

// Log the token metadata object to the console
console.log("Token Metadata: ", tokenMetadata);


// Store the token metadata and log the result
const storeTokenMetadata = await sdk.storeMetadata({ metadata: tokenMetadata });

console.log("Store Token Metadata: ", storeTokenMetadata);

Create the Contract Metadata

Contract metadata refers to additional information or data associated with a smart contract on a blockchain network. This metadata can include information such as the contract's name, symbol, version, and other attributes that describe the contract or give it context.

The metadata is stored on-chain and typically represented as URI or URL that points to a JSON file containing the metadata.

Create contract metadata using the following code snippet:

//...

// Define the properties of the collection, including its description, external URL, image, name, and attributes
const collectionMetadata = Metadata.openSeaCollectionLevelStandard({

  name: "Emojis collection", // Sets the name of the collection to "Emojis collection"

  description:
    "A small digital image or icon used to express an idea or emotion in electronic communication. Emoji's come in many forms, such as smiley faces, animals, food, and activities. ", // Sets the description of the collection
  image: await sdk.storeFile({

    // Sets the image property of the collection using the storeFile method
    metadata:
"https://res.cloudinary.com/olanetsoft/image/upload/c_pad,b_auto:predominant,fl_preserve_transparency/v1672327921/demo.jpg", // The URL of the image file
  }),

  external_link: "https://google.com/", // Sets the external link property of the collection
});

// Logs the collection metadata to the console
console.log("Collection Metadata:- ", collectionMetadata); 

// stores the metadata using the storeMetadata method
const storeMetadata = await sdk.storeMetadata({ metadata: collectionMetadata }); 

// Logs the store metadata to the console
console.log("Store Metadata: ", storeMetadata);

This code snippet above creates an object collectionMetadata using the openSeaCollectionLevelStandard method from the Metadata class. The openSeaCollectionLevelStandard method creates standard collection-level metadata compatible with OpenSea, a leading marketplace for NFTs. It sets the collection's name, description, image, and external link properties; stores the metadata using the storeMetadata method; then logs it in the console for debugging.

Create a New Contract and Mint an NFT

Add the following code to create a new contract and mint an NFT using the Infura NFT SDK. Most of this functionality comes to us from our new NFT SDK!

//...

// Create a new contract
const newContract = await sdk.deploy({   // deploys a new contract using the sdk.deploy method

  template: TEMPLATES.ERC721Mintable,     // sets the template for the contract to ERC721Mintable
  params: {
    name: "1507Contract",                  // sets the name of the contract as "1507Contract"
    symbol: "EMOJI",                        // sets the symbol of the contract as "EMOJI"
    contractURI: storeMetadata,             // sets the contract URI with the storeMetadata
  },
});

console.log("Contract Address: \n", newContract.contractAddress);  // logs the contract address to the console

// mint an NFT
const mint = await newContract.mint({  // mints a new NFT using the mint method from the new contract

  publicAddress:
    process.env.WALLET_PUBLIC_ADDRESS ??

    "0x510e5EA32386B7C48C4DEEAC80e86859b5e2416C", // sets the public address of the wallet, if not set it will use the given address

  tokenURI: storeTokenMetadata,                // sets the token URI with the storeTokenMetadata

});

const minted = await mint.wait();            // waits for the minting process to complete

console.log("Minted: ", minted);               // logs the minted NFT to the console

This code creates a new contract using the sdk.deploy method and sets the template for the contract to ERC721Mintable. Then it sets the contract's name, symbol, and contract URI. The contract address is logged for debugging.

It then mints a new NFT using the mint method from the new contract and sets the wallet's public address. If not specified, it uses the given address and then sets the token URI with the storeTokenMetadata.

Finally, it waits for the minting process to complete and logs the minted NFT to the console.

Let's test it out!

ts-node-esm nft.ts

You should see something similar to what is shown below:

Verify Contract on Account and Goerli Etherscan

Finally, let's verify the contract using a blockchain explorer on the Goerli Etherscan. Go to the Goerli Ethereum testnet site and paste the transaction hash from your output above (as shown below).

You should see the details.

That was easy! We successfully utilized the Infura NFT SDK to build, deploy, and mint an NFT on the Goerli testnet.

Import Token on MetaMask

Let's look at our new NFT from a front-end perspective using MetaMask. First, we have to import our wallet to MetaMask. Click "Import Tokens", as shown in MetaMask. (Be sure you are connected to the Goerli Testnet as shown.)

Copy and paste the contract address to import your token on MetaMask, as shown below.

And there it is! An easy and fast way to add NFTs to your DApps. You can use the SDK now to manage the NFTs and more (see the docs for current capabilities).

Verify Minted NFT on OpenSea

We've successfully imported the minted NFT on MetaMask, but now let's verify on OpenSea tesnet. Connect your wallet and view your new NFT. You should have something similar to what is shown below.

For reference, here's the OpenSea link to the NFT created. You can find the complete code on a GitHub repository here.

D_D Newsletter CTA

Conclusion

In conclusion, the new Infura NFT SDK for TypeScript is a powerful tool for developers looking to incorporate NFTs into their DApps. With its easy-to-use functions and comprehensive features, this SDK makes it simple to deploy, mint, and manage NFTs on the Ethereum blockchain. Sign up and start building!

I'd love to connect with you on Twitter | LinkedIn | GitHub | Portfolio

See you in my next blog article. Take care!!!