Web3Auth PnP Modal React Quick Start
This guide is designed to help you quickly integrate a basic instance of Web3Auth Plug and Play Modal in your React app.
If you face any problem anytime, you can always find help in the Web3Auth Community.
-
Clone the PnP Modal React Quick Start Application
- npm
- Yarn
- pnpm
npx degit Web3Auth/web3auth-pnp-examples/web-modal-sdk/quick-starts/react-modal-quick-start w3a-quick-start
npx degit Web3Auth/web3auth-pnp-examples/web-modal-sdk/quick-starts/react-modal-quick-start w3a-quick-start
npx degit Web3Auth/web3auth-pnp-examples/web-modal-sdk/quick-starts/react-modal-quick-start w3a-quick-start
-
Install & Run
- npm
- Yarn
- pnpm
cd w3a-quick-start
npm install
npm run startcd w3a-quick-start
yarn install
yarn run startcd w3a-quick-start
pnpm install
pnpm run start
Install Web3Auth
Install the Web3Auth package in your project.
- npm
- Yarn
- pnpm
npm install --save @web3auth/modal
yarn add @web3auth/modal
pnpm add @web3auth/modal
Fixing Bundler Issues
While using Web3Auth in React, you may run into issues building. This issue occurs because some core packages like eccrypto
have certain
dependencies which are not present within the browser build environment.
To solve this, please have a look at our troubleshooting pages:
Get your Client ID from the Web3Auth Dashboard
Visit the Web3Auth Dashboard and create a new project. Use the Client ID of the project to start your integration.
Go to the Developer DashboardInitialize Web3Auth
Web3Auth needs to be initialized as soon as your app loads up to enable the user to log in. Preferably done within a constructor, initialization is the step where you can pass on all the configurations for Web3Auth you want.
For initializing Web3Auth PnP Modal SDK, you need to provide your Client ID, the Web3Auth Network of your project and the configuration of the chain you're looking to connect to. A simple integration for some of the popular blockchains will look like this:
- EVM Chains
- Polygon
- Solana
- Any Other Blockchain
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x1", // Please use 0x1 for Mainnet
rpcTarget: "https://rpc.ankr.com/eth",
displayName: "Ethereum Mainnet",
blockExplorerUrl: "https://etherscan.io/",
ticker: "ETH",
tickerName: "Ethereum",
};
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x89",
rpcTarget: "https://rpc.ankr.com/polygon",
displayName: "Polygon Mainnet",
blockExplorerUrl: "https://polygon.etherscan.io",
ticker: "MATIC",
tickerName: "Polygon",
};
import { SolanaPrivateKeyProvider } from "@web3auth/solana-provider";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.SOLANA,
chainId: "0x1",
rpcTarget: "https://api.devnet.solana.com",
displayName: "Solana Mainnet",
blockExplorerUrl: "https://explorer.solana.com/",
ticker: "SOL",
tickerName: "Solana",
};
const privateKeyProvider = new SolanaPrivateKeyProvider({
config: { chainConfig },
});
const openloginAdapter = new OpenloginAdapter({
privateKeyProvider: privateKeyProvider,
});
web3auth.configureAdapter(openloginAdapter);
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.OTHER,
chainId: "0x1",
rpcTarget: "RPC_URL",
};
const privateKeyProvider = new CommonPrivateKeyProvider({
config: { chainConfig },
});
const openloginAdapter = new OpenloginAdapter({
privateKeyProvider: privateKeyProvider,
});
web3auth.configureAdapter(openloginAdapter);
Logging in your User
Use the connect
function in the Web3Auth Instance to display the modal. The modal will prompt the user to login with their wallet and handle the
authentication for you.
After a successful user login, the connect
function returns a provider that can be used to interact with the blockchain and sign transactions.
Get User Info
Once logged in, Web3Auth state exposes some information about your logged in user. This is fetched directly from the JWT token and Web3Auth doesn't store this info anywhere.
This information can help you identify your users and provide a more personalized experience.
Making Blockchain Calls
Web3Auth is chain agnostic. This means that you can use it with any blockchain with the provider exposed by Web3Auth. For EVM, Solana and XRPL Blockchain Web3Auth exposes special providers for native integrations.
Have a look at our Connect Blockchain section of the documentation and choose your blockchain to get started.
Log the user out
Use the logout
function of the Web3Auth Instance to log the user out. This will also delete the session information from the local storage of the
browser.
- App.tsx
- config-overrides.js
- package.json
import { useEffect, useState } from "react";
import { Web3Auth } from "@web3auth/modal";
import { CHAIN_NAMESPACES, IProvider, WEB3AUTH_NETWORK } from "@web3auth/base";
import Web3 from "web3";
import "./App.css";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
const clientId =
"BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ"; // get from https://dashboard.web3auth.io
const chainConfig = {
chainId: "0x1", // Please use 0x1 for Mainnet
rpcTarget: "https://rpc.ankr.com/eth",
chainNamespace: CHAIN_NAMESPACES.EIP155,
displayName: "Ethereum Mainnet",
blockExplorerUrl: "https://etherscan.io/",
ticker: "ETH",
tickerName: "Ethereum",
logo: "https://images.toruswallet.io/eth.svg",
};
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: { chainConfig: chainConfig }
});
const web3auth = new Web3Auth({
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider: privateKeyProvider,
});
function App() {
const [provider, setProvider] = useState<IProvider | null>(null);
const [loggedIn, setLoggedIn] = useState(false);
useEffect(() => {
const init = async () => {
try {
await web3auth.initModal();
setProvider(web3auth.provider);
if (web3auth.connected) {
setLoggedIn(true);
}
} catch (error) {
console.error(error);
}
};
init();
}, []);
const login = async () => {
const web3authProvider = await web3auth.connect();
setProvider(web3authProvider);
if (web3auth.connected) {
setLoggedIn(true);
}
};
const getUserInfo = async () => {
const user = await web3auth.getUserInfo();
uiConsole(user);
};
const logout = async () => {
await web3auth.logout();
setProvider(null);
setLoggedIn(false);
uiConsole("logged out");
};
const getAccounts = async () => {
if (!provider) {
uiConsole("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const address = await web3.eth.getAccounts();
uiConsole(address);
};
const getBalance = async () => {
if (!provider) {
uiConsole("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const address = (await web3.eth.getAccounts())[0];
// Get user's balance in ether
const balance = web3.utils.fromWei(
await web3.eth.getBalance(address), // Balance is in wei
"ether"
);
uiConsole(balance);
};
const signMessage = async () => {
if (!provider) {
uiConsole("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const fromAddress = (await web3.eth.getAccounts())[0];
const originalMessage = "YOUR_MESSAGE";
// Sign the message
const signedMessage = await web3.eth.personal.sign(
originalMessage,
fromAddress,
"test password!" // configure your own password here.
);
uiConsole(signedMessage);
};
function uiConsole(...args: any[]): void {
const el = document.querySelector("#console>p");
if (el) {
el.innerHTML = JSON.stringify(args || {}, null, 2);
}
console.log(...args);
}
const loggedInView = (
<>
<div className="flex-container">
<div>
<button onClick={getUserInfo} className="card">
Get User Info
</button>
</div>
<div>
<button onClick={getAccounts} className="card">
Get Accounts
</button>
</div>
<div>
<button onClick={getBalance} className="card">
Get Balance
</button>
</div>
<div>
<button onClick={signMessage} className="card">
Sign Message
</button>
</div>
<div>
<button onClick={logout} className="card">
Log Out
</button>
</div>
</div>
</>
);
const unloggedInView = (
<button onClick={login} className="card">
Login
</button>
);
return (
<div className="container">
<h1 className="title">
<a target="_blank" href="https://web3auth.io/docs/sdk/pnp/web/modal" rel="noreferrer">
Web3Auth{" "}
</a>
& ReactJS (Webpack) Quick Start
</h1>
<div className="grid">{loggedIn ? loggedInView : unloggedInView}</div>
<div id="console" style={{ whiteSpace: "pre-line" }}>
<p style={{ whiteSpace: "pre-line" }}></p>
</div>
<footer className="footer">
<a
href="https://github.com/Web3Auth/web3auth-pnp-examples/tree/main/web-modal-sdk/quick-starts/react-modal-quick-start"
target="_blank"
rel="noopener noreferrer"
>
Source code
</a>
</footer>
</div>
);
}
export default App;