- SDK Version: @web3auth/modal
: Version
7.3.1` - Platform: React (for web development)
Hi everyone, I have gotten the modal to run, but I am trying to connect to the Polygon zkEVM testnet, so how should I properly configure chainConfig? I have this so far (it does not work, but the default chainConfig that is provided with the example in the docs works, so I’m confident the problem is due to my configuration here ):
It allows the user to login, and it gets the user info, but when I request account info, balance, or sign message, I get this error in the console:
Must provide fallback error with integer number code and string message
Here’s the what happens when I console log the provider:
CommonJRPCProvider {_events: {…}, _eventsCount: 0, _maxListeners: undefined, defaultConfig: {…}, defaultState: {…}, …}chainConfig: {chainNamespace: ‘other’, chainId: ‘1422’, rpcTarget: ‘https://polygonzkevm-testnet.g.alchemy.com/v2/demo’, displayName: ‘Polygon zkEVM Testnet’, blockExplorer: ‘https://zkevm.polygonscan.com/’, …}defaultConfig: {chainConfig: {…}, networks: {…}}defaultState: {chainId: ‘loading’}disabled: falseinitialConfig: {chainConfig: {…}}initialState: {}internalConfig: {chainConfig: {…}, networks: {…}}internalState: {chainId: ‘1422’}name: "BaseController"networks: {1422: {…}}_events: {message: Array(2)}_eventsCount: 1_maxListeners: undefined_providerEngineProxy: Proxy(Object) {}chainId: (…)config: (…)currentChainConfig: (…)provider: (…)state: (…)[[Prototype]]: BaseProvider
Web3
Here’s the default chainConfig that comes with the example and works:
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: “0x1”, // Please use 0x1 for Mainnet
rpcTarget: “https://rpc.ankr.com/eth”,
displayName: “Ethereum Mainnet”,
blockExplorer: “https://etherscan.io/”,
ticker: “ETH”,
tickerName: “Ethereum”,
};
Here’s the current file with the Polygon Zkevm Testnet chainConfig for reference:
// Configuration for Web3Auth
import { useEffect, useState } from "react";
import { Web3Auth } from "@web3auth/modal";
import { CHAIN_NAMESPACES, IProvider } from "@web3auth/base";
import Web3 from "web3";
import { CommonPrivateKeyProvider } from "@web3auth/base-provider";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
import React from "react";
const clientId = process.env.REACT_APP_WEB3AUTH_CLIENT_ID!;
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.OTHER,
chainId: "0x59E", // Polygon zkEVM Testnet Chain ID
rpcTarget: "https://rpc.public.zkevm-test.net", // RPC URL
displayName: "Polygon zkEVM Testnet", // Display name for the network
blockExplorer: "https://explorer.public.zkevm-test.net", // Block Explorer URL
ticker: "ETH", // Currency symbol
tickerName: "Ethereum" // Currency name
};
// Declare and instantiate web3auth first
const web3auth = new Web3Auth({
clientId,
chainConfig,
web3AuthNetwork: "testnet",
});
// Then configure it with privateKeyProvider and openloginAdapter
const privateKeyProvider = new CommonPrivateKeyProvider({ config: { chainConfig } });
const openloginAdapter = new OpenloginAdapter({ privateKeyProvider: privateKeyProvider });
web3auth.configureAdapter(openloginAdapter);
function Web3AuthDashboard() {
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 during initialization:", error);
// Handle the error appropriately here
}
};
init();
}, []);
const login = async () => {
const web3authProvider = await web3auth.connect();
setProvider(web3authProvider);
if (web3auth.connected) {
setLoggedIn(true);
}
};
const getUserInfo = async () => {
try {
console.log("provider", provider);
if (!provider) {
throw new Error("Provider not initialized");
}
const user = await web3auth.getUserInfo();
uiConsole(user);
} catch (error) {
if (error instanceof Error) {
console.error("Error getting user info:", error.message);
uiConsole("Error getting user info: " + error.message);
} else {
console.error("An unknown error occurred");
uiConsole("An unknown error occurred");
}
}
};
const logout = async () => {
await web3auth.logout();
setProvider(null);
setLoggedIn(false);
uiConsole("logged out");
};
const getAccounts = async () => {
try {
console.log("provider", provider);
if (!provider) {
throw new Error("Provider not initialized yet");
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const address = await web3.eth.getAccounts();
uiConsole(address);
} catch (error) {
if (error instanceof Error) {
console.error("Error getting accounts:", error.message);
uiConsole("Error getting accounts: " + error.message);
} else {
console.error("An unknown error occurred");
uiConsole("An unknown error occurred");
}
}
};
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 Web3AuthDashboard;
Thanks!