visit
If you know typescript, it’s easy to add the ability to create, mint, and manage non-fungible tokens (NFTs) to your app. The 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 you are 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.
Write
Read
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:
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.
Now, let’s create an IPFS project. 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.
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 the API KEY section of your dashboard. You’ll need this later as well, so copy it and keep it somewhere safe.
mkdir typescript-nft-demo && cd typescript-nft-demo
npm init -y
npm install -D typescript ts-node
npx tsc --init
code .
npm install @infura/sdk dotenv
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=//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>
<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.<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.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 (mnemonic) with anyone, and keep them secure.
Remember: keep your private key safe and never share your private key with anyone else. Also, be sure you're connected to the Goerli testnet, not the mainnet, as shown in the image below.
Now that we’ve successfully configured our project, create a new TypeScript file nft.ts
at the root level.
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 should be included 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": {},
//...
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.
// 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: "//consensys.net/",
image: await sdk.storeFile({
// Store the image from the given URL
metadata: "//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);
//...
// 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:
"//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: "//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 , 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 and stores it in the console for debugging.
//...
// 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
.
ts-node-esm nft.ts
Copy and paste the contract address to import your token on MetaMask, as shown below.
I'd love to connect with you on | | |