UNPKG

@reown/appkit-controllers

Version:

The full stack toolkit to build onchain app UX.

832 lines • 30.9 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, transactionsHistory: 15000, tokenPrice: 15000, // 7 Days latestAppKitVersion: 604_800_000, // 1 Day tonWallets: 86_400_000 }, 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)); SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLET, JSON.stringify(wallet)); } } 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 []; }, getRecentWallet() { try { const recent = SafeLocalStorage.getItem(SafeLocalStorageKeys.RECENT_WALLET); return recent ? JSON.parse(recent) : null; } catch { console.info('Unable to get AppKit recent'); } return null; }, deleteRecentWallet() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.RECENT_WALLET); } catch { console.info('Unable to delete AppKit recent'); } }, 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); } }, getTonWalletsCache() { try { const cache = SafeLocalStorage.getItem(SafeLocalStorageKeys.TON_WALLETS_CACHE); const parsedCache = cache ? JSON.parse(cache) : undefined; if (parsedCache && !this.isCacheExpired(parsedCache.timestamp, this.cacheExpiry.tonWallets)) { return parsedCache; } StorageUtil.removeTonWalletsCache(); } catch { console.info('Unable to get ton wallets cache'); } return undefined; }, updateTonWalletsCache(wallets) { try { const cache = StorageUtil.getTonWalletsCache() || { timestamp: 0, wallets: [] }; cache.timestamp = new Date().getTime(); cache.wallets = wallets; SafeLocalStorage.setItem(SafeLocalStorageKeys.TON_WALLETS_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update ton wallets cache', wallets); } }, removeTonWalletsCache() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.TON_WALLETS_CACHE); } catch { console.info('Unable to remove ton wallets cache'); } }, clearAddressCache() { try { SafeLocalStorage.removeItem(SafeLocalStorageKeys.PORTFOLIO_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.NATIVE_BALANCE_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.ENS_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.IDENTITY_CACHE); SafeLocalStorage.removeItem(SafeLocalStorageKeys.HISTORY_TRANSACTIONS_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; }, getTransactionsCache() { try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.HISTORY_TRANSACTIONS_CACHE); return result ? JSON.parse(result) : {}; } catch { console.info('Unable to get transactions cache'); } return {}; }, getTransactionsCacheForAddress({ address, chainId = '' }) { try { const cache = StorageUtil.getTransactionsCache(); const transactionsCache = cache[address]?.[chainId]; // We want to discard cache if it's older than the cache expiry if (transactionsCache && !this.isCacheExpired(transactionsCache.timestamp, this.cacheExpiry.transactionsHistory)) { return transactionsCache.transactions; } StorageUtil.removeTransactionsCache({ address, chainId }); } catch { console.info('Unable to get transactions cache'); } return undefined; }, updateTransactionsCache({ address, chainId = '', timestamp, transactions }) { try { const cache = StorageUtil.getTransactionsCache(); cache[address] = { ...cache[address], [chainId]: { timestamp, transactions } }; SafeLocalStorage.setItem(SafeLocalStorageKeys.HISTORY_TRANSACTIONS_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update transactions cache', { address, chainId, timestamp, transactions }); } }, removeTransactionsCache({ address, chainId }) { try { const cache = StorageUtil.getTransactionsCache(); const addressCache = cache?.[address] || {}; // eslint-disable-next-line @typescript-eslint/no-unused-vars const { [chainId]: _removed, ...updatedChainData } = addressCache; SafeLocalStorage.setItem(SafeLocalStorageKeys.HISTORY_TRANSACTIONS_CACHE, JSON.stringify({ ...cache, [address]: updatedChainData })); } catch { console.info('Unable to remove transactions cache', { address, chainId }); } }, getTokenPriceCache() { try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.TOKEN_PRICE_CACHE); return result ? JSON.parse(result) : {}; } catch { console.info('Unable to get token price cache'); } return {}; }, getTokenPriceCacheForAddresses(addresses) { try { const cache = StorageUtil.getTokenPriceCache(); const tokenPriceCache = cache[addresses.join(',')]; if (tokenPriceCache && !this.isCacheExpired(tokenPriceCache.timestamp, this.cacheExpiry.tokenPrice)) { return tokenPriceCache.tokenPrice; } StorageUtil.removeTokenPriceCache(addresses); } catch { console.info('Unable to get token price cache for addresses', addresses); } return undefined; }, updateTokenPriceCache(params) { try { const cache = StorageUtil.getTokenPriceCache(); cache[params.addresses.join(',')] = { timestamp: params.timestamp, tokenPrice: params.tokenPrice }; SafeLocalStorage.setItem(SafeLocalStorageKeys.TOKEN_PRICE_CACHE, JSON.stringify(cache)); } catch { console.info('Unable to update token price cache', params); } }, removeTokenPriceCache(addresses) { try { const cache = StorageUtil.getTokenPriceCache(); SafeLocalStorage.setItem(SafeLocalStorageKeys.TOKEN_PRICE_CACHE, JSON.stringify({ ...cache, [addresses.join(',')]: undefined })); } catch { console.info('Unable to remove token price cache', addresses); } }, /* ----- AppKit Latest Version ------------------------- */ getLatestAppKitVersion() { try { const result = this.getLatestAppKitVersionCache(); const version = result?.version; if (version && !this.isCacheExpired(result.timestamp, this.cacheExpiry.latestAppKitVersion)) { return version; } return undefined; } catch { console.info('Unable to get latest AppKit version'); } return undefined; }, getLatestAppKitVersionCache() { try { const result = SafeLocalStorage.getItem(SafeLocalStorageKeys.LATEST_APPKIT_VERSION); return result ? JSON.parse(result) : {}; } catch { console.info('Unable to get latest AppKit version cache'); } return {}; }, updateLatestAppKitVersion(params) { try { const cache = StorageUtil.getLatestAppKitVersionCache(); cache.timestamp = params.timestamp; cache.version = params.version; SafeLocalStorage.setItem(SafeLocalStorageKeys.LATEST_APPKIT_VERSION, JSON.stringify(cache)); } catch { console.info('Unable to update latest AppKit version on local storage', params); } } }; //# sourceMappingURL=StorageUtil.js.map