UNPKG

sui-svelte-wallet-kit

Version:

Svelte 5 wallet kit for Sui: connect wallets, manage accounts, SuiNS, balance, sign transactions/messages

178 lines (177 loc) 6.38 kB
import { AllDefaultWallets, WalletRadar } from '@suiet/wallet-sdk'; import { getWallets } from '@wallet-standard/core'; // Browser guard const isBrowser = typeof window !== 'undefined'; // Debug toggle export const isDiscoveryDebugEnabled = () => { if (!isBrowser) return false; try { return window.localStorage.getItem('sui-wallet-kit-debug') === '1'; } catch { return false; } }; // Adapter detection export const uniqueAdaptersByName = (adapters) => { const map = new Map(); for (const a of adapters || []) { if (!a || !a.name) continue; if (!map.has(a.name)) map.set(a.name, a); } return Array.from(map.values()); }; export const detectWalletAdapters = () => { if (!isBrowser) return []; const walletRadar = new WalletRadar(); walletRadar.activate(); const radarAdapters = walletRadar.getDetectedWalletAdapters(); let registryWallets = []; try { const registry = getWallets?.(); if (registry && typeof registry.get === 'function') { registryWallets = registry.get() || []; } } catch { } walletRadar.deactivate(); return uniqueAdaptersByName([...(radarAdapters || []), ...Array.from(registryWallets || [])]); }; // Wallet list construction const normalizeWalletName = (name) => (name || '') .toLowerCase() .replace(/wallet$/g, '') .replace(/[^a-z0-9]/g, ''); const applyWalletConfig = (wallets, config) => { const { customNames = {}, ordering = [] } = config; const walletsWithCustomNames = wallets.map((wallet) => { const customName = customNames[wallet.name]; return customName ? { ...wallet, displayName: customName, originalName: wallet.name } : wallet; }); const result = ordering.length > 0 ? walletsWithCustomNames.sort((a, b) => { const aName = a.originalName || a.name; const bName = b.originalName || b.name; const aIndex = ordering.indexOf(aName); const bIndex = ordering.indexOf(bName); if (aIndex !== -1 && bIndex !== -1) { return aIndex - bIndex; } if (aIndex !== -1) return -1; if (bIndex !== -1) return 1; return aName.localeCompare(bName); }) : walletsWithCustomNames; return result; }; export const getAvailableWallets = (defaultWallets, detectedAdapters, config = {}) => { const adapters = Array.isArray(detectedAdapters) ? detectedAdapters : detectWalletAdapters(); const list = defaultWallets.map((item) => { const normalizedItem = normalizeWalletName(item.name); const foundAdapter = adapters.find((walletAdapter) => { const normalizedAdapter = normalizeWalletName(walletAdapter.name); return (normalizedItem.includes(normalizedAdapter) || normalizedAdapter.includes(normalizedItem)); }); return { ...item, name: item.name, iconUrl: item.iconUrl, adapter: foundAdapter ? foundAdapter : undefined, installed: !!foundAdapter }; }); const defaultNormalizedNames = defaultWallets.map((w) => normalizeWalletName(w.name)); const extraAdapters = adapters.filter((a) => { const na = normalizeWalletName(a.name); return !defaultNormalizedNames.some((dn) => dn.includes(na) || na.includes(dn)); }); const extraWalletEntries = extraAdapters.map((a) => ({ name: a.name, originalName: a.name, displayName: a.name, iconUrl: typeof a.icon === 'string' ? a.icon : undefined, adapter: a, installed: true })); return applyWalletConfig([...list, ...extraWalletEntries], config); }; const _discoverySubscribers = new Set(); export const subscribeWalletDiscovery = (callback) => { if (typeof callback !== 'function') return () => { }; _discoverySubscribers.add(callback); return () => { _discoverySubscribers.delete(callback); }; }; export const notifyDiscoverySubscribers = (adapters, wallets) => { try { for (const cb of _discoverySubscribers) { try { cb(adapters, wallets); } catch { } } } catch { } }; export const setModuleWalletDiscovery = (adapters, wallets, targetAdapters, targetWallets) => { const nextAdapters = Array.isArray(adapters) ? adapters : []; const nextWallets = Array.isArray(wallets) ? wallets : []; targetAdapters.length = 0; targetAdapters.push(...nextAdapters); targetWallets.length = 0; targetWallets.push(...nextWallets); notifyDiscoverySubscribers(targetAdapters, targetWallets); }; let _lastDiscoveryLogKey = ''; let _lastAvailableLogKey = ''; let _discoveryAttempt = 0; export const refreshDiscoverySnapshot = (attemptLabel, walletConfig) => { const snapshot = uniqueAdaptersByName(detectWalletAdapters()); try { const adapterNames = snapshot .map((a) => a?.name) .filter(Boolean) .sort(); const key = adapterNames.join('|'); if (key !== _lastDiscoveryLogKey) { _lastDiscoveryLogKey = key; if (isDiscoveryDebugEnabled()) { const ts = new Date().toISOString(); console.log(`[SuiModule] [${ts}] [attempt:${attemptLabel ?? '-'}] Detected adapters:`, adapterNames); } } } catch { } const wallets = getAvailableWallets(AllDefaultWallets, snapshot, walletConfig); try { const walletNames = wallets .map((w) => w?.name) .filter(Boolean) .sort(); const wkey = walletNames.join('|'); if (wkey !== _lastAvailableLogKey) { _lastAvailableLogKey = wkey; if (isDiscoveryDebugEnabled()) { const ts = new Date().toISOString(); console.log(`[SuiModule] [${ts}] [attempt:${attemptLabel ?? '-'}] Available wallets:`, walletNames); } } } catch { } return { adapters: snapshot, wallets }; }; export const getDiscoveryAttempt = () => { return _discoveryAttempt; }; export const incrementDiscoveryAttempt = () => { _discoveryAttempt += 1; return _discoveryAttempt; };