@web3auth/wallet-connect-v2-adapter
Version:
wallet connect v2 adapter for web3auth
1,134 lines (1,087 loc) • 46.5 kB
JavaScript
/******/ (() => { // 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__;
/******/ })()
;