@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
89 lines (86 loc) • 3.46 kB
JavaScript
import { signChallenge } from '@toruslabs/base-controllers';
import { bytesToHexPrefixedString, utf8ToBytes } from '@toruslabs/metadata-helpers';
import { EVM_METHOD_TYPES } from '@web3auth/ws-embed';
import { checksumAddress } from 'viem';
import { generateSiweNonce } from 'viem/siwe';
import { WalletLoginError, WalletInitializationError } from '../../base/errors/index.js';
import { citadelServerUrl } from '../../base/utils.js';
import { BaseConnector } from '../../base/connector/baseConnector.js';
import { CONNECTOR_STATUS, CONNECTOR_EVENTS } from '../../base/connector/constants.js';
class BaseEvmConnector extends BaseConnector {
async init(_) {}
async getAuthTokenInfo() {
if (!this.provider || !this.canAuthorize) throw WalletLoginError.notConnectedError();
if (!this.coreOptions) throw WalletInitializationError.invalidParams("Please initialize Web3Auth with valid options");
this.status = CONNECTOR_STATUS.AUTHORIZING;
this.emit(CONNECTOR_EVENTS.AUTHORIZING, {
connector: this.name
});
const accounts = await this.provider.request({
method: EVM_METHOD_TYPES.GET_ACCOUNTS
});
if (accounts && accounts.length > 0) {
const cached = await this.getCachedOrNullAuthTokenInfo(accounts[0]);
if (cached) return cached;
const authServer = citadelServerUrl(this.coreOptions.authBuildEnv);
const {
challenge,
signature,
chainNamespace
} = await this.generateChallengeAndSign(authServer, accounts);
return this.verifyAndAuthorize({
chainNamespace,
signedMessage: signature,
challenge,
authServer
});
}
throw WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first");
}
async generateChallengeAndSign(authServerUrl, accounts) {
const accountsToUse = accounts || (await this.provider.request({
method: EVM_METHOD_TYPES.GET_ACCOUNTS
}));
if (!accountsToUse || accountsToUse.length === 0) {
throw WalletLoginError.notConnectedError("No accounts found in the connected wallet");
}
const chainId = await this.provider.request({
method: "eth_chainId"
});
const currentChainConfig = this.coreOptions.chains.find(x => x.chainId === chainId);
if (!currentChainConfig) throw WalletInitializationError.invalidParams("chainConfig is required before authentication");
const {
chainNamespace
} = currentChainConfig;
const authServer = authServerUrl || citadelServerUrl(this.coreOptions.authBuildEnv);
const payload = {
domain: window.location.host,
uri: window.location.href,
address: checksumAddress(accountsToUse[0]),
chainId: parseInt(chainId, 16),
version: "1",
nonce: generateSiweNonce(),
issuedAt: new Date().toISOString()
};
const challenge = await signChallenge(payload, chainNamespace, authServer);
const hexChallenge = bytesToHexPrefixedString(utf8ToBytes(challenge));
const signature = await this.provider.request({
method: EVM_METHOD_TYPES.PERSONAL_SIGN,
params: [hexChallenge, accountsToUse[0]]
});
return {
challenge,
signature,
chainNamespace
};
}
async disconnectSession() {
super.checkDisconnectionRequirements();
await this.clearWalletSession();
}
async disconnect() {
this.rehydrated = false;
this.emit(CONNECTOR_EVENTS.DISCONNECTED);
}
}
export { BaseEvmConnector };