Getting Started with Infura

Get Started with Infura:  Using the Infura Ethereum API, IPFS API and other Features!

Welcome to Infura! We provide developers with simple, rock-solid, scalable access to Web3 tools and infrastructure. Our Ethereum and IPFS API suite serves and supports thousands of decentralized applications(dApps) every day.

Major pieces of web3 infrastructure run on Infura such as Metamask, Uniswap and MakerDAO.  So when making the decision on how your dApp will access the blockchain, you can rest assured that Infura will grow with your dApp and provide the scalability and up-time that your users demand.

In this post, we’ll walk you through how to get started with Infura so you can connect to the Ethereum blockchain and focus on building awesome software!

Topics covered:

  1. Signing up for an account and creating a new project
  2. Send a transaction to your Metamask wallet
  3. IPFS Operations
  4. Deploying a NFT smart contract
  5. Minting an NFT

Learning Outcomes

By the end of this article you will be able to use a React/Typescript project to programmatically send and lookup transactions on the Ethereum network, upload IPFS data and mint NFTs!

Let’s get started on your Web3 developer journey!

Module One: Register and Create an Infura Project

First, let's create an account. Protecting user information is one of our core values. All you need is an email address to register!

Infura only uses your email address to communicate with you about critical service updates, new product and features releases and other event news.

For more information, check out the Infura Docs!

Module 1.1: Create a Project

Verify your email, login and then you’ll be taken to your Infura Dashboard.

From this environment, you can:

Once you’re in, navigate to your Ethereum workspace and click “Create New Key”.


Check out the Infura Docs for more info on creating a new project.

Module 1.2: Execute your First Request

Let’s test our new API credentials and query the Ethereum Mainnet for the current block number.

In your console, execute the following curl command:

curl https://mainnet.infura.io/v3/[YOUR_API_KEY] \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

Check out other Ethereum JSON-RPC methods you can try!

Learn more about securing your project in the Infura Docs.

Module Two: Send a Transaction using your Metamask Wallet

In this module, we are going to show you how to connect to an Infura Ethereum node with a React/Typescript application using web3.js.

Keep in mind that all requests are POST requests.  Check out this Github Repository to follow along!

We will connect to your MetaMask wallet, send a transaction, and then review a transaction, all using the Infura API.

Learn more about Ethereum transactions!

We will accomplish the following in Module Two:

  • Connect to your wallet
  • Display the current balance of your wallet
  • Send a transaction from one wallet address to another
  • View the details of the transaction on the blockchain
  • Review code implementation

Module 2.1: Configuration and Setup

Download and install the Metamask wallet.

Check out this article for more information on getting started with Metamask!

Clone the project locally:

git clone https://github.com/anataliocs/Getting-Started-With-Infura.git

Clone the project and import into your IDE.

Use the Infura Sepolia Testnet Faucet:

Get some Sepolia testnet ETH using our faucet.  This is a free faucet from Infura that grants 0.5 ETH per day.

Install the dotenv npm package to be able to use an .env file

yarn add dotenv

Setup your .env file in your project root directory:

# Send Transaction Variables
NEXT_PUBLIC_WEB3_TEST_ETHEREUM_NETWORK=sepolia
NEXT_PUBLIC_WEB3_INFURA_API_KEY=

Check out the project README for more details on how to setup your local developer environment.

Install dependencies:

Install the Yarn package manager here.

yarn

Next, let's add the hierarchical deterministic wallet (HD Wallet). hdwallet-provider is a separate package that holds our keys and signs transactions for addresses derived from a 12 or 24-word mnemonic.

yarn add @truffle/hdwallet-provider

Run your app locally:

yarn dev

Module 2.2: Execute a Transaction with Infura in the Browser

Navigate to http://localhost:3000/ in a browser.

Ensure the "Sepolia" testnet is chosen in Metamask:

Then navigate to:  http://localhost:3000/transaction/connect

Click “CONNECT WALLET” and follow the Metamask prompt to connect your wallet to the dapp.

Then click “NEXT” to move to the transaction screen.

