Use ethers.js InfuraProvider or Web3Provider | INFURA (2024)

In this tutorial, we'll create a simple React app to show the differences between using the ethers.js library's InfuraProvider and Web3Provider methods to send a transaction.

The key difference we'll highlight is that with Web3Provider you can load the private key from a Web3 wallet (MetaMask in this example), while InfuraProvider needs a wallet created locally with a stored private key.

This tutorial uses the Sepolia testnet.

Prerequisites

You can run the following to confirm that Node and NPM are installed:

node -v && npm -v

info

This tutorial was tested using ethers v5.7.2 and Node.js v16.17.0.

Steps

1. Create the React app

In the terminal, run the following command to create an app called my-app:

npx create-react-app my-app

Change into the project directory:

cd my-app

2. Install ethers.js

Install ethers.js in the project directory.

3. Create the environment variables

Create a .env file in your project directory to store the project and Ethereum account details.

REACT_APP_API_KEY="<YOUR-API-KEY>"
REACT_APP_PRIVATE_KEY="<PRIVATE-KEY>"

Ensure you replace the following values in the .env file:

danger

Never disclose your private key. Anyone with your private keys can steal any assets held in your account.

4. Build the app

info

You can copy the complete code sample from the final section.

Import dependencies and create providers

Import the required dependencies and create the providers for communicating with the blockchain.

In the src directory open the App.js file. Remove the existing code and add the following code:

App.js

import React, { useState } from "react";
import "./App.css";

function App() {
const ethers = require("ethers");
const API_KEY = process.env.REACT_APP_API_KEY;
const PRIVATE_KEY = process.env.REACT_APP_PRIVATE_KEY;
const provider_Metamask = new ethers.providers.Web3Provider(window.ethereum);
const infuraProvider = new ethers.providers.InfuraProvider(
"sepolia",
API_KEY,
);
}
export default App;

Maintain the app state

Next, use the useState hook function to maintain the state of the app. Add the following code below the const declarations (inside the App() declaration):

App.js

// Use the useState hook function to add state variables to a functional component.
const [blockNumber, setBlockNumber] = useState(null);
const [txSent, setTxSent] = useState(null);
const [txSentInfura, setTxSentInfura] = useState(null);

Create the app frontend.

Next, create the app front-end that includes two forms for sending the transactions, and buttons for each provider to fetch the latest block number.

App.js

// Configure the app frontend
return (
<div className="App">
<header className="App-header">
<h3> Press one of the buttons to find out the latest block number: </h3>
<div>
<button onClick={handleButton1}>InfuraProvider</button>
<button onClick={handleButton2}>Web3Provider</button>
<p>{blockNumber}</p>
</div>
<h3> Fill out the form to send a transaction via Web3Provider: </h3>
<div>
<form onSubmit={handleSubmitWeb3}>
<input type="text" name="address" placeholder="Recipient Address" />
<input type="text" name="amount" placeholder="Amount (ETH)" />
<input type="submit" value="Send w/ Web3Provider" />
</form>
<p>{txSent}</p>
</div>
<h3> Fill out the form to send a transaction via InfuraProvider: </h3>
<div>
<form onSubmit={handleSubmitInfura}>
<input type="text" name="address" placeholder="Recipient Address" />
<input type="text" name="amount" placeholder="Amount (ETH)" />
<input type="submit" value="Send w/ InfuraProvider" />
</form>
<p>{txSentInfura}</p>
</div>
</header>
</div>
);

Retrieve the latest block number

Create the code to retrieve the latest block number. Add the following code above the return statement.

// Get the latest block using the InfuraProvider or wallet
const handleButton1 = async () => {
const latest_block = await infuraProvider.getBlockNumber("latest");
setBlockNumber(latest_block);
};

const handleButton2 = async () => {
const latest_block = await provider_Metamask.getBlockNumber("latest");
setBlockNumber(latest_block);
};

Send the transaction

To send the transaction, you need the target address and the amount to send. Add the following code below the code that retrieves the latest block number.

// Handle the form submissions to send the transactions
const handleSubmitWeb3 = async (e) => {
e.preventDefault();
const data = new FormData(e.target);
const address = data.get("address");
const amount = data.get("amount");
sendTransaction(address, amount);
};

