@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
190 lines (187 loc) • 6.95 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { normalizeWalletName } from '../../base/utils.js';
import { BaseEvmConnector } from '../base-evm-connector/baseEvmConnector.js';
import { CONNECTOR_NAMESPACES } from '../../base/chain/IChainInterface.js';
import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
import { CONNECTOR_CATEGORY, CONNECTOR_STATUS, CONNECTOR_EVENTS } from '../../base/connector/constants.js';
import { log } from '../../base/loglevel.js';
import { WalletLoginError, Web3AuthError } from '../../base/errors/index.js';
class InjectedEvmConnector extends BaseEvmConnector {
constructor(options) {
super(options);
_defineProperty(this, "connectorNamespace", CONNECTOR_NAMESPACES.EIP155);
_defineProperty(this, "currentChainNamespace", CHAIN_NAMESPACES.EIP155);
_defineProperty(this, "type", CONNECTOR_CATEGORY.EXTERNAL);
_defineProperty(this, "name", void 0);
_defineProperty(this, "isInjected", true);
_defineProperty(this, "status", CONNECTOR_STATUS.NOT_READY);
_defineProperty(this, "injectedProvider", null);
this.name = options.name;
this.injectedProvider = options.provider;
this.icon = options.icon;
}
get provider() {
if (this.status !== CONNECTOR_STATUS.NOT_READY && this.injectedProvider) {
return this.injectedProvider;
}
return null;
}
set provider(_) {
throw new Error("Not implemented");
}
async init(options) {
await super.init(options);
const chainConfig = this.coreOptions.chains.find(x => x.chainId === options.chainId);
super.checkInitializationRequirements({
chainConfig
});
this.status = CONNECTOR_STATUS.READY;
this.emit(CONNECTOR_EVENTS.READY, this.name);
try {
log.debug(`initializing ${this.name} injected connector`);
if (options.autoConnect) {
this.rehydrated = true;
const provider = await this.connect({
chainId: options.chainId,
getIdentityToken: options.getIdentityToken
});
if (!provider) {
this.rehydrated = false;
throw WalletLoginError.connectionError("Failed to rehydrate.");
}
}
} catch (error) {
this.emit(CONNECTOR_EVENTS.REHYDRATION_ERROR, error);
}
}
async connect({
chainId,
getIdentityToken
}) {
super.checkConnectionRequirements();
if (!this.injectedProvider) throw WalletLoginError.connectionError("Injected provider is not available");
const chainConfig = this.coreOptions.chains.find(x => x.chainId === chainId);
if (!chainConfig) throw WalletLoginError.connectionError("Chain config is not available");
this.status = CONNECTOR_STATUS.CONNECTING;
this.emit(CONNECTOR_EVENTS.CONNECTING, {
connector: this.name
});
try {
await this.injectedProvider.request({
method: "eth_requestAccounts"
});
// switch chain if not connected to the right chain
if (this.injectedProvider.chainId !== chainConfig.chainId) {
try {
await this.switchChain(chainConfig, true);
} catch {
await this.addChain(chainConfig, true);
await this.switchChain(chainConfig, true);
}
}
this.status = CONNECTOR_STATUS.CONNECTED;
const accountDisconnectHandler = accounts => {
if (accounts.length === 0) {
var _this$injectedProvide;
this.disconnect();
if ((_this$injectedProvide = this.injectedProvider) !== null && _this$injectedProvide !== void 0 && _this$injectedProvide.removeListener) this.injectedProvider.removeListener("accountsChanged", accountDisconnectHandler);
}
};
this.injectedProvider.on("accountsChanged", accountDisconnectHandler);
let identityTokenInfo;
this.emit(CONNECTOR_EVENTS.CONNECTED, {
connector: this.name,
reconnected: this.rehydrated,
provider: this.injectedProvider,
identityTokenInfo
});
if (getIdentityToken) {
identityTokenInfo = await this.getIdentityToken();
}
return this.injectedProvider;
} catch (error) {
// ready again to be connected
this.status = CONNECTOR_STATUS.READY;
if (!this.rehydrated) this.emit(CONNECTOR_EVENTS.ERRORED, error);
this.rehydrated = false;
if (error instanceof Web3AuthError) throw error;
throw WalletLoginError.connectionError(`Failed to login with ${this.name} injected wallet`);
}
}
async disconnect(options = {
cleanup: false
}) {
if (!this.injectedProvider) throw WalletLoginError.connectionError("Injected provider is not available");
await super.disconnectSession();
if (typeof this.injectedProvider.removeAllListeners !== "undefined") this.injectedProvider.removeAllListeners();
try {
await this.injectedProvider.request({
method: "wallet_revokePermissions",
params: [{
eth_accounts: {}
}]
});
} catch {
// ignore error
}
if (options.cleanup) {
this.status = CONNECTOR_STATUS.NOT_READY;
this.injectedProvider = null;
} else {
// ready to be connected again
this.status = CONNECTOR_STATUS.READY;
}
await super.disconnect();
}
async getUserInfo() {
if (!this.canAuthorize) throw WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first");
return {};
}
async addChain(chainConfig, _init = false) {
if (!this.injectedProvider) throw WalletLoginError.connectionError("Injected provider is not available");
await this.injectedProvider.request({
method: "wallet_addEthereumChain",
params: [{
chainId: chainConfig.chainId,
chainName: chainConfig.displayName,
rpcUrls: [chainConfig.rpcTarget],
blockExplorerUrls: [chainConfig.blockExplorerUrl],
nativeCurrency: {
name: chainConfig.tickerName,
symbol: chainConfig.ticker,
decimals: chainConfig.decimals || 18
},
iconUrls: [chainConfig.logo]
}]
});
}
async switchChain(params, init = false) {
if (!this.injectedProvider) throw WalletLoginError.connectionError("Injected provider is not available");
super.checkSwitchChainRequirements(params, init);
await this.injectedProvider.request({
method: "wallet_switchEthereumChain",
params: [{
chainId: params.chainId
}]
});
}
async enableMFA() {
throw new Error("Method Not implemented");
}
async manageMFA() {
throw new Error("Method Not implemented");
}
}
const injectedEvmConnector = providerDetail => {
return ({
coreOptions
}) => {
return new InjectedEvmConnector({
name: normalizeWalletName(providerDetail.info.name),
provider: providerDetail.provider,
icon: providerDetail.info.icon,
coreOptions
});
};
};
export { InjectedEvmConnector, injectedEvmConnector };