Enter in another ETH wallet address and the amount in ETH to transfer.

You can use this faucet donation address for example: 0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455

Then click submit and approve the transaction in Metamask.  Copy the broadcasted transaction hash then click “NEXT”

Finally, you can review the transaction details.  For additional information, click the “View on Etherscan link.

Etherscan is a Block Explorer and analytics platform for Ethereum.

Here is an example transaction on Etherscan.

Check out the Getting Started with Infura Github Repository README for more info.

You can learn more about sending Ethereum transaction in this tutorial!

Module 2.3: Transaction Code Implementation

Now let’s dive into the code and see what is happening behind the scenes to execute this Ethereum transaction on Infura.

The app is executing Ethereum JSON RPC calls based on the config parameters from your .env file.

Setup Infura as a web3.js HttpProvider

First off, the app server configures the Infura Ethereum node endpoint as a HttpProvider.

On line 4 of utils/transaction.ts, we can see the web3.js library creating a new instance of HttpProvider:

transaction.ts

// Configure the connection to an Ethereum node
export const web3 = new Web3(
    new Web3.providers.HttpProvider(
        `https://${process.env.NEXT_PUBLIC_WEB3_TEST_ETHEREUM_NETWORK}.infura.io/v3/${process.env.NEXT_PUBLIC_WEB3_INFURA_API_KEY}`)
);

The web3.js library will now use your Infura endpoint for Ethereum JSON RPC calls.

Getting your current ETH Balance

After connecting your wallet, the app uses the eth_getBalance endpoint to display your balance.

On line 24 of pages/api/transactions/getBalance.ts, we can see the following:

  • Use web3.js to get the current balance of your wallet
  • Convert that value from Wei to ETH using web3.js
  • Return your wallet balance denominated in ETH

getBalance.ts

const balanceWei = await web3.eth.getBalance(accountAddress);
const balanceEther = await web3.utils.fromWei(balanceWei, 'ether');
const balanceEtherNumber: number = +balanceEther;

return res.status(200).json({
	balance: balanceEtherNumber,
});

This balance is then displayed!

On line 81 of components/ConnectWallet.tsx, the walletBalance is read from the Redux store and displayed

ConnectWallet.tsx

<p className={styles.card__balance_value}>
	<EthereumIcon className={styles.card__balance_ethIcon} />
	<span>{parseFloat(walletBalance.toFixed(4))}</span>
</p>

Broadcast Transaction

On the next page, after you enter in the destination address and the amount of ETH to send, the transaction is validated and broadcast to the Ethereum network.

The transfer web form is expressed on line 130 of pages/transaction/transfer.tsx.

transfer.tsx

<TextInput
	label="Address" id="toAddress" value={transferToAddress}
	onChange={(event) => {
		const target = event.target as HTMLInputElement;
		setTransferToAddress(target.value);
	}}
	helperText="The address you want to send ETH to"
	containerClassName={styles.card__input}
	labelClassName={styles.card__input1_label}
/>
<TextInput
	label="Amount" id="amount" type="number"  value={transferAmount}
	onChange={(event) => {
		const target = event.target as HTMLInputElement;
		setTransferAmount(target.value);
	}}
	helperText="Enter the amount in ETH"
	containerClassName={styles.card__input}
	labelClassName={styles.card__input2_label}
	step="any"
/>

Sending a transaction uses the eth_sendTransaction endpoint.

Then the handleTransactionSubmit function handles sending the request.

On line 44 of pages/transaction/transfer.tsx, the eth_sendTransaction request is submitted asynchronously and then a transaction hash is returned.

transfer.tsx

const txHash = await ethereum.request({
	method: 'eth_sendTransaction',
	params: [
		{
			from: account,
			to: transferToAddress,
			value: amt,
		},
	],
});

Get the Transaction Details

After the transaction completes successfully, on line 27 of pages/api/transactions/getTransaction.ts, the backend uses the web3.js library to execute the request and get the transaction details which are then stored in Redux.

Redux is a library to help manage state in React applications.

getTransactions.ts

