@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
270 lines (266 loc) • 10.2 kB
JavaScript
'use strict';
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var utils = require('@walletconnect/utils');
var auth = require('@web3auth/auth');
require('@segment/analytics-next');
var loglevel = require('../../base/loglevel.js');
var baseControllers = require('@toruslabs/base-controllers');
var index = require('../../base/errors/index.js');
require('../../base/wallet/index.js');
require('../../base/connector/connectorStatus.js');
require('../../base/connector/constants.js');
require('jwt-decode');
require('../../base/plugin/errors.js');
require('../../base/plugin/IPlugin.js');
require('@toruslabs/constants');
require('@toruslabs/http-helpers');
var baseProvider = require('../../providers/base-provider/baseProvider.js');
require('../../providers/base-provider/CommonJRPCProvider.js');
require('../../providers/base-provider/commonPrivateKeyProvider.js');
require('../../providers/base-provider/utils.js');
require('@ethereumjs/util');
require('bignumber.js');
require('../../providers/ethereum-provider/providers/converter.js');
require('bn.js');
require('../../providers/ethereum-provider/providers/privateKeyProviders/TransactionFormatter/interfaces.js');
var ethRpcMiddlewares = require('../../providers/ethereum-provider/rpc/ethRpcMiddlewares.js');
var jrpcClient = require('../../providers/ethereum-provider/rpc/jrpcClient.js');
require('viem');
require('@solana/wallet-standard-features');
require('@solana/web3.js');
require('@toruslabs/bs58');
var JrpcClient = require('../../providers/solana-provider/rpc/JrpcClient.js');
var solanaRpcMiddlewares = require('../../providers/solana-provider/rpc/solanaRpcMiddlewares.js');
require('@web3auth/ws-embed');
var utils$1 = require('./utils.js');
var walletConnectV2Utils = require('./walletConnectV2Utils.js');
var _WalletConnectV2Provider;
class WalletConnectV2Provider extends baseProvider.BaseProvider {
constructor({
config,
state,
connector
}) {
super({
config: {
chain: config.chain,
chains: config.chains,
skipLookupNetwork: !!config.skipLookupNetwork
},
state: _objectSpread(_objectSpread({}, state || {}), {}, {
chainId: "loading",
accounts: []
})
});
_defineProperty(this, "connector", null);
this.connector = connector || null;
}
async enable() {
if (!this.connector) throw auth.providerErrors.custom({
message: "Connector is not initialized, pass wallet connect connector in constructor",
code: 4902
});
await this.setupProvider(this.connector);
return this._providerEngineProxy.request({
method: "eth_accounts"
});
}
async setupProvider(connector) {
this.onConnectorStateUpdate(connector);
await this.setupEngine(connector, this.config.chain.chainId);
}
async switchChain({
chainId
}) {
if (!this.connector) throw auth.providerErrors.custom({
message: "Connector is not initialized, pass wallet connect connector in constructor",
code: 4902
});
const newChainConfig = this.getChain(chainId);
if (!newChainConfig) throw index.WalletLoginError.connectionError("Chain config is not available");
const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
await walletConnectV2Utils.switchChain({
connector: this.connector,
chainId: currentNumChainId,
newChainId: chainId
});
await this.setupEngine(this.connector, chainId);
this.lookupNetwork(this.connector, chainId);
this.update({
chainId
});
}
async addChain(chainConfig) {
if (!this.connector) throw auth.providerErrors.custom({
message: "Connector is not initialized, pass wallet connect connector in constructor",
code: 4902
});
const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
await walletConnectV2Utils.addChain({
connector: this.connector,
chainId: currentNumChainId,
chainConfig
});
}
// no need to implement this method in wallet connect v2.
async lookupNetwork(_, chainId) {
return chainId;
}
async setupEngine(connector, chainId) {
const chain = this.getChain(chainId);
if (chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.EIP155) {
await this.setupEthEngine(connector, chainId);
} else if (chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA) {
await this.setupSolEngine(connector, chainId);
} else {
throw new Error(`Unsupported chainNamespace: ${chain.chainNamespace}`);
}
this.emit("chainChanged", chainId);
this.emit("connect", {
chainId
});
this.update({
chainId
});
}
async setupEthEngine(connector, chainId) {
const chain = this.getChain(chainId);
const numChainId = parseInt(chainId, 16);
const providerHandlers = walletConnectV2Utils.getEthProviderHandlers({
connector,
chainId: numChainId
});
const jrpcRes = await walletConnectV2Utils.getAccounts(connector);
this.update({
accounts: jrpcRes || []
});
const ethMiddleware = ethRpcMiddlewares.createEthMiddleware(providerHandlers);
const chainSwitchMiddleware = this.getEthChainSwitchMiddleware();
const engine = new auth.JRPCEngine();
const {
networkMiddleware
} = jrpcClient.createEthJsonRpcClient(chain);
engine.push(ethMiddleware);
engine.push(chainSwitchMiddleware);
engine.push(networkMiddleware);
const provider = auth.providerFromEngine(engine);
this.updateProviderEngineProxy(provider);
}
async setupSolEngine(connector, chainId) {
const chain = this.getChain(chainId);
const providerHandlers = walletConnectV2Utils.getSolProviderHandlers({
connector,
chainId
});
const jrpcRes = await walletConnectV2Utils.getAccounts(connector);
this.update({
accounts: jrpcRes || []
});
const solMiddleware = solanaRpcMiddlewares.createSolanaMiddleware(providerHandlers);
const engine = new auth.JRPCEngine();
const {
networkMiddleware
} = JrpcClient.createSolanaJsonRpcClient(chain);
engine.push(solMiddleware);
engine.push(networkMiddleware);
const provider = auth.providerFromEngine(engine);
this.updateProviderEngineProxy(provider);
}
getEthChainSwitchMiddleware() {
const chainSwitchHandlers = {
switchChain: async params => {
const {
chainId
} = params;
await this.switchChain({
chainId
});
},
addChain: async params => {
await this.addChain(params);
}
};
const chainSwitchMiddleware = ethRpcMiddlewares.createEthChainSwitchMiddleware(chainSwitchHandlers);
return chainSwitchMiddleware;
}
connectedTopic() {
var _this$connector;
if (!this.connector) throw index.WalletLoginError.notConnectedError("Wallet connect connector is not connected");
if ((_this$connector = this.connector) !== null && _this$connector !== void 0 && (_this$connector = _this$connector.session) !== null && _this$connector !== void 0 && _this$connector.length) {
var _this$connector$sessi;
// currently we are supporting only 1 active session
const lastKeyIndex = this.connector.session.keys.length - 1;
return (_this$connector$sessi = this.connector.session.get(this.connector.session.keys[lastKeyIndex])) === null || _this$connector$sessi === void 0 ? void 0 : _this$connector$sessi.topic;
}
return undefined;
}
checkIfAccountAllowed(address) {
if (!this.connector || !this.connectedTopic()) return false;
const sessionData = this.connector.session.get(this.connectedTopic());
const allAccounts = utils.getAccountsFromNamespaces(sessionData.namespaces);
let accountAllowed = false;
for (const account of allAccounts) {
var _parsedAccount$addres;
const parsedAccount = utils.parseAccountId(account);
if (((_parsedAccount$addres = parsedAccount.address) === null || _parsedAccount$addres === void 0 ? void 0 : _parsedAccount$addres.toLowerCase()) === (address === null || address === void 0 ? void 0 : address.toLowerCase())) {
accountAllowed = true;
break;
}
}
return accountAllowed;
}
async onConnectorStateUpdate(connector) {
connector.events.on("session_event", async payload => {
loglevel.log.debug("session_event data", payload);
if (!this.provider) throw index.WalletLoginError.notConnectedError("Wallet connect connector is not connected");
const {
event
} = payload.params;
const {
name,
data
} = event || {};
// Check if accounts changed and trigger event
if (name === "accountsChanged" && data !== null && data !== void 0 && data.length && this.state.accounts[0] !== data[0] && this.checkIfAccountAllowed(data[0])) {
this.update({
accounts: data
});
this.emit("accountsChanged", data);
}
if (event.name === "chainChanged") {
if (!data) return;
const connectedChainId = data;
const formattedChainId = utils$1.formatChainId(connectedChainId);
// Check if chainId changed and trigger event
const {
currentChain
} = this;
if (formattedChainId && currentChain.chainId !== formattedChainId) {
// Handle rpcUrl update
await this.setupEngine(connector, formattedChainId);
}
}
});
}
getCurrentChainId() {
const currentChain = this.state.chainId;
if (!currentChain || currentChain === "loading") {
return this.config.chains[0].chainId;
}
return currentChain;
}
}
_WalletConnectV2Provider = WalletConnectV2Provider;
_defineProperty(WalletConnectV2Provider, "getProviderInstance", async params => {
const providerFactory = new _WalletConnectV2Provider({
config: {
chain: params.chain,
chains: params.chains,
skipLookupNetwork: params.skipLookupNetwork
}
});
await providerFactory.setupProvider(params.connector);
return providerFactory;
});
exports.WalletConnectV2Provider = WalletConnectV2Provider;