Building a Browser Extension with Web3Auth
This guide will walk you through the process of building a browser extension with Web3Auth.
Repository: Google Chrome Browser Extension Example
Quick Start
npx degit Web3Auth/web3auth-pnp-examples/web-modal-sdk/browser-extensions/chrome-extension-modal-example w3a-chrome-extension-demo && cd w3a-chrome-extension-demo && npm install && npm run build
- In your browser go to
chrome://extensions
- Enable Developer mode
- Click on Load unpacked and select the
build
folder from the folder path mentioned above
The extension should now be installed and you can click on the extension icon to interact with it.
End product of this guide:

Once logged in you can have all the features Web3Auth provides and along with blockchain libraries like ethers.js, web3.js, etc you can interact with the blockchain.

How it works?
We can integrate @web3auth/no-modal
as well as @web3auth/modal
to build a browser extension with Web3Auth. You can read more about both the SDKs
in the SDKs section. The login flow of the user is as follows:
Prerequisites
For Web Apps: A basic knowledge of JavaScript is required to use Web3Auth SDK.
For Mobile Apps: For the Web3Auth Mobile SDKs, you have a choice between iOS, Android, React Native & Flutter. Please refer to the Web3Auth SDK Reference for more information.
Create a Web3Auth account on the Web3Auth Dashboard
We will be building the chrome extension with create-react-app
in this guide.
Setup
Setup your Web3Auth Dashboard
Create a Project from the Project Section of the Web3Auth Developer Dashboard.
Enter your desired Project name.
Select the Product you want to use. For this guide, we'll be using the Plug n Play product.
Select the Platform type you want to use. For this guide, we'll be using the Web Application as the platform.
Select the Web3Auth Network as
Sapphire Devnet
. We recommend creating a project in thesapphire_devnet
ortesnet
network during development. While moving to a production environment, make sure to convert your project tosapphire_mainnet
or any of the legacy mainnet networkmainnet
,aqua
, orcyan
network. Otherwise, you'll end up losing users and keys.Select the blockchain(s) you'll be building this project on. For interoperability with Torus Wallets, you have the option of allowing the user's private key to be used in other applications using Torus Wallets (EVM, Solana, XRPL & Casper).
Finally, once you create the project, you have the option to whitelist your URLs for the project. Please whitelist the domains where your project will be hosted.
Once you have the build folder ready for the extension, you would need to go to chrome://extensions/
and load the unpacked extension from the build
folder. That will give you the extension ID which you would need to add to the Web3Auth Dashboard.
Add chrome-extension://<extension-id>
to the Whitelisted URLs in the Web3Auth Dashboard.
Using the Web3Auth SDK
Installation
Install @web3auth/no-modal
, @web3auth/openlogin-adapter
& @web3auth/base
- npm
- Yarn
- pnpm
npm install @web3auth/no-modal @web3auth/base @web3auth/openlogin-adapter
yarn add @web3auth/no-modal @web3auth/base @web3auth/openlogin-adapter
pnpm add @web3auth/no-modal @web3auth/base @web3auth/openlogin-adapter
Import the Web3Auth Modules into your project
import { useEffect, useState } from "react";
import { Web3Auth } from "@web3auth/no-modal";
import { CHAIN_NAMESPACES, IProvider } from "@web3auth/base";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
Fixing Webpack 5 issues
While using create-react-app, you may run into issues building. This is because NodeJS polyfills are not included in the latest version of webpack 5. To solve this, please have a look at this troubleshooting page where we have added the resolution.
Initialization
Create the Web3Auth instance and configure the Openlogin adapter as per your requirements.
const web3auth = new Web3AuthNoModal({
clientId,
chainConfig: {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x13881",
rpcTarget: "https://rpc.ankr.com/polygon_mumbai",
},
web3AuthNetwork: "sapphire_mainnet",
});
// refer to https://web3auth.io/docs/sdk/pnp/web/adapters/openlogin for learning more about configuring the adapter
const openloginAdapter = new OpenloginAdapter();
web3auth.configureAdapter(openloginAdapter);
Authentication
Once initialized, you can use the connectTo
method to authenticate the user.
const provider = await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider: "google",
});
Get the User Profile
// Assuming the user is logged in.
const user = await web3auth.getUserInfo();
Logout
Logging out your user is as simple as calling the web3auth.logout()
function.
await web3auth.logout();
Interacting with the Blockchain
So if you have completed this far, it means that you have successfully authenticated your user. Now, you can use the provider returned by Web3Auth as
web3auth.provider
to interact with your blockchain. You can use the Provider SDKs to perform RPC Calls to your
blockchain.
Web3Auth is chain agnostic, ie. depending on whatever blockchain or layer-2 you use, Web3Auth can easily support that. Web3Auth has native providers
for EVM and Solana blockchains and for others, you can get the private key in the user scope and make RPC calls. For standardising the type of
provider, Web3Auth Base provides a IProvider
from which you can create your own provider.
- Ethereum Provider gives you the capability of making RPC calls to the EVM compatible blockchains.
- Solana Provider gives you the capability of making RPC calls to the Solana blockchain.
- XRPL Provider gives you the capability of making RPC calls to the XRPL blockchain.
- If you want to use any other chain except Solana or EVM chains, for ex: Starknet, you can specify the value of
chainNamespace
field as other in the Web3Auth SDK Constructor. Refer to: Using other blockchains
Get User Accounts
- Web3
- Ethers.js
const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const userAccounts = await web3.eth.getAccounts();
console.log(userAccounts);
};
const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider as any);
const signer = provider.getSigner();
const userAccounts = await signer.getAddress();
console.log(userAccounts);
};
View User Balance
- Web3
- Ethers.js
const getBalance = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const balance = await web3.eth.getBalance(accounts[0]);
console.log(web3.utils.fromWei(balance));
};
const getBalance = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(this.provider as any);
const signer = provider.getSigner();
const account = await signer.getAddress();
// Get user's balance in ether
// For ethers v5
// const balance = ethers.utils.formatEther(
// await ethersProvider.getBalance(address) // Balance is in wei
// );
const balance = ethers.formatEther(
await provider.getBalance(account) // Balance is in wei
);
console.log(balance);
};
Sign Message
- Web3
- Ethers.js
const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const account = (await web3.eth.getAccounts())[0];
// Message
const message = "Hello MPC, Bye Bye SeedPhrase";
const typedMessage = [
{
type: "string",
name: "message",
value: message,
},
];
const params = [JSON.stringify(typedMessage), account];
const method = "eth_signTypedData";
const signedMessage = await this.provider.request({
method,
params,
});
console.log(signedMessage);
};
const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider);
const signer = provider.getSigner();
const originalMessage = "Hello MPC, Bye Bye SeedPhrase";
const signedMessage = await signer.signMessage(originalMessage);
console.log(signedMessage);
};
Sign Transaction
const signTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const txRes = await web3.eth.signTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};
Send Transaction
- Web3
- Ethers.js
const sendTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const txRes = await web3.eth.sendTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};
const sendTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider);
const signer = await provider.getSigner();
const address = signer.getAddress();
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther("0.0001"),
chainId: 1, // change it to your specific chain id.
});
const receipt = await tx.wait();
console.log(receipt.transactionHash);
};
Example code
The code for the application we developed in this guide can be found in the Web3Auth Browser Extension. Check it out and try running it locally yourself!
Questions?
Ask us on Web3Auth's Community Portal