const handleSubmitInfura = async (e) => {
e.preventDefault();
const data = new FormData(e.target);
const address = data.get("address");
const amount = data.get("amount");
const signer = new ethers.Wallet(PRIVATE_KEY, infuraProvider);
sendTransaction(address, amount, signer);
};

Next, create the sendTransaction() function that sends the transaction. Place the following code below the two handleSubmit methods.

 // Send the transaction using either the Web3Provider or InfuraProvider
const sendTransaction = async (address, amount, signer=null) => {
if (signer==null){ // Web3 Provider
if (!window.ethereum)
console.error("No wallet found!");
else {
await window.ethereum.send("eth_requestAccounts");
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther(amount)
});
console.log("tx", tx);
setTxSent('Transaction initiated! Tx hash: ' + tx.hash);
}
}
else // InfuraProvider
{
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther(amount)
});
console.log("tx", tx);
setTxSentInfura('Transaction initiated! Tx hash: ' + tx.hash);
}
}Ja

5. Run the app

Run the app from the root of the directory:

npm start

warning

If you are using create-react-app version >=5 you may run into issues building, such as:

Module not found: Error: Can't resolve 'crypto' in 'C:\Users\Username\Projects\testProject\client\node_modules\eth-lib\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

This is because NodeJS polyfills are not included in the latest version of create-react-app.

Follow these instructions to resolve the issue.

In the app, notice that when you try and send a transaction using Web3Provider, the app opens a MetaMask instance to transfer your funds.

Use ethers.js InfuraProvider or Web3Provider | INFURA (1)

If you transfer funds using the InfuraProvider, then the funds are transferred directly from your app.

Use ethers.js InfuraProvider or Web3Provider | INFURA (2)

Complete code sample

The complete code sample looks like this:

import React, { useState } from "react";
import "./App.css";

function App() {
const ethers = require("ethers");
const API_KEY = process.env.REACT_APP_API_KEY;
const PRIVATE_KEY = process.env.REACT_APP_PRIVATE_KEY;
const provider_Metamask = new ethers.providers.Web3Provider(window.ethereum);
const infuraProvider = new ethers.providers.InfuraProvider("goerli", API_KEY);

// Use the useState hook function to add state variables to a functional component.
const [blockNumber, setBlockNumber] = useState(null);
const [txSent, setTxSent] = useState(null);
const [txSentInfura, setTxSentInfura] = useState(null);

// Get the latest block using the InfuraProvider or wallet
const handleButton1 = async () => {
const latest_block = await infuraProvider.getBlockNumber("latest");
setBlockNumber(latest_block);
};

const handleButton2 = async () => {
const latest_block = await provider_Metamask.getBlockNumber("latest");
setBlockNumber(latest_block);
};

// Handle the form submissions to send the transactions
const handleSubmitWeb3 = async (e) => {
e.preventDefault();
const data = new FormData(e.target);
const address = data.get("address");
const amount = data.get("amount");
sendTransaction(address, amount);
};

const handleSubmitInfura = async (e) => {
e.preventDefault();
const data = new FormData(e.target);
const address = data.get("address");
const amount = data.get("amount");
const signer = new ethers.Wallet(PRIVATE_KEY, infuraProvider);
sendTransaction(address, amount, signer);
};

// Send the transaction using either the Web3Provider or InfuraProvider
const sendTransaction = async (address, amount, signer = null) => {
if (signer == null) {
// Web3 Provider
if (!window.ethereum) console.error("No wallet found!");
else {
await window.ethereum.send("eth_requestAccounts");
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther(amount),
});
console.log("tx", tx);
setTxSent("Transaction initiated! Tx hash: " + tx.hash);
}
} // InfuraProvider
else {
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther(amount),
});
console.log("tx", tx);
setTxSentInfura("Transaction initiated! Tx hash: " + tx.hash);
}
};

