Hi, I am an engineer from Japan.
I am writing this question using a translation tool.
Thanks for developing a great tool!
I have a question about MFA authentication using no-modal-SDK.
I have set mfaLevel: “mandatory”, but when I set up the MFA element for the first time, the deviceShareFactor and other settings are skipped after the second time. Am I wrong in setting it to “mandatory” to ensure that the MFA element is always set up? Why is it skipped? Also, how do I check the MFA elements I have set?
I would like to ask for your help!
Thank you in advance!
"use client";
import {
CHAIN_NAMESPACES,
IProvider,
WALLET_ADAPTERS,
WEB3AUTH_NETWORK,
} from "@web3auth/base";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { Web3AuthNoModal } from "@web3auth/no-modal";
import {
OpenloginAdapter,
OpenloginUserInfo,
WhiteLabelData,
} from "@web3auth/openlogin-adapter";
import { useEffect, useState } from "react";
import Web3 from "web3";
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x61", // BNB Smart Chain Testnet
rpcTarget: "https://data-seed-prebsc-1-s1.binance.org:8545/",
displayName: "BNB Smart Chain Testnet",
blockExplorer: "https://testnet.bscscan.com/",
ticker: "BSC",
tickerName: "BNB",
};
const uiConfig: WhiteLabelData = {
appName: "My App",
mode: "dark",
theme: {
primary: "#FF0000",
},
};
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: {
chainConfig,
},
});
const web3auth = new Web3AuthNoModal({
clientId:
"****",
chainConfig,
web3AuthNetwork: "sapphire_devnet",
privateKeyProvider,
uiConfig,
});
const openloginAdapter = new OpenloginAdapter({
loginSettings: {
mfaLevel: "mandatory",
},
adapterSettings: {
uxMode: "popup",
loginConfig: {
jwt: {
verifier: "*****",
typeOfLogin: "jwt",
clientId:
"*****",
},
},
mfaSettings: {
deviceShareFactor: {
enable: true,
priority: 1,
mandatory: true,
},
backUpShareFactor: {
enable: true,
priority: 2,
mandatory: true,
},
socialBackupFactor: {
enable: true,
priority: 3,
mandatory: true,
},
passwordFactor: {
enable: true,
priority: 4,
mandatory: true,
},
},
},
});
web3auth.configureAdapter(openloginAdapter);
const Page = () => {
const [provider, setProvider] = useState<IProvider | null>(null);
const [loggedIn, setLoggedIn] = useState(false);
const [user, setUser] = useState<Partial<OpenloginUserInfo>>();
const [address, setAddress] = useState<string[]>([]);
useEffect(() => {
const init = async () => {
try {
await web3auth.init();
setProvider(web3auth.provider);
if (web3auth.connected) {
setLoggedIn(true);
}
} catch (error) {
console.error(error);
}
};
init();
}, []);
const login = async () => {
const web3authProvider = await web3auth.connectTo(
WALLET_ADAPTERS.OPENLOGIN,
{
loginProvider: "jwt",
extraLoginOptions: {
verifier: "*****",
id_token:
"*********",
verifierIdField: "sub",
},
}
);
setProvider(web3authProvider);
if (web3auth.connected) {
setLoggedIn(true);
}
};
const logout = async () => {
await web3auth.logout();
setProvider(null);
setLoggedIn(false);
uiConsole("logged out");
};
const getUserInfo = async () => {
const user = await web3auth.getUserInfo();
uiConsole(user);
setUser(user);
};
const getAccounts = async () => {
if (!provider) {
uiConsole("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const address = await web3.eth.getAccounts();
uiConsole(address);
setAddress(address);
};
const getBalance = async () => {
if (!provider) {
uiConsole("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const address = (await web3.eth.getAccounts())[0];
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);
const fromAddress = (await web3.eth.getAccounts())[0];
const originalMessage = "YOUR_MESSAGE";
const signedMessage = await web3.eth.personal.sign(
originalMessage,
fromAddress,
"test password!" // configure your own password here.
);
uiConsole(signedMessage);
};
const uiConsole = (...args: any[]): void => {
const el = document.querySelector("#console>p");
if (el) {
el.innerHTML = JSON.stringify(args || {}, null, 2);
console.log(...args);
}
};
const unloggedInView = (
<button onClick={login} className="card">
Login
</button>
);
const loggedInView = (
<>
<div className="flex-container">
<div>
<button onClick={getUserInfo} className="card">
Get User Info
</button>
<div>{JSON.stringify(user)}</div>
</div>
<div>
<button onClick={getAccounts} className="card">
Get Accounts
</button>
<div>{JSON.stringify(address)}</div>
</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>
</>
);
return (
<>
<div>{loggedIn ? loggedInView : unloggedInView}</div>
</>
);
};
export default Page;