UNPKG

@web3auth/wallet-connect-v2-adapter

Version:
1,134 lines (1,087 loc) 46.5 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ 493: /***/ ((module) => { module.exports = require("@solana/web3.js"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/create fake namespace object */ /******/ (() => { /******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); /******/ var leafPrototypes; /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 16: return value when it's Promise-like /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = this(value); /******/ if(mode & 8) return value; /******/ if(typeof value === 'object' && value) { /******/ if((mode & 4) && value.__esModule) return value; /******/ if((mode & 16) && typeof value.then === 'function') return value; /******/ } /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ var def = {}; /******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; /******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { /******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); /******/ } /******/ def['default'] = () => (value); /******/ __webpack_require__.d(ns, def); /******/ return ns; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { DEFAULT_EIP155_METHODS: () => (/* reexport */ DEFAULT_EIP155_METHODS), DEFAULT_EIP_155_EVENTS: () => (/* reexport */ DEFAULT_EIP_155_EVENTS), DEFAULT_SOLANA_EVENTS: () => (/* reexport */ DEFAULT_SOLANA_EVENTS), DEFAULT_SOLANA_METHODS: () => (/* reexport */ DEFAULT_SOLANA_METHODS), SOLANA_CAIP_CHAIN_MAP: () => (/* reexport */ SOLANA_CAIP_CHAIN_MAP), WalletConnectV2Adapter: () => (/* reexport */ WalletConnectV2Adapter), WalletConnectV2Provider: () => (/* reexport */ WalletConnectV2Provider), getNamespacesFromChains: () => (/* reexport */ getNamespacesFromChains), getRequiredNamespaces: () => (/* reexport */ getRequiredNamespaces), getSupportedEventsByNamespace: () => (/* reexport */ getSupportedEventsByNamespace), getSupportedMethodsByNamespace: () => (/* reexport */ getSupportedMethodsByNamespace), getWalletConnectV2Settings: () => (/* reexport */ getWalletConnectV2Settings) }); ;// external "@web3auth/base" const base_namespaceObject = require("@web3auth/base"); ;// ./src/config.ts let DEFAULT_EIP155_METHODS = /*#__PURE__*/function (DEFAULT_EIP155_METHODS) { DEFAULT_EIP155_METHODS["ETH_SEND_TRANSACTION"] = "eth_sendTransaction"; DEFAULT_EIP155_METHODS["ETH_SIGN_TRANSACTION"] = "eth_signTransaction"; DEFAULT_EIP155_METHODS["ETH_SIGN"] = "eth_sign"; DEFAULT_EIP155_METHODS["PERSONAL_SIGN"] = "personal_sign"; DEFAULT_EIP155_METHODS["ETH_SIGN_TYPED_DATA"] = "eth_signTypedData"; DEFAULT_EIP155_METHODS["ETH_SIGN_TYPED_DATA_V3"] = "eth_signTypedData_v3"; DEFAULT_EIP155_METHODS["ETH_SIGN_TYPED_DATA_V4"] = "eth_signTypedData_v4"; DEFAULT_EIP155_METHODS["ADD_ETHEREUM_CHAIN"] = "wallet_addEthereumChain"; DEFAULT_EIP155_METHODS["SWITCH_ETHEREUM_CHAIN"] = "wallet_switchEthereumChain"; return DEFAULT_EIP155_METHODS; }({}); let DEFAULT_SOLANA_METHODS = /*#__PURE__*/function (DEFAULT_SOLANA_METHODS) { DEFAULT_SOLANA_METHODS["SIGN_TRANSACTION"] = "solana_signTransaction"; DEFAULT_SOLANA_METHODS["SIGN_MESSAGE"] = "solana_signMessage"; return DEFAULT_SOLANA_METHODS; }({}); let DEFAULT_EIP_155_EVENTS = /*#__PURE__*/function (DEFAULT_EIP_155_EVENTS) { DEFAULT_EIP_155_EVENTS["ETH_CHAIN_CHANGED"] = "chainChanged"; DEFAULT_EIP_155_EVENTS["ETH_ACCOUNTS_CHANGED"] = "accountsChanged"; return DEFAULT_EIP_155_EVENTS; }({}); let DEFAULT_SOLANA_EVENTS = /*#__PURE__*/function (DEFAULT_SOLANA_EVENTS) { DEFAULT_SOLANA_EVENTS["SOL_CHAIN_CHANGED"] = "chainChanged"; DEFAULT_SOLANA_EVENTS["SOL_ACCOUNTS_CHANGED"] = "accountsChanged"; return DEFAULT_SOLANA_EVENTS; }({}); const SOLANA_CAIP_CHAIN_MAP = { "0x65": "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "0x66": "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z", "0x67": "EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }; /** * Extracts a name for the site from the DOM */ const getSiteName = window => { const { document } = window; const siteName = document.querySelector('head > meta[property="og:site_name"]'); if (siteName) { return siteName.content; } const metaTitle = document.querySelector('head > meta[name="title"]'); if (metaTitle) { return metaTitle.content; } if (document.title && document.title.length > 0) { return document.title; } return window.location.hostname; }; /** * Returns whether the given image URL exists * @param url - the url of the image * @returns - whether the image exists */ function imgExists(url) { return new Promise((resolve, reject) => { try { const img = document.createElement("img"); img.onload = () => resolve(true); img.onerror = () => resolve(false); img.src = url; } catch (e) { reject(e); } }); } /** * Extracts an icon for the site from the DOM */ async function getSiteIcon(window) { const { document } = window; // Use the site's favicon if it exists let icon = document.querySelector('head > link[rel="shortcut icon"]'); if (icon && (await imgExists(icon.href))) { return icon.href; } // Search through available icons in no particular order icon = Array.from(document.querySelectorAll('head > link[rel="icon"]')).find(_icon => Boolean(_icon.href)) || null; if (icon && (await imgExists(icon.href))) { return icon.href; } return null; } /** * Gets site metadata and returns it * */ const getSiteMetadata = async () => ({ name: getSiteName(window), icon: await getSiteIcon(window) }); const getNamespacesFromChains = chains => { const supportedNamespaces = []; chains.forEach(chainId => { const [namespace] = chainId.split(":"); if (!supportedNamespaces.includes(namespace)) { supportedNamespaces.push(namespace); } }); return supportedNamespaces; }; const getSupportedMethodsByNamespace = namespace => { switch (namespace) { case base_namespaceObject.CHAIN_NAMESPACES.EIP155: return Object.values(DEFAULT_EIP155_METHODS); case base_namespaceObject.CHAIN_NAMESPACES.SOLANA: return Object.values(DEFAULT_SOLANA_METHODS); default: throw new Error(`No default methods for namespace: ${namespace}`); } }; const getSupportedEventsByNamespace = namespace => { switch (namespace) { case base_namespaceObject.CHAIN_NAMESPACES.EIP155: return Object.values(DEFAULT_EIP_155_EVENTS); case base_namespaceObject.CHAIN_NAMESPACES.SOLANA: return Object.values(DEFAULT_SOLANA_EVENTS); default: throw new Error(`No default events for namespace: ${namespace}`); } }; const getRequiredNamespaces = chains => { const selectedNamespaces = getNamespacesFromChains(chains); return Object.fromEntries(selectedNamespaces.map(namespace => [namespace, { methods: getSupportedMethodsByNamespace(namespace), chains: chains.filter(chain => chain.startsWith(namespace)), events: getSupportedEventsByNamespace(namespace) }])); }; const getWalletConnectV2Settings = async (namespace, chainIds, projectID) => { if (namespace === base_namespaceObject.CHAIN_NAMESPACES.EIP155 || namespace === base_namespaceObject.CHAIN_NAMESPACES.SOLANA) { const appMetadata = await getSiteMetadata(); const adapterSettings = { walletConnectInitOptions: { projectId: projectID, relayUrl: "wss://relay.walletconnect.com", metadata: { name: appMetadata.name, description: appMetadata.name, url: window.location.origin, icons: [appMetadata.icon || ""] } } }; const chainNamespaces = chainIds.map(chainId => { return `${namespace}:${namespace === base_namespaceObject.CHAIN_NAMESPACES.SOLANA ? SOLANA_CAIP_CHAIN_MAP[chainId] : parseInt(chainId, 16)}`; }); const loginSettings = { optionalNamespaces: getRequiredNamespaces(chainNamespaces) }; return { adapterSettings, loginSettings }; } throw new Error(`Unsupported chain namespace: ${namespace}`); }; ;// external "@babel/runtime/helpers/objectSpread2" const objectSpread2_namespaceObject = require("@babel/runtime/helpers/objectSpread2"); var objectSpread2_default = /*#__PURE__*/__webpack_require__.n(objectSpread2_namespaceObject); ;// external "@babel/runtime/helpers/defineProperty" const defineProperty_namespaceObject = require("@babel/runtime/helpers/defineProperty"); var defineProperty_default = /*#__PURE__*/__webpack_require__.n(defineProperty_namespaceObject); ;// external "@toruslabs/base-controllers" const base_controllers_namespaceObject = require("@toruslabs/base-controllers"); ;// external "@walletconnect/sign-client" const sign_client_namespaceObject = require("@walletconnect/sign-client"); var sign_client_default = /*#__PURE__*/__webpack_require__.n(sign_client_namespaceObject); ;// external "@walletconnect/utils" const utils_namespaceObject = require("@walletconnect/utils"); ;// external "bs58" const external_bs58_namespaceObject = require("bs58"); var external_bs58_default = /*#__PURE__*/__webpack_require__.n(external_bs58_namespaceObject); ;// external "deepmerge" const external_deepmerge_namespaceObject = require("deepmerge"); var external_deepmerge_default = /*#__PURE__*/__webpack_require__.n(external_deepmerge_namespaceObject); ;// external "@web3auth/auth" const auth_namespaceObject = require("@web3auth/auth"); ;// external "@web3auth/base-provider" const base_provider_namespaceObject = require("@web3auth/base-provider"); ;// external "@web3auth/ethereum-provider" const ethereum_provider_namespaceObject = require("@web3auth/ethereum-provider"); ;// external "@web3auth/solana-provider" const solana_provider_namespaceObject = require("@web3auth/solana-provider"); ;// ./src/walletConnectV2Utils.ts async function getLastActiveSession(signClient) { if (signClient.session.length) { const lastKeyIndex = signClient.session.keys.length - 1; return signClient.session.get(signClient.session.keys[lastKeyIndex]); } return null; } function isMobileDevice() { return /Mobi|Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(window.navigator.userAgent); } function isSolanaChain(chainId) { return chainId.startsWith("solana:"); } async function sendJrpcRequest(signClient, chainId, method, params) { const session = await getLastActiveSession(signClient); if (!session) { throw auth_namespaceObject.providerErrors.disconnected(); } if (typeof window !== "undefined" && isMobileDevice()) { if (session.peer.metadata.redirect && session.peer.metadata.redirect.native) { window.open(session.peer.metadata.redirect.native, "_blank"); } } return signClient.request({ topic: session.topic, chainId, request: { method, params: isSolanaChain(chainId) ? objectSpread2_default()(objectSpread2_default()({}, params), {}, { pubkey: session.self.publicKey }) : params } }); } async function getAccounts(signClient) { const session = await getLastActiveSession(signClient); if (!session) { throw auth_namespaceObject.providerErrors.disconnected(); } const accounts = (0,utils_namespaceObject.getAccountsFromNamespaces)(session.namespaces); if (accounts && accounts.length) { return [...new Set(accounts.map(add => { return (0,utils_namespaceObject.parseAccountId)(add).address; }))]; } throw base_namespaceObject.WalletLoginError.connectionError("Failed to get accounts"); } function getEthProviderHandlers({ connector, chainId }) { return { getPrivateKey: async () => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, getPublicKey: async () => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, getAccounts: async _ => { return getAccounts(connector); }, processTransaction: async (txParams, _) => { const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "eth_sendTransaction", [txParams]); return methodRes; }, processSignTransaction: async (txParams, _) => { const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "eth_signTransaction", [txParams]); return methodRes; }, processEthSignMessage: async (msgParams, _) => { const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "eth_sign", [msgParams.from, msgParams.data]); return methodRes; }, processPersonalMessage: async (msgParams, _) => { const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "personal_sign", [msgParams.data, msgParams.from]); return methodRes; }, processTypedMessageV4: async msgParams => { const methodRes = await sendJrpcRequest(connector, `eip155:${chainId}`, "eth_signTypedData_v4", [msgParams.from, msgParams.data]); return methodRes; } }; } function getSolProviderHandlers({ connector, chainId }) { return { requestAccounts: async _ => { return getAccounts(connector); }, getPrivateKey: async () => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, getSecretKey: async () => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, getPublicKey: async () => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, getAccounts: async _ => { return getAccounts(connector); }, signAllTransactions: async _ => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, signAndSendTransaction: async _ => { throw auth_namespaceObject.rpcErrors.methodNotSupported(); }, signMessage: async req => { const methodRes = await sendJrpcRequest(connector, `solana:${SOLANA_CAIP_CHAIN_MAP[chainId]}`, "solana_signMessage", { message: external_bs58_default().encode(req.params.message) }); return external_bs58_default().decode(methodRes.signature); }, signTransaction: async req => { const [{ PublicKey }, accounts] = await Promise.all([Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 493, 23)), getAccounts(connector)]); if (accounts.length === 0) { throw auth_namespaceObject.providerErrors.disconnected(); } const methodRes = await sendJrpcRequest(connector, `solana:${SOLANA_CAIP_CHAIN_MAP[chainId]}`, "solana_signTransaction", { transaction: req.params.message.serialize({ requireAllSignatures: false }).toString("base64") }); const finalTransaction = req.params.message; finalTransaction.addSignature(new PublicKey(accounts[0]), Buffer.from(external_bs58_default().decode(methodRes.signature))); return finalTransaction; } }; } async function switchChain({ connector, chainId, newChainId }) { await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_switchEthereumChain", [{ chainId: newChainId }]); } async function addChain({ connector, chainId, chainConfig }) { await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_addEthereumChain", [chainConfig]); } ;// ./src/WalletConnectV2Provider.ts var _WalletConnectV2Provider; class WalletConnectV2Provider extends base_provider_namespaceObject.BaseProvider { constructor({ clientId, config, state, connector }) { super({ config: { chainConfig: config.chainConfig, skipLookupNetwork: !!config.skipLookupNetwork }, state: objectSpread2_default()(objectSpread2_default()({}, state || {}), {}, { chainId: "loading", accounts: [] }) }); defineProperty_default()(this, "connector", null); defineProperty_default()(this, "clientId", void 0); this.connector = connector || null; this.clientId = clientId; } async enable() { if (!this.connector) throw auth_namespaceObject.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); } async switchChain({ chainId }) { if (!this.connector) throw auth_namespaceObject.providerErrors.custom({ message: "Connector is not initialized, pass wallet connect connector in constructor", code: 4902 }); const currentChainConfig = this.getChainConfig(chainId); const { chainId: currentChainId } = this.config.chainConfig; const currentNumChainId = parseInt(currentChainId, 16); await switchChain({ connector: this.connector, chainId: currentNumChainId, newChainId: chainId }); this.configure({ chainConfig: currentChainConfig }); await this.setupEngine(this.connector); this.lookupNetwork(this.connector); } async addChain(chainConfig) { const { chainId: currentChainId } = this.config.chainConfig; const numChainId = parseInt(currentChainId, 16); await addChain({ connector: this.connector, chainId: numChainId, chainConfig: { chainId: chainConfig.chainId, chainName: chainConfig.displayName, nativeCurrency: { name: chainConfig.tickerName, symbol: chainConfig.ticker.toLocaleUpperCase(), decimals: chainConfig.decimals || 18 }, rpcUrls: [chainConfig.rpcTarget], blockExplorerUrls: [chainConfig.blockExplorerUrl], iconUrls: [chainConfig.logo] } }); super.addChain(chainConfig); } // no need to implement this method in wallet connect v2. async lookupNetwork(_) { const newChainId = this.config.chainConfig.chainId; this.update({ chainId: newChainId }); this.emit("chainChanged", newChainId); this.emit("connect", { chainId: newChainId }); return this.config.chainConfig.chainId; } async setupEngine(connector) { if (this.config.chainConfig.chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.EIP155) { return this.setupEthEngine(connector); } else if (this.config.chainConfig.chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.SOLANA) { return this.setupSolEngine(connector); } throw new Error(`Unsupported chainNamespace: ${this.config.chainConfig.chainNamespace}`); } async setupEthEngine(connector) { const { chainId } = this.config.chainConfig; const numChainId = parseInt(chainId, 16); const providerHandlers = getEthProviderHandlers({ connector, chainId: numChainId }); const jrpcRes = await getAccounts(connector); this.update({ accounts: jrpcRes || [] }); const ethMiddleware = (0,ethereum_provider_namespaceObject.createEthMiddleware)(providerHandlers); const chainSwitchMiddleware = this.getEthChainSwitchMiddleware(); const engine = new auth_namespaceObject.JRPCEngine(); const { networkMiddleware } = (0,ethereum_provider_namespaceObject.createJsonRpcClient)(this.config.chainConfig); engine.push(ethMiddleware); engine.push(chainSwitchMiddleware); engine.push(networkMiddleware); const provider = (0,auth_namespaceObject.providerFromEngine)(engine); this.updateProviderEngineProxy(provider); } async setupSolEngine(connector) { const { chainId } = this.config.chainConfig; const providerHandlers = getSolProviderHandlers({ connector, chainId }); const jrpcRes = await getAccounts(connector); this.update({ accounts: jrpcRes || [] }); const solMiddleware = (0,solana_provider_namespaceObject.createSolanaMiddleware)(providerHandlers); const engine = new auth_namespaceObject.JRPCEngine(); const { networkMiddleware } = (0,solana_provider_namespaceObject.createJsonRpcClient)(this.config.chainConfig); engine.push(solMiddleware); engine.push(networkMiddleware); const provider = (0,auth_namespaceObject.providerFromEngine)(engine); this.updateProviderEngineProxy(provider); } getEthChainSwitchMiddleware() { const chainSwitchHandlers = { addChain: async params => { const { chainId, chainName, rpcUrls, blockExplorerUrls, nativeCurrency, iconUrls } = params; this.addChain({ chainNamespace: base_namespaceObject.CHAIN_NAMESPACES.EIP155, chainId, ticker: (nativeCurrency === null || nativeCurrency === void 0 ? void 0 : nativeCurrency.symbol) || "ETH", tickerName: (nativeCurrency === null || nativeCurrency === void 0 ? void 0 : nativeCurrency.name) || "Ether", displayName: chainName, rpcTarget: rpcUrls[0], blockExplorerUrl: (blockExplorerUrls === null || blockExplorerUrls === void 0 ? void 0 : blockExplorerUrls[0]) || "", decimals: (nativeCurrency === null || nativeCurrency === void 0 ? void 0 : nativeCurrency.decimals) || 18, logo: (iconUrls === null || iconUrls === void 0 ? void 0 : iconUrls[0]) || "https://images.toruswallet.io/eth.svg" }); }, switchChain: async params => { const { chainId } = params; await this.switchChain({ chainId }); } }; const chainSwitchMiddleware = (0,ethereum_provider_namespaceObject.createChainSwitchMiddleware)(chainSwitchHandlers); return chainSwitchMiddleware; } connectedTopic() { var _this$connector; if (!this.connector) throw base_namespaceObject.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 = (0,utils_namespaceObject.getAccountsFromNamespaces)(sessionData.namespaces); let accountAllowed = false; for (const account of allAccounts) { var _parsedAccount$addres; const parsedAccount = (0,utils_namespaceObject.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 => { base_namespaceObject.log.debug("session_event data", payload); if (!this.provider) throw base_namespaceObject.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 connectedHexChainId = `0x${connectedChainId.toString(16)}`; // Check if chainId changed and trigger event if (connectedHexChainId && this.state.chainId !== connectedHexChainId) { const maybeConfig = (0,base_namespaceObject.getChainConfig)(base_namespaceObject.CHAIN_NAMESPACES.EIP155, connectedHexChainId, this.clientId); // Handle rpcUrl update this.configure({ chainConfig: objectSpread2_default()(objectSpread2_default()({}, maybeConfig), {}, { chainId: connectedHexChainId, chainNamespace: base_namespaceObject.CHAIN_NAMESPACES.EIP155 }) }); await this.setupEngine(connector); } } }); } } _WalletConnectV2Provider = WalletConnectV2Provider; defineProperty_default()(WalletConnectV2Provider, "getProviderInstance", async params => { const providerFactory = new _WalletConnectV2Provider({ clientId: params.clientId, config: { chainConfig: params.chainConfig, skipLookupNetwork: params.skipLookupNetwork } }); await providerFactory.setupProvider(params.connector); return providerFactory; }); ;// ./src/walletConnectV2adapter.ts class WalletConnectV2Adapter extends base_namespaceObject.BaseAdapter { constructor(options = {}) { super(options); defineProperty_default()(this, "name", base_namespaceObject.WALLET_ADAPTERS.WALLET_CONNECT_V2); defineProperty_default()(this, "adapterNamespace", base_namespaceObject.ADAPTER_NAMESPACES.MULTICHAIN); defineProperty_default()(this, "currentChainNamespace", base_namespaceObject.CHAIN_NAMESPACES.OTHER); defineProperty_default()(this, "type", base_namespaceObject.ADAPTER_CATEGORY.EXTERNAL); defineProperty_default()(this, "adapterOptions", {}); defineProperty_default()(this, "status", base_namespaceObject.ADAPTER_STATUS.NOT_READY); defineProperty_default()(this, "adapterData", { uri: "" }); defineProperty_default()(this, "connector", null); defineProperty_default()(this, "activeSession", null); defineProperty_default()(this, "wcProvider", null); this.adapterOptions = objectSpread2_default()({}, options); this.setAdapterSettings(options); } get connected() { return !!this.activeSession; } get provider() { if (this.status !== base_namespaceObject.ADAPTER_STATUS.NOT_READY && this.wcProvider) { return this.wcProvider; } return null; } set provider(_) { throw new Error("Not implemented"); } async init(options) { var _this$adapterOptions$, _this$chainConfig, _this$chainConfig2; super.checkInitializationRequirements(); const projectId = (_this$adapterOptions$ = this.adapterOptions.adapterSettings) === null || _this$adapterOptions$ === void 0 || (_this$adapterOptions$ = _this$adapterOptions$.walletConnectInitOptions) === null || _this$adapterOptions$ === void 0 ? void 0 : _this$adapterOptions$.projectId; if (!projectId) { throw base_namespaceObject.WalletInitializationError.invalidParams("Wallet connect project id is required in wallet connect v2 adapter"); } const wc2Settings = await getWalletConnectV2Settings((_this$chainConfig = this.chainConfig) === null || _this$chainConfig === void 0 ? void 0 : _this$chainConfig.chainNamespace, [(_this$chainConfig2 = this.chainConfig) === null || _this$chainConfig2 === void 0 ? void 0 : _this$chainConfig2.chainId], projectId); if (!this.adapterOptions.loginSettings || Object.keys(this.adapterOptions.loginSettings).length === 0) { this.adapterOptions.loginSettings = wc2Settings.loginSettings; } this.adapterOptions.adapterSettings = external_deepmerge_default()(wc2Settings.adapterSettings || {}, this.adapterOptions.adapterSettings || {}); const { adapterSettings } = this.adapterOptions; this.connector = await sign_client_default().init(adapterSettings === null || adapterSettings === void 0 ? void 0 : adapterSettings.walletConnectInitOptions); this.wcProvider = new WalletConnectV2Provider({ clientId: this.clientId, config: { chainConfig: this.chainConfig }, connector: this.connector }); this.emit(base_namespaceObject.ADAPTER_EVENTS.READY, base_namespaceObject.WALLET_ADAPTERS.WALLET_CONNECT_V2); this.status = base_namespaceObject.ADAPTER_STATUS.READY; base_namespaceObject.log.debug("initializing wallet connect v2 adapter"); if (options.autoConnect) { await this.checkForPersistedSession(); if (this.connected) { this.rehydrated = true; try { await this.onConnectHandler(); } catch (error) { base_namespaceObject.log.error("wallet auto connect", error); this.emit(base_namespaceObject.ADAPTER_EVENTS.ERRORED, error); } } else { this.status = base_namespaceObject.ADAPTER_STATUS.NOT_READY; this.emit(base_namespaceObject.ADAPTER_EVENTS.CACHE_CLEAR); } } } async connect() { super.checkConnectionRequirements(); if (!this.connector) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); try { // if already connected if (this.connected) { await this.onConnectHandler(); return this.provider; } if (this.status !== base_namespaceObject.ADAPTER_STATUS.CONNECTING) { await this.createNewSession(); } return this.provider; } catch (error) { base_namespaceObject.log.error("Wallet connect v2 adapter error while connecting", error); // ready again to be connected this.status = base_namespaceObject.ADAPTER_STATUS.READY; this.rehydrated = true; this.emit(base_namespaceObject.ADAPTER_EVENTS.ERRORED, error); const finalError = error instanceof base_namespaceObject.Web3AuthError ? error : base_namespaceObject.WalletLoginError.connectionError(`Failed to login with wallet connect: ${(error === null || error === void 0 ? void 0 : error.message) || ""}`, error); throw finalError; } } // should be called only before initialization. setAdapterSettings(adapterSettings) { var _this$adapterOptions$2, _this$adapterOptions, _this$adapterOptions$3, _this$adapterOptions2, _this$adapterOptions$4; super.setAdapterSettings(adapterSettings); const { qrcodeModal, walletConnectInitOptions } = (adapterSettings === null || adapterSettings === void 0 ? void 0 : adapterSettings.adapterSettings) || {}; this.adapterOptions = objectSpread2_default()(objectSpread2_default()({}, this.adapterOptions), {}, { adapterSettings: (_this$adapterOptions$2 = (_this$adapterOptions = this.adapterOptions) === null || _this$adapterOptions === void 0 ? void 0 : _this$adapterOptions.adapterSettings) !== null && _this$adapterOptions$2 !== void 0 ? _this$adapterOptions$2 : {}, loginSettings: (_this$adapterOptions$3 = (_this$adapterOptions2 = this.adapterOptions) === null || _this$adapterOptions2 === void 0 ? void 0 : _this$adapterOptions2.loginSettings) !== null && _this$adapterOptions$3 !== void 0 ? _this$adapterOptions$3 : {} }); if (qrcodeModal) this.adapterOptions.adapterSettings.qrcodeModal = qrcodeModal; if (walletConnectInitOptions) this.adapterOptions.adapterSettings.walletConnectInitOptions = objectSpread2_default()(objectSpread2_default()({}, (_this$adapterOptions$4 = this.adapterOptions.adapterSettings.walletConnectInitOptions) !== null && _this$adapterOptions$4 !== void 0 ? _this$adapterOptions$4 : {}), walletConnectInitOptions); const { loginSettings } = adapterSettings; if (loginSettings) this.adapterOptions.loginSettings = objectSpread2_default()(objectSpread2_default()({}, this.adapterOptions.loginSettings || {}), loginSettings); } async addChain(chainConfig, init = false) { var _this$wcProvider; super.checkAddChainRequirements(chainConfig, init); await ((_this$wcProvider = this.wcProvider) === null || _this$wcProvider === void 0 ? void 0 : _this$wcProvider.addChain(chainConfig)); this.addChainConfig(chainConfig); } async switchChain(params, init = false) { var _this$wcProvider2; super.checkSwitchChainRequirements(params, init); await ((_this$wcProvider2 = this.wcProvider) === null || _this$wcProvider2 === void 0 ? void 0 : _this$wcProvider2.switchChain({ chainId: params.chainId })); this.setAdapterSettings({ chainConfig: this.getChainConfig(params.chainId) }); } async getUserInfo() { if (!this.connected) throw base_namespaceObject.WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first"); return {}; } async disconnect(options = { cleanup: false, sessionRemovedByWallet: false }) { var _this$activeSession, _this$activeSession2; const { cleanup } = options; if (!this.connector || !this.connected || !((_this$activeSession = this.activeSession) !== null && _this$activeSession !== void 0 && _this$activeSession.topic)) throw base_namespaceObject.WalletLoginError.notConnectedError("Not connected with wallet"); if (!options.sessionRemovedByWallet) await this.connector.disconnect({ topic: (_this$activeSession2 = this.activeSession) === null || _this$activeSession2 === void 0 ? void 0 : _this$activeSession2.topic, reason: (0,utils_namespaceObject.getSdkError)("USER_DISCONNECTED") }); this.rehydrated = false; if (cleanup) { this.connector = null; this.status = base_namespaceObject.ADAPTER_STATUS.NOT_READY; this.wcProvider = null; } else { // ready to connect again this.status = base_namespaceObject.ADAPTER_STATUS.READY; } this.activeSession = null; this.emit(base_namespaceObject.ADAPTER_EVENTS.DISCONNECTED); } async authenticateUser() { if (!this.provider || this.status !== base_namespaceObject.ADAPTER_STATUS.CONNECTED) throw base_namespaceObject.WalletLoginError.notConnectedError(); const { chainNamespace, chainId } = this.chainConfig; const accounts = await this.provider.request({ method: chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.EIP155 ? "eth_accounts" : "getAccounts" }); if (accounts && accounts.length > 0) { const existingToken = (0,base_namespaceObject.getSavedToken)(accounts[0], this.name); if (existingToken) { const isExpired = (0,base_namespaceObject.checkIfTokenIsExpired)(existingToken); if (!isExpired) { return { idToken: existingToken }; } } const payload = { domain: window.location.origin, uri: window.location.href, address: accounts[0], chainId: parseInt(chainId, 16), version: "1", nonce: Math.random().toString(36).slice(2), issuedAt: new Date().toISOString() }; const challenge = await (0,base_controllers_namespaceObject.signChallenge)(payload, chainNamespace); const signedMessage = await this._getSignedMessage(challenge, accounts, chainNamespace); const idToken = await (0,base_controllers_namespaceObject.verifySignedChallenge)(chainNamespace, signedMessage, challenge, this.name, this.sessionTime, this.clientId, this.web3AuthNetwork); (0,base_namespaceObject.saveToken)(accounts[0], this.name, idToken); return { idToken }; } throw base_namespaceObject.WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first"); } async enableMFA() { throw new Error("Method Not implemented"); } async manageMFA() { throw new Error("Method Not implemented"); } cleanupPendingPairings() { if (!this.connector) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); const inactivePairings = this.connector.pairing.getAll({ active: false }); if (!(0,utils_namespaceObject.isValidArray)(inactivePairings)) return; inactivePairings.forEach(pairing => { if (this.connector) { this.connector.pairing.delete(pairing.topic, (0,utils_namespaceObject.getSdkError)("USER_DISCONNECTED")); } }); } async checkForPersistedSession() { if (!this.connector) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); if (this.connector.session.length) { const lastKeyIndex = this.connector.session.keys.length - 1; this.activeSession = this.connector.session.get(this.connector.session.keys[lastKeyIndex]); } return this.activeSession; } async createNewSession(opts = { forceNewSession: false }) { try { var _this$activeSession3, _this$adapterOptions3; if (!this.connector) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); if (!this.adapterOptions.loginSettings || Object.keys(this.adapterOptions.loginSettings).length === 0) throw base_namespaceObject.WalletInitializationError.notReady("login settings are not set yet"); this.status = base_namespaceObject.ADAPTER_STATUS.CONNECTING; this.emit(base_namespaceObject.ADAPTER_EVENTS.CONNECTING, { adapter: base_namespaceObject.WALLET_ADAPTERS.WALLET_CONNECT_V2 }); if (opts.forceNewSession && (_this$activeSession3 = this.activeSession) !== null && _this$activeSession3 !== void 0 && _this$activeSession3.topic) { var _this$activeSession4; await this.connector.disconnect({ topic: (_this$activeSession4 = this.activeSession) === null || _this$activeSession4 === void 0 ? void 0 : _this$activeSession4.topic, reason: (0,utils_namespaceObject.getSdkError)("USER_DISCONNECTED") }); } const { uri, approval } = await this.connector.connect(this.adapterOptions.loginSettings); const qrcodeModal = (_this$adapterOptions3 = this.adapterOptions) === null || _this$adapterOptions3 === void 0 || (_this$adapterOptions3 = _this$adapterOptions3.adapterSettings) === null || _this$adapterOptions3 === void 0 ? void 0 : _this$adapterOptions3.qrcodeModal; // Open QRCode modal if a URI was returned (i.e. we're not connecting with an existing pairing). if (uri) { if (qrcodeModal) { try { await qrcodeModal.openModal({ uri }); base_namespaceObject.log.debug("EVENT", "QR Code Modal closed"); this.status = base_namespaceObject.ADAPTER_STATUS.READY; this.emit(base_namespaceObject.ADAPTER_EVENTS.READY, base_namespaceObject.WALLET_ADAPTERS.WALLET_CONNECT_V2); } catch (error) { base_namespaceObject.log.error("unable to open qr code modal"); } } else { this.updateAdapterData({ uri }); } } base_namespaceObject.log.info("awaiting session approval from wallet"); // Await session approval from the wallet. const session = await approval(); this.activeSession = session; // Handle the returned session (e.g. update UI to "connected" state). await this.onConnectHandler(); if (qrcodeModal) { qrcodeModal.closeModal(); } } catch (error) { var _message; if ((_message = error.message) !== null && _message !== void 0 && _message.toLowerCase().includes("proposal expired")) { // Retry if adapter status is still connecting base_namespaceObject.log.info("current adapter status: ", this.status); if (this.status === base_namespaceObject.ADAPTER_STATUS.CONNECTING) { base_namespaceObject.log.info("retrying to create new wallet connect session since proposal expired"); return this.createNewSession({ forceNewSession: true }); } if (this.status === base_namespaceObject.ADAPTER_STATUS.READY) { base_namespaceObject.log.info("ignoring proposal expired error since some other adapter is connected"); return; } } base_namespaceObject.log.error("error while creating new wallet connect session", error); this.emit(base_namespaceObject.ADAPTER_EVENTS.ERRORED, error); throw error; } } async onConnectHandler() { var _this$adapterOptions$5; if (!this.connector || !this.wcProvider) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); if (!this.chainConfig) throw base_namespaceObject.WalletInitializationError.invalidParams("Chain config is not set"); this.subscribeEvents(); if ((_this$adapterOptions$5 = this.adapterOptions.adapterSettings) !== null && _this$adapterOptions$5 !== void 0 && _this$adapterOptions$5.qrcodeModal) { this.wcProvider = new WalletConnectV2Provider({ clientId: this.clientId, config: { chainConfig: this.chainConfig, skipLookupNetwork: true }, connector: this.connector }); } await this.wcProvider.setupProvider(this.connector); this.cleanupPendingPairings(); this.status = base_namespaceObject.ADAPTER_STATUS.CONNECTED; this.emit(base_namespaceObject.ADAPTER_EVENTS.CONNECTED, { adapter: base_namespaceObject.WALLET_ADAPTERS.WALLET_CONNECT_V2, reconnected: this.rehydrated, provider: this.provider }); } subscribeEvents() { if (!this.connector) throw base_namespaceObject.WalletInitializationError.notReady("Wallet adapter is not ready yet"); this.connector.events.on("session_update", ({ topic, params }) => { if (!this.connector) return; const { namespaces } = params; const _session = this.connector.session.get(topic); // Overwrite the `namespaces` of the existing session with the incoming one. const updatedSession = objectSpread2_default()(objectSpread2_default()({}, _session), {}, { namespaces }); // Integrate the updated session state into your dapp state. this.activeSession = updatedSession; }); this.connector.events.on("session_delete", () => { // Session was deleted -> reset the dapp state, clean up from user session, etc. this.disconnect({ sessionRemovedByWallet: true }); }); } async _getSignedMessage(challenge, accounts, chainNamespace) { const signedMessage = await this.provider.request({ method: chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.EIP155 ? "personal_sign" : "signMessage", params: chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.EIP155 ? [challenge, accounts[0]] : { message: Buffer.from(challenge) } }); if (chainNamespace === base_namespaceObject.CHAIN_NAMESPACES.SOLANA) return external_bs58_default().encode(signedMessage); return signedMessage; } } ;// ./src/index.ts module.exports = __webpack_exports__; /******/ })() ;