UNPKG

@walletconnect/modal-core

Version:

#### 🔎 [Examples](https://github.com/WalletConnect/web3modal-examples)

536 lines (524 loc) • 17.2 kB
import { proxy, subscribe, snapshot } from 'valtio/vanilla'; const state$7 = proxy({ history: ["ConnectWallet"], view: "ConnectWallet", data: void 0 }); const RouterCtrl = { state: state$7, subscribe(callback) { return subscribe(state$7, () => callback(state$7)); }, push(view, data) { if (view !== state$7.view) { state$7.view = view; if (data) { state$7.data = data; } state$7.history.push(view); } }, reset(view) { state$7.view = view; state$7.history = [view]; }, replace(view) { if (state$7.history.length > 1) { state$7.history[state$7.history.length - 1] = view; state$7.view = view; } }, goBack() { if (state$7.history.length > 1) { state$7.history.pop(); const [last] = state$7.history.slice(-1); state$7.view = last; } }, setData(data) { state$7.data = data; } }; const CoreUtil = { WALLETCONNECT_DEEPLINK_CHOICE: "WALLETCONNECT_DEEPLINK_CHOICE", WCM_VERSION: "WCM_VERSION", RECOMMENDED_WALLET_AMOUNT: 9, isMobile() { if (typeof window !== "undefined") { return Boolean( window.matchMedia("(pointer:coarse)").matches || /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini/u.test(navigator.userAgent) ); } return false; }, isAndroid() { return CoreUtil.isMobile() && navigator.userAgent.toLowerCase().includes("android"); }, isIos() { const ua = navigator.userAgent.toLowerCase(); return CoreUtil.isMobile() && (ua.includes("iphone") || ua.includes("ipad")); }, isHttpUrl(url) { return url.startsWith("http://") || url.startsWith("https://"); }, isArray(data) { return Array.isArray(data) && data.length > 0; }, isTelegram() { return typeof window !== "undefined" && // eslint-disable-next-line @typescript-eslint/no-explicit-any (Boolean(window.TelegramWebviewProxy) || // eslint-disable-next-line @typescript-eslint/no-explicit-any Boolean(window.Telegram) || // eslint-disable-next-line @typescript-eslint/no-explicit-any Boolean(window.TelegramWebviewProxyProto)); }, formatNativeUrl(appUrl, wcUri, name) { if (CoreUtil.isHttpUrl(appUrl)) { return this.formatUniversalUrl(appUrl, wcUri, name); } let safeAppUrl = appUrl; if (!safeAppUrl.includes("://")) { safeAppUrl = appUrl.replaceAll("/", "").replaceAll(":", ""); safeAppUrl = `${safeAppUrl}://`; } if (!safeAppUrl.endsWith("/")) { safeAppUrl = `${safeAppUrl}/`; } this.setWalletConnectDeepLink(safeAppUrl, name); const encodedWcUrl = encodeURIComponent(wcUri); return `${safeAppUrl}wc?uri=${encodedWcUrl}`; }, formatUniversalUrl(appUrl, wcUri, name) { if (!CoreUtil.isHttpUrl(appUrl)) { return this.formatNativeUrl(appUrl, wcUri, name); } let safeAppUrl = appUrl; if (safeAppUrl.startsWith("https://t.me")) { const formattedUri = Buffer.from(wcUri).toString("base64").replace(/[=]/g, ""); if (safeAppUrl.endsWith("/")) { safeAppUrl = safeAppUrl.slice(0, -1); } this.setWalletConnectDeepLink(safeAppUrl, name); const url = new URL(safeAppUrl); url.searchParams.set("startapp", formattedUri); const link = url.toString(); return link; } if (!safeAppUrl.endsWith("/")) { safeAppUrl = `${safeAppUrl}/`; } this.setWalletConnectDeepLink(safeAppUrl, name); const encodedWcUrl = encodeURIComponent(wcUri); return `${safeAppUrl}wc?uri=${encodedWcUrl}`; }, async wait(miliseconds) { return new Promise((resolve) => { setTimeout(resolve, miliseconds); }); }, openHref(href, target) { const adjustedTarget = this.isTelegram() ? "_blank" : target; window.open(href, adjustedTarget, "noreferrer noopener"); }, setWalletConnectDeepLink(href, name) { try { localStorage.setItem(CoreUtil.WALLETCONNECT_DEEPLINK_CHOICE, JSON.stringify({ href, name })); } catch (e) { console.info("Unable to set WalletConnect deep link"); } }, setWalletConnectAndroidDeepLink(wcUri) { try { const [href] = wcUri.split("?"); localStorage.setItem( CoreUtil.WALLETCONNECT_DEEPLINK_CHOICE, JSON.stringify({ href, name: "Android" }) ); } catch (e) { console.info("Unable to set WalletConnect android deep link"); } }, removeWalletConnectDeepLink() { try { localStorage.removeItem(CoreUtil.WALLETCONNECT_DEEPLINK_CHOICE); } catch (e) { console.info("Unable to remove WalletConnect deep link"); } }, setModalVersionInStorage() { try { if (typeof localStorage !== "undefined") { localStorage.setItem(CoreUtil.WCM_VERSION, "2.7.0"); } } catch (e) { console.info("Unable to set Web3Modal version in storage"); } }, getWalletRouterData() { var _a; const routerData = (_a = RouterCtrl.state.data) == null ? void 0 : _a.Wallet; if (!routerData) { throw new Error('Missing "Wallet" view data'); } return routerData; } }; const isEnabled = typeof location !== "undefined" && (location.hostname.includes("localhost") || location.protocol.includes("https")); const state$6 = proxy({ enabled: isEnabled, userSessionId: "", events: [], connectedWalletId: void 0 }); const EventsCtrl = { state: state$6, subscribe(callback) { return subscribe(state$6.events, () => callback(snapshot(state$6.events[state$6.events.length - 1]))); }, initialize() { if (state$6.enabled && typeof (crypto == null ? void 0 : crypto.randomUUID) !== "undefined") { state$6.userSessionId = crypto.randomUUID(); } }, setConnectedWalletId(connectedWalletId) { state$6.connectedWalletId = connectedWalletId; }, click(data) { if (state$6.enabled) { const event = { type: "CLICK", name: data.name, userSessionId: state$6.userSessionId, timestamp: Date.now(), data }; state$6.events.push(event); } }, track(data) { if (state$6.enabled) { const event = { type: "TRACK", name: data.name, userSessionId: state$6.userSessionId, timestamp: Date.now(), data }; state$6.events.push(event); } }, view(data) { if (state$6.enabled) { const event = { type: "VIEW", name: data.name, userSessionId: state$6.userSessionId, timestamp: Date.now(), data }; state$6.events.push(event); } } }; const state$5 = proxy({ chains: void 0, walletConnectUri: void 0, isAuth: false, isCustomDesktop: false, isCustomMobile: false, isDataLoaded: false, isUiLoaded: false }); const OptionsCtrl = { state: state$5, subscribe(callback) { return subscribe(state$5, () => callback(state$5)); }, setChains(chains) { state$5.chains = chains; }, setWalletConnectUri(walletConnectUri) { state$5.walletConnectUri = walletConnectUri; }, setIsCustomDesktop(isCustomDesktop) { state$5.isCustomDesktop = isCustomDesktop; }, setIsCustomMobile(isCustomMobile) { state$5.isCustomMobile = isCustomMobile; }, setIsDataLoaded(isDataLoaded) { state$5.isDataLoaded = isDataLoaded; }, setIsUiLoaded(isUiLoaded) { state$5.isUiLoaded = isUiLoaded; }, setIsAuth(isAuth) { state$5.isAuth = isAuth; } }; const state$4 = proxy({ projectId: "", mobileWallets: void 0, desktopWallets: void 0, walletImages: void 0, chains: void 0, enableAuthMode: false, enableExplorer: true, explorerExcludedWalletIds: void 0, explorerRecommendedWalletIds: void 0, termsOfServiceUrl: void 0, privacyPolicyUrl: void 0 }); const ConfigCtrl = { state: state$4, subscribe(callback) { return subscribe(state$4, () => callback(state$4)); }, setConfig(config) { var _a, _b; EventsCtrl.initialize(); OptionsCtrl.setChains(config.chains); OptionsCtrl.setIsAuth(Boolean(config.enableAuthMode)); OptionsCtrl.setIsCustomMobile(Boolean((_a = config.mobileWallets) == null ? void 0 : _a.length)); OptionsCtrl.setIsCustomDesktop(Boolean((_b = config.desktopWallets) == null ? void 0 : _b.length)); CoreUtil.setModalVersionInStorage(); Object.assign(state$4, config); } }; var __defProp$2 = Object.defineProperty; var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols; var __hasOwnProp$2 = Object.prototype.hasOwnProperty; var __propIsEnum$2 = Object.prototype.propertyIsEnumerable; var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$2 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]); if (__getOwnPropSymbols$2) for (var prop of __getOwnPropSymbols$2(b)) { if (__propIsEnum$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]); } return a; }; const W3M_API = "https://explorer-api.walletconnect.com"; const SDK_TYPE = "wcm"; const SDK_VERSION = `js-${"2.7.0"}`; async function fetchListings(endpoint, params) { const allParams = __spreadValues$2({ sdkType: SDK_TYPE, sdkVersion: SDK_VERSION }, params); const url = new URL(endpoint, W3M_API); url.searchParams.append("projectId", ConfigCtrl.state.projectId); Object.entries(allParams).forEach(([key, value]) => { if (value) { url.searchParams.append(key, String(value)); } }); const request = await fetch(url); return request.json(); } const ExplorerUtil = { async getDesktopListings(params) { return fetchListings("/w3m/v1/getDesktopListings", params); }, async getMobileListings(params) { return fetchListings("/w3m/v1/getMobileListings", params); }, async getInjectedListings(params) { return fetchListings("/w3m/v1/getInjectedListings", params); }, async getAllListings(params) { return fetchListings("/w3m/v1/getAllListings", params); }, getWalletImageUrl(imageId) { return `${W3M_API}/w3m/v1/getWalletImage/${imageId}?projectId=${ConfigCtrl.state.projectId}&sdkType=${SDK_TYPE}&sdkVersion=${SDK_VERSION}`; }, getAssetImageUrl(imageId) { return `${W3M_API}/w3m/v1/getAssetImage/${imageId}?projectId=${ConfigCtrl.state.projectId}&sdkType=${SDK_TYPE}&sdkVersion=${SDK_VERSION}`; } }; var __defProp$1 = Object.defineProperty; var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols; var __hasOwnProp$1 = Object.prototype.hasOwnProperty; var __propIsEnum$1 = Object.prototype.propertyIsEnumerable; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$1 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]); if (__getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(b)) { if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]); } return a; }; const isMobile = CoreUtil.isMobile(); const state$3 = proxy({ wallets: { listings: [], total: 0, page: 1 }, search: { listings: [], total: 0, page: 1 }, recomendedWallets: [] }); const ExplorerCtrl = { state: state$3, async getRecomendedWallets() { const { explorerRecommendedWalletIds, explorerExcludedWalletIds } = ConfigCtrl.state; if (explorerRecommendedWalletIds === "NONE" || explorerExcludedWalletIds === "ALL" && !explorerRecommendedWalletIds) { return state$3.recomendedWallets; } if (CoreUtil.isArray(explorerRecommendedWalletIds)) { const recommendedIds = explorerRecommendedWalletIds.join(","); const params = { recommendedIds }; const { listings } = await ExplorerUtil.getAllListings(params); const listingsArr = Object.values(listings); listingsArr.sort((a, b) => { const aIndex = explorerRecommendedWalletIds.indexOf(a.id); const bIndex = explorerRecommendedWalletIds.indexOf(b.id); return aIndex - bIndex; }); state$3.recomendedWallets = listingsArr; } else { const { chains, isAuth } = OptionsCtrl.state; const chainsFilter = chains == null ? void 0 : chains.join(","); const isExcluded = CoreUtil.isArray(explorerExcludedWalletIds); const params = { page: 1, sdks: isAuth ? "auth_v1" : void 0, entries: CoreUtil.RECOMMENDED_WALLET_AMOUNT, chains: chainsFilter, version: 2, excludedIds: isExcluded ? explorerExcludedWalletIds.join(",") : void 0 }; const { listings } = isMobile ? await ExplorerUtil.getMobileListings(params) : await ExplorerUtil.getDesktopListings(params); state$3.recomendedWallets = Object.values(listings); } return state$3.recomendedWallets; }, async getWallets(params) { const extendedParams = __spreadValues$1({}, params); const { explorerRecommendedWalletIds, explorerExcludedWalletIds } = ConfigCtrl.state; const { recomendedWallets } = state$3; if (explorerExcludedWalletIds === "ALL") { return state$3.wallets; } if (recomendedWallets.length) { extendedParams.excludedIds = recomendedWallets.map((wallet) => wallet.id).join(","); } else if (CoreUtil.isArray(explorerRecommendedWalletIds)) { extendedParams.excludedIds = explorerRecommendedWalletIds.join(","); } if (CoreUtil.isArray(explorerExcludedWalletIds)) { extendedParams.excludedIds = [extendedParams.excludedIds, explorerExcludedWalletIds].filter(Boolean).join(","); } if (OptionsCtrl.state.isAuth) { extendedParams.sdks = "auth_v1"; } const { page, search } = params; const { listings: listingsObj, total } = isMobile ? await ExplorerUtil.getMobileListings(extendedParams) : await ExplorerUtil.getDesktopListings(extendedParams); const listings = Object.values(listingsObj); const type = search ? "search" : "wallets"; state$3[type] = { listings: [...state$3[type].listings, ...listings], total, page: page != null ? page : 1 }; return { listings, total }; }, getWalletImageUrl(imageId) { return ExplorerUtil.getWalletImageUrl(imageId); }, getAssetImageUrl(imageId) { return ExplorerUtil.getAssetImageUrl(imageId); }, resetSearch() { state$3.search = { listings: [], total: 0, page: 1 }; } }; const state$2 = proxy({ open: false }); const ModalCtrl = { state: state$2, subscribe(callback) { return subscribe(state$2, () => callback(state$2)); }, async open(options) { return new Promise((resolve) => { const { isUiLoaded, isDataLoaded } = OptionsCtrl.state; CoreUtil.removeWalletConnectDeepLink(); OptionsCtrl.setWalletConnectUri(options == null ? void 0 : options.uri); OptionsCtrl.setChains(options == null ? void 0 : options.chains); RouterCtrl.reset("ConnectWallet"); if (isUiLoaded && isDataLoaded) { state$2.open = true; resolve(); } else { const interval = setInterval(() => { const opts = OptionsCtrl.state; if (opts.isUiLoaded && opts.isDataLoaded) { clearInterval(interval); state$2.open = true; resolve(); } }, 200); } }); }, close() { state$2.open = false; } }; var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; function isDarkMode() { return typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)").matches; } const state$1 = proxy({ themeMode: isDarkMode() ? "dark" : "light" }); const ThemeCtrl = { state: state$1, subscribe(callback) { return subscribe(state$1, () => callback(state$1)); }, setThemeConfig(theme) { const { themeMode, themeVariables } = theme; if (themeMode) { state$1.themeMode = themeMode; } if (themeVariables) { state$1.themeVariables = __spreadValues({}, themeVariables); } } }; const state = proxy({ open: false, message: "", variant: "success" }); const ToastCtrl = { state, subscribe(callback) { return subscribe(state, () => callback(state)); }, openToast(message, variant) { state.open = true; state.message = message; state.variant = variant; }, closeToast() { state.open = false; } }; export { ConfigCtrl, CoreUtil, EventsCtrl, ExplorerCtrl, ModalCtrl, OptionsCtrl, RouterCtrl, ThemeCtrl, ToastCtrl }; //# sourceMappingURL=index.js.map