UNPKG

@reown/appkit-controllers

Version:

#### 🔗 [Website](https://reown.com/appkit)

628 lines • 23.3 kB
/* eslint-disable no-console */ import { ConstantsUtil as CommonConstantsUtil, SafeLocalStorage, SafeLocalStorageKeys, getSafeConnectorIdKey } from '@reown/appkit-common'; // -- Utility ----------------------------------------------------------------- export const StorageUtil = { // Cache expiry in milliseconds cacheExpiry: { portfolio: 30000, nativeBalance: 30000, ens: 300000, identity: 300000 }, isCacheExpired(timestamp, cacheExpiry) { return Date.now() - timestamp > cacheExpiry; }, getActiveNetworkProps() { const namespace = StorageUtil.getActiveNamespace(); const caipNetworkId = StorageUtil.getActiveCaipNetworkId(); const stringChainId = caipNetworkId ? caipNetworkId.split(':')[1] : undefined; // eslint-disable-next-line no-nested-ternary const chainId = stringChainId ? isNaN(Number(stringChainId)) ? stringChainId : Number(stringChainId) : undefined; return { namespace, caipNetworkId, chainId }; }, setWalletConnectDeepLink({ name, href }) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, JSON.stringify({ href, name })); } catch { console.info('Unable to set WalletConnect deep link'); } }, getWalletConnectDeepLink() { try { const deepLink = SafeLocalStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE); if (deepLink) { return JSON.parse(deepLink); } } catch { console.info('Unable to get WalletConnect deep link'); } return undefined; }, deleteWalletConnectDeepLink() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE); } catch { console.info('Unable to delete WalletConnect deep link'); } }, setActiveNamespace(namespace) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_NAMESPACE, namespace); } catch { console.info('Unable to set active namespace'); } }, setActiveCaipNetworkId(caipNetworkId) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID, caipNetworkId); StorageUtil.setActiveNamespace(caipNetworkId.split(':')[0]); } catch { console.info('Unable to set active caip network id'); } }, getActiveCaipNetworkId() { try { return SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID); } catch { console.info('Unable to get active caip network id'); return undefined; } }, deleteActiveCaipNetworkId() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID); } catch { console.info('Unable to delete active caip network id'); } }, deleteConnectedConnectorId(namespace) { try { const key = getSafeConnectorIdKey(namespace); SafeLocalStorage.removeItem(key); } catch { console.info('Unable to delete connected connector id'); } }, setAppKitRecent(wallet) { try { const recentWallets = StorageUtil.getRecentWallets(); const exists = recentWallets.find(w => w.id === wallet.id); if (!exists) { recentWallets.unshift(wallet); if (recentWallets.length > 2) { recentWallets.pop(); } SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)); } } catch { console.info('Unable to set AppKit recent'); } }, getRecentWallets() { try { const recent = SafeLocalStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS); return recent ? JSON.parse(recent) : []; } catch { console.info('Unable to get AppKit recent'); } return []; }, setConnectedConnectorId(namespace, connectorId) { try { const key = getSafeConnectorIdKey(namespace); SafeLocalStorage.setItem(key, connectorId); } catch { console.info('Unable to set Connected Connector Id'); } }, getActiveNamespace() { try { const activeNamespace = SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_NAMESPACE); return activeNamespace; } catch { console.info('Unable to get active namespace'); } return undefined; }, getConnectedConnectorId(namespace) { if (!namespace) { return undefined; } try { const key = getSafeConnectorIdKey(namespace); return SafeLocalStorage.getItem(key); } catch (e) { console.info('Unable to get connected connector id in namespace', namespace); } return undefined; }, setConnectedSocialProvider(socialProvider) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider); } catch { console.info('Unable to set connected social provider'); } }, getConnectedSocialProvider() { try { return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL); } catch { console.info('Unable to get connected social provider'); } return undefined; }, deleteConnectedSocialProvider() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.CONNECTED_SOCIAL); } catch { console.info('Unable to delete connected social provider'); } }, getConnectedSocialUsername() { try { return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME); } catch { console.info('Unable to get connected social username'); } return undefined; }, getStoredActiveCaipNetworkId() { const storedCaipNetworkId = SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID); const networkId = storedCaipNetworkId?.split(':')?.[1]; return networkId; }, setConnectionStatus(status) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTION_STATUS, status); } catch { console.info('Unable to set connection status'); } }, getConnectionStatus() { try { return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTION_STATUS); } catch { return undefined; } }, getConnectedNamespaces() { try { const namespaces = SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_NAMESPACES); if (!namespaces?.length) { return []; } return namespaces.split(','); } catch { return []; } }, setConnectedNamespaces(namespaces) { try { const uniqueNamespaces = Array.from(new Set(namespaces)); SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_NAMESPACES, uniqueNamespaces.join(',')); } catch { console.info('Unable to set namespaces in storage'); } }, addConnectedNamespace(namespace) { try { const namespaces = StorageUtil.getConnectedNamespaces(); if (!namespaces.includes(namespace)) { namespaces.push(namespace); StorageUtil.setConnectedNamespaces(namespaces); } } catch { console.info('Unable to add connected namespace'); } }, removeConnectedNamespace(namespace) { try { const namespaces = StorageUtil.getConnectedNamespaces(); const index = namespaces.indexOf(namespace); if (index > -1) { namespaces.splice(index, 1); StorageUtil.setConnectedNamespaces(namespaces); } } catch { console.info('Unable to remove connected namespace'); } }, getTelegramSocialProvider() { try { return SafeLocalStorage.getItem(SafeLocalStorageKeys.TELEGRAM_SOCIAL_PROVIDER); } catch { console.info('Unable to get telegram social provider'); return null; } }, setTelegramSocialProvider(socialProvider) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.TELEGRAM_SOCIAL_PROVIDER, socialProvider); } catch { console.info('Unable to set telegram social provider'); } }, removeTelegramSocialProvider() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.TELEGRAM_SOCIAL_PROVIDER); } catch { console.info('Unable to remove telegram social provider'); } }, getBalanceCache() { let cache = {}; try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.PORTFOLIO_CACHE); cache = result ? JSON.parse(result) : {}; } catch { console.info('Unable to get balance cache'); } return cache; }, removeAddressFromBalanceCache(caipAddress) { try { const cache = StorageUtil.getBalanceCache(); SafeLocalStorage.setItem(SafeLocalStorageKeys.PORTFOLIO_CACHE, JSON.stringify({ ...cache, [caipAddress]: undefined })); } catch { console.info('Unable to remove address from balance cache', caipAddress); } }, getBalanceCacheForCaipAddress(caipAddress) { try { const cache = StorageUtil.getBalanceCache(); const balanceCache = cache[caipAddress]; // We want to discard cache if it's older than the cache expiry if (balanceCache && !this.isCacheExpired(balanceCache.timestamp, this.cacheExpiry.portfolio)) { return balanceCache.balance; } StorageUtil.removeAddressFromBalanceCache(caipAddress); } catch { console.info('Unable to get balance cache for address', caipAddress); } return undefined; }, updateBalanceCache(params) { try { const cache = StorageUtil.getBalanceCache(); cache[params.caipAddress] = params; SafeLocalStorage.setItem(SafeLocalStorageKeys.PORTFOLIO_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update balance cache', params); } }, getNativeBalanceCache() { let cache = {}; try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.NATIVE_BALANCE_CACHE); cache = result ? JSON.parse(result) : {}; } catch { console.info('Unable to get balance cache'); } return cache; }, removeAddressFromNativeBalanceCache(caipAddress) { try { const cache = StorageUtil.getBalanceCache(); SafeLocalStorage.setItem(SafeLocalStorageKeys.NATIVE_BALANCE_CACHE, JSON.stringify({ ...cache, [caipAddress]: undefined })); } catch { console.info('Unable to remove address from balance cache', caipAddress); } }, getNativeBalanceCacheForCaipAddress(caipAddress) { try { const cache = StorageUtil.getNativeBalanceCache(); const nativeBalanceCache = cache[caipAddress]; // We want to discard cache if it's older than the cache expiry if (nativeBalanceCache && !this.isCacheExpired(nativeBalanceCache.timestamp, this.cacheExpiry.nativeBalance)) { return nativeBalanceCache; } console.info('Discarding cache for address', caipAddress); StorageUtil.removeAddressFromBalanceCache(caipAddress); } catch { console.info('Unable to get balance cache for address', caipAddress); } return undefined; }, updateNativeBalanceCache(params) { try { const cache = StorageUtil.getNativeBalanceCache(); cache[params.caipAddress] = params; SafeLocalStorage.setItem(SafeLocalStorageKeys.NATIVE_BALANCE_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update balance cache', params); } }, getEnsCache() { let cache = {}; try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.ENS_CACHE); cache = result ? JSON.parse(result) : {}; } catch { console.info('Unable to get ens name cache'); } return cache; }, getEnsFromCacheForAddress(address) { try { const cache = StorageUtil.getEnsCache(); const ensCache = cache[address]; // We want to discard cache if it's older than the cache expiry if (ensCache && !this.isCacheExpired(ensCache.timestamp, this.cacheExpiry.ens)) { return ensCache.ens; } StorageUtil.removeEnsFromCache(address); } catch { console.info('Unable to get ens name from cache', address); } return undefined; }, updateEnsCache(params) { try { const cache = StorageUtil.getEnsCache(); cache[params.address] = params; SafeLocalStorage.setItem(SafeLocalStorageKeys.ENS_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update ens name cache', params); } }, removeEnsFromCache(address) { try { const cache = StorageUtil.getEnsCache(); SafeLocalStorage.setItem(SafeLocalStorageKeys.ENS_CACHE, JSON.stringify({ ...cache, [address]: undefined })); } catch { console.info('Unable to remove ens name from cache', address); } }, getIdentityCache() { let cache = {}; try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.IDENTITY_CACHE); cache = result ? JSON.parse(result) : {}; } catch { console.info('Unable to get identity cache'); } return cache; }, getIdentityFromCacheForAddress(address) { try { const cache = StorageUtil.getIdentityCache(); const identityCache = cache[address]; // We want to discard cache if it's older than the cache expiry if (identityCache && !this.isCacheExpired(identityCache.timestamp, this.cacheExpiry.identity)) { return identityCache.identity; } StorageUtil.removeIdentityFromCache(address); } catch { console.info('Unable to get identity from cache', address); } return undefined; }, updateIdentityCache(params) { try { const cache = StorageUtil.getIdentityCache(); cache[params.address] = { identity: params.identity, timestamp: params.timestamp }; SafeLocalStorage.setItem(SafeLocalStorageKeys.IDENTITY_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update identity cache', params); } }, removeIdentityFromCache(address) { try { const cache = StorageUtil.getIdentityCache(); SafeLocalStorage.setItem(SafeLocalStorageKeys.IDENTITY_CACHE, JSON.stringify({ ...cache, [address]: undefined })); } catch { console.info('Unable to remove identity from cache', address); } }, clearAddressCache() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.PORTFOLIO_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.NATIVE_BALANCE_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.ENS_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.IDENTITY_CACHE); } catch { console.info('Unable to clear address cache'); } }, setPreferredAccountTypes(accountTypes) { try { SafeLocalStorage.setItem(SafeLocalStorageKeys.PREFERRED_ACCOUNT_TYPES, JSON.stringify(accountTypes)); } catch { console.info('Unable to set preferred account types', accountTypes); } }, getPreferredAccountTypes() { try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.PREFERRED_ACCOUNT_TYPES); if (!result) { return {}; } return JSON.parse(result); } catch { console.info('Unable to get preferred account types'); } return {}; }, setConnections(connections, chainNamespace) { try { const existingConnections = StorageUtil.getConnections(); const existing = existingConnections[chainNamespace] ?? []; const connectorConnectionMap = new Map(); for (const conn of existing) { connectorConnectionMap.set(conn.connectorId, { ...conn }); } for (const conn of connections) { const existingConn = connectorConnectionMap.get(conn.connectorId); const isAuth = conn.connectorId === CommonConstantsUtil.CONNECTOR_ID.AUTH; if (existingConn && !isAuth) { const existingAddrs = new Set(existingConn.accounts.map(a => a.address.toLowerCase())); const newAccounts = conn.accounts.filter(a => !existingAddrs.has(a.address.toLowerCase())); existingConn.accounts.push(...newAccounts); } else { connectorConnectionMap.set(conn.connectorId, { ...conn }); } } const dedupedConnections = { ...existingConnections, [chainNamespace]: Array.from(connectorConnectionMap.values()) }; SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTIONS, JSON.stringify(dedupedConnections)); } catch (error) { console.error('Unable to sync connections to storage', error); } }, getConnections() { try { const connectionsStorage = SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTIONS); if (!connectionsStorage) { return {}; } return JSON.parse(connectionsStorage); } catch (error) { console.error('Unable to get connections from storage', error); return {}; } }, deleteAddressFromConnection({ connectorId, address, namespace }) { try { const connections = StorageUtil.getConnections(); const namespaceConnections = connections[namespace] ?? []; const connectionMap = new Map(namespaceConnections.map(conn => [conn.connectorId, conn])); const connector = connectionMap.get(connectorId); if (connector) { const updatedAccounts = connector.accounts.filter(acc => acc.address.toLowerCase() !== address.toLowerCase()); if (updatedAccounts.length === 0) { connectionMap.delete(connectorId); } else { connectionMap.set(connectorId, { ...connector, accounts: connector.accounts.filter(acc => acc.address.toLowerCase() !== address.toLowerCase()) }); } } SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTIONS, JSON.stringify({ ...connections, [namespace]: Array.from(connectionMap.values()) })); } catch { console.error(`Unable to remove address "${address}" from connector "${connectorId}" in namespace "${namespace}"`); } }, getDisconnectedConnectorIds() { try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.DISCONNECTED_CONNECTOR_IDS); if (!result) { return {}; } return JSON.parse(result); } catch { console.info('Unable to get disconnected connector ids'); } return {}; }, addDisconnectedConnectorId(connectorId, chainNamespace) { try { const currentDisconnectedConnectorIds = StorageUtil.getDisconnectedConnectorIds(); const disconnectedConnectorIdsByNamespace = currentDisconnectedConnectorIds[chainNamespace] ?? []; disconnectedConnectorIdsByNamespace.push(connectorId); SafeLocalStorage.setItem(SafeLocalStorageKeys.DISCONNECTED_CONNECTOR_IDS, JSON.stringify({ ...currentDisconnectedConnectorIds, [chainNamespace]: Array.from(new Set(disconnectedConnectorIdsByNamespace)) })); } catch { console.error(`Unable to set disconnected connector id "${connectorId}" for namespace "${chainNamespace}"`); } }, removeDisconnectedConnectorId(connectorId, chainNamespace) { try { const currentDisconnectedConnectorIds = StorageUtil.getDisconnectedConnectorIds(); let disconnectedConnectorIdsByNamespace = currentDisconnectedConnectorIds[chainNamespace] ?? []; disconnectedConnectorIdsByNamespace = disconnectedConnectorIdsByNamespace.filter(id => id.toLowerCase() !== connectorId.toLowerCase()); SafeLocalStorage.setItem(SafeLocalStorageKeys.DISCONNECTED_CONNECTOR_IDS, JSON.stringify({ ...currentDisconnectedConnectorIds, [chainNamespace]: Array.from(new Set(disconnectedConnectorIdsByNamespace)) })); } catch { console.error(`Unable to remove disconnected connector id "${connectorId}" for namespace "${chainNamespace}"`); } }, isConnectorDisconnected(connectorId, chainNamespace) { try { const currentDisconnectedConnectorIds = StorageUtil.getDisconnectedConnectorIds(); const disconnectedConnectorIdsByNamespace = currentDisconnectedConnectorIds[chainNamespace] ?? []; return disconnectedConnectorIdsByNamespace.some(id => id.toLowerCase() === connectorId.toLowerCase()); } catch { console.info(`Unable to get disconnected connector id "${connectorId}" for namespace "${chainNamespace}"`); } return false; } }; //# sourceMappingURL=StorageUtil.js.map