UNPKG

@web3auth/no-modal

Version:
89 lines (86 loc) 3.46 kB
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 };