// Configure the app frontend
return (
<div className="App">
<header className="App-header">
<h3> Press one of the buttons to find out the latest block number: </h3>
<div>
<button onClick={handleButton1}>InfuraProvider</button>
<button onClick={handleButton2}>Web3Provider</button>
<p>{blockNumber}</p>
</div>
<h3> Fill out the form to send a transaction via Web3Provider: </h3>
<div>
<form onSubmit={handleSubmitWeb3}>
<input type="text" name="address" placeholder="Recipient Address" />
<input type="text" name="amount" placeholder="Amount (ETH)" />
<input type="submit" value="Send w/ Web3Provider" />
</form>
<p>{txSent}</p>
</div>
<h3> Fill out the form to send a transaction via InfuraProvider: </h3>
<div>
<form onSubmit={handleSubmitInfura}>
<input type="text" name="address" placeholder="Recipient Address" />
<input type="text" name="amount" placeholder="Amount (ETH)" />
<input type="submit" value="Send w/ InfuraProvider" />
</form>
<p>{txSentInfura}</p>
</div>
</header>
</div>
);
}

export default App;
Use ethers.js InfuraProvider or Web3Provider | INFURA (2024)
Top Articles
Top 5 LEAST ethical banks – and where to move for good
Co-op reports profit increase and membership growth
#ridwork guides | fountainpenguin
Evil Dead Rise Showtimes Near Massena Movieplex
50 Meowbahh Fun Facts: Net Worth, Age, Birthday, Face Reveal, YouTube Earnings, Girlfriend, Doxxed, Discord, Fanart, TikTok, Instagram, Etc
Pickswise the Free Sports Handicapping Service 2023
Visustella Battle Core
Ohiohealth Esource Employee Login
Natureza e Qualidade de Produtos - Gestão da Qualidade
Power Outage Map Albany Ny
Dusk
Elbasha Ganash Corporation · 2521 31st Ave, Apt B21, Astoria, NY 11106
Cbs Trade Value Chart Fantasy Football
Money blog: Domino's withdraws popular dips; 'we got our dream £30k kitchen for £1,000'
Crossword Nexus Solver
Cinebarre Drink Menu
Navy Female Prt Standards 30 34
Mals Crazy Crab
Accident On May River Road Today
50 Shades Of Grey Movie 123Movies
Joann Ally Employee Portal
Full Standard Operating Guideline Manual | Springfield, MO
How your diet could help combat climate change in 2019 | CNN
Gran Turismo Showtimes Near Marcus Renaissance Cinema
Directions To Cvs Pharmacy
SN100C, An Australia Trademark of Nihon Superior Co., Ltd.. Application Number: 2480607 :: Trademark Elite Trademarks
Everything To Know About N Scale Model Trains - My Hobby Models
Delectable Birthday Dyes
At 25 Years, Understanding The Longevity Of Craigslist
Tire Plus Hunters Creek
13301 South Orange Blossom Trail
Encore Atlanta Cheer Competition
Tire Pro Candler
140000 Kilometers To Miles
Powerball lottery winning numbers for Saturday, September 7. $112 million jackpot
Eleceed Mangaowl
Toonily The Carry
Case Funeral Home Obituaries
Sc Pick 4 Evening Archives
Cookie Clicker The Advanced Method
Low Tide In Twilight Manga Chapter 53
St Vrain Schoology
Professors Helpers Abbreviation
What is a lifetime maximum benefit? | healthinsurance.org
Willkommen an der Uni Würzburg | WueStart
Naomi Soraya Zelda
Is Chanel West Coast Pregnant Due Date
Craigslist Charlestown Indiana
Coors Field Seats In The Shade
Noaa Duluth Mn
Latest Posts
Article information

Author: Rev. Leonie Wyman

Last Updated:

Views: 5981

Rating: 4.9 / 5 (59 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Rev. Leonie Wyman

Birthday: 1993-07-01

Address: Suite 763 6272 Lang Bypass, New Xochitlport, VT 72704-3308

Phone: +22014484519944

Job: Banking Officer

Hobby: Sailing, Gaming, Basketball, Calligraphy, Mycology, Astronomy, Juggling

Introduction: My name is Rev. Leonie Wyman, I am a colorful, tasty, splendid, fair, witty, gorgeous, splendid person who loves writing and wants to share my knowledge and understanding with you.