const transaction = await Web3.eth.getTransaction(txHash);

if (transaction) {
	useTransactionStore.setState({
	transaction: transaction,
});

Display Transaction Details

The following transaction details are then displayed:

  • Transaction Hash
  • Transaction From Address
  • Transaction To Address

transfer.tsx

<div className={styles.readOnly__group}>
	<div>
	<ReadOnly
		label="Transaction Hash"
		value={transaction.hash}
		copyable
	/>
	<HelpText className={styles.helpText}>
		Copy the transaction hash to review the transaction in the
		next step
	</HelpText>
	</div>

<ReadOnly label="Sent From" value={transaction.from} />
<ReadOnly label="Sent To" value={transaction.to} />
</div>

After clicking “Next”, you then can review the transaction, entering in the transaction hash to again display the transaction data.

Check out the Infura docs to learn about other Ethereum JSON RPC endpoints.

You can dive deeper into Ethereum Developer Onboarding and learn more about Ethereum on our Developer Portal.

Module Three: Uploading and Pinning Image data to IPFS

Now let’s walk through uploading and pinning image data to IPFS using Infura.

We will accomplish the following in Module Three:

  • Upload and pin data to IPFS
  • Retrieve IPFS data
  • Review code implementation

Module 3.1: Update your .env config

First, we will need to create a new project on Infura and then update your .env file with your Infura IPFS project.

Go to your Infura dashboard and just like in Module 1, create a new project.  Except this time select IPFS for network.

Navigate to your project root directory and execute the command:

vi .env

Then scroll down in your .env file and update the IPFS variables with the info from your Infura IPFS project:

# IPFS Variables
NEXT_PUBLIC_INFURA_IPFS_ENDPOINT=
NEXT_PUBLIC_INFURA_IPFS_PROJECT_ID=
NEXT_PUBLIC_INFURA_IPFS_PROJECT_SECRET=

Then close vim by entering:

:wq

Module 3.2: Upload and Pin Image Data to IPFS with Infura

Navigate to http://localhost:3000/ipfs/upload in a browser.

Select an Image file to upload, enter in the name, description and optional metadata.

Metadata is an open-ended set of key-value pairs that are attached to your file.

To learn more about NFT metadata check out these links:

After clicking upload, the image will be uploaded to IPFS via Infura and then the following fields will be displayed:

  • Image
  • File Name
  • File Size
  • Name
  • IPFS Hash

Copy the generated IPFS Hash and click “NEXT”.

Module 3.3: Retrieve IPFS Data with Infura

After clicking next you will be brought to the display page.

Enter in the generated IPFS hash from the previous step and click “SUBMIT”.

The app will then lookup the file data from IPFS and display it for you!

Module 3.4: Code Implementation of IPFS Image Upload

Now let’s take a look at the code used to accomplish this operation.

IPFS Upload Form

First up, is the form used to upload the file.

The IPFS upload webform is defined on line 286 of components/IPFSUploadForm.tsx.  

These snippets of code demonstrate how the web form handles:

  • File upload
  • File details fields
  • Metadata

IPFSUploadForm.tsx - File upload

…
<div className={styles['ipfs__content-wrap']}>
	<h1 className={styles.ipfs__header}>Upload Document</h1>
	<div
		className={styles.ipfs__dropBox}
		onDragOver={(e) => e.preventDefault()}
		onDrop={(e) => handleFileDrop(e)}
	>
	{!fileData && (
		<div
			className={styles['ipfs__drop-box']}
			onDragOver={(e) => e.preventDefault()}
			onDrop={(e) => handleFileDrop(e)}
		>
	<p className={styles['ipfs__upload-text']}>
		Drag and drop a file to upload
	</p>
	<input
		type="file"
		className={styles['ipfs__file-input']}
		onChange={(e) => handleFileSelect(e.currentTarget.files)}
	/>
	<p className={styles['ipfs__file-format-text']}>
		File types supported png, jpg, json
	</p>
	<UploadIcon />
</div>

)}

	{!!fileData && (
		<div className={styles['ipfs__file-added']}>
		<p className={styles['ipfs__added-text']}>File Added</p>
		{imagePreview()}
		<p className={styles['ipfs__file-name']}>{fileData.name}
		</p>
		<p className={styles['ipfs__file-size']}>
			{calculateFileSize(fileData.size)}
		</p>
         
		<IconButton
			onClick={handleFileReset}
			className={styles['ipfs__close-icon']}
			flat
		>
		<CloseWithBGIcon />
		</IconButton>
		</div>
	)}
</div>
…

IPFSUploadForm.tsx - File details

<p className={styles.ipfs__subheader}>File Details</p>

<div className={styles['ipfs__file-details']}>
	<TextInput
		label="Name"
		id="ipfs-name"
		type="text"
		placeholder="Enter Name"
		onChange={(e) => setMetaName(e.currentTarget.value)}
		value={metaName}
		containerClassName={styles['ipfs__input-row']}
		labelClassName="bg-[#0E0E0E]"
	/>
	<TextInput
		label="Description"
		id="ipfs-description"
		type="text"
		placeholder="Enter Description"
		onChange={(e) => 
        	setMetaDescription(e.currentTarget.value)}
		value={metaDescription}
		containerClassName={styles['ipfs__input-row']}
		labelClassName="bg-[#0A0A0A]"
	/>
</div>

IPFSUploadForm.tsx - File metadata

<p className={styles.ipfs__subheader}>Metadata</p>

	{metaDataList.map((data, index) => {return (
	<div className={styles['ipfs__meta-row']} key={`meta-	row-${index}`}>

		<TextInput
			label="Attribute Name"
			id={`meta-name-${index}`}
			type="text"
			placeholder="Enter Attribute Name"
			value={data[MetaDataKeys.traitType]}
			onChange={(e) => 
			setMetaItem(e, index, MetaDataKeys.traitType)}
			containerClassName={styles['ipfs__meta-input']}
			labelClassName="bg-[#060606]"
		/>

		<TextInput
			label="Attribute Value"
			id={`meta-value-${index}`}
			type="text"
			placeholder="Enter Attribute Value"
			value={data[MetaDataKeys.value]}
			onChange={(e) => 
			setMetaItem(e, index, MetaDataKeys.value)}
			containerClassName={styles['ipfs__meta-input']}
			labelClassName="bg-[#060606]"
		/>
		{addSubtractButton(index)}
	</div>
	);
	})}

<PrimaryButton
	className={styles['ipfs__primary-btn']}
	onClick={handleFileUpload}
	disabled={isLoading || !uploadReady()}
	isLoading={isLoading}
>
Upload
</PrimaryButton>

This form will handle validation and failure conditions as well.

IPFS Upload Operation

Now let’s look at how the actual IPFS upload is performed.  We are using the IFPS Upload JavaScript HTTP RPC API client library. This client library is built with TypeScript and implements the IPFS Core API which is compatible with an embedded js-ipfs node or any remote IPFS node. There are also a set of utility functions.

This library is imported via NPM.  Check out more info about the ipfs-http-client NPM package.

The specific version of the library is defined in the package.json file.

package.json

"ipfs-http-client": "^56.0.2",

Import and Define the IPFS Http Client

The IPFSHTTPClient is imported into IPFSUploadForm.tsx.

The IPFSHTTPClient is import statement is defined on line 11 of components/IPFSUploadForm.tsx.

IPFSUploadForm.tsx

import { IPFSHTTPClient } from 'ipfs-http-client';

Then the client is defined as constant to be used later.

The IPFS client instantiation is defined on line 66 of components/IPFSUploadForm.tsx.

IPFSUploadForm.tsx

const client: IPFSHTTPClient | undefined = useMemo(() => {
	return ipfs_client();
}, []);

Use Client to perform IPFS Upload

The ipfs_add function of the client is invoked, passing in the upload data and errors are logged to console.

Learn more about the IPFS Core API function to import a file or data into IPFS.

IPFSUploadForm.tsx

const ipfs_add = async (
	uploadData: File | string
): Promise<AddResult | undefined> => {
	if (client) {
		try {
			const response: AddResult = await client.add(uploadData);
		return response;
		} catch (err) {
			console.log(err);
		}
		}
	};

Display IFPS Details

Next, let’s take a look at how the uploaded and pinned IPFS file details are displayed after a successful upload.

Display IPFS File Web Form

After successfully uploading the file and hitting the next button, you will navigate to the Display File Form.

The display file form is defined on line 144 of pages/ipfs/display.tsx.

display.tsx

const hashForm = (): JSX.Element => {
	return (
		<div className={styles['ipfs__content-wrap']}>
		<h1 className={styles.ipfs__header}>Display File</h1>
		<TextInput
			label="IPFS Hash"
			id="ipfs-hash"
			type="text"
			placeholder="Enter IPFS Hash"
			value={metaHash}
			onChange={(e) => setMetaHash(e.currentTarget.value)}
			containerClassName={styles['ipfs__input-row']}
			labelClassName="bg-[#121212]"
		/>
	<PrimaryButton
		className={styles['ipfs__primary-btn']}
			onClick={() => requestAllData()}
			disabled={isLoading || metaHash === ''}
			isLoading={isLoading}
	>
	Submit
	</PrimaryButton>
	</div>
	);
};

Lookup IPFS File Data via Hash

The hash you generated during the upload step will now be used to lookup the IPFS data. The ipfs-http-client is imported and instantiated in the same manner as in IPFSUploadForm.tsx.

After entering in the IPFS hash and clicking submit, the IPFS HTTP Client cat function is invoked.

This functionality is defined on line 75 of pages/ipfs/display.tsx.

This call returns an async iterable that yields Uint8Array objects with the contents of path which are then parsed and stored to be displayed.

Learn more about the IPFS Core API function to returns a file addressed by a valid IPFS Path.

display.tsx

const ipfs_get = async (hash: string): Promise<Uint8Array | undefined> => {
	if (client) {
		try {
			const response: Uint8Array[] = [];
			let responseLength = 0;
			for await (const buf of client.cat(hash)) {
			response.push(buf);
			responseLength += buf.length;
		}
	if (responseLength) {
		const mergedArray = new Uint8Array(responseLength);
		let offset = 0;
		response.map((el) => {
		mergedArray.set(el, offset);
		offset += el.length;
	});
	return mergedArray;
	}
	} catch (err) {
		setError('Unexpected error occured, please try again.');
	}
	}
};

Display Data returned by IPFS Cat Function

Finally, we take the response from our IPFS HTTP Client call and display that data.

The display elements are defined on line 167 of pages/ipfs/display.tsx.

display.tsx

const resultDisplay = (): JSX.Element | undefined => {
	if (!metadata || !objectUrl) {
		return;
	}
    
return (
	<div className={styles['ipfs__content-wrap']}>
	<h1 className={styles.ipfs__header}>Display File</h1>
	<p className={styles.ipfs__subheader}>Image</p>
	<div
		style={{ backgroundImage: `url(${objectUrl})` }}
		className={styles['ipfs__image-preview']}
	/>
	<p className={styles.ipfs__subheader}>Details</p>
	<div className={styles['ipfs__image-details']}>
	<div className={styles['ipfs__image-details--rows']}>
	<ReadOnly
		className={styles['ipfs__grid-data--left']}
		label="Name"
		value={metadata.name}
	/>
	<ReadOnly label="Size" value={getAttributeValue('fileSize')} />
	</div>
	<div className={styles['ipfs__image-details--columns']}>
		<ReadOnly
			label="IPFS Hash"
			value={getAttributeValue('objectHash')}
			copyable
		/>
	</div>

	<div className={styles['ipfs__image-details--columns']}>
		<ReadOnly label="Description" value={metadata.description} />
	</div>
</div>

<p className={styles['ipfs__data-header']}>Attributes</p>
<div>
	{filteredAttributes().map((el: MetaData, index: number) => {
	return (
	<div
			key={`meta-item-${index}`}
			className={styles['ipfs__meta-result-row']}
		>
		<p className={styles['ipfs__grid-data--left']}>
		{el[MetaDataKeys.traitType]}
		</p>
		<p>{el[MetaDataKeys.value]}</p>
	</div>
	);
})}

</div>
<div className={styles['ipfs__hr']} />

<div className="text-center">
	<p className="mt-5">
	Congrats on finishing the tutorial, to view more 
	information on your
	file view on IPFS
	</p>
	<Link
	href={`https://ipfs.infura.io/ipfs/${getAttributeValue(
	'objectHash'
	)}`}
	target="_blank"
	className={`mt-3 flex flex-row items-center justify-center 
	hover-within:text-white ${styles.settings__documentation_link}`}
	>

View file on IPFS
<ChevronRight />
</Link>
</div>
</div>
);
};


Now you know how to leverage the IPFS HTTP client to upload and retrieve IPFS data using Infura!

In the next module, we will use this IPFS data to mint an NFT on testnet.

Module Four: Minting a NFT on Testnet

Shut down your application using the keyboard shortcut ctrl+c while on the terminal where your app is running.

Now let’s actually mint a NFT on testnet with Infura.  You can learn more about NFT standards such as ERC-721 and ERC-1155 in another article on the Infura blog!

Interested in learning more about the basics of NFTs?  Check out our video, NFT Crash Course, featured on Microsoft Inspire 2022.

We will accomplish the following in Module Four:

  • Deploy a NFT smart contract
  • Mint a NFT
  • Review the code implementation

Module 4.1: Deploy NFT Smart Contract and Update .env File

First, we need to deploy our NFT contract to a Ethereum testnet.  Alternatively, you can use the hash of an already existing deployed version of this contract.

Navigate to your project root directory and execute the following command:

yarn truffle migrate -—network sepolia

This will deploy your smart contract to the sepolia test network.  Copy the hash of the deployed contract.

Grab the has labeled "contract address" of the deployed NFTDemoContract smart contract.

   Deploying 'NFTDemoContract'
   ---------------------------
   > transaction hash:    0x1cc1784156a0ca6347945568969a31cf2d3a58f8622e065891e6827b9854411c
   > Blocks: 1            Seconds: 20
   > contract address:    0x5C89dD43A6D19b5E2Be2fd453ED6F0764352cfCf
   > block number:        7919674
   > block timestamp:     1667969520
   > account:             0x89bAc1D8466c58f980315636FBF5211a041f0775
   > balance:             0.30195899350380442
   > gas used:            2653510 (0x287d46)
   > gas price:           2.500022614 gwei
   > value sent:          0 ETH
   > total cost:          0.00663383500647514 ETH

Truffle is a development environment, testing framework and asset pipeline for Ethereum and other EVM-compatible blockchains.

Learn more about deploying smart contracts using Truffle in this tutorial.

Then open up your .env file and update the “Minting variable section”.

WALLET_MNEMONIC=
NEXT_PUBLIC_MINTING_INFURA_PROJECT_ID=
NEXT_PUBLIC_SMART_CONTRACT_ADDRESS=

If you are not interested in deploying the contract you can use this pre-deployed contract hash in your .env file: 0x2C017A0E568B158a34e86D463e515BED2DDBB3f2

Module 4.2: Mint an NFT with Infura in the Browser

Navigate to http://localhost:3000/mint/upload in your browser.

Similar to the previous module, we will start by uploading an image to IPFS.  Fill out the relevant fields and click “UPLOAD”.

After successfully performing an upload, you will get an IPFS Hash that you need to copy for the next step.  Copy that hash and click “NEXT”.

On the next page, enter in your IFPS url and click submit.  in the following format substituting in the IPFS Hash you generated:

ipfs://QmUx286mcSbq1FYZTHnpdvnarMSGYaVRhhy7FQ2YkEdibw

Your Metamask wallet will then prompt you to confirm the transaction.  Then finally, you will see the details of the NFT you just minted!

Module 4.3: Mint an NFT Code Implementation Walkthrough

First, a similar upload web form is used to upload to IPFS as the previous module.  Then let’s check out the code used to mint an NFT.

After the IPFS upload, the next screen prompts you to input the IPFS metadata tokenURI.  

This web form is defined on line 105 of pages/mint/mint.tsx.

mint.tsx

const addTokenForm = () => {
return (
	<div className={styles['mint__content-wrap']}>
	<h1 className={styles.mint__header}>Mint NFT</h1>
	<TextInput
		label="Metadata token URI"
		id="token-uri"
		type="text"
		placeholder="Enter IPFS metadata token URI"
		value={tokenURI}
		onChange={(e) => setTokenURI(e.currentTarget.value)}
		containerClassName={styles['mint__input-row']}
		labelClassName="bg-[#121212]"
	/>
            
	<PrimaryButton
		className={styles['mint__primary-btn']}
		onClick={() => submitForMinting()}
		disabled={isLoading || tokenURI === ''}
		isLoading={isLoading}
	>
            
	Submit
	</PrimaryButton>
	</div>
);
};

After clicking submit, the submitForMinting() function is executed which calls performMinting().

The function to perform the mint is defined on line of 45 of pages/mint/mint.tsx.

This function gets an instance of the NFT smart contract then executes the mint function passing in the address and tokenURI.

mint.tsx

const performMinting = async (): Promise<string> => {
const { ethereum } = window;
if (!ethereum) {
	throw 'We could not detect your wallet. 
    Please download the MetaMask extension.';
}
    
const smartContractAddress = process.env.NEXT_PUBLIC_SMART_CONTRACT_ADDRESS;
await ethereum.request({
	method: 'eth_requestAccounts',
});
    
const nftContract = new web3.eth.Contract(
	NFTDemoContract.abi as AbiItem[],
	smartContractAddress
);
    
try {
	const tx = {
	to: smartContractAddress,
	from: ethereum.selectedAddress,
	gas: '200000',
	data: nftContract.methods
	.mint(ethereum.selectedAddress, tokenURI)
	.encodeABI(),
};
    
const receipt = await ethereum.request({
	method: 'eth_sendTransaction',
	params: [tx],
});
    
return receipt;
} catch (err) {
	throw 'Oops, something went wrong minting your NFT.';
}
};

Working with NFTs with Traditional Web2 REST APIs

You can also use the Infura NFT API to mint NFTs without the need for smart contracts using our REST API.  Check out the NFT Dashboard project on Github to learn more about using the NFT API in a Java/React project.

Hands-on coding with the NFT API & SDK

Next steps

Congratulations!  You’ve completed the Getting Started with Infura developer journey!

You’ve learned a lot over the course of completing the modules in this article.  You should be proud of yourself!

  • You can now use a React/Typescript project to programmatically send and lookup transactions on the Ethereum network
  • Upload IPFS data
  • Deploy Solidity Smar Contracts
  • Mint NFTs
  • And more!

In the next article, we will go over Infura notifications, filters and subscriptions, Dashboard stats, Ethereum archive data, other L1 blockchains, Ethereum L2s and more!

Additional Resources to Continue your Web3 Developer Journey

Check out these resources to continue building your web3 developer skillset and to learn more about the ecosystem.

You can follow along with additional Infura Tutorials here!

If you’re looking for a formal Ethereum developer program you can look into our ConsenSys Developer Bootcamp.

There are also many free ConsenSys and community resources available as well!

If you need to ramp up on Unix/Linux environments, command line, code editors, Git, Javascript, Node.js and web frameworks check out ConsenSys Basic Training.

Also, check out the LearnWeb3 DAO for a detailed, project-oriented approach to learning Web3 development and earn some NFTs along the way!

Check out our ConsenSys Developer Portal Articles

Newsletters

YouTube

And finally, check out Speedrun Ethereum by Austin Griffith of the Ethereum Foundation!


Inspired to join the revolutionary world of blockchain? Check out https://consensys.net/careers/ today!

Want to get started on your journey as a Web3 developer? https://infura.io/register

Read more stories like this at: https://blog.infura.io/

Follow Infura: