@rango-dev/wallets-react 0.37.0 → 0.37.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [0.37.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.36.0...wallets-react@0.37.0) (2025-09-29)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * connect queue precalling ([b421f62](https://github.com/rango-exchange/rango-client/commit/b421f62252f5fdbb023ba6732c2fca6d3670376a))
7
+
8
+
9
+ ### Features
10
+
11
+ * add single selection to detached modal ([07c7d44](https://github.com/rango-exchange/rango-client/commit/07c7d44ffd3def69e83c54d988c1279ac68d5889))
12
+ * migrate ledger provider to use hub ([a114101](https://github.com/rango-exchange/rango-client/commit/a114101bd9c317ec5c82c6146a6e88813bcbebf3))
13
+
14
+
15
+
1
16
  # [0.36.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.35.0...wallets-react@0.36.0) (2025-09-06)
2
17
 
3
18
 
@@ -1,2 +1,2 @@
1
- var w=Object.defineProperty;var r=(u,e)=>w(u,"name",{value:e,configurable:!0});import{LegacyEvents as $e}from"@rango-dev/wallets-core/legacy";import"@rango-dev/wallets-core/utils";import{pickVersion as E}from"@rango-dev/wallets-core/utils";import{convertEvmBlockchainMetaToEvmChainInfo as Ge}from"@rango-dev/wallets-shared";import{isEvmBlockchain as ze}from"rango-types";var s="last-connected-wallets",a="hub-v1-last-connected-wallets";import{createContext as v}from"react";var c="Context hasn't been initialized yet.",y={async connect(){throw new Error(c)},async disconnect(){throw new Error(c)},async disconnectAll(){throw new Error(c)},async suggestAndConnect(){throw new Error(c)},state(){throw new Error(c)},canSwitchNetworkTo(){throw new Error(c)},providers(){throw new Error(c)},getWalletInfo(){throw new Error(c)},getSigners(){throw new Error(c)}},f=v(y);import{useEffect as we,useReducer as ve}from"react";import{Persistor as l}from"@rango-dev/wallets-core/legacy";var i=class{static{r(this,"LastConnectedWalletsFromStorage")}#e;constructor(e){this.#e=e}addWallet(e,t){if(this.#e===a)return this.#t(e,t);if(this.#e===s)return this.#a(e);throw new Error("Not implemented")}removeWallets(e){if(this.#e===a)return this.#o(e);if(this.#e===s)return this.#c(e);throw new Error("Not implemented")}list(){if(this.#e===a)return this.#n();if(this.#e===s)return this.#r();throw new Error("Not implemented")}removeNamespacesFromWallet(e,t){if(this.#e===a)return this.#s(e,t);throw new Error("Not implemented")}#r(){let t=new l().getItem(s)||[],o={};return t.forEach(n=>{o[n]=[]}),o}#n(){return new l().getItem(a)||{}}#t(e,t){let o=new l,n=o.getItem(this.#e)||{},p=t;if(n[e]){let d=n[e];p=d.concat(t.filter(m=>!d.some(h=>h.namespace===m.namespace)))}o.setItem(this.#e,{...n,[e]:p})}#a(e){let t=new l,o=t.getItem(this.#e)||[];t.setItem(s,o.concat(e))}#o(e){let t=new l,o=t.getItem(this.#e)||{};if(!e){t.setItem(this.#e,{});return}e.forEach(n=>{o[n]&&delete o[n]}),t.setItem(this.#e,o)}#s(e,t){let d=(new l().getItem(this.#e)||{})[e]?.filter(m=>!t.includes(m.namespace));this.#o([e]),d?.length>0&&this.#t(e,d)}#c(e){let t=new l,o=t.getItem(this.#e)||[];if(!e){t.setItem(this.#e,[]);return}t.setItem(s,o.filter(n=>!e.includes(n)))}};import{Persistor as _}from"@rango-dev/wallets-core/legacy";import{LegacyWallet as V}from"@rango-dev/wallets-core/legacy";import{useContext as q,useRef as M}from"react";import{useEffect as ee,useRef as te}from"react";import{legacyFormatAddressWithNetwork as xe}from"@rango-dev/wallets-core/legacy";import{CAIP_BITCOIN_CHAIN_ID as Fe}from"@rango-dev/wallets-core/namespaces/utxo";import{CAIP as He}from"@rango-dev/wallets-core/utils";import{Err as _e,Ok as Oe}from"ts-results";var et=new i(a);function g(u){let e="0.0.0",t=[];return u.forEach(o=>{let n=E(o,e);t.push(n[1])}),t}r(g,"getAllLegacyProviders");import{utils as Ht}from"@rango-dev/wallets-core/namespaces/evm";import"@rango-dev/wallets-shared";import{useEffect as Ot,useRef as Dt,useState as Yt}from"react";import{Ok as Ut,Result as Vt}from"ts-results";import{legacyIsEvmNamespace as st}from"@rango-dev/wallets-core/legacy";import{Result as it}from"ts-results";var mt=new i(a);import{createStore as vt,Hub as yt}from"@rango-dev/wallets-core";import{useRef as Pt}from"react";export{g as getAllLegacyProviders};
1
+ var w=Object.defineProperty;var r=(u,e)=>w(u,"name",{value:e,configurable:!0});import{LegacyEvents as $e}from"@rango-dev/wallets-core/legacy";import"@rango-dev/wallets-core/utils";import{pickVersion as E}from"@rango-dev/wallets-core/utils";import{convertEvmBlockchainMetaToEvmChainInfo as Ge}from"@rango-dev/wallets-shared";import{isEvmBlockchain as ze}from"rango-types";var s="last-connected-wallets",a="hub-v1-last-connected-wallets";import{createContext as v}from"react";var c="Context hasn't been initialized yet.",y={async connect(){throw new Error(c)},async disconnect(){throw new Error(c)},async disconnectAll(){throw new Error(c)},async suggestAndConnect(){throw new Error(c)},state(){throw new Error(c)},canSwitchNetworkTo(){throw new Error(c)},providers(){throw new Error(c)},getWalletInfo(){throw new Error(c)},getSigners(){throw new Error(c)}},f=v(y);import{useEffect as we,useReducer as ve}from"react";import{Persistor as l}from"@rango-dev/wallets-core/legacy";var i=class{static{r(this,"LastConnectedWalletsFromStorage")}#e;constructor(e){this.#e=e}addWallet(e,t){if(this.#e===a)return this.#t(e,t);if(this.#e===s)return this.#a(e);throw new Error("Not implemented")}removeWallets(e){if(this.#e===a)return this.#o(e);if(this.#e===s)return this.#c(e);throw new Error("Not implemented")}list(){if(this.#e===a)return this.#n();if(this.#e===s)return this.#r();throw new Error("Not implemented")}removeNamespacesFromWallet(e,t){if(this.#e===a)return this.#s(e,t);throw new Error("Not implemented")}#r(){let t=new l().getItem(s)||[],o={};return t.forEach(n=>{o[n]=[]}),o}#n(){return new l().getItem(a)||{}}#t(e,t){let o=new l,n=o.getItem(this.#e)||{},p=t;if(n[e]){let d=n[e];p=d.concat(t.filter(m=>!d.some(h=>h.namespace===m.namespace)))}o.setItem(this.#e,{...n,[e]:p})}#a(e){let t=new l,o=t.getItem(this.#e)||[];t.setItem(s,o.concat(e))}#o(e){let t=new l,o=t.getItem(this.#e)||{};if(!e){t.setItem(this.#e,{});return}e.forEach(n=>{o[n]&&delete o[n]}),t.setItem(this.#e,o)}#s(e,t){let d=(new l().getItem(this.#e)||{})[e]?.filter(m=>!t.includes(m.namespace));this.#o([e]),d?.length>0&&this.#t(e,d)}#c(e){let t=new l,o=t.getItem(this.#e)||[];if(!e){t.setItem(this.#e,[]);return}t.setItem(s,o.filter(n=>!e.includes(n)))}};import{Persistor as _}from"@rango-dev/wallets-core/legacy";import{LegacyWallet as V}from"@rango-dev/wallets-core/legacy";import{useContext as q,useRef as M}from"react";import{useEffect as ee,useRef as te}from"react";import{legacyFormatAddressWithNetwork as xe}from"@rango-dev/wallets-core/legacy";import{CAIP_BITCOIN_CHAIN_ID as Fe}from"@rango-dev/wallets-core/namespaces/utxo";import{CAIP as He}from"@rango-dev/wallets-core/utils";import{Err as _e,Ok as Oe}from"ts-results";var et=new i(a);function g(u){let e="0.0.0",t=[];return u.forEach(o=>{let n=E(o,e);t.push(n[1])}),t}r(g,"getAllLegacyProviders");import{utils as _t}from"@rango-dev/wallets-core/namespaces/evm";import"@rango-dev/wallets-shared";import{useEffect as Yt,useRef as jt,useState as Ut}from"react";import{Ok as $t,Result as qt}from"ts-results";import{Provider as st}from"@rango-dev/wallets-core";import{legacyIsEvmNamespace as it}from"@rango-dev/wallets-core/legacy";import{Result as dt}from"ts-results";var gt=new i(a);import{createStore as Ct,Hub as Pt}from"@rango-dev/wallets-core";import{useRef as Wt}from"react";export{g as getAllLegacyProviders};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hub/utils.ts", "../../src/hub/constants.ts", "../../src/legacy/context.ts", "../../src/legacy/useLegacyProviders.ts", "../../src/hub/lastConnectedWallets.ts", "../../src/legacy/helpers.ts", "../../src/legacy/hooks.ts", "../../src/legacy/useAutoConnect.ts", "../../src/hub/helpers.ts", "../../src/hub/useHubAdapter.ts", "../../src/hub/autoConnect.ts", "../../src/hub/useHubRefs.ts"],
4
- "sourcesContent": ["import type { AllProxiedNamespaces } from './types.js';\nimport type { Hub, Provider, ProxiedNamespace } from '@rango-dev/wallets-core';\nimport type {\n LegacyNamespaceInputForConnect,\n LegacyProviderInterface,\n LegacyEventHandler as WalletEventHandler,\n} from '@rango-dev/wallets-core/legacy';\nimport type { CosmosActions } from '@rango-dev/wallets-core/namespaces/cosmos';\nimport type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm';\nimport type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana';\nimport type { SuiActions } from '@rango-dev/wallets-core/namespaces/sui';\nimport type { UtxoActions } from '@rango-dev/wallets-core/namespaces/utxo';\nimport type { Event } from '@rango-dev/wallets-core/store';\n\nimport { LegacyEvents as Events } from '@rango-dev/wallets-core/legacy';\nimport { type VersionedProviders } from '@rango-dev/wallets-core/utils';\nimport { pickVersion } from '@rango-dev/wallets-core/utils';\nimport {\n type AddEthereumChainParameter,\n convertEvmBlockchainMetaToEvmChainInfo,\n type WalletType,\n} from '@rango-dev/wallets-shared';\nimport { type BlockchainMeta, isEvmBlockchain } from 'rango-types';\n\nimport {\n type ConnectResult,\n HUB_LAST_CONNECTED_WALLETS,\n type ProviderProps,\n} from '../legacy/mod.js';\n\nimport {\n fromAccountIdToLegacyAddressFormat,\n isConnectResultEvm,\n isConnectResultSolana,\n} from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\n\n/* Gets a list of hub and legacy providers and returns a tuple which separates them. */\nexport function separateLegacyAndHubProviders(\n providers: VersionedProviders[]\n): [LegacyProviderInterface[], Provider[]] {\n const LEGACY_VERSION = '0.0.0';\n const HUB_VERSION = '1.0.0';\n\n const legacyProviders: LegacyProviderInterface[] = [];\n const hubProviders: Provider[] = [];\n\n providers.forEach((provider) => {\n try {\n const target = pickVersion(provider, HUB_VERSION);\n hubProviders.push(target[1]);\n } catch {\n const target = pickVersion(provider, LEGACY_VERSION);\n legacyProviders.push(target[1]);\n }\n });\n\n return [legacyProviders, hubProviders];\n}\n\nexport function findProviderByType(\n providers: Provider[],\n type: string\n): Provider | undefined {\n return providers.find((provider) => provider.id === type);\n}\n\n/**\n * We will call this function on hub's `subscribe`.\n * it will check states and will emit legacy events for backward compatibility.\n */\n\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\nexport function getSupportedChainsFromProvider(\n provider: Provider,\n allBlockChains: ProviderProps['allBlockChains']\n) {\n const namespacesProperty = provider\n .info()\n ?.metadata.properties?.find((property) => property.name === 'namespaces');\n\n const supportedChains =\n namespacesProperty?.value.data.flatMap((namespace) =>\n namespace.getSupportedChains(allBlockChains || [])\n ) || [];\n\n return supportedChains;\n}\n\nexport function mapHubEventsToLegacy(\n hub: Hub,\n event: Event,\n onUpdateState: WalletEventHandler,\n metadata: {\n allBlockChains: ProviderProps['allBlockChains'];\n lastConnectAttemptParams: {\n [type: WalletType]: LegacyNamespaceInputForConnect[];\n };\n }\n): void {\n const provider = hub.get(event.provider);\n if (!provider) {\n throw new Error(\n \"Currently all the events have assigned to a provider. The event doesn't include one.\",\n {\n cause: event,\n }\n );\n }\n\n // @ts-expect-error for those events that doesn't have namespace, it will be undefinded\n const namespaceId: string | undefined = event.namespace;\n\n const namespace = namespaceId\n ? provider.findByNamespace(namespaceId)\n : undefined;\n let accounts: string[] | null = null;\n let network: string | null = null;\n let derivationPath: string | undefined;\n\n if (namespace) {\n const [getNamespaceState] = namespace.state();\n accounts = getNamespaceState().accounts;\n network = getNamespaceState().network;\n\n if (metadata.lastConnectAttemptParams[event.provider]) {\n derivationPath = metadata.lastConnectAttemptParams[event.provider].find(\n (namespace) => namespace.namespace === namespaceId\n )?.derivationPath;\n }\n }\n\n const [getProviderState] = provider.state();\n const coreState = {\n connected: getProviderState().connected,\n connecting: getProviderState().connecting,\n installed: getProviderState().installed,\n accounts,\n network,\n reachable: true,\n derivationPath,\n };\n\n const eventInfo = {\n supportedBlockchains: getSupportedChainsFromProvider(\n provider,\n metadata.allBlockChains\n ),\n isContractWallet: false,\n isHub: true,\n namespace: namespaceId,\n };\n\n switch (event.type) {\n case 'provider_detected':\n onUpdateState(\n event.provider,\n Events.INSTALLED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connecting':\n onUpdateState(\n event.provider,\n Events.CONNECTING,\n event.value,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connected':\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_disconnected':\n onUpdateState(\n event.provider,\n Events.PROVIDER_DISCONNECTED,\n event.provider,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n false,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n null,\n coreState,\n eventInfo\n );\n break;\n case 'namespace_disconnected':\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n event.provider,\n [event.namespace]\n );\n\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n // onUpdateState(event.provider, Events.ACCOUNTS, null, coreState, eventInfo);\n break;\n case 'namespace_connected':\n case 'namespace_account_switched':\n {\n if (event.type === 'namespace_account_switched') {\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n eventInfo\n );\n }\n\n const formattedAddresses = event.accounts.map(\n fromAccountIdToLegacyAddressFormat\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n formattedAddresses,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n }\n break;\n case 'namespace_network_switched':\n onUpdateState(event.provider, Events.NETWORK, event.network, coreState, {\n ...eventInfo,\n namespace: event.namespace,\n });\n break;\n }\n}\n\nexport function getAllLegacyProviders(\n allProviders: VersionedProviders[]\n): LegacyProviderInterface[] {\n const LEGACY_VERSION = '0.0.0';\n\n const legacyProviders: LegacyProviderInterface[] = [];\n\n allProviders.forEach((provider) => {\n const target = pickVersion(provider, LEGACY_VERSION);\n legacyProviders.push(target[1]);\n });\n\n return legacyProviders;\n}\n\nexport function getLegacyProvider(\n allProviders: VersionedProviders[],\n type: string\n): LegacyProviderInterface {\n const legacyProviders: LegacyProviderInterface[] =\n getAllLegacyProviders(allProviders);\n\n const provider = legacyProviders.find((legacyProvider) => {\n return legacyProvider.config.type === type;\n });\n\n if (!provider) {\n console.warn(\n `You have a provider that doesn't have legacy provider. It causes some problems since we need some legacy functionality. Provider Id: ${type}`\n );\n throw new Error(\n `You need to have legacy implementation to use some methods. Provider Id: ${type}`\n );\n }\n\n return provider;\n}\n\n/**\n * In legacy mode, for those who have switch network functionality (like evm), we are using an enum for network names\n * this enum only has meaning for us, and when we are going to connect an instance (e.g. window.ethereum) we should pass chain id.\n */\nexport function convertNamespaceNetworkToEvmChainId(\n namespace: LegacyNamespaceInputForConnect,\n meta: BlockchainMeta[]\n) {\n if (!namespace.network) {\n return undefined;\n }\n\n const evmBlockchainsList = meta.filter(isEvmBlockchain);\n const evmChains = convertEvmBlockchainMetaToEvmChainInfo(evmBlockchainsList);\n\n return evmChains[namespace.network];\n}\n\n/**\n * We are passing an string for chain id (e.g. ETH, POLYGON), but wallet's instances (e.g. window.ethereum) needs chainId (e.g. 0x1).\n * This function will help us to map these strings to proper hex ids.\n *\n * If you need same functionality for other blockchain types (e.g. Cosmos), You can make a separate function and add it here.\n */\nexport function tryConvertNamespaceNetworkToChainInfo(\n namespace: LegacyNamespaceInputForConnect,\n meta: BlockchainMeta[]\n): string | AddEthereumChainParameter | undefined {\n // `undefined` means it's not evm or we couldn't find it in meta.\n const evmChain = convertNamespaceNetworkToEvmChainId(namespace, meta);\n const network = evmChain || namespace.network;\n\n return network;\n}\n\nexport function transformHubResultToLegacyResult(\n res: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): ConnectResult {\n if (isConnectResultEvm(res)) {\n return {\n accounts: res.accounts,\n network: res.network,\n provider: undefined,\n };\n } else if (isConnectResultSolana(res)) {\n return {\n accounts: res,\n network: null,\n provider: undefined,\n };\n }\n\n return {\n accounts: [res],\n network: null,\n provider: undefined,\n };\n}\n\n/**\n * Synchronizes providers in the hub with the configuration providers.\n * - Registers and initializes any configuration providers not yet in the hub\n * - Removes providers from the hub that aren't in the configuration\n */\nexport function synchronizeHubWithConfigProviders(\n hub: Hub,\n configurationProviders: Provider[]\n) {\n const registeredProviders = hub.getAll();\n\n // Register and initialize providers that exist in config but not in hub\n const providersToRegister = configurationProviders.filter(\n (configProvider) => !registeredProviders.get(configProvider.id)\n );\n\n providersToRegister.forEach((providerToRegister) => {\n hub.add(providerToRegister.id, providerToRegister);\n providerToRegister.init();\n });\n\n // Remove providers that exist in hub but not in config\n registeredProviders.forEach((registeredProvider) => {\n const isProviderInConfig = configurationProviders.some(\n (configProvider) => configProvider.id === registeredProvider.id\n );\n\n if (!isProviderInConfig) {\n hub.remove(registeredProvider.id);\n }\n });\n}\n\nexport function isSolanaNamespace(\n ns: ProxiedNamespace<\n EvmActions | SolanaActions | CosmosActions | SuiActions | UtxoActions\n >\n): ns is ProxiedNamespace<SolanaActions> & { namespaceId: 'Solana' } {\n return ns.namespaceId === 'Solana';\n}\nexport function isEvmNamespace(\n ns: ProxiedNamespace<\n EvmActions | SolanaActions | CosmosActions | SuiActions | UtxoActions\n >\n): ns is ProxiedNamespace<EvmActions> & { namespaceId: 'EVM' } {\n return ns.namespaceId === 'EVM';\n}\n", "export const LEGACY_LAST_CONNECTED_WALLETS = 'last-connected-wallets';\nexport const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets';\n", "import type { ProviderContext } from './types.js';\n\nimport { createContext } from 'react';\n\nconst defaultErrorMessage = \"Context hasn't been initialized yet.\";\nconst defaultContext: ProviderContext = {\n async connect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnectAll() {\n throw new Error(defaultErrorMessage);\n },\n async suggestAndConnect() {\n throw new Error(defaultErrorMessage);\n },\n state() {\n throw new Error(defaultErrorMessage);\n },\n canSwitchNetworkTo() {\n throw new Error(defaultErrorMessage);\n },\n providers() {\n throw new Error(defaultErrorMessage);\n },\n getWalletInfo() {\n throw new Error(defaultErrorMessage);\n },\n getSigners() {\n throw new Error(defaultErrorMessage);\n },\n};\n\nexport const WalletContext = createContext<ProviderContext>(defaultContext);\n", "import type { ProviderContext, ProviderProps } from './types.js';\nimport type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { useEffect, useReducer } from 'react';\n\nimport { autoConnect } from './autoConnect.js';\nimport {\n availableWallets,\n checkWalletProviders,\n clearPersistance,\n connectedWallets,\n defaultWalletState,\n makeEventHandler,\n stateReducer,\n tryPersistWallet,\n tryRemoveWalletFromPersistance,\n} from './helpers.js';\nimport { useInitializers } from './hooks.js';\nimport { useAutoConnect } from './useAutoConnect.js';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ProviderType = any;\n\nexport type LegacyProviderProps = Omit<ProviderProps, 'providers'> & {\n providers: LegacyProviderInterface[];\n};\n\nexport function useLegacyProviders(\n props: LegacyProviderProps\n): ProviderContext {\n const [providersState, dispatch] = useReducer(stateReducer, {});\n\n // Get (or add) wallet instance (`provider`s will be wrapped in a `Wallet`)\n const getWalletInstance = useInitializers(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n\n // Getting providers from props and put all of them in a `Map` with an appropriate interface.\n const listOfProviders = props.providers;\n const wallets = checkWalletProviders(listOfProviders);\n\n useAutoConnect({\n allBlockChains: props.allBlockChains,\n autoConnect: props.autoConnect,\n autoConnectHandler: async () => autoConnect(wallets, getWalletInstance),\n });\n\n // Final API we put in context and it will be available to use for users.\n const api: ProviderContext = {\n async connect(type, namespaces) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n // Legacy providers doesn't implemented multiple namespaces, so it will always be one value.\n let network = undefined;\n if (namespaces && namespaces.length > 0) {\n /*\n * This may not be safe in cases there are two `network` for namespaces, the first one will be picked always.\n * But since legacy provider only accepts one value, it shouldn't be happened when we are using legacy mode.\n */\n network = namespaces.find((ns) => !!ns.network)?.network;\n }\n\n const walletInstance = getWalletInstance(wallet);\n const result = await walletInstance.connect(network, namespaces);\n if (props.autoConnect) {\n void tryPersistWallet({\n type,\n walletActions: wallet.actions,\n getState: api.state,\n });\n }\n\n return [result];\n },\n async disconnect(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const walletInstance = getWalletInstance(wallet);\n await walletInstance.disconnect();\n if (props.autoConnect) {\n tryRemoveWalletFromPersistance({ type, walletActions: wallet.actions });\n }\n },\n async disconnectAll() {\n const disconnect_promises: Promise<void>[] = [];\n\n /*\n * When a wallet is initializing, a record will be added to `providersState`\n * So we use them to know what wallet has been initialized then we need to\n * filter connected wallets only.\n */\n connectedWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n disconnect_promises.push(walletInstance.disconnect());\n }\n });\n\n if (props.autoConnect) {\n clearPersistance();\n }\n return await Promise.allSettled(disconnect_promises);\n },\n\n async suggestAndConnect(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const result = await walletInstance.suggestAndConnect(network);\n\n return result;\n },\n\n state(type) {\n return providersState[type] || defaultWalletState;\n },\n canSwitchNetworkTo(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n return false;\n }\n\n const walletInstance = getWalletInstance(wallet);\n return walletInstance.canSwitchNetworkTo\n ? walletInstance.canSwitchNetworkTo(network, walletInstance.provider)\n : false;\n },\n providers() {\n const providers: { [type in WalletType]?: ProviderType } = {};\n availableWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n providers[type] = walletInstance.provider;\n }\n });\n\n return providers;\n },\n getWalletInfo(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n /*\n * Get wallet info could be used in render methods to show wallets data\n * So, addWalletRef method shouldn't be called in this method\n */\n\n return wallet.actions.getWalletInfo(props.allBlockChains || []);\n },\n async getSigners(type) {\n const wallet = wallets.get(type);\n\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const provider = walletInstance.provider;\n const result = walletInstance.getSigners(provider);\n\n return result;\n },\n };\n\n // Initialize instances\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const runOnInit = () => {\n if (walletInstance.onInit) {\n walletInstance.onInit();\n }\n };\n\n const initWhenPageIsReady = (event: Event) => {\n if (\n event.target &&\n (event.target as Document).readyState === 'complete'\n ) {\n runOnInit();\n\n document.removeEventListener('readystatechange', initWhenPageIsReady);\n }\n };\n\n // Try to run, maybe it's ready.\n runOnInit();\n\n /*\n * Try again when the page has been completely loaded.\n * Some of wallets, take some time to be fully injected and loaded.\n */\n document.addEventListener('readystatechange', initWhenPageIsReady);\n });\n }, []);\n\n // Setting supported blockchains on instances\n useEffect(() => {\n const allBlockChains = props.allBlockChains;\n if (allBlockChains) {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const walletInfo = walletInstance.getWalletInfo(\n props.allBlockChains || []\n );\n walletInstance.setInfo({\n supportedBlockchains: walletInfo.supportedChains,\n isContractWallet: !!walletInfo.isContractWallet,\n });\n });\n }\n }, [props.allBlockChains]);\n\n // Setting event handler on instances\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n walletInstance.setHandler(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n });\n }, [props.onUpdateState]);\n\n return api;\n}\n", "import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';\n\nimport { Persistor } from '@rango-dev/wallets-core/legacy';\n\nimport {\n HUB_LAST_CONNECTED_WALLETS,\n LEGACY_LAST_CONNECTED_WALLETS,\n} from './constants.js';\n\nexport interface NamespaceInput {\n namespace: Namespace;\n network: string | undefined;\n}\n\nexport interface LastConnectedWalletsStorage {\n [providerId: string]: NamespaceInput[];\n}\n\nexport type LegacyLastConnectedWalletsStorage = string[];\n\n/**\n * We are doing some certain actions on storage for `last-connected-wallets` key.\n * This class helps us to define them in one place and also it has support for both legacy and hub.\n */\nexport class LastConnectedWalletsFromStorage {\n #storageKey: string;\n\n constructor(storageKey: string) {\n this.#storageKey = storageKey;\n }\n\n addWallet(providerId: string, namespaces: NamespaceInput[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToHub(providerId, namespaces);\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToLegacy(providerId);\n }\n throw new Error('Not implemented');\n }\n removeWallets(providerIds?: string[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromHub(providerIds);\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromLegacy(providerIds);\n }\n throw new Error('Not implemented');\n }\n list(): LastConnectedWalletsStorage {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#listFromHub();\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#listFromLegacy();\n }\n throw new Error('Not implemented');\n }\n removeNamespacesFromWallet(providerId: string, namespaceIds: string[]) {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeNamespaceFromWalletHub(providerId, namespaceIds);\n }\n throw new Error('Not implemented');\n }\n\n #listFromLegacy(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS) || [];\n const output: LastConnectedWalletsStorage = {};\n lastConnectedWallets.forEach((provider) => {\n // Setting empty namespaces\n output[provider] = [];\n });\n return output;\n }\n #listFromHub(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};\n return lastConnectedWallets;\n }\n #addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {\n const storage = new Persistor<LastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || {};\n\n let toBeAddedNamespaces = namespaces;\n\n // If provider already exits in the storage, we should just add new namespaces to the previously added namespaces.\n if (!!storageState[providerId]) {\n const storedNamespaces = storageState[providerId];\n toBeAddedNamespaces = storedNamespaces.concat(\n namespaces.filter(\n (namespace) =>\n !storedNamespaces.some(\n (storedNamespace) =>\n storedNamespace.namespace === namespace.namespace\n )\n )\n );\n }\n\n storage.setItem(this.#storageKey, {\n ...storageState,\n [providerId]: toBeAddedNamespaces,\n });\n }\n #addWalletToLegacy(providerId: string): void {\n const storage = new Persistor<LegacyLastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || [];\n\n storage.setItem(\n LEGACY_LAST_CONNECTED_WALLETS,\n storageState.concat(providerId)\n );\n }\n #removeWalletsFromHub(providerIds?: string[]): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, {});\n return;\n }\n\n // Remove some of the wallets\n providerIds.forEach((providerId) => {\n if (storageState[providerId]) {\n delete storageState[providerId];\n }\n });\n\n persistor.setItem(this.#storageKey, storageState);\n }\n #removeNamespaceFromWalletHub(\n providerId: string,\n namespaceIds: string[]\n ): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n const currentProviderNamespaces = storageState[providerId];\n const newProviderNamespaces = currentProviderNamespaces?.filter(\n (namespace) => !namespaceIds.includes(namespace.namespace)\n );\n\n this.#removeWalletsFromHub([providerId]);\n if (newProviderNamespaces?.length > 0) {\n this.#addWalletToHub(providerId, newProviderNamespaces);\n }\n }\n #removeWalletsFromLegacy(providerIds?: string[]): void {\n const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || [];\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, []);\n return;\n }\n\n // Remove some of the wallets\n persistor.setItem(\n LEGACY_LAST_CONNECTED_WALLETS,\n storageState.filter((wallet) => !providerIds.includes(wallet))\n );\n }\n}\n", "import type {\n ProviderInterface,\n State,\n WalletActions,\n WalletProviders,\n} from './types.js';\nimport type {\n LegacyOptions as Options,\n LegacyEventHandler as WalletEventHandler,\n LegacyState as WalletState,\n} from '@rango-dev/wallets-core/legacy';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { Persistor } from '@rango-dev/wallets-core/legacy';\n\nimport { LEGACY_LAST_CONNECTED_WALLETS } from '../hub/constants.js';\nimport { LastConnectedWalletsFromStorage } from '../hub/lastConnectedWallets.js';\n\nexport function choose(wallets: any[], type: WalletType): any | null {\n return wallets.find((wallet) => wallet.type === type) || null;\n}\n\nexport const defaultWalletState: WalletState = {\n connected: false,\n connecting: false,\n reachable: false,\n installed: false,\n accounts: null,\n network: null,\n};\n\nexport function stateReducer(state: State, action: any) {\n if (action.type === 'new_state') {\n // TODO fix problem and remove ts-ignore\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const target_wallet = state[action.wallet];\n if (!target_wallet) {\n return {\n ...state,\n [action.wallet]: {\n ...defaultWalletState,\n [action.name]: action.value,\n },\n };\n }\n\n return {\n ...state,\n [action.wallet]: {\n ...target_wallet,\n [action.name]: action.value,\n },\n };\n }\n\n return state;\n}\n\nexport function connectedWallets(providersState: State): WalletType[] {\n return Object.entries(providersState)\n .filter(([, wallet_state]) => {\n return wallet_state?.connected;\n })\n .map(([type]) => {\n return type;\n });\n}\n\nexport function availableWallets(providersState: State): WalletType[] {\n return Object.entries(providersState).map(([type]) => {\n return type;\n });\n}\n\nexport function checkWalletProviders(\n list: ProviderInterface[]\n): WalletProviders {\n const wallets: WalletProviders = new Map();\n\n list.forEach((provider) => {\n const { config, ...actions } = provider;\n wallets.set(config.type, {\n actions,\n config,\n });\n });\n\n return wallets;\n}\n\n/* eslint-disable @typescript-eslint/ban-types */\nexport function isAsync(fn: Function) {\n return fn?.constructor?.name === 'AsyncFunction';\n}\n\nexport function needsCheckInstallation(options: Options) {\n const { checkInstallation = true } = options.config;\n return checkInstallation;\n}\n\nexport async function tryPersistWallet({\n type,\n walletActions,\n getState,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n getState: (walletType: WalletType) => WalletState;\n}) {\n if (walletActions.canEagerConnect) {\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n LEGACY_LAST_CONNECTED_WALLETS\n );\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletAlreadyPersisted = !!lastConnectedWallets[type];\n\n /*\n *If on the last attempt we are unable to eagerly connect to any wallet and the user connects any wallet manualy,\n *persistance will be outdated and will need to be removed.\n */\n if (walletAlreadyPersisted && !getState(type).connected) {\n clearPersistance();\n }\n\n if (!walletAlreadyPersisted) {\n lastConnectedWalletsFromStorage.addWallet(type, []);\n }\n }\n}\n\nexport function tryRemoveWalletFromPersistance({\n type,\n walletActions,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n}) {\n if (walletActions.canEagerConnect) {\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n LEGACY_LAST_CONNECTED_WALLETS\n );\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n}\n\nexport function clearPersistance() {\n const persistor = new Persistor<string[]>();\n const wallets = persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS);\n if (wallets) {\n persistor.removeItem(LEGACY_LAST_CONNECTED_WALLETS);\n }\n}\n\n/*\n *Our event handler includes an internal state updater, and a notifier\n *for the outside listener.\n *On creating first wallet refrence, and on chaning `props.onUpdateState`\n *we are using this function.\n */\nexport function makeEventHandler(\n dispatcher: any,\n onUpdateState?: WalletEventHandler\n) {\n const handler: WalletEventHandler = (\n type,\n name,\n value,\n coreState,\n supportedChains\n ) => {\n const action = { type: 'new_state', wallet: type, name, value };\n // Update state\n dispatcher(action);\n\n // Giving the event to the outside listener\n if (onUpdateState) {\n onUpdateState(type, name, value, coreState, supportedChains);\n }\n };\n\n return handler;\n}\n", "import type { ProviderContext, WalletActions, WalletConfig } from './types.js';\nimport type { LegacyEventHandler as WalletEventHandler } from '@rango-dev/wallets-core/legacy';\n\nimport { LegacyWallet as Wallet } from '@rango-dev/wallets-core/legacy';\nimport { useContext, useRef } from 'react';\n\nimport { WalletContext } from './context.js';\n\nexport type GetWalletInstance = (wallet: {\n actions: WalletActions;\n config: WalletConfig;\n}) => Wallet;\n\nexport function useInitializers(\n onChangeState: WalletEventHandler\n): GetWalletInstance {\n const availableWallets = useRef<{\n [key: string]: Wallet | undefined;\n }>({});\n\n /*\n * If `wallet` hasn't been added to `availableWallets`,\n * Get a instance of `Wallet` and save the refrence in `availableWallets`.\n * Otherwise, return the already created instance.\n */\n function updater(wallet: {\n actions: WalletActions;\n config: WalletConfig;\n }): Wallet {\n const type = wallet.config.type;\n // We only update, if there is no instance available.\n if (typeof availableWallets.current[type] === 'undefined') {\n availableWallets.current[type] = new Wallet(\n {\n config: wallet.config,\n handler: onChangeState,\n },\n wallet.actions\n );\n }\n\n return availableWallets.current[type]!;\n }\n\n return updater;\n}\n\nexport function useWallets(): ProviderContext {\n const context = useContext(WalletContext);\n if (!context) {\n throw Error('useWallet can only be used within the Provider component');\n }\n return context;\n}\n", "import type { ProviderProps } from './types.js';\n\nimport { useEffect, useRef } from 'react';\n\nimport { shouldTryAutoConnect } from './utils.js';\n\nexport function useAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'> & {\n /**\n * A function to run autoConnect on instances\n */\n autoConnectHandler: () => void;\n }\n) {\n const autoConnectInitiated = useRef(false);\n\n useEffect(() => {\n if (shouldTryAutoConnect(props) && !autoConnectInitiated.current) {\n autoConnectInitiated.current = true;\n props.autoConnectHandler();\n }\n }, [props.autoConnect, props.allBlockChains]);\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type {\n Accounts,\n AccountsWithActiveChain,\n} from '@rango-dev/wallets-core/namespaces/common';\nimport type { Result } from 'ts-results';\n\nimport { legacyFormatAddressWithNetwork as formatAddressWithNetwork } from '@rango-dev/wallets-core/legacy';\nimport { CAIP_BITCOIN_CHAIN_ID } from '@rango-dev/wallets-core/namespaces/utxo';\nimport { CAIP } from '@rango-dev/wallets-core/utils';\nimport { Err, Ok } from 'ts-results';\n\nexport function mapCaipNamespaceToLegacyNetworkName(\n chainId: CAIP.ChainIdParams | string\n): string {\n if (typeof chainId === 'string') {\n return chainId;\n }\n const useNamespaceAsNetworkFor = ['solana'];\n\n if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) {\n return chainId.namespace.toUpperCase();\n }\n\n if (chainId.namespace.toLowerCase() === 'eip155') {\n return 'ETH';\n } else if (chainId.reference === CAIP_BITCOIN_CHAIN_ID) {\n return 'BTC';\n }\n\n if (chainId.namespace === 'sui') {\n return chainId.reference.toUpperCase();\n }\n\n return chainId.reference;\n}\n\n/**\n * CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * This function will try to convert this two format.\n *\n * @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md\n */\nexport function fromAccountIdToLegacyAddressFormat(account: string): string {\n const { chainId, address } = CAIP.AccountId.parse(account);\n const network = mapCaipNamespaceToLegacyNetworkName(chainId);\n return formatAddressWithNetwork(address, network);\n}\n\n/**\n * Getting a list of (lazy) promises and run them one after another.\n */\n\nexport async function runSequentiallyWithoutFailure<R>(\n promises: Array<() => Promise<R>>\n): Promise<Result<R, unknown>[]> {\n return promises.reduce(async (prevPromise, task) => {\n const previousResults = await prevPromise;\n try {\n const taskResult = await task();\n return [...previousResults, new Ok(taskResult)];\n } catch (error) {\n return [...previousResults, new Err(error)];\n }\n }, Promise.resolve<Result<R, unknown>[]>([]));\n}\n\nexport function isConnectResultEvm(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is AccountsWithActiveChain {\n return typeof result === 'object' && !Array.isArray(result);\n}\n\nexport function isConnectResultSolana(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is Accounts {\n return Array.isArray(result);\n}\n\ntype QueueItem<T> = {\n task: () => Promise<T>;\n resolve: (value: Result<T, unknown>) => void;\n key: string;\n};\n/**\n * Creates a queue manager that ensures sequential execution of tasks by key.\n * When multiple tasks with the same key are queued, they are executed one at a time\n * in the order they were added. This prevents race conditions and ensures\n * predictable task execution order.\n *\n */\nexport function createQueue(options?: {\n onError?: (\n error: unknown,\n actions: {\n removeCurrentKeyFromQueue: () => void;\n }\n ) => void;\n}) {\n const processingKeys = new Set<string>();\n let queue: QueueItem<unknown>[] = [];\n\n const removeKeyFromQueue = (\n key: string,\n result: Result<unknown, unknown>\n ) => {\n queue = queue.filter((q) => {\n if (q.key !== key) {\n return true;\n }\n q.resolve(result);\n return false;\n });\n };\n\n const processQueue = async () => {\n const currentItem = queue.find((item) => !processingKeys.has(item.key));\n if (!currentItem) {\n return;\n }\n\n const { task, resolve, key } = currentItem;\n processingKeys.add(key);\n\n try {\n const result = await task();\n resolve(new Ok(result));\n } catch (error) {\n if (options?.onError) {\n options.onError(error, {\n removeCurrentKeyFromQueue: () =>\n removeKeyFromQueue(key, new Err(error)),\n });\n }\n\n resolve(new Err(error));\n } finally {\n const indexOfCurrentItem = queue.findIndex((item) => item.key === key);\n if (indexOfCurrentItem >= 0) {\n queue.splice(indexOfCurrentItem, 1);\n }\n processingKeys.delete(key);\n void processQueue();\n }\n };\n\n const queueTask = async <T>(\n task: () => Promise<T>,\n key: string\n ): Promise<Result<T, unknown>> =>\n new Promise((resolve) => {\n queue.push({\n task,\n resolve: resolve as (value: Result<unknown, unknown>) => void,\n key,\n });\n void processQueue();\n });\n\n return queueTask;\n}\n", "import type { AllProxiedNamespaces, ExtensionLink } from './types.js';\nimport type { ProviderContext, Providers } from '../index.js';\nimport type { Provider } from '@rango-dev/wallets-core';\nimport type { LegacyNamespaceInputForConnect } from '@rango-dev/wallets-core/legacy';\nimport type {\n Accounts,\n AccountsWithActiveChain,\n} from '@rango-dev/wallets-core/namespaces/common';\nimport type { VersionedProviders } from '@rango-dev/wallets-core/utils';\n\nimport { utils } from '@rango-dev/wallets-core/namespaces/evm';\nimport { type WalletInfo, type WalletType } from '@rango-dev/wallets-shared';\nimport { useEffect, useRef, useState } from 'react';\nimport { Ok, Result } from 'ts-results';\n\nimport {\n type ConnectResult,\n HUB_LAST_CONNECTED_WALLETS,\n type ProviderProps,\n} from '../legacy/mod.js';\nimport { useAutoConnect } from '../legacy/useAutoConnect.js';\n\nimport { autoConnect } from './autoConnect.js';\nimport { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport { useHubRefs } from './useHubRefs.js';\nimport {\n getLegacyProvider,\n getSupportedChainsFromProvider,\n isEvmNamespace,\n isSolanaNamespace,\n mapHubEventsToLegacy,\n transformHubResultToLegacyResult,\n tryConvertNamespaceNetworkToChainInfo,\n} from './utils.js';\n\nexport type UseAdapterParams = Omit<ProviderProps, 'providers'> & {\n providers: Provider[];\n /** This is only will be used to access some parts of the legacy provider that doesn't exists in Hub. */\n allVersionedProviders: VersionedProviders[];\n};\n\nexport function useHubAdapter(params: UseAdapterParams): ProviderContext {\n const { getStore, getHub } = useHubRefs(params.providers);\n const [, rerender] = useState(0);\n // useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes.\n const dataRef = useRef({\n onUpdateState: params.onUpdateState,\n allVersionedProviders: params.allVersionedProviders,\n allBlockChains: params.allBlockChains,\n });\n\n /*\n * Params of each connection attempt for each wallet type are stored here.\n * Derivation path from params is used in `mapHubEventsToLegacy` to be added to the payload of connect events.\n */\n const lastConnectAttemptParamsRef = useRef<{\n [type: WalletType]: LegacyNamespaceInputForConnect[];\n }>({});\n\n const updateLastConnectAttemptParams = (\n type: WalletType,\n namespaces: LegacyNamespaceInputForConnect[] | undefined\n ) => {\n lastConnectAttemptParamsRef.current[type] = namespaces || [];\n };\n\n const queueTask = createQueue({\n onError: (error, actions) => {\n if (utils.isUserRejectionError(error)) {\n actions.removeCurrentKeyFromQueue();\n }\n },\n });\n\n useEffect(() => {\n dataRef.current = {\n onUpdateState: params.onUpdateState,\n allVersionedProviders: params.allVersionedProviders,\n allBlockChains: params.allBlockChains,\n };\n }, [params]);\n\n // Initialize instances\n useEffect(() => {\n const runOnInit = () => {\n getHub().init();\n\n rerender((currentRender) => currentRender + 1);\n };\n\n // Then will call init whenever page is ready.\n const initHubWhenPageIsReady = (event: Event) => {\n // Then will call init whenever page is ready.\n if (\n event.target &&\n (event.target as Document).readyState === 'complete'\n ) {\n runOnInit();\n document.removeEventListener(\n 'readystatechange',\n initHubWhenPageIsReady\n );\n }\n };\n\n // Try to run, maybe it's ready.\n runOnInit();\n\n /*\n * Try again when the page has been completely loaded.\n * Some of wallets, take some time to be fully injected and loaded.\n */\n document.addEventListener('readystatechange', initHubWhenPageIsReady);\n\n getStore()\n .subscribe((event) => {\n if (dataRef.current.onUpdateState) {\n try {\n mapHubEventsToLegacy(\n getHub(),\n event,\n dataRef.current.onUpdateState,\n {\n allBlockChains: dataRef.current.allBlockChains,\n lastConnectAttemptParams: lastConnectAttemptParamsRef.current,\n }\n );\n } catch (e) {\n console.error(e);\n }\n }\n rerender((currentRender) => currentRender + 1);\n })\n .flushEvents();\n }, []);\n\n useAutoConnect({\n autoConnect: params.autoConnect,\n allBlockChains: params.allBlockChains,\n autoConnectHandler: () => {\n void autoConnect({\n allBlockChains: params.allBlockChains,\n getHub,\n wallets: params.configs?.wallets,\n });\n },\n });\n\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n );\n\n const api: ProviderContext = {\n canSwitchNetworkTo(type, network, namespace) {\n const provider = getHub().get(type);\n\n if (!provider) {\n throw new Error(\n `You should add ${type} to provider first then call 'canSwitchNetworkTo'.`\n );\n }\n\n if (!namespace) {\n throw new Error(\n 'Passing namespace to `canSwitchNetworkTo` is required.'\n );\n }\n\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('canSwitchNetwork' in proxiedNamespace)) {\n return false;\n }\n const namespacesProperty = provider\n .info()\n ?.metadata?.properties?.find(\n (property) => property.name === 'namespaces'\n );\n\n if (!dataRef.current.allBlockChains) {\n throw new Error(`Blockchains are not available`);\n }\n const providerSupportedChainsOfNamespace = namespacesProperty?.value.data\n .find(\n (providerNamespace) => providerNamespace.value === namespace.namespace\n )\n ?.getSupportedChains(dataRef.current.allBlockChains);\n\n if (!providerSupportedChainsOfNamespace) {\n throw new Error(\n `NamespaceMeta is not defined for requested namespace: ${namespace.namespace}`\n );\n }\n\n return proxiedNamespace.canSwitchNetwork({\n network,\n supportedChains: providerSupportedChainsOfNamespace,\n });\n },\n async connect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespaces) {\n throw new Error('Passing namespace to `connect` is required.');\n }\n\n updateLastConnectAttemptParams(type, namespaces);\n\n // Check `namespace` and look into hub to see how it can match given namespace to hub namespace.\n const targetNamespaces: [\n LegacyNamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespaces.forEach((namespace) => {\n const targetNamespace = namespace.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`\n );\n }\n\n targetNamespaces.push([namespace, result]);\n });\n\n // Try to run `connect` on matched namespaces\n const connectResultFromTargetNamespaces = targetNamespaces.map(\n async ([namespaceInput, namespace]) => {\n const network = tryConvertNamespaceNetworkToChainInfo(\n namespaceInput,\n params.allBlockChains || []\n );\n\n let connectNamespacePromise: () => Promise<\n Accounts | string | AccountsWithActiveChain\n >;\n\n if (isSolanaNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect(network, {\n derivationPath: namespaceInput.derivationPath,\n });\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n\n const connectNamespaceProcess = async () =>\n connectNamespacePromise()\n .then<ConnectResult>(transformHubResultToLegacyResult)\n .then((connectResult) => {\n return {\n response: connectResult,\n input: {\n namespace: namespaceInput.namespace,\n network: namespaceInput.network,\n supportsEagerConnect: 'canEagerConnect' in namespace,\n },\n };\n });\n return queueTask(connectNamespaceProcess, type);\n }\n );\n\n /*\n * We need to connect to namespace one after another, sending multiple requests at the same time may be failed.\n * e.g. when wallet popup opens and asking for the password from the user, it should be resolved first, then other request will be resolved.\n */\n const connectResultWithLegacyFormat = await Promise.all(\n connectResultFromTargetNamespaces\n );\n\n // Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.\n const successfullyConnectedSupportingEagerConnectNamespaces =\n connectResultWithLegacyFormat\n .filter(<T, E>(result: Result<T, E>): result is Ok<T> => result.ok)\n .filter((result) => result.val.input.supportsEagerConnect)\n .map((result) => ({\n namespace: result.val.input.namespace,\n network: result.val.input.network,\n }));\n\n if (successfullyConnectedSupportingEagerConnectNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.addWallet(\n type,\n successfullyConnectedSupportingEagerConnectNamespaces\n );\n }\n\n // Getting rid of `input` from Result\n const connectResults = connectResultWithLegacyFormat.map((result) =>\n result.andThen((okResult) => new Ok(okResult.response))\n );\n\n const allResult = Result.all(...connectResults);\n if (allResult.err) {\n throw allResult.val;\n }\n\n return allResult.unwrap();\n },\n async disconnect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'disconnect'.`\n );\n }\n\n wallet.getAll().forEach((namespace) => {\n const namespaceShouldBeDisconnected =\n !namespaces || namespaces.includes(namespace.namespaceId);\n const namespaceIsConnected = namespace.state()[0]().connected;\n if (namespaceShouldBeDisconnected && namespaceIsConnected) {\n return namespace.disconnect();\n }\n });\n\n if (params.autoConnect) {\n if (namespaces) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n namespaces\n );\n } else {\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n }\n },\n async disconnectAll() {\n const disconnectPromises: Promise<void>[] = Array.from(\n getHub().getAll().values()\n ).map(async (provider) => this.disconnect(provider.id));\n\n return await Promise.allSettled(disconnectPromises);\n },\n async getSigners(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const providerProperties = info.metadata.properties;\n\n const signerProperty = providerProperties?.find(\n (property) => property.name === 'signers'\n );\n if (!signerProperty) {\n throw new Error('Your provider should contain signers property.');\n }\n\n return signerProperty.value.getSigners();\n },\n getWalletInfo(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const installLink: Exclude<WalletInfo['installLink'], string> = {\n DEFAULT: '',\n };\n\n const { metadata, deepLink } = info;\n const { extensions } = metadata;\n // `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage`\n Object.keys(extensions).forEach((k) => {\n const key = k as ExtensionLink;\n\n if (key === 'homepage') {\n installLink.DEFAULT = extensions[key] || '';\n }\n\n const allowedKeys: ExtensionLink[] = [\n 'firefox',\n 'chrome',\n 'brave',\n 'edge',\n ];\n if (allowedKeys.includes(key)) {\n const upperCasedKey = key.toUpperCase() as keyof Exclude<\n WalletInfo['installLink'],\n string\n >;\n installLink[upperCasedKey] = extensions[key] || '';\n }\n });\n\n const providerProperties = metadata.properties;\n\n const namespacesProperty = providerProperties?.find(\n (property) => property.name === 'namespaces'\n );\n const derivationPathProperty = providerProperties?.find(\n (property) => property.name === 'derivationPath'\n );\n const detailsProperty = providerProperties?.find(\n (property) => property.name === 'details'\n );\n\n return {\n name: metadata.name,\n img: metadata.icon,\n installLink: installLink,\n // We don't have this values anymore, fill them with some values that communicate this.\n color: 'red',\n supportedChains: getSupportedChainsFromProvider(\n wallet,\n dataRef.current.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet,\n mobileWallet: detailsProperty?.value?.mobileWallet,\n // if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.\n showOnMobile: detailsProperty?.value?.showOnMobile,\n needsNamespace: namespacesProperty?.value,\n needsDerivationPath: derivationPathProperty?.value,\n generateDeepLink: deepLink,\n isHub: true,\n properties: metadata.properties,\n };\n },\n providers() {\n const output: Providers = {};\n\n Array.from(getHub().getAll().keys()).forEach((id) => {\n try {\n const provider = getLegacyProvider(params.allVersionedProviders, id);\n output[id] = provider.getInstance();\n } catch (e) {\n console.warn(e);\n }\n });\n\n return output;\n },\n state(type) {\n const hubState = getHub().state();\n const wallet = getHub().get(type);\n const walletState = hubState[type];\n\n if (!walletState || !wallet) {\n throw new Error(\n `It seems your requested provider doesn't exist in hub. Provider Id: ${type}`\n );\n }\n\n const accounts = walletState.namespaces\n .filter((namespace) => namespace.connected)\n .flatMap((namespace) =>\n namespace.accounts?.map(fromAccountIdToLegacyAddressFormat)\n )\n .filter((account): account is string => !!account);\n\n const namespacesState = new Map(\n Array.from(wallet.getAll(), ([_, value]) => [\n value.namespaceId,\n value.state()[0](),\n ])\n );\n\n const coreState = {\n connected: walletState.connected,\n connecting: walletState.connecting,\n installed: walletState.installed,\n reachable: true,\n accounts: accounts,\n network: null,\n namespaces: namespacesState,\n };\n return coreState;\n },\n suggestAndConnect(_type, _network): never {\n throw new Error('`suggestAndConnect` is not implemented');\n },\n };\n\n return api;\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { UseAdapterParams } from './useHubAdapter.js';\nimport type { Hub, Provider } from '@rango-dev/wallets-core';\nimport type {\n LegacyNamespaceInputForConnect,\n LegacyProviderInterface,\n} from '@rango-dev/wallets-core/legacy';\nimport type { Namespace } from '@rango-dev/wallets-core/namespaces/common';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { legacyIsEvmNamespace } from '@rango-dev/wallets-core/legacy';\nimport { Result } from 'ts-results';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from '../legacy/mod.js';\n\nimport { runSequentiallyWithoutFailure } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport {\n convertNamespaceNetworkToEvmChainId,\n isEvmNamespace,\n} from './utils.js';\n\n// Getting connected wallets from storage\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\n/**\n * Run `.connect` action on some selected namespaces (passed as param) for a provider.\n */\nasync function eagerConnect(\n type: string,\n namespacesInput: LegacyNamespaceInputForConnect[] | undefined,\n params: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n }\n) {\n const { getHub, allBlockChains } = params;\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespacesInput) {\n throw new Error('Passing namespace to `connect` is required. ');\n }\n\n const targetNamespaces: [\n LegacyNamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespacesInput.forEach((namespaceInput) => {\n const targetNamespace: Namespace = namespaceInput.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespaceInput.namespace})`\n );\n }\n\n targetNamespaces.push([namespaceInput, result]);\n });\n\n const connectNamespacesPromises = targetNamespaces.map(\n ([info, namespace]) => {\n const evmChain = legacyIsEvmNamespace(info)\n ? convertNamespaceNetworkToEvmChainId(info, allBlockChains || [])\n : undefined;\n const chain = evmChain || info.network;\n\n return async () => {\n const connectNamespacePromise = isEvmNamespace(namespace)\n ? namespace.connect(chain)\n : namespace.connect();\n return await connectNamespacePromise.catch((e) => {\n /*\n * Since we check for connect failures using `instanceof Error`\n * this check is added here to make sure the thrown error always is an instance of `Error`\n */\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e);\n });\n };\n }\n );\n\n /**\n * Sometimes calling methods on a instance in parallel, would cause an error in wallet.\n * We are running a method at a time to make sure we are covering this.\n * e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error.\n */\n const connectNamespacesResult = await runSequentiallyWithoutFailure(\n connectNamespacesPromises\n );\n\n const failedNamespaces: LegacyNamespaceInputForConnect[] = targetNamespaces\n .filter((_, index) => connectNamespacesResult[index].err)\n .map((targetNamespace) => targetNamespace[0]);\n\n if (failedNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n\n const atLeastOneNamespaceConnectedSuccessfully = connectNamespacesResult.some(\n (result) => result.ok\n );\n if (!atLeastOneNamespaceConnectedSuccessfully) {\n throw new Error(`No namespace connected for ${type}`);\n }\n return Result.all(\n ...connectNamespacesResult.filter((result) => result.ok)\n ).unwrap();\n}\n\n/**\n * Run `.canEagerConnect` action on some selected namespaces of a wallet.\n */\nasync function tryRunCanEagerConnect(\n namespaces: LegacyNamespaceInputForConnect[],\n wallet: Provider\n): Promise<{\n successNamespaces: LegacyNamespaceInputForConnect[];\n failedNamespaces: LegacyNamespaceInputForConnect[];\n}> {\n const foundNamespaces: LegacyNamespaceInputForConnect[] = [];\n const successNamespaces: LegacyNamespaceInputForConnect[] = [];\n const failedNamespaces: LegacyNamespaceInputForConnect[] = [];\n const canEagerConnectPromises: (() => Promise<boolean>)[] = [];\n\n // 1. Try find namespace instances and create canEagerConnect promises\n namespaces.forEach((namespace) => {\n const namespaceInstance = wallet.findByNamespace(namespace.namespace);\n if (namespaceInstance) {\n foundNamespaces.push(namespace);\n canEagerConnectPromises.push(\n async () => await namespaceInstance.canEagerConnect()\n );\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n // 2. Run canEagerConnect sequentially on namespaces\n const canEagerConnectResults = await runSequentiallyWithoutFailure(\n canEagerConnectPromises\n );\n\n // 3. Separate success and failed namespaces based on canEagerConnect result\n foundNamespaces.forEach((namespace, index) => {\n if (canEagerConnectResults[index].ok && canEagerConnectResults[index].val) {\n successNamespaces.push(namespace);\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n return { successNamespaces, failedNamespaces };\n}\n\n/*\n * Get last connected wallets and last connected namespaces for each of them from storage\n * Then run `.connect` on each namespace if `.canEagerConnect` returns true.\n */\nexport async function autoConnect(deps: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n wallets?: (WalletType | LegacyProviderInterface)[];\n}): Promise<void> {\n const { getHub, allBlockChains, wallets } = deps;\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletIds = Object.keys(lastConnectedWallets);\n\n const walletsToRemoveFromPersistence: string[] = [];\n\n if (walletIds.length) {\n const eagerConnectQueue: Promise<unknown>[] = [];\n\n // Run `.connect` if `.canEagerConnect` returns `true`.\n walletIds.forEach(async (providerName) => {\n if (wallets && !wallets.includes(providerName)) {\n console.warn(\n 'Trying to run auto connect for a wallet which is not included in config. Desired wallet:',\n providerName\n );\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const wallet = getHub().get(providerName);\n\n const lastConnectedNamespaces: LegacyNamespaceInputForConnect[] =\n lastConnectedWallets[providerName].map((namespace) => ({\n namespace: namespace.namespace,\n network: namespace.network,\n }));\n\n if (!lastConnectedNamespaces.length || !wallet) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const { successNamespaces, failedNamespaces } =\n await tryRunCanEagerConnect(lastConnectedNamespaces, wallet);\n\n if (!successNamespaces.length) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n } else if (failedNamespaces.length) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n wallet.id,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n eagerConnectQueue.push(\n eagerConnect(providerName, successNamespaces, {\n allBlockChains,\n getHub,\n }).catch((error) => console.warn(error))\n );\n });\n\n lastConnectedWalletsFromStorage.removeWallets(\n walletsToRemoveFromPersistence\n );\n\n await Promise.all(eagerConnectQueue);\n }\n}\n", "import type { Provider, Store } from '@rango-dev/wallets-core';\n\nimport { createStore, Hub } from '@rango-dev/wallets-core';\nimport { useRef } from 'react';\n\nimport { synchronizeHubWithConfigProviders } from './utils.js';\n\nexport function useHubRefs(providers: Provider[]) {\n const store = useRef<Store | null>(null);\n\n const hub = useRef<Hub | null>(null);\n\n function createHub() {\n const createdHub = new Hub({\n store: getStore(),\n });\n /*\n * First add providers to hub\n * This helps to `getWalletInfo` be usable, before initialize.\n */\n providers.forEach((provider) => {\n createdHub.add(provider.id, provider);\n });\n hub.current = createdHub;\n return createdHub;\n }\n\n // https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents\n function getStore() {\n if (store.current !== null) {\n return store.current;\n }\n const createdStore = createStore();\n store.current = createdStore;\n return createdStore;\n }\n\n function getHub(): Hub {\n const hubProviders = hub.current?.getAll();\n\n if (!hub.current || !hubProviders) {\n return createHub();\n }\n\n synchronizeHubWithConfigProviders(hub.current, providers);\n return hub.current;\n }\n\n return { getStore, getHub };\n}\n"],
5
- "mappings": "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",
6
- "names": ["Events", "pickVersion", "convertEvmBlockchainMetaToEvmChainInfo", "isEvmBlockchain", "LEGACY_LAST_CONNECTED_WALLETS", "HUB_LAST_CONNECTED_WALLETS", "createContext", "defaultErrorMessage", "defaultContext", "WalletContext", "useEffect", "useReducer", "Persistor", "LastConnectedWalletsFromStorage", "__name", "#storageKey", "storageKey", "providerId", "namespaces", "HUB_LAST_CONNECTED_WALLETS", "#addWalletToHub", "LEGACY_LAST_CONNECTED_WALLETS", "#addWalletToLegacy", "providerIds", "#removeWalletsFromHub", "#removeWalletsFromLegacy", "#listFromHub", "#listFromLegacy", "namespaceIds", "#removeNamespaceFromWalletHub", "lastConnectedWallets", "Persistor", "output", "provider", "storage", "storageState", "toBeAddedNamespaces", "storedNamespaces", "namespace", "storedNamespace", "persistor", "newProviderNamespaces", "wallet", "Persistor", "Wallet", "useContext", "useRef", "useEffect", "useRef", "formatAddressWithNetwork", "CAIP_BITCOIN_CHAIN_ID", "CAIP", "Err", "Ok", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "getAllLegacyProviders", "allProviders", "LEGACY_VERSION", "legacyProviders", "provider", "target", "pickVersion", "__name", "utils", "useEffect", "useRef", "useState", "Ok", "Result", "legacyIsEvmNamespace", "Result", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "createStore", "Hub", "useRef"]
4
+ "sourcesContent": ["import type { AllProxiedNamespaces } from './types.js';\nimport type { Hub, Provider, ProxiedNamespace } from '@rango-dev/wallets-core';\nimport type {\n LegacyNamespaceInputForConnect,\n LegacyProviderInterface,\n LegacyEventHandler as WalletEventHandler,\n} from '@rango-dev/wallets-core/legacy';\nimport type { CosmosActions } from '@rango-dev/wallets-core/namespaces/cosmos';\nimport type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm';\nimport type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana';\nimport type { SuiActions } from '@rango-dev/wallets-core/namespaces/sui';\nimport type { UtxoActions } from '@rango-dev/wallets-core/namespaces/utxo';\nimport type { Event } from '@rango-dev/wallets-core/store';\n\nimport { LegacyEvents as Events } from '@rango-dev/wallets-core/legacy';\nimport { type VersionedProviders } from '@rango-dev/wallets-core/utils';\nimport { pickVersion } from '@rango-dev/wallets-core/utils';\nimport {\n type AddEthereumChainParameter,\n convertEvmBlockchainMetaToEvmChainInfo,\n type WalletType,\n} from '@rango-dev/wallets-shared';\nimport { type BlockchainMeta, isEvmBlockchain } from 'rango-types';\n\nimport {\n type ConnectResult,\n HUB_LAST_CONNECTED_WALLETS,\n type ProviderProps,\n} from '../legacy/mod.js';\n\nimport {\n fromAccountIdToLegacyAddressFormat,\n isConnectResultEvm,\n isConnectResultSolana,\n} from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\n\n/* Gets a list of hub and legacy providers and returns a tuple which separates them. */\nexport function separateLegacyAndHubProviders(\n providers: VersionedProviders[]\n): [LegacyProviderInterface[], Provider[]] {\n const LEGACY_VERSION = '0.0.0';\n const HUB_VERSION = '1.0.0';\n\n const legacyProviders: LegacyProviderInterface[] = [];\n const hubProviders: Provider[] = [];\n\n providers.forEach((provider) => {\n try {\n const target = pickVersion(provider, HUB_VERSION);\n hubProviders.push(target[1]);\n } catch {\n const target = pickVersion(provider, LEGACY_VERSION);\n legacyProviders.push(target[1]);\n }\n });\n\n return [legacyProviders, hubProviders];\n}\n\nexport function findProviderByType(\n providers: Provider[],\n type: string\n): Provider | undefined {\n return providers.find((provider) => provider.id === type);\n}\n\n/**\n * We will call this function on hub's `subscribe`.\n * it will check states and will emit legacy events for backward compatibility.\n */\n\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\nexport function getSupportedChainsFromProvider(\n provider: Provider,\n allBlockChains: ProviderProps['allBlockChains']\n) {\n const namespacesProperty = provider\n .info()\n ?.metadata.properties?.find((property) => property.name === 'namespaces');\n\n const supportedChains =\n namespacesProperty?.value.data.flatMap((namespace) =>\n namespace.getSupportedChains(allBlockChains || [])\n ) || [];\n\n return supportedChains;\n}\n\nexport function mapHubEventsToLegacy(\n hub: Hub,\n event: Event,\n onUpdateState: WalletEventHandler,\n metadata: {\n allBlockChains: ProviderProps['allBlockChains'];\n lastConnectAttemptParams: {\n [type: WalletType]: LegacyNamespaceInputForConnect[];\n };\n }\n): void {\n const provider = hub.get(event.provider);\n if (!provider) {\n throw new Error(\n \"Currently all the events have assigned to a provider. The event doesn't include one.\",\n {\n cause: event,\n }\n );\n }\n\n // @ts-expect-error for those events that doesn't have namespace, it will be undefinded\n const namespaceId: string | undefined = event.namespace;\n\n const namespace = namespaceId\n ? provider.findByNamespace(namespaceId)\n : undefined;\n let accounts: string[] | null = null;\n let network: string | null = null;\n let derivationPath: string | undefined;\n\n if (namespace) {\n const [getNamespaceState] = namespace.state();\n accounts = getNamespaceState().accounts;\n network = getNamespaceState().network;\n\n if (metadata.lastConnectAttemptParams[event.provider]) {\n derivationPath = metadata.lastConnectAttemptParams[event.provider].find(\n (namespace) => namespace.namespace === namespaceId\n )?.derivationPath;\n }\n }\n\n const [getProviderState] = provider.state();\n const coreState = {\n connected: getProviderState().connected,\n connecting: getProviderState().connecting,\n installed: getProviderState().installed,\n accounts,\n network,\n reachable: true,\n derivationPath,\n };\n\n const eventInfo = {\n supportedBlockchains: getSupportedChainsFromProvider(\n provider,\n metadata.allBlockChains\n ),\n isContractWallet: false,\n isHub: true,\n namespace: namespaceId,\n };\n\n switch (event.type) {\n case 'provider_detected':\n onUpdateState(\n event.provider,\n Events.INSTALLED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connecting':\n onUpdateState(\n event.provider,\n Events.CONNECTING,\n event.value,\n coreState,\n eventInfo\n );\n break;\n case 'provider_connected':\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n true,\n coreState,\n eventInfo\n );\n break;\n case 'provider_disconnected':\n onUpdateState(\n event.provider,\n Events.PROVIDER_DISCONNECTED,\n event.provider,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.CONNECTED,\n false,\n coreState,\n eventInfo\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n null,\n coreState,\n eventInfo\n );\n break;\n case 'namespace_disconnected':\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n event.provider,\n [event.namespace]\n );\n\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n // onUpdateState(event.provider, Events.ACCOUNTS, null, coreState, eventInfo);\n break;\n case 'namespace_connected':\n case 'namespace_account_switched':\n {\n if (event.type === 'namespace_account_switched') {\n onUpdateState(\n event.provider,\n Events.NAMESPACE_DISCONNECTED,\n event.namespace,\n coreState,\n eventInfo\n );\n }\n\n const formattedAddresses = event.accounts.map(\n fromAccountIdToLegacyAddressFormat\n );\n onUpdateState(\n event.provider,\n Events.ACCOUNTS,\n formattedAddresses,\n coreState,\n {\n ...eventInfo,\n namespace: event.namespace,\n }\n );\n }\n break;\n case 'namespace_network_switched':\n onUpdateState(event.provider, Events.NETWORK, event.network, coreState, {\n ...eventInfo,\n namespace: event.namespace,\n });\n break;\n }\n}\n\nexport function getAllLegacyProviders(\n allProviders: VersionedProviders[]\n): LegacyProviderInterface[] {\n const LEGACY_VERSION = '0.0.0';\n\n const legacyProviders: LegacyProviderInterface[] = [];\n\n allProviders.forEach((provider) => {\n const target = pickVersion(provider, LEGACY_VERSION);\n legacyProviders.push(target[1]);\n });\n\n return legacyProviders;\n}\n\nexport function getLegacyProvider(\n allProviders: VersionedProviders[],\n type: string\n): LegacyProviderInterface {\n const legacyProviders: LegacyProviderInterface[] =\n getAllLegacyProviders(allProviders);\n\n const provider = legacyProviders.find((legacyProvider) => {\n return legacyProvider.config.type === type;\n });\n\n if (!provider) {\n console.warn(\n `You have a provider that doesn't have legacy provider. It causes some problems since we need some legacy functionality. Provider Id: ${type}`\n );\n throw new Error(\n `You need to have legacy implementation to use some methods. Provider Id: ${type}`\n );\n }\n\n return provider;\n}\n\n/**\n * In legacy mode, for those who have switch network functionality (like evm), we are using an enum for network names\n * this enum only has meaning for us, and when we are going to connect an instance (e.g. window.ethereum) we should pass chain id.\n */\nexport function convertNamespaceNetworkToEvmChainId(\n namespace: LegacyNamespaceInputForConnect,\n meta: BlockchainMeta[]\n) {\n if (!namespace.network) {\n return undefined;\n }\n\n const evmBlockchainsList = meta.filter(isEvmBlockchain);\n const evmChains = convertEvmBlockchainMetaToEvmChainInfo(evmBlockchainsList);\n\n return evmChains[namespace.network];\n}\n\n/**\n * We are passing an string for chain id (e.g. ETH, POLYGON), but wallet's instances (e.g. window.ethereum) needs chainId (e.g. 0x1).\n * This function will help us to map these strings to proper hex ids.\n *\n * If you need same functionality for other blockchain types (e.g. Cosmos), You can make a separate function and add it here.\n */\nexport function tryConvertNamespaceNetworkToChainInfo(\n namespace: LegacyNamespaceInputForConnect,\n meta: BlockchainMeta[]\n): string | AddEthereumChainParameter | undefined {\n // `undefined` means it's not evm or we couldn't find it in meta.\n const evmChain = convertNamespaceNetworkToEvmChainId(namespace, meta);\n const network = evmChain || namespace.network;\n\n return network;\n}\n\nexport function transformHubResultToLegacyResult(\n res: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): ConnectResult {\n if (isConnectResultEvm(res)) {\n return {\n accounts: res.accounts,\n network: res.network,\n provider: undefined,\n };\n } else if (isConnectResultSolana(res)) {\n return {\n accounts: res,\n network: null,\n provider: undefined,\n };\n }\n\n return {\n accounts: [res],\n network: null,\n provider: undefined,\n };\n}\n\n/**\n * Synchronizes providers in the hub with the configuration providers.\n * - Registers and initializes any configuration providers not yet in the hub\n * - Removes providers from the hub that aren't in the configuration\n */\nexport function synchronizeHubWithConfigProviders(\n hub: Hub,\n configurationProviders: Provider[]\n) {\n const registeredProviders = hub.getAll();\n\n // Register and initialize providers that exist in config but not in hub\n const providersToRegister = configurationProviders.filter(\n (configProvider) => !registeredProviders.get(configProvider.id)\n );\n\n providersToRegister.forEach((providerToRegister) => {\n hub.add(providerToRegister.id, providerToRegister);\n providerToRegister.init();\n });\n\n // Remove providers that exist in hub but not in config\n registeredProviders.forEach((registeredProvider) => {\n const isProviderInConfig = configurationProviders.some(\n (configProvider) => configProvider.id === registeredProvider.id\n );\n\n if (!isProviderInConfig) {\n hub.remove(registeredProvider.id);\n }\n });\n}\n\nexport function isSolanaNamespace(\n ns: ProxiedNamespace<\n EvmActions | SolanaActions | CosmosActions | SuiActions | UtxoActions\n >\n): ns is ProxiedNamespace<SolanaActions> & { namespaceId: 'Solana' } {\n return ns.namespaceId === 'Solana';\n}\nexport function isEvmNamespace(\n ns: ProxiedNamespace<\n EvmActions | SolanaActions | CosmosActions | SuiActions | UtxoActions\n >\n): ns is ProxiedNamespace<EvmActions> & { namespaceId: 'EVM' } {\n return ns.namespaceId === 'EVM';\n}\n", "export const LEGACY_LAST_CONNECTED_WALLETS = 'last-connected-wallets';\nexport const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets';\n", "import type { ProviderContext } from './types.js';\n\nimport { createContext } from 'react';\n\nconst defaultErrorMessage = \"Context hasn't been initialized yet.\";\nconst defaultContext: ProviderContext = {\n async connect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnect() {\n throw new Error(defaultErrorMessage);\n },\n async disconnectAll() {\n throw new Error(defaultErrorMessage);\n },\n async suggestAndConnect() {\n throw new Error(defaultErrorMessage);\n },\n state() {\n throw new Error(defaultErrorMessage);\n },\n canSwitchNetworkTo() {\n throw new Error(defaultErrorMessage);\n },\n providers() {\n throw new Error(defaultErrorMessage);\n },\n getWalletInfo() {\n throw new Error(defaultErrorMessage);\n },\n getSigners() {\n throw new Error(defaultErrorMessage);\n },\n};\n\nexport const WalletContext = createContext<ProviderContext>(defaultContext);\n", "import type { ProviderContext, ProviderProps } from './types.js';\nimport type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { useEffect, useReducer } from 'react';\n\nimport { autoConnect } from './autoConnect.js';\nimport {\n availableWallets,\n checkWalletProviders,\n clearPersistance,\n connectedWallets,\n defaultWalletState,\n makeEventHandler,\n stateReducer,\n tryPersistWallet,\n tryRemoveWalletFromPersistance,\n} from './helpers.js';\nimport { useInitializers } from './hooks.js';\nimport { useAutoConnect } from './useAutoConnect.js';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ProviderType = any;\n\nexport type LegacyProviderProps = Omit<ProviderProps, 'providers'> & {\n providers: LegacyProviderInterface[];\n};\n\nexport function useLegacyProviders(\n props: LegacyProviderProps\n): ProviderContext {\n const [providersState, dispatch] = useReducer(stateReducer, {});\n\n // Get (or add) wallet instance (`provider`s will be wrapped in a `Wallet`)\n const getWalletInstance = useInitializers(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n\n // Getting providers from props and put all of them in a `Map` with an appropriate interface.\n const listOfProviders = props.providers;\n const wallets = checkWalletProviders(listOfProviders);\n\n useAutoConnect({\n allBlockChains: props.allBlockChains,\n autoConnect: props.autoConnect,\n autoConnectHandler: async () => autoConnect(wallets, getWalletInstance),\n });\n\n // Final API we put in context and it will be available to use for users.\n const api: ProviderContext = {\n async connect(type, namespaces) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n // Legacy providers doesn't implemented multiple namespaces, so it will always be one value.\n let network = undefined;\n if (namespaces && namespaces.length > 0) {\n /*\n * This may not be safe in cases there are two `network` for namespaces, the first one will be picked always.\n * But since legacy provider only accepts one value, it shouldn't be happened when we are using legacy mode.\n */\n network = namespaces.find((ns) => !!ns.network)?.network;\n }\n\n const walletInstance = getWalletInstance(wallet);\n const result = await walletInstance.connect(network, namespaces);\n if (props.autoConnect) {\n void tryPersistWallet({\n type,\n walletActions: wallet.actions,\n getState: api.state,\n });\n }\n\n return [result];\n },\n async disconnect(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const walletInstance = getWalletInstance(wallet);\n await walletInstance.disconnect();\n if (props.autoConnect) {\n tryRemoveWalletFromPersistance({ type, walletActions: wallet.actions });\n }\n },\n async disconnectAll() {\n const disconnect_promises: Promise<void>[] = [];\n\n /*\n * When a wallet is initializing, a record will be added to `providersState`\n * So we use them to know what wallet has been initialized then we need to\n * filter connected wallets only.\n */\n connectedWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n disconnect_promises.push(walletInstance.disconnect());\n }\n });\n\n if (props.autoConnect) {\n clearPersistance();\n }\n return await Promise.allSettled(disconnect_promises);\n },\n\n async suggestAndConnect(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const result = await walletInstance.suggestAndConnect(network);\n\n return result;\n },\n\n state(type) {\n return providersState[type] || defaultWalletState;\n },\n canSwitchNetworkTo(type, network) {\n const wallet = wallets.get(type);\n if (!wallet) {\n return false;\n }\n\n const walletInstance = getWalletInstance(wallet);\n return walletInstance.canSwitchNetworkTo\n ? walletInstance.canSwitchNetworkTo(network, walletInstance.provider)\n : false;\n },\n providers() {\n const providers: { [type in WalletType]?: ProviderType } = {};\n availableWallets(providersState).forEach((type) => {\n const wallet = wallets.get(type);\n if (wallet) {\n const walletInstance = getWalletInstance(wallet);\n providers[type] = walletInstance.provider;\n }\n });\n\n return providers;\n },\n getWalletInfo(type) {\n const wallet = wallets.get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n /*\n * Get wallet info could be used in render methods to show wallets data\n * So, addWalletRef method shouldn't be called in this method\n */\n\n return wallet.actions.getWalletInfo(props.allBlockChains || []);\n },\n async getSigners(type) {\n const wallet = wallets.get(type);\n\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n const walletInstance = getWalletInstance(wallet);\n const provider = walletInstance.provider;\n const result = walletInstance.getSigners(provider);\n\n return result;\n },\n };\n\n // Initialize instances\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const runOnInit = () => {\n if (walletInstance.onInit) {\n walletInstance.onInit();\n }\n };\n\n const initWhenPageIsReady = (event: Event) => {\n if (\n event.target &&\n (event.target as Document).readyState === 'complete'\n ) {\n runOnInit();\n\n document.removeEventListener('readystatechange', initWhenPageIsReady);\n }\n };\n\n // Try to run, maybe it's ready.\n runOnInit();\n\n /*\n * Try again when the page has been completely loaded.\n * Some of wallets, take some time to be fully injected and loaded.\n */\n document.addEventListener('readystatechange', initWhenPageIsReady);\n });\n }, []);\n\n // Setting supported blockchains on instances\n useEffect(() => {\n const allBlockChains = props.allBlockChains;\n if (allBlockChains) {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n const walletInfo = walletInstance.getWalletInfo(\n props.allBlockChains || []\n );\n walletInstance.setInfo({\n supportedBlockchains: walletInfo.supportedChains,\n isContractWallet: !!walletInfo.isContractWallet,\n });\n });\n }\n }, [props.allBlockChains]);\n\n // Setting event handler on instances\n useEffect(() => {\n wallets.forEach((wallet) => {\n const walletInstance = getWalletInstance(wallet);\n walletInstance.setHandler(\n makeEventHandler(dispatch, props.onUpdateState)\n );\n });\n }, [props.onUpdateState]);\n\n return api;\n}\n", "import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';\n\nimport { Persistor } from '@rango-dev/wallets-core/legacy';\n\nimport {\n HUB_LAST_CONNECTED_WALLETS,\n LEGACY_LAST_CONNECTED_WALLETS,\n} from './constants.js';\n\nexport interface NamespaceInput {\n namespace: Namespace;\n network: string | undefined;\n}\n\nexport interface LastConnectedWalletsStorage {\n [providerId: string]: NamespaceInput[];\n}\n\nexport type LegacyLastConnectedWalletsStorage = string[];\n\n/**\n * We are doing some certain actions on storage for `last-connected-wallets` key.\n * This class helps us to define them in one place and also it has support for both legacy and hub.\n */\nexport class LastConnectedWalletsFromStorage {\n #storageKey: string;\n\n constructor(storageKey: string) {\n this.#storageKey = storageKey;\n }\n\n addWallet(providerId: string, namespaces: NamespaceInput[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToHub(providerId, namespaces);\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#addWalletToLegacy(providerId);\n }\n throw new Error('Not implemented');\n }\n removeWallets(providerIds?: string[]): void {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromHub(providerIds);\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#removeWalletsFromLegacy(providerIds);\n }\n throw new Error('Not implemented');\n }\n list(): LastConnectedWalletsStorage {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#listFromHub();\n } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {\n return this.#listFromLegacy();\n }\n throw new Error('Not implemented');\n }\n removeNamespacesFromWallet(providerId: string, namespaceIds: string[]) {\n if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {\n return this.#removeNamespaceFromWalletHub(providerId, namespaceIds);\n }\n throw new Error('Not implemented');\n }\n\n #listFromLegacy(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS) || [];\n const output: LastConnectedWalletsStorage = {};\n lastConnectedWallets.forEach((provider) => {\n // Setting empty namespaces\n output[provider] = [];\n });\n return output;\n }\n #listFromHub(): LastConnectedWalletsStorage {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const lastConnectedWallets =\n persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};\n return lastConnectedWallets;\n }\n #addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {\n const storage = new Persistor<LastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || {};\n\n let toBeAddedNamespaces = namespaces;\n\n // If provider already exits in the storage, we should just add new namespaces to the previously added namespaces.\n if (!!storageState[providerId]) {\n const storedNamespaces = storageState[providerId];\n toBeAddedNamespaces = storedNamespaces.concat(\n namespaces.filter(\n (namespace) =>\n !storedNamespaces.some(\n (storedNamespace) =>\n storedNamespace.namespace === namespace.namespace\n )\n )\n );\n }\n\n storage.setItem(this.#storageKey, {\n ...storageState,\n [providerId]: toBeAddedNamespaces,\n });\n }\n #addWalletToLegacy(providerId: string): void {\n const storage = new Persistor<LegacyLastConnectedWalletsStorage>();\n const storageState = storage.getItem(this.#storageKey) || [];\n\n storage.setItem(\n LEGACY_LAST_CONNECTED_WALLETS,\n storageState.concat(providerId)\n );\n }\n #removeWalletsFromHub(providerIds?: string[]): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, {});\n return;\n }\n\n // Remove some of the wallets\n providerIds.forEach((providerId) => {\n if (storageState[providerId]) {\n delete storageState[providerId];\n }\n });\n\n persistor.setItem(this.#storageKey, storageState);\n }\n #removeNamespaceFromWalletHub(\n providerId: string,\n namespaceIds: string[]\n ): void {\n const persistor = new Persistor<LastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || {};\n\n const currentProviderNamespaces = storageState[providerId];\n const newProviderNamespaces = currentProviderNamespaces?.filter(\n (namespace) => !namespaceIds.includes(namespace.namespace)\n );\n\n this.#removeWalletsFromHub([providerId]);\n if (newProviderNamespaces?.length > 0) {\n this.#addWalletToHub(providerId, newProviderNamespaces);\n }\n }\n #removeWalletsFromLegacy(providerIds?: string[]): void {\n const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();\n const storageState = persistor.getItem(this.#storageKey) || [];\n\n // Remove all wallets\n if (!providerIds) {\n persistor.setItem(this.#storageKey, []);\n return;\n }\n\n // Remove some of the wallets\n persistor.setItem(\n LEGACY_LAST_CONNECTED_WALLETS,\n storageState.filter((wallet) => !providerIds.includes(wallet))\n );\n }\n}\n", "import type {\n ProviderInterface,\n State,\n WalletActions,\n WalletProviders,\n} from './types.js';\nimport type {\n LegacyOptions as Options,\n LegacyEventHandler as WalletEventHandler,\n LegacyState as WalletState,\n} from '@rango-dev/wallets-core/legacy';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { Persistor } from '@rango-dev/wallets-core/legacy';\n\nimport { LEGACY_LAST_CONNECTED_WALLETS } from '../hub/constants.js';\nimport { LastConnectedWalletsFromStorage } from '../hub/lastConnectedWallets.js';\n\nexport function choose(wallets: any[], type: WalletType): any | null {\n return wallets.find((wallet) => wallet.type === type) || null;\n}\n\nexport const defaultWalletState: WalletState = {\n connected: false,\n connecting: false,\n reachable: false,\n installed: false,\n accounts: null,\n network: null,\n};\n\nexport function stateReducer(state: State, action: any) {\n if (action.type === 'new_state') {\n // TODO fix problem and remove ts-ignore\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const target_wallet = state[action.wallet];\n if (!target_wallet) {\n return {\n ...state,\n [action.wallet]: {\n ...defaultWalletState,\n [action.name]: action.value,\n },\n };\n }\n\n return {\n ...state,\n [action.wallet]: {\n ...target_wallet,\n [action.name]: action.value,\n },\n };\n }\n\n return state;\n}\n\nexport function connectedWallets(providersState: State): WalletType[] {\n return Object.entries(providersState)\n .filter(([, wallet_state]) => {\n return wallet_state?.connected;\n })\n .map(([type]) => {\n return type;\n });\n}\n\nexport function availableWallets(providersState: State): WalletType[] {\n return Object.entries(providersState).map(([type]) => {\n return type;\n });\n}\n\nexport function checkWalletProviders(\n list: ProviderInterface[]\n): WalletProviders {\n const wallets: WalletProviders = new Map();\n\n list.forEach((provider) => {\n const { config, ...actions } = provider;\n wallets.set(config.type, {\n actions,\n config,\n });\n });\n\n return wallets;\n}\n\n/* eslint-disable @typescript-eslint/ban-types */\nexport function isAsync(fn: Function) {\n return fn?.constructor?.name === 'AsyncFunction';\n}\n\nexport function needsCheckInstallation(options: Options) {\n const { checkInstallation = true } = options.config;\n return checkInstallation;\n}\n\nexport async function tryPersistWallet({\n type,\n walletActions,\n getState,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n getState: (walletType: WalletType) => WalletState;\n}) {\n if (walletActions.canEagerConnect) {\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n LEGACY_LAST_CONNECTED_WALLETS\n );\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletAlreadyPersisted = !!lastConnectedWallets[type];\n\n /*\n *If on the last attempt we are unable to eagerly connect to any wallet and the user connects any wallet manualy,\n *persistance will be outdated and will need to be removed.\n */\n if (walletAlreadyPersisted && !getState(type).connected) {\n clearPersistance();\n }\n\n if (!walletAlreadyPersisted) {\n lastConnectedWalletsFromStorage.addWallet(type, []);\n }\n }\n}\n\nexport function tryRemoveWalletFromPersistance({\n type,\n walletActions,\n}: {\n type: WalletType;\n walletActions: WalletActions;\n}) {\n if (walletActions.canEagerConnect) {\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n LEGACY_LAST_CONNECTED_WALLETS\n );\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n}\n\nexport function clearPersistance() {\n const persistor = new Persistor<string[]>();\n const wallets = persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS);\n if (wallets) {\n persistor.removeItem(LEGACY_LAST_CONNECTED_WALLETS);\n }\n}\n\n/*\n *Our event handler includes an internal state updater, and a notifier\n *for the outside listener.\n *On creating first wallet refrence, and on chaning `props.onUpdateState`\n *we are using this function.\n */\nexport function makeEventHandler(\n dispatcher: any,\n onUpdateState?: WalletEventHandler\n) {\n const handler: WalletEventHandler = (\n type,\n name,\n value,\n coreState,\n supportedChains\n ) => {\n const action = { type: 'new_state', wallet: type, name, value };\n // Update state\n dispatcher(action);\n\n // Giving the event to the outside listener\n if (onUpdateState) {\n onUpdateState(type, name, value, coreState, supportedChains);\n }\n };\n\n return handler;\n}\n", "import type { ProviderContext, WalletActions, WalletConfig } from './types.js';\nimport type { LegacyEventHandler as WalletEventHandler } from '@rango-dev/wallets-core/legacy';\n\nimport { LegacyWallet as Wallet } from '@rango-dev/wallets-core/legacy';\nimport { useContext, useRef } from 'react';\n\nimport { WalletContext } from './context.js';\n\nexport type GetWalletInstance = (wallet: {\n actions: WalletActions;\n config: WalletConfig;\n}) => Wallet;\n\nexport function useInitializers(\n onChangeState: WalletEventHandler\n): GetWalletInstance {\n const availableWallets = useRef<{\n [key: string]: Wallet | undefined;\n }>({});\n\n /*\n * If `wallet` hasn't been added to `availableWallets`,\n * Get a instance of `Wallet` and save the refrence in `availableWallets`.\n * Otherwise, return the already created instance.\n */\n function updater(wallet: {\n actions: WalletActions;\n config: WalletConfig;\n }): Wallet {\n const type = wallet.config.type;\n // We only update, if there is no instance available.\n if (typeof availableWallets.current[type] === 'undefined') {\n availableWallets.current[type] = new Wallet(\n {\n config: wallet.config,\n handler: onChangeState,\n },\n wallet.actions\n );\n }\n\n return availableWallets.current[type]!;\n }\n\n return updater;\n}\n\nexport function useWallets(): ProviderContext {\n const context = useContext(WalletContext);\n if (!context) {\n throw Error('useWallet can only be used within the Provider component');\n }\n return context;\n}\n", "import type { ProviderProps } from './types.js';\n\nimport { useEffect, useRef } from 'react';\n\nimport { shouldTryAutoConnect } from './utils.js';\n\nexport function useAutoConnect(\n props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'> & {\n /**\n * A function to run autoConnect on instances\n */\n autoConnectHandler: () => void;\n }\n) {\n const autoConnectInitiated = useRef(false);\n\n useEffect(() => {\n if (shouldTryAutoConnect(props) && !autoConnectInitiated.current) {\n autoConnectInitiated.current = true;\n props.autoConnectHandler();\n }\n }, [props.autoConnect, props.allBlockChains]);\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type {\n Accounts,\n AccountsWithActiveChain,\n} from '@rango-dev/wallets-core/namespaces/common';\nimport type { Result } from 'ts-results';\n\nimport { legacyFormatAddressWithNetwork as formatAddressWithNetwork } from '@rango-dev/wallets-core/legacy';\nimport { CAIP_BITCOIN_CHAIN_ID } from '@rango-dev/wallets-core/namespaces/utxo';\nimport { CAIP } from '@rango-dev/wallets-core/utils';\nimport { Err, Ok } from 'ts-results';\n\nexport function mapCaipNamespaceToLegacyNetworkName(\n chainId: CAIP.ChainIdParams | string\n): string {\n if (typeof chainId === 'string') {\n return chainId;\n }\n const useNamespaceAsNetworkFor = ['solana'];\n\n if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) {\n return chainId.namespace.toUpperCase();\n }\n\n if (chainId.namespace.toLowerCase() === 'eip155') {\n return 'ETH';\n } else if (chainId.reference === CAIP_BITCOIN_CHAIN_ID) {\n return 'BTC';\n }\n\n if (chainId.namespace === 'sui') {\n return chainId.reference.toUpperCase();\n }\n\n return chainId.reference;\n}\n\n/**\n * CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb\n * This function will try to convert this two format.\n *\n * @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md\n */\nexport function fromAccountIdToLegacyAddressFormat(account: string): string {\n const { chainId, address } = CAIP.AccountId.parse(account);\n const network = mapCaipNamespaceToLegacyNetworkName(chainId);\n return formatAddressWithNetwork(address, network);\n}\n\n/**\n * Getting a list of (lazy) promises and run them one after another.\n */\n\nexport async function runSequentiallyWithoutFailure<R>(\n promises: Array<() => Promise<R>>\n): Promise<Result<R, unknown>[]> {\n return promises.reduce(async (prevPromise, task) => {\n const previousResults = await prevPromise;\n try {\n const taskResult = await task();\n return [...previousResults, new Ok(taskResult)];\n } catch (error) {\n return [...previousResults, new Err(error)];\n }\n }, Promise.resolve<Result<R, unknown>[]>([]));\n}\n\nexport function isConnectResultEvm(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is AccountsWithActiveChain {\n return typeof result === 'object' && !Array.isArray(result);\n}\n\nexport function isConnectResultSolana(\n result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>\n): result is Accounts {\n return Array.isArray(result);\n}\n\ntype QueueItem<T> = {\n task: () => Promise<T>;\n resolve: (value: Result<T, unknown>) => void;\n key: string;\n};\n/**\n * Creates a queue manager that ensures sequential execution of tasks by key.\n * When multiple tasks with the same key are queued, they are executed one at a time\n * in the order they were added. This prevents race conditions and ensures\n * predictable task execution order.\n *\n */\nexport function createQueue(options?: {\n onError?: (\n error: unknown,\n actions: {\n removeCurrentKeyFromQueue: () => void;\n }\n ) => void;\n}) {\n const processingKeys = new Set<string>();\n let queue: QueueItem<unknown>[] = [];\n\n const removeKeyFromQueue = (\n key: string,\n result: Result<unknown, unknown>\n ) => {\n queue = queue.filter((q) => {\n if (q.key !== key) {\n return true;\n }\n q.resolve(result);\n return false;\n });\n };\n\n const processQueue = async () => {\n const currentItem = queue.find((item) => !processingKeys.has(item.key));\n if (!currentItem) {\n return;\n }\n\n const { task, resolve, key } = currentItem;\n processingKeys.add(key);\n\n try {\n const result = await task();\n resolve(new Ok(result));\n } catch (error) {\n if (options?.onError) {\n options.onError(error, {\n removeCurrentKeyFromQueue: () =>\n removeKeyFromQueue(key, new Err(error)),\n });\n }\n\n resolve(new Err(error));\n } finally {\n const indexOfCurrentItem = queue.findIndex((item) => item.key === key);\n if (indexOfCurrentItem >= 0) {\n queue.splice(indexOfCurrentItem, 1);\n }\n processingKeys.delete(key);\n void processQueue();\n }\n };\n\n const queueTask = async <T>(\n task: () => Promise<T>,\n key: string\n ): Promise<Result<T, unknown>> =>\n new Promise((resolve) => {\n queue.push({\n task,\n resolve: resolve as (value: Result<unknown, unknown>) => void,\n key,\n });\n void processQueue();\n });\n\n return queueTask;\n}\n", "import type { AllProxiedNamespaces, ExtensionLink } from './types.js';\nimport type { ProviderContext, Providers } from '../index.js';\nimport type { Provider } from '@rango-dev/wallets-core';\nimport type { LegacyNamespaceInputForConnect } from '@rango-dev/wallets-core/legacy';\nimport type {\n Accounts,\n AccountsWithActiveChain,\n} from '@rango-dev/wallets-core/namespaces/common';\nimport type { VersionedProviders } from '@rango-dev/wallets-core/utils';\n\nimport { utils } from '@rango-dev/wallets-core/namespaces/evm';\nimport { type WalletInfo, type WalletType } from '@rango-dev/wallets-shared';\nimport { useEffect, useRef, useState } from 'react';\nimport { Ok, Result } from 'ts-results';\n\nimport {\n type ConnectResult,\n HUB_LAST_CONNECTED_WALLETS,\n type ProviderProps,\n} from '../legacy/mod.js';\nimport { useAutoConnect } from '../legacy/useAutoConnect.js';\n\nimport { autoConnect } from './autoConnect.js';\nimport { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport { useHubRefs } from './useHubRefs.js';\nimport {\n getLegacyProvider,\n getSupportedChainsFromProvider,\n isEvmNamespace,\n isSolanaNamespace,\n mapHubEventsToLegacy,\n transformHubResultToLegacyResult,\n tryConvertNamespaceNetworkToChainInfo,\n} from './utils.js';\n\nexport type UseAdapterParams = Omit<ProviderProps, 'providers'> & {\n providers: Provider[];\n /** This is only will be used to access some parts of the legacy provider that doesn't exists in Hub. */\n allVersionedProviders: VersionedProviders[];\n};\n\nexport function useHubAdapter(params: UseAdapterParams): ProviderContext {\n const { getStore, getHub } = useHubRefs(params.providers);\n const [, rerender] = useState(0);\n // useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes.\n const dataRef = useRef({\n onUpdateState: params.onUpdateState,\n allVersionedProviders: params.allVersionedProviders,\n allBlockChains: params.allBlockChains,\n });\n\n /*\n * Params of each connection attempt for each wallet type are stored here.\n * Derivation path from params is used in `mapHubEventsToLegacy` to be added to the payload of connect events.\n */\n const lastConnectAttemptParamsRef = useRef<{\n [type: WalletType]: LegacyNamespaceInputForConnect[];\n }>({});\n\n const updateLastConnectAttemptParams = (\n type: WalletType,\n namespaces: LegacyNamespaceInputForConnect[] | undefined\n ) => {\n lastConnectAttemptParamsRef.current[type] = namespaces || [];\n };\n\n const queueTask = createQueue({\n onError: (error, actions) => {\n if (utils.isUserRejectionError(error)) {\n actions.removeCurrentKeyFromQueue();\n }\n },\n });\n\n useEffect(() => {\n dataRef.current = {\n onUpdateState: params.onUpdateState,\n allVersionedProviders: params.allVersionedProviders,\n allBlockChains: params.allBlockChains,\n };\n }, [params]);\n\n // Initialize instances\n useEffect(() => {\n const runOnInit = () => {\n getHub().init();\n\n rerender((currentRender) => currentRender + 1);\n };\n\n // Then will call init whenever page is ready.\n const initHubWhenPageIsReady = (event: Event) => {\n // Then will call init whenever page is ready.\n if (\n event.target &&\n (event.target as Document).readyState === 'complete'\n ) {\n runOnInit();\n document.removeEventListener(\n 'readystatechange',\n initHubWhenPageIsReady\n );\n }\n };\n\n // Try to run, maybe it's ready.\n runOnInit();\n\n /*\n * Try again when the page has been completely loaded.\n * Some of wallets, take some time to be fully injected and loaded.\n */\n document.addEventListener('readystatechange', initHubWhenPageIsReady);\n\n getStore()\n .subscribe((event) => {\n if (dataRef.current.onUpdateState) {\n try {\n mapHubEventsToLegacy(\n getHub(),\n event,\n dataRef.current.onUpdateState,\n {\n allBlockChains: dataRef.current.allBlockChains,\n lastConnectAttemptParams: lastConnectAttemptParamsRef.current,\n }\n );\n } catch (e) {\n console.error(e);\n }\n }\n rerender((currentRender) => currentRender + 1);\n })\n .flushEvents();\n }, []);\n\n useAutoConnect({\n autoConnect: params.autoConnect,\n allBlockChains: params.allBlockChains,\n autoConnectHandler: () => {\n void autoConnect({\n allBlockChains: params.allBlockChains,\n getHub,\n wallets: params.configs?.wallets,\n });\n },\n });\n\n const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n );\n\n const api: ProviderContext = {\n canSwitchNetworkTo(type, network, namespace) {\n const provider = getHub().get(type);\n\n if (!provider) {\n throw new Error(\n `You should add ${type} to provider first then call 'canSwitchNetworkTo'.`\n );\n }\n\n if (!namespace) {\n throw new Error(\n 'Passing namespace to `canSwitchNetworkTo` is required.'\n );\n }\n\n const proxiedNamespace = provider.findByNamespace(namespace.namespace);\n if (!proxiedNamespace) {\n throw new Error(\n `We couldn't find any matched namespace on your request provider. (requested namespace: ${namespace.namespace})`\n );\n }\n if (!('canSwitchNetwork' in proxiedNamespace)) {\n return false;\n }\n const namespacesProperty = provider\n .info()\n ?.metadata?.properties?.find(\n (property) => property.name === 'namespaces'\n );\n\n if (!dataRef.current.allBlockChains) {\n throw new Error(`Blockchains are not available`);\n }\n const providerSupportedChainsOfNamespace = namespacesProperty?.value.data\n .find(\n (providerNamespace) => providerNamespace.value === namespace.namespace\n )\n ?.getSupportedChains(dataRef.current.allBlockChains);\n\n if (!providerSupportedChainsOfNamespace) {\n throw new Error(\n `NamespaceMeta is not defined for requested namespace: ${namespace.namespace}`\n );\n }\n\n return proxiedNamespace.canSwitchNetwork({\n network,\n supportedChains: providerSupportedChainsOfNamespace,\n });\n },\n async connect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespaces) {\n throw new Error('Passing namespace to `connect` is required.');\n }\n\n updateLastConnectAttemptParams(type, namespaces);\n\n // Check `namespace` and look into hub to see how it can match given namespace to hub namespace.\n const targetNamespaces: [\n LegacyNamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespaces.forEach((namespace) => {\n const targetNamespace = namespace.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`\n );\n }\n\n targetNamespaces.push([namespace, result]);\n });\n\n // Try to run `connect` on matched namespaces\n const connectResultFromTargetNamespaces = targetNamespaces.map(\n async ([namespaceInput, namespace]) => {\n const network = tryConvertNamespaceNetworkToChainInfo(\n namespaceInput,\n params.allBlockChains || []\n );\n\n let connectNamespacePromise: () => Promise<\n Accounts | string | AccountsWithActiveChain\n >;\n\n if (isSolanaNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect({\n derivationPath: namespaceInput.derivationPath,\n });\n } else if (isEvmNamespace(namespace)) {\n connectNamespacePromise = async () =>\n namespace.connect(network, {\n derivationPath: namespaceInput.derivationPath,\n });\n } else {\n connectNamespacePromise = async () => namespace.connect();\n }\n\n const connectNamespaceProcess = async () =>\n connectNamespacePromise()\n .then<ConnectResult>(transformHubResultToLegacyResult)\n .then((connectResult) => {\n return {\n response: connectResult,\n input: {\n namespace: namespaceInput.namespace,\n network: namespaceInput.network,\n supportsEagerConnect: 'canEagerConnect' in namespace,\n },\n };\n });\n return queueTask(connectNamespaceProcess, type);\n }\n );\n\n /*\n * We need to connect to namespace one after another, sending multiple requests at the same time may be failed.\n * e.g. when wallet popup opens and asking for the password from the user, it should be resolved first, then other request will be resolved.\n */\n const connectResultWithLegacyFormat = await Promise.all(\n connectResultFromTargetNamespaces\n );\n\n // Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.\n const successfullyConnectedSupportingEagerConnectNamespaces =\n connectResultWithLegacyFormat\n .filter(<T, E>(result: Result<T, E>): result is Ok<T> => result.ok)\n .filter((result) => result.val.input.supportsEagerConnect)\n .map((result) => ({\n namespace: result.val.input.namespace,\n network: result.val.input.network,\n }));\n\n if (successfullyConnectedSupportingEagerConnectNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.addWallet(\n type,\n successfullyConnectedSupportingEagerConnectNamespaces\n );\n }\n\n // Getting rid of `input` from Result\n const connectResults = connectResultWithLegacyFormat.map((result) =>\n result.andThen((okResult) => new Ok(okResult.response))\n );\n\n const allResult = Result.all(...connectResults);\n if (allResult.err) {\n throw allResult.val;\n }\n\n return allResult.unwrap();\n },\n async disconnect(type, namespaces) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'disconnect'.`\n );\n }\n\n wallet.getAll().forEach((namespace) => {\n const namespaceShouldBeDisconnected =\n !namespaces || namespaces.includes(namespace.namespaceId);\n const namespaceIsConnected = namespace.state()[0]().connected;\n if (namespaceShouldBeDisconnected && namespaceIsConnected) {\n return namespace.disconnect();\n }\n });\n\n if (params.autoConnect) {\n if (namespaces) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n namespaces\n );\n } else {\n lastConnectedWalletsFromStorage.removeWallets([type]);\n }\n }\n },\n async disconnectAll() {\n const disconnectPromises: Promise<void>[] = Array.from(\n getHub().getAll().values()\n ).map(async (provider) => this.disconnect(provider.id));\n\n return await Promise.allSettled(disconnectPromises);\n },\n async getSigners(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const providerProperties = info.metadata.properties;\n\n const signerProperty = providerProperties?.find(\n (property) => property.name === 'signers'\n );\n if (!signerProperty) {\n throw new Error('Your provider should contain signers property.');\n }\n\n return signerProperty.value.getSigners();\n },\n getWalletInfo(type) {\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(`You should add ${type} to provider first.`);\n }\n\n const info = wallet.info();\n if (!info) {\n throw new Error('Your provider should have required `info`.');\n }\n\n const installLink: Exclude<WalletInfo['installLink'], string> = {\n DEFAULT: '',\n };\n\n const { metadata, deepLink } = info;\n const { extensions } = metadata;\n // `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage`\n Object.keys(extensions).forEach((k) => {\n const key = k as ExtensionLink;\n\n if (key === 'homepage') {\n installLink.DEFAULT = extensions[key] || '';\n }\n\n const allowedKeys: ExtensionLink[] = [\n 'firefox',\n 'chrome',\n 'brave',\n 'edge',\n ];\n if (allowedKeys.includes(key)) {\n const upperCasedKey = key.toUpperCase() as keyof Exclude<\n WalletInfo['installLink'],\n string\n >;\n installLink[upperCasedKey] = extensions[key] || '';\n }\n });\n\n const providerProperties = metadata.properties;\n\n const namespacesProperty = providerProperties?.find(\n (property) => property.name === 'namespaces'\n );\n const derivationPathProperty = providerProperties?.find(\n (property) => property.name === 'derivationPath'\n );\n const detailsProperty = providerProperties?.find(\n (property) => property.name === 'details'\n );\n\n return {\n name: metadata.name,\n img: metadata.icon,\n installLink: installLink,\n // We don't have this values anymore, fill them with some values that communicate this.\n color: 'red',\n supportedChains: getSupportedChainsFromProvider(\n wallet,\n dataRef.current.allBlockChains\n ),\n isContractWallet: detailsProperty?.value?.isContractWallet,\n mobileWallet: detailsProperty?.value?.mobileWallet,\n // if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.\n showOnMobile: detailsProperty?.value?.showOnMobile,\n needsNamespace: namespacesProperty?.value,\n needsDerivationPath: derivationPathProperty?.value,\n generateDeepLink: deepLink,\n isHub: true,\n properties: metadata.properties,\n };\n },\n providers() {\n const output: Providers = {};\n\n Array.from(getHub().getAll().keys()).forEach((id) => {\n try {\n const provider = getLegacyProvider(params.allVersionedProviders, id);\n output[id] = provider.getInstance();\n } catch (e) {\n console.warn(e);\n }\n });\n\n return output;\n },\n state(type) {\n const hubState = getHub().state();\n const wallet = getHub().get(type);\n const walletState = hubState[type];\n\n if (!walletState || !wallet) {\n throw new Error(\n `It seems your requested provider doesn't exist in hub. Provider Id: ${type}`\n );\n }\n\n const accounts = walletState.namespaces\n .filter((namespace) => namespace.connected)\n .flatMap((namespace) =>\n namespace.accounts?.map(fromAccountIdToLegacyAddressFormat)\n )\n .filter((account): account is string => !!account);\n\n const namespacesState = new Map(\n Array.from(wallet.getAll(), ([_, value]) => [\n value.namespaceId,\n value.state()[0](),\n ])\n );\n\n const coreState = {\n connected: walletState.connected,\n connecting: walletState.connecting,\n installed: walletState.installed,\n reachable: true,\n accounts: accounts,\n network: null,\n namespaces: namespacesState,\n };\n return coreState;\n },\n suggestAndConnect(_type, _network): never {\n throw new Error('`suggestAndConnect` is not implemented');\n },\n };\n\n return api;\n}\n", "import type { AllProxiedNamespaces } from './types.js';\nimport type { UseAdapterParams } from './useHubAdapter.js';\nimport type { Hub } from '@rango-dev/wallets-core';\nimport type {\n LegacyNamespaceInputForConnect,\n LegacyProviderInterface,\n} from '@rango-dev/wallets-core/legacy';\nimport type { Namespace } from '@rango-dev/wallets-core/namespaces/common';\nimport type { WalletType } from '@rango-dev/wallets-shared';\n\nimport { Provider } from '@rango-dev/wallets-core';\nimport { legacyIsEvmNamespace } from '@rango-dev/wallets-core/legacy';\nimport { Result } from 'ts-results';\n\nimport { HUB_LAST_CONNECTED_WALLETS } from '../legacy/mod.js';\n\nimport { runSequentiallyWithoutFailure } from './helpers.js';\nimport { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';\nimport {\n convertNamespaceNetworkToEvmChainId,\n isEvmNamespace,\n} from './utils.js';\n\n// Getting connected wallets from storage\nconst lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(\n HUB_LAST_CONNECTED_WALLETS\n);\n\n/**\n * Run `.connect` action on some selected namespaces (passed as param) for a provider.\n */\nasync function eagerConnect(\n type: string,\n namespacesInput: LegacyNamespaceInputForConnect[] | undefined,\n params: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n }\n) {\n const { getHub, allBlockChains } = params;\n const wallet = getHub().get(type);\n if (!wallet) {\n throw new Error(\n `You should add ${type} to provider first then call 'connect'.`\n );\n }\n\n if (!namespacesInput) {\n throw new Error('Passing namespace to `connect` is required. ');\n }\n\n const targetNamespaces: [\n LegacyNamespaceInputForConnect,\n AllProxiedNamespaces\n ][] = [];\n namespacesInput.forEach((namespaceInput) => {\n const targetNamespace: Namespace = namespaceInput.namespace;\n\n const result = wallet.findByNamespace(targetNamespace);\n\n if (!result) {\n throw new Error(\n `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespaceInput.namespace})`\n );\n }\n\n targetNamespaces.push([namespaceInput, result]);\n });\n\n const connectNamespacesPromises = targetNamespaces.map(\n ([info, namespace]) => {\n const evmChain = legacyIsEvmNamespace(info)\n ? convertNamespaceNetworkToEvmChainId(info, allBlockChains || [])\n : undefined;\n const chain = evmChain || info.network;\n\n return async () => {\n const connectNamespacePromise = isEvmNamespace(namespace)\n ? namespace.connect(chain)\n : namespace.connect();\n return await connectNamespacePromise.catch((e) => {\n /*\n * Since we check for connect failures using `instanceof Error`\n * this check is added here to make sure the thrown error always is an instance of `Error`\n */\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(e);\n });\n };\n }\n );\n\n /**\n * Sometimes calling methods on a instance in parallel, would cause an error in wallet.\n * We are running a method at a time to make sure we are covering this.\n * e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error.\n */\n const connectNamespacesResult = await runSequentiallyWithoutFailure(\n connectNamespacesPromises\n );\n\n const failedNamespaces: LegacyNamespaceInputForConnect[] = targetNamespaces\n .filter((_, index) => connectNamespacesResult[index].err)\n .map((targetNamespace) => targetNamespace[0]);\n\n if (failedNamespaces.length > 0) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n type,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n\n const atLeastOneNamespaceConnectedSuccessfully = connectNamespacesResult.some(\n (result) => result.ok\n );\n if (!atLeastOneNamespaceConnectedSuccessfully) {\n throw new Error(`No namespace connected for ${type}`);\n }\n return Result.all(\n ...connectNamespacesResult.filter((result) => result.ok)\n ).unwrap();\n}\n\n/**\n * Run `.canEagerConnect` action on some selected namespaces of a wallet.\n */\nasync function tryRunCanEagerConnect(\n namespaces: LegacyNamespaceInputForConnect[],\n wallet: Provider\n): Promise<{\n successNamespaces: LegacyNamespaceInputForConnect[];\n failedNamespaces: LegacyNamespaceInputForConnect[];\n}> {\n const foundNamespaces: LegacyNamespaceInputForConnect[] = [];\n const successNamespaces: LegacyNamespaceInputForConnect[] = [];\n const failedNamespaces: LegacyNamespaceInputForConnect[] = [];\n const canEagerConnectPromises: (() => Promise<boolean>)[] = [];\n\n // 1. Try find namespace instances and create canEagerConnect promises\n namespaces.forEach((namespace) => {\n const namespaceInstance = wallet.findByNamespace(namespace.namespace);\n if (namespaceInstance) {\n foundNamespaces.push(namespace);\n canEagerConnectPromises.push(\n async () => await namespaceInstance.canEagerConnect()\n );\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n // 2. Run canEagerConnect sequentially on namespaces\n const canEagerConnectResults = await runSequentiallyWithoutFailure(\n canEagerConnectPromises\n );\n\n // 3. Separate success and failed namespaces based on canEagerConnect result\n foundNamespaces.forEach((namespace, index) => {\n if (canEagerConnectResults[index].ok && canEagerConnectResults[index].val) {\n successNamespaces.push(namespace);\n } else {\n failedNamespaces.push(namespace);\n }\n });\n\n return { successNamespaces, failedNamespaces };\n}\n\n/*\n * Get last connected wallets and last connected namespaces for each of them from storage\n * Then run `.connect` on each namespace if `.canEagerConnect` returns true.\n */\nexport async function autoConnect(deps: {\n getHub: () => Hub;\n allBlockChains: UseAdapterParams['allBlockChains'];\n wallets?: (WalletType | LegacyProviderInterface | Provider)[];\n}): Promise<void> {\n const { getHub, allBlockChains, wallets } = deps;\n const lastConnectedWallets = lastConnectedWalletsFromStorage.list();\n const walletIds = Object.keys(lastConnectedWallets);\n\n const walletsToRemoveFromPersistence: string[] = [];\n\n if (walletIds.length) {\n const eagerConnectQueue: Promise<unknown>[] = [];\n\n const configWalletNames = wallets?.map((wallet) => {\n if (typeof wallet === 'string') {\n return wallet;\n }\n if (wallet instanceof Provider) {\n return wallet.id;\n }\n return wallet.config.type;\n });\n // Run `.connect` if `.canEagerConnect` returns `true`.\n walletIds.forEach(async (providerName) => {\n if (configWalletNames && !configWalletNames.includes(providerName)) {\n console.warn(\n 'Trying to run auto connect for a wallet which is not included in config. Desired wallet:',\n providerName\n );\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const wallet = getHub().get(providerName);\n\n const lastConnectedNamespaces: LegacyNamespaceInputForConnect[] =\n lastConnectedWallets[providerName].map((namespace) => ({\n namespace: namespace.namespace,\n network: namespace.network,\n }));\n\n if (!lastConnectedNamespaces.length || !wallet) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n }\n\n const { successNamespaces, failedNamespaces } =\n await tryRunCanEagerConnect(lastConnectedNamespaces, wallet);\n\n if (!successNamespaces.length) {\n walletsToRemoveFromPersistence.push(providerName);\n return;\n } else if (failedNamespaces.length) {\n lastConnectedWalletsFromStorage.removeNamespacesFromWallet(\n wallet.id,\n failedNamespaces.map((namespace) => namespace.namespace)\n );\n }\n eagerConnectQueue.push(\n eagerConnect(providerName, successNamespaces, {\n allBlockChains,\n getHub,\n }).catch((error) => console.warn(error))\n );\n });\n\n lastConnectedWalletsFromStorage.removeWallets(\n walletsToRemoveFromPersistence\n );\n\n await Promise.all(eagerConnectQueue);\n }\n}\n", "import type { Provider, Store } from '@rango-dev/wallets-core';\n\nimport { createStore, Hub } from '@rango-dev/wallets-core';\nimport { useRef } from 'react';\n\nimport { synchronizeHubWithConfigProviders } from './utils.js';\n\nexport function useHubRefs(providers: Provider[]) {\n const store = useRef<Store | null>(null);\n\n const hub = useRef<Hub | null>(null);\n\n function createHub() {\n const createdHub = new Hub({\n store: getStore(),\n });\n /*\n * First add providers to hub\n * This helps to `getWalletInfo` be usable, before initialize.\n */\n providers.forEach((provider) => {\n createdHub.add(provider.id, provider);\n });\n hub.current = createdHub;\n return createdHub;\n }\n\n // https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents\n function getStore() {\n if (store.current !== null) {\n return store.current;\n }\n const createdStore = createStore();\n store.current = createdStore;\n return createdStore;\n }\n\n function getHub(): Hub {\n const hubProviders = hub.current?.getAll();\n\n if (!hub.current || !hubProviders) {\n return createHub();\n }\n\n synchronizeHubWithConfigProviders(hub.current, providers);\n return hub.current;\n }\n\n return { getStore, getHub };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Events", "pickVersion", "convertEvmBlockchainMetaToEvmChainInfo", "isEvmBlockchain", "LEGACY_LAST_CONNECTED_WALLETS", "HUB_LAST_CONNECTED_WALLETS", "createContext", "defaultErrorMessage", "defaultContext", "WalletContext", "useEffect", "useReducer", "Persistor", "LastConnectedWalletsFromStorage", "__name", "#storageKey", "storageKey", "providerId", "namespaces", "HUB_LAST_CONNECTED_WALLETS", "#addWalletToHub", "LEGACY_LAST_CONNECTED_WALLETS", "#addWalletToLegacy", "providerIds", "#removeWalletsFromHub", "#removeWalletsFromLegacy", "#listFromHub", "#listFromLegacy", "namespaceIds", "#removeNamespaceFromWalletHub", "lastConnectedWallets", "Persistor", "output", "provider", "storage", "storageState", "toBeAddedNamespaces", "storedNamespaces", "namespace", "storedNamespace", "persistor", "newProviderNamespaces", "wallet", "Persistor", "Wallet", "useContext", "useRef", "useEffect", "useRef", "formatAddressWithNetwork", "CAIP_BITCOIN_CHAIN_ID", "CAIP", "Err", "Ok", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "getAllLegacyProviders", "allProviders", "LEGACY_VERSION", "legacyProviders", "provider", "target", "pickVersion", "__name", "utils", "useEffect", "useRef", "useState", "Ok", "Result", "Provider", "legacyIsEvmNamespace", "Result", "lastConnectedWalletsFromStorage", "LastConnectedWalletsFromStorage", "HUB_LAST_CONNECTED_WALLETS", "createStore", "Hub", "useRef"]
7
7
  }
@@ -2,9 +2,10 @@ import type { UseAdapterParams } from './useHubAdapter.js';
2
2
  import type { Hub } from '@rango-dev/wallets-core';
3
3
  import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';
4
4
  import type { WalletType } from '@rango-dev/wallets-shared';
5
+ import { Provider } from '@rango-dev/wallets-core';
5
6
  export declare function autoConnect(deps: {
6
7
  getHub: () => Hub;
7
8
  allBlockChains: UseAdapterParams['allBlockChains'];
8
- wallets?: (WalletType | LegacyProviderInterface)[];
9
+ wallets?: (WalletType | LegacyProviderInterface | Provider)[];
9
10
  }): Promise<void>;
10
11
  //# sourceMappingURL=autoConnect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"autoConnect.d.ts","sourceRoot":"","sources":["../../src/hub/autoConnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,GAAG,EAAY,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAqK5D,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,GAAG,CAAC;IAClB,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,uBAAuB,CAAC,EAAE,CAAC;CACpD,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DhB"}
1
+ {"version":3,"file":"autoConnect.d.ts","sourceRoot":"","sources":["../../src/hub/autoConnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAoKnD,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,GAAG,CAAC;IAClB,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,uBAAuB,GAAG,QAAQ,CAAC,EAAE,CAAC;CAC/D,GAAG,OAAO,CAAC,IAAI,CAAC,CAqEhB"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var We=Object.defineProperty;var c=(t,e)=>We(t,"name",{value:e,configurable:!0});import{Persistor as Ee}from"@rango-dev/wallets-core/legacy";var h="last-connected-wallets",W="hub-v1-last-connected-wallets";import{Persistor as T}from"@rango-dev/wallets-core/legacy";var E=class{static{c(this,"LastConnectedWalletsFromStorage")}#e;constructor(e){this.#e=e}addWallet(e,o){if(this.#e===W)return this.#t(e,o);if(this.#e===h)return this.#a(e);throw new Error("Not implemented")}removeWallets(e){if(this.#e===W)return this.#o(e);if(this.#e===h)return this.#c(e);throw new Error("Not implemented")}list(){if(this.#e===W)return this.#n();if(this.#e===h)return this.#r();throw new Error("Not implemented")}removeNamespacesFromWallet(e,o){if(this.#e===W)return this.#s(e,o);throw new Error("Not implemented")}#r(){let o=new T().getItem(h)||[],s={};return o.forEach(n=>{s[n]=[]}),s}#n(){return new T().getItem(W)||{}}#t(e,o){let s=new T,n=s.getItem(this.#e)||{},p=o;if(n[e]){let d=n[e];p=d.concat(o.filter(l=>!d.some(r=>r.namespace===l.namespace)))}s.setItem(this.#e,{...n,[e]:p})}#a(e){let o=new T,s=o.getItem(this.#e)||[];o.setItem(h,s.concat(e))}#o(e){let o=new T,s=o.getItem(this.#e)||{};if(!e){o.setItem(this.#e,{});return}e.forEach(n=>{s[n]&&delete s[n]}),o.setItem(this.#e,s)}#s(e,o){let d=(new T().getItem(this.#e)||{})[e]?.filter(l=>!o.includes(l.namespace));this.#o([e]),d?.length>0&&this.#t(e,d)}#c(e){let o=new T,s=o.getItem(this.#e)||[];if(!e){o.setItem(this.#e,[]);return}o.setItem(h,s.filter(n=>!e.includes(n)))}};function it(t,e){return t.find(o=>o.type===e)||null}c(it,"choose");var _={connected:!1,connecting:!1,reachable:!1,installed:!1,accounts:null,network:null};function K(t,e){if(e.type==="new_state"){let o=t[e.wallet];return o?{...t,[e.wallet]:{...o,[e.name]:e.value}}:{...t,[e.wallet]:{..._,[e.name]:e.value}}}return t}c(K,"stateReducer");function z(t){return Object.entries(t).filter(([,e])=>e?.connected).map(([e])=>e)}c(z,"connectedWallets");function J(t){return Object.entries(t).map(([e])=>e)}c(J,"availableWallets");function X(t){let e=new Map;return t.forEach(o=>{let{config:s,...n}=o;e.set(s.type,{actions:n,config:s})}),e}c(X,"checkWalletProviders");function lt(t){return t?.constructor?.name==="AsyncFunction"}c(lt,"isAsync");function dt(t){let{checkInstallation:e=!0}=t.config;return e}c(dt,"needsCheckInstallation");async function Z({type:t,walletActions:e,getState:o}){if(e.canEagerConnect){let s=new E(h),p=!!s.list()[t];p&&!o(t).connected&&O(),p||s.addWallet(t,[])}}c(Z,"tryPersistWallet");function ee({type:t,walletActions:e}){e.canEagerConnect&&new E(h).removeWallets([t])}c(ee,"tryRemoveWalletFromPersistance");function O(){let t=new Ee;t.getItem(h)&&t.removeItem(h)}c(O,"clearPersistance");function D(t,e){return c((s,n,p,d,l)=>{t({type:"new_state",wallet:s,name:n,value:p}),e&&e(s,n,p,d,l)},"handler")}c(D,"makeEventHandler");import ze from"react";import{createContext as ke}from"react";var I="Context hasn't been initialized yet.",Ne={async connect(){throw new Error(I)},async disconnect(){throw new Error(I)},async disconnectAll(){throw new Error(I)},async suggestAndConnect(){throw new Error(I)},state(){throw new Error(I)},canSwitchNetworkTo(){throw new Error(I)},providers(){throw new Error(I)},getWalletInfo(){throw new Error(I)},getSigners(){throw new Error(I)}},x=ke(Ne);import{LegacyEvents as A}from"@rango-dev/wallets-core/legacy";import"@rango-dev/wallets-core/utils";import{pickVersion as V}from"@rango-dev/wallets-core/utils";import{convertEvmBlockchainMetaToEvmChainInfo as _e}from"@rango-dev/wallets-shared";import{isEvmBlockchain as Oe}from"rango-types";import{useEffect as M,useReducer as be}from"react";async function te(t,e){let o=new E(h),s=o.list(),n=Object.keys(s);if(n.length){let p=[];n.forEach(r=>{let u=t.get(r);if(u){let a=e(u);p.push({walletType:r,eagerConnect:a.eagerConnect.bind(a)})}});let d=await Promise.allSettled(p.map(async({eagerConnect:r})=>r())),l=[];d.forEach((r,u)=>{let{status:a}=r;a==="rejected"&&l.push(p[u].walletType)}),l.length&&o.removeWallets(l)}}c(te,"autoConnect");import{LegacyWallet as Ae}from"@rango-dev/wallets-core/legacy";import{useContext as Ie,useRef as Se}from"react";function oe(t){let e=Se({});function o(s){let n=s.config.type;return typeof e.current[n]>"u"&&(e.current[n]=new Ae({config:s.config,handler:t},s.actions)),e.current[n]}return c(o,"updater"),o}c(oe,"useInitializers");function Le(){let t=Ie(x);if(!t)throw Error("useWallet can only be used within the Provider component");return t}c(Le,"useWallets");import{useEffect as Te,useRef as xe}from"react";function re(t){return!!t.allBlockChains?.length&&!!t.autoConnect}c(re,"shouldTryAutoConnect");function b(t){let e=xe(!1);Te(()=>{re(t)&&!e.current&&(e.current=!0,t.autoConnectHandler())},[t.autoConnect,t.allBlockChains])}c(b,"useAutoConnect");function j(t){let[e,o]=be(K,{}),s=oe(D(o,t.onUpdateState)),n=t.providers,p=X(n);b({allBlockChains:t.allBlockChains,autoConnect:t.autoConnect,autoConnectHandler:async()=>te(p,s)});let d={async connect(l,r){let u=p.get(l);if(!u)throw new Error(`You should add ${l} to provider first.`);let a;r&&r.length>0&&(a=r.find(f=>!!f.network)?.network);let m=await s(u).connect(a,r);return t.autoConnect&&Z({type:l,walletActions:u.actions,getState:d.state}),[m]},async disconnect(l){let r=p.get(l);if(!r)throw new Error(`You should add ${l} to provider first.`);await s(r).disconnect(),t.autoConnect&&ee({type:l,walletActions:r.actions})},async disconnectAll(){let l=[];return z(e).forEach(r=>{let u=p.get(r);if(u){let a=s(u);l.push(a.disconnect())}}),t.autoConnect&&O(),await Promise.allSettled(l)},async suggestAndConnect(l,r){let u=p.get(l);if(!u)throw new Error(`You should add ${l} to provider first.`);return await s(u).suggestAndConnect(r)},state(l){return e[l]||_},canSwitchNetworkTo(l,r){let u=p.get(l);if(!u)return!1;let a=s(u);return a.canSwitchNetworkTo?a.canSwitchNetworkTo(r,a.provider):!1},providers(){let l={};return J(e).forEach(r=>{let u=p.get(r);if(u){let a=s(u);l[r]=a.provider}}),l},getWalletInfo(l){let r=p.get(l);if(!r)throw new Error(`You should add ${l} to provider first.`);return r.actions.getWalletInfo(t.allBlockChains||[])},async getSigners(l){let r=p.get(l);if(!r)throw new Error(`You should add ${l} to provider first.`);let u=s(r),a=u.provider;return u.getSigners(a)}};return M(()=>{p.forEach(l=>{let r=s(l),u=c(()=>{r.onInit&&r.onInit()},"runOnInit"),a=c(i=>{i.target&&i.target.readyState==="complete"&&(u(),document.removeEventListener("readystatechange",a))},"initWhenPageIsReady");u(),document.addEventListener("readystatechange",a)})},[]),M(()=>{t.allBlockChains&&p.forEach(r=>{let u=s(r),a=u.getWalletInfo(t.allBlockChains||[]);u.setInfo({supportedBlockchains:a.supportedChains,isContractWallet:!!a.isContractWallet})})},[t.allBlockChains]),M(()=>{p.forEach(l=>{s(l).setHandler(D(o,t.onUpdateState))})},[t.onUpdateState]),d}c(j,"useLegacyProviders");import{legacyFormatAddressWithNetwork as Be}from"@rango-dev/wallets-core/legacy";import{CAIP_BITCOIN_CHAIN_ID as Re}from"@rango-dev/wallets-core/namespaces/utxo";import{CAIP as Fe}from"@rango-dev/wallets-core/utils";import{Err as U,Ok as ne}from"ts-results";function He(t){return typeof t=="string"?t:["solana"].includes(t.namespace.toLowerCase())?t.namespace.toUpperCase():t.namespace.toLowerCase()==="eip155"?"ETH":t.reference===Re?"BTC":t.namespace==="sui"?t.reference.toUpperCase():t.reference}c(He,"mapCaipNamespaceToLegacyNetworkName");function B(t){let{chainId:e,address:o}=Fe.AccountId.parse(t),s=He(e);return Be(o,s)}c(B,"fromAccountIdToLegacyAddressFormat");async function Y(t){return t.reduce(async(e,o)=>{let s=await e;try{let n=await o();return[...s,new ne(n)]}catch(n){return[...s,new U(n)]}},Promise.resolve([]))}c(Y,"runSequentiallyWithoutFailure");function ae(t){return typeof t=="object"&&!Array.isArray(t)}c(ae,"isConnectResultEvm");function se(t){return Array.isArray(t)}c(se,"isConnectResultSolana");function ce(t){let e=new Set,o=[],s=c((d,l)=>{o=o.filter(r=>r.key!==d?!0:(r.resolve(l),!1))},"removeKeyFromQueue"),n=c(async()=>{let d=o.find(a=>!e.has(a.key));if(!d)return;let{task:l,resolve:r,key:u}=d;e.add(u);try{let a=await l();r(new ne(a))}catch(a){t?.onError&&t.onError(a,{removeCurrentKeyFromQueue:()=>s(u,new U(a))}),r(new U(a))}finally{let a=o.findIndex(i=>i.key===u);a>=0&&o.splice(a,1),e.delete(u),n()}},"processQueue");return c(async(d,l)=>new Promise(r=>{o.push({task:d,resolve:r,key:l}),n()}),"queueTask")}c(ce,"createQueue");function $(t){let e="0.0.0",o="1.0.0",s=[],n=[];return t.forEach(p=>{try{let d=V(p,o);n.push(d[1])}catch{let d=V(p,e);s.push(d[1])}}),[s,n]}c($,"separateLegacyAndHubProviders");function S(t,e){return t.find(o=>o.id===e)}c(S,"findProviderByType");var De=new E(W);function q(t,e){return t.info()?.metadata.properties?.find(n=>n.name==="namespaces")?.value.data.flatMap(n=>n.getSupportedChains(e||[]))||[]}c(q,"getSupportedChainsFromProvider");function ie(t,e,o,s){let n=t.get(e.provider);if(!n)throw new Error("Currently all the events have assigned to a provider. The event doesn't include one.",{cause:e});let p=e.namespace,d=p?n.findByNamespace(p):void 0,l=null,r=null,u;if(d){let[f]=d.state();l=f().accounts,r=f().network,s.lastConnectAttemptParams[e.provider]&&(u=s.lastConnectAttemptParams[e.provider].find(g=>g.namespace===p)?.derivationPath)}let[a]=n.state(),i={connected:a().connected,connecting:a().connecting,installed:a().installed,accounts:l,network:r,reachable:!0,derivationPath:u},m={supportedBlockchains:q(n,s.allBlockChains),isContractWallet:!1,isHub:!0,namespace:p};switch(e.type){case"provider_detected":o(e.provider,A.INSTALLED,!0,i,m);break;case"provider_connecting":o(e.provider,A.CONNECTING,e.value,i,m);break;case"provider_connected":o(e.provider,A.CONNECTED,!0,i,m);break;case"provider_disconnected":o(e.provider,A.PROVIDER_DISCONNECTED,e.provider,i,m),o(e.provider,A.CONNECTED,!1,i,m),o(e.provider,A.ACCOUNTS,null,i,m);break;case"namespace_disconnected":De.removeNamespacesFromWallet(e.provider,[e.namespace]),o(e.provider,A.NAMESPACE_DISCONNECTED,e.namespace,i,{...m,namespace:e.namespace});break;case"namespace_connected":case"namespace_account_switched":{e.type==="namespace_account_switched"&&o(e.provider,A.NAMESPACE_DISCONNECTED,e.namespace,i,m);let f=e.accounts.map(B);o(e.provider,A.ACCOUNTS,f,i,{...m,namespace:e.namespace})}break;case"namespace_network_switched":o(e.provider,A.NETWORK,e.network,i,{...m,namespace:e.namespace});break}}c(ie,"mapHubEventsToLegacy");function le(t){let e="0.0.0",o=[];return t.forEach(s=>{let n=V(s,e);o.push(n[1])}),o}c(le,"getAllLegacyProviders");function de(t,e){let s=le(t).find(n=>n.config.type===e);if(!s)throw console.warn(`You have a provider that doesn't have legacy provider. It causes some problems since we need some legacy functionality. Provider Id: ${e}`),new Error(`You need to have legacy implementation to use some methods. Provider Id: ${e}`);return s}c(de,"getLegacyProvider");function G(t,e){if(!t.network)return;let o=e.filter(Oe);return _e(o)[t.network]}c(G,"convertNamespaceNetworkToEvmChainId");function pe(t,e){return G(t,e)||t.network}c(pe,"tryConvertNamespaceNetworkToChainInfo");function ue(t){return ae(t)?{accounts:t.accounts,network:t.network,provider:void 0}:se(t)?{accounts:t,network:null,provider:void 0}:{accounts:[t],network:null,provider:void 0}}c(ue,"transformHubResultToLegacyResult");function me(t,e){let o=t.getAll();e.filter(n=>!o.get(n.id)).forEach(n=>{t.add(n.id,n),n.init()}),o.forEach(n=>{e.some(d=>d.id===n.id)||t.remove(n.id)})}c(me,"synchronizeHubWithConfigProviders");function fe(t){return t.namespaceId==="Solana"}c(fe,"isSolanaNamespace");function R(t){return t.namespaceId==="EVM"}c(R,"isEvmNamespace");import{utils as qe}from"@rango-dev/wallets-core/namespaces/evm";import"@rango-dev/wallets-shared";import{useEffect as he,useRef as we,useState as Ge}from"react";import{Ok as Qe,Result as Ke}from"ts-results";import{legacyIsEvmNamespace as Me}from"@rango-dev/wallets-core/legacy";import{Result as je}from"ts-results";var F=new E(W);async function Ue(t,e,o){let{getHub:s,allBlockChains:n}=o,p=s().get(t);if(!p)throw new Error(`You should add ${t} to provider first then call 'connect'.`);if(!e)throw new Error("Passing namespace to `connect` is required. ");let d=[];e.forEach(i=>{let m=i.namespace,f=p.findByNamespace(m);if(!f)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${i.namespace})`);d.push([i,f])});let l=d.map(([i,m])=>{let g=(Me(i)?G(i,n||[]):void 0)||i.network;return async()=>await(R(m)?m.connect(g):m.connect()).catch(w=>{throw w instanceof Error?w:new Error(w)})}),r=await Y(l),u=d.filter((i,m)=>r[m].err).map(i=>i[0]);if(u.length>0&&F.removeNamespacesFromWallet(t,u.map(i=>i.namespace)),!r.some(i=>i.ok))throw new Error(`No namespace connected for ${t}`);return je.all(...r.filter(i=>i.ok)).unwrap()}c(Ue,"eagerConnect");async function Ye(t,e){let o=[],s=[],n=[],p=[];t.forEach(l=>{let r=e.findByNamespace(l.namespace);r?(o.push(l),p.push(async()=>await r.canEagerConnect())):n.push(l)});let d=await Y(p);return o.forEach((l,r)=>{d[r].ok&&d[r].val?s.push(l):n.push(l)}),{successNamespaces:s,failedNamespaces:n}}c(Ye,"tryRunCanEagerConnect");async function ge(t){let{getHub:e,allBlockChains:o,wallets:s}=t,n=F.list(),p=Object.keys(n),d=[];if(p.length){let l=[];p.forEach(async r=>{if(s&&!s.includes(r)){console.warn("Trying to run auto connect for a wallet which is not included in config. Desired wallet:",r),d.push(r);return}let u=e().get(r),a=n[r].map(f=>({namespace:f.namespace,network:f.network}));if(!a.length||!u){d.push(r);return}let{successNamespaces:i,failedNamespaces:m}=await Ye(a,u);if(i.length)m.length&&F.removeNamespacesFromWallet(u.id,m.map(f=>f.namespace));else{d.push(r);return}l.push(Ue(r,i,{allBlockChains:o,getHub:e}).catch(f=>console.warn(f)))}),F.removeWallets(d),await Promise.all(l)}}c(ge,"autoConnect");import{createStore as Ve,Hub as $e}from"@rango-dev/wallets-core";import{useRef as ye}from"react";function ve(t){let e=ye(null),o=ye(null);function s(){let d=new $e({store:n()});return t.forEach(l=>{d.add(l.id,l)}),o.current=d,d}c(s,"createHub");function n(){if(e.current!==null)return e.current;let d=Ve();return e.current=d,d}c(n,"getStore");function p(){let d=o.current?.getAll();return!o.current||!d?s():(me(o.current,t),o.current)}return c(p,"getHub"),{getStore:n,getHub:p}}c(ve,"useHubRefs");function Q(t){let{getStore:e,getHub:o}=ve(t.providers),[,s]=Ge(0),n=we({onUpdateState:t.onUpdateState,allVersionedProviders:t.allVersionedProviders,allBlockChains:t.allBlockChains}),p=we({}),d=c((a,i)=>{p.current[a]=i||[]},"updateLastConnectAttemptParams"),l=ce({onError:(a,i)=>{qe.isUserRejectionError(a)&&i.removeCurrentKeyFromQueue()}});he(()=>{n.current={onUpdateState:t.onUpdateState,allVersionedProviders:t.allVersionedProviders,allBlockChains:t.allBlockChains}},[t]),he(()=>{let a=c(()=>{o().init(),s(m=>m+1)},"runOnInit"),i=c(m=>{m.target&&m.target.readyState==="complete"&&(a(),document.removeEventListener("readystatechange",i))},"initHubWhenPageIsReady");a(),document.addEventListener("readystatechange",i),e().subscribe(m=>{if(n.current.onUpdateState)try{ie(o(),m,n.current.onUpdateState,{allBlockChains:n.current.allBlockChains,lastConnectAttemptParams:p.current})}catch(f){console.error(f)}s(f=>f+1)}).flushEvents()},[]),b({autoConnect:t.autoConnect,allBlockChains:t.allBlockChains,autoConnectHandler:()=>{ge({allBlockChains:t.allBlockChains,getHub:o,wallets:t.configs?.wallets})}});let r=new E(W);return{canSwitchNetworkTo(a,i,m){let f=o().get(a);if(!f)throw new Error(`You should add ${a} to provider first then call 'canSwitchNetworkTo'.`);if(!m)throw new Error("Passing namespace to `canSwitchNetworkTo` is required.");let g=f.findByNamespace(m.namespace);if(!g)throw new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${m.namespace})`);if(!("canSwitchNetwork"in g))return!1;let P=f.info()?.metadata?.properties?.find(v=>v.name==="namespaces");if(!n.current.allBlockChains)throw new Error("Blockchains are not available");let w=P?.value.data.find(v=>v.value===m.namespace)?.getSupportedChains(n.current.allBlockChains);if(!w)throw new Error(`NamespaceMeta is not defined for requested namespace: ${m.namespace}`);return g.canSwitchNetwork({network:i,supportedChains:w})},async connect(a,i){let m=o().get(a);if(!m)throw new Error(`You should add ${a} to provider first then call 'connect'.`);if(!i)throw new Error("Passing namespace to `connect` is required.");d(a,i);let f=[];i.forEach(y=>{let C=y.namespace,k=m.findByNamespace(C);if(!k)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${y.namespace})`);f.push([y,k])});let g=f.map(async([y,C])=>{let k=pe(y,t.allBlockChains||[]),N;return fe(C)?N=c(async()=>C.connect({derivationPath:y.derivationPath}),"connectNamespacePromise"):R(C)?N=c(async()=>C.connect(k,{derivationPath:y.derivationPath}),"connectNamespacePromise"):N=c(async()=>C.connect(),"connectNamespacePromise"),l(c(async()=>N().then(ue).then(H=>({response:H,input:{namespace:y.namespace,network:y.network,supportsEagerConnect:"canEagerConnect"in C}})),"connectNamespaceProcess"),a)}),P=await Promise.all(g),w=P.filter(y=>y.ok).filter(y=>y.val.input.supportsEagerConnect).map(y=>({namespace:y.val.input.namespace,network:y.val.input.network}));w.length>0&&r.addWallet(a,w);let v=P.map(y=>y.andThen(C=>new Qe(C.response))),L=Ke.all(...v);if(L.err)throw L.val;return L.unwrap()},async disconnect(a,i){let m=o().get(a);if(!m)throw new Error(`You should add ${a} to provider first then call 'disconnect'.`);m.getAll().forEach(f=>{let g=!i||i.includes(f.namespaceId),P=f.state()[0]().connected;if(g&&P)return f.disconnect()}),t.autoConnect&&(i?r.removeNamespacesFromWallet(a,i):r.removeWallets([a]))},async disconnectAll(){let a=Array.from(o().getAll().values()).map(async i=>this.disconnect(i.id));return await Promise.allSettled(a)},async getSigners(a){let i=o().get(a);if(!i)throw new Error(`You should add ${a} to provider first.`);let m=i.info();if(!m)throw new Error("Your provider should have required `info`.");let g=m.metadata.properties?.find(P=>P.name==="signers");if(!g)throw new Error("Your provider should contain signers property.");return g.value.getSigners()},getWalletInfo(a){let i=o().get(a);if(!i)throw new Error(`You should add ${a} to provider first.`);let m=i.info();if(!m)throw new Error("Your provider should have required `info`.");let f={DEFAULT:""},{metadata:g,deepLink:P}=m,{extensions:w}=g;Object.keys(w).forEach(k=>{let N=k;if(N==="homepage"&&(f.DEFAULT=w[N]||""),["firefox","chrome","brave","edge"].includes(N)){let H=N.toUpperCase();f[H]=w[N]||""}});let v=g.properties,L=v?.find(k=>k.name==="namespaces"),y=v?.find(k=>k.name==="derivationPath"),C=v?.find(k=>k.name==="details");return{name:g.name,img:g.icon,installLink:f,color:"red",supportedChains:q(i,n.current.allBlockChains),isContractWallet:C?.value?.isContractWallet,mobileWallet:C?.value?.mobileWallet,showOnMobile:C?.value?.showOnMobile,needsNamespace:L?.value,needsDerivationPath:y?.value,generateDeepLink:P,isHub:!0,properties:g.properties}},providers(){let a={};return Array.from(o().getAll().keys()).forEach(i=>{try{let m=de(t.allVersionedProviders,i);a[i]=m.getInstance()}catch(m){console.warn(m)}}),a},state(a){let i=o().state(),m=o().get(a),f=i[a];if(!f||!m)throw new Error(`It seems your requested provider doesn't exist in hub. Provider Id: ${a}`);let g=f.namespaces.filter(v=>v.connected).flatMap(v=>v.accounts?.map(B)).filter(v=>!!v),P=new Map(Array.from(m.getAll(),([v,L])=>[L.namespaceId,L.state()[0]()]));return{connected:f.connected,connecting:f.connecting,installed:f.installed,reachable:!0,accounts:g,network:null,namespaces:P}},suggestAndConnect(a,i){throw new Error("`suggestAndConnect` is not implemented")}}}c(Q,"useHubAdapter");function Ce(t){let{providers:e,...o}=t,[s,n]=$(e),p=j({...o,providers:s}),d=Q({...o,providers:n,allVersionedProviders:e});return{canSwitchNetworkTo(r,u,a){return S(n,r)?d.canSwitchNetworkTo(r,u,a):p.canSwitchNetworkTo(r,u)},async connect(r,u){return S(n,r)?await d.connect(r,u):await p.connect(r,u)},async disconnect(r,u){return S(n,r)?await d.disconnect(r,u):await p.disconnect(r)},async disconnectAll(){return await Promise.allSettled([d.disconnectAll(),p.disconnectAll()])},async getSigners(r){return S(n,r)?d.getSigners(r):p.getSigners(r)},getWalletInfo(r){return S(n,r)?d.getWalletInfo(r):p.getWalletInfo(r)},providers(){let r={};return n.length>0&&(r={...r,...d.providers()}),s.length>0&&(r={...r,...p.providers()}),r},state(r){return S(n,r)?d.state(r):p.state(r)},async suggestAndConnect(r,u){return S(n,r)?d.suggestAndConnect(r,u):await p.suggestAndConnect(r,u)}}}c(Ce,"useProviders");function Je(t){let e=Ce(t);return ze.createElement(x.Provider,{value:e},t.children)}c(Je,"Provider");var Xe=Je;import{LegacyEvents as Yo}from"@rango-dev/wallets-core/legacy";export{Yo as Events,Xe as Provider,J as availableWallets,X as checkWalletProviders,it as choose,O as clearPersistance,z as connectedWallets,_ as defaultWalletState,lt as isAsync,D as makeEventHandler,dt as needsCheckInstallation,K as stateReducer,Z as tryPersistWallet,ee as tryRemoveWalletFromPersistance,Le as useWallets};
1
+ var We=Object.defineProperty;var c=(t,e)=>We(t,"name",{value:e,configurable:!0});import{Persistor as Ee}from"@rango-dev/wallets-core/legacy";var h="last-connected-wallets",W="hub-v1-last-connected-wallets";import{Persistor as T}from"@rango-dev/wallets-core/legacy";var E=class{static{c(this,"LastConnectedWalletsFromStorage")}#e;constructor(e){this.#e=e}addWallet(e,o){if(this.#e===W)return this.#t(e,o);if(this.#e===h)return this.#a(e);throw new Error("Not implemented")}removeWallets(e){if(this.#e===W)return this.#o(e);if(this.#e===h)return this.#c(e);throw new Error("Not implemented")}list(){if(this.#e===W)return this.#n();if(this.#e===h)return this.#r();throw new Error("Not implemented")}removeNamespacesFromWallet(e,o){if(this.#e===W)return this.#s(e,o);throw new Error("Not implemented")}#r(){let o=new T().getItem(h)||[],s={};return o.forEach(n=>{s[n]=[]}),s}#n(){return new T().getItem(W)||{}}#t(e,o){let s=new T,n=s.getItem(this.#e)||{},u=o;if(n[e]){let p=n[e];u=p.concat(o.filter(d=>!p.some(r=>r.namespace===d.namespace)))}s.setItem(this.#e,{...n,[e]:u})}#a(e){let o=new T,s=o.getItem(this.#e)||[];o.setItem(h,s.concat(e))}#o(e){let o=new T,s=o.getItem(this.#e)||{};if(!e){o.setItem(this.#e,{});return}e.forEach(n=>{s[n]&&delete s[n]}),o.setItem(this.#e,s)}#s(e,o){let p=(new T().getItem(this.#e)||{})[e]?.filter(d=>!o.includes(d.namespace));this.#o([e]),p?.length>0&&this.#t(e,p)}#c(e){let o=new T,s=o.getItem(this.#e)||[];if(!e){o.setItem(this.#e,[]);return}o.setItem(h,s.filter(n=>!e.includes(n)))}};function lt(t,e){return t.find(o=>o.type===e)||null}c(lt,"choose");var _={connected:!1,connecting:!1,reachable:!1,installed:!1,accounts:null,network:null};function K(t,e){if(e.type==="new_state"){let o=t[e.wallet];return o?{...t,[e.wallet]:{...o,[e.name]:e.value}}:{...t,[e.wallet]:{..._,[e.name]:e.value}}}return t}c(K,"stateReducer");function z(t){return Object.entries(t).filter(([,e])=>e?.connected).map(([e])=>e)}c(z,"connectedWallets");function J(t){return Object.entries(t).map(([e])=>e)}c(J,"availableWallets");function X(t){let e=new Map;return t.forEach(o=>{let{config:s,...n}=o;e.set(s.type,{actions:n,config:s})}),e}c(X,"checkWalletProviders");function dt(t){return t?.constructor?.name==="AsyncFunction"}c(dt,"isAsync");function pt(t){let{checkInstallation:e=!0}=t.config;return e}c(pt,"needsCheckInstallation");async function Z({type:t,walletActions:e,getState:o}){if(e.canEagerConnect){let s=new E(h),u=!!s.list()[t];u&&!o(t).connected&&O(),u||s.addWallet(t,[])}}c(Z,"tryPersistWallet");function ee({type:t,walletActions:e}){e.canEagerConnect&&new E(h).removeWallets([t])}c(ee,"tryRemoveWalletFromPersistance");function O(){let t=new Ee;t.getItem(h)&&t.removeItem(h)}c(O,"clearPersistance");function D(t,e){return c((s,n,u,p,d)=>{t({type:"new_state",wallet:s,name:n,value:u}),e&&e(s,n,u,p,d)},"handler")}c(D,"makeEventHandler");import Je from"react";import{createContext as ke}from"react";var I="Context hasn't been initialized yet.",Ne={async connect(){throw new Error(I)},async disconnect(){throw new Error(I)},async disconnectAll(){throw new Error(I)},async suggestAndConnect(){throw new Error(I)},state(){throw new Error(I)},canSwitchNetworkTo(){throw new Error(I)},providers(){throw new Error(I)},getWalletInfo(){throw new Error(I)},getSigners(){throw new Error(I)}},x=ke(Ne);import{LegacyEvents as A}from"@rango-dev/wallets-core/legacy";import"@rango-dev/wallets-core/utils";import{pickVersion as V}from"@rango-dev/wallets-core/utils";import{convertEvmBlockchainMetaToEvmChainInfo as _e}from"@rango-dev/wallets-shared";import{isEvmBlockchain as Oe}from"rango-types";import{useEffect as M,useReducer as be}from"react";async function te(t,e){let o=new E(h),s=o.list(),n=Object.keys(s);if(n.length){let u=[];n.forEach(r=>{let i=t.get(r);if(i){let a=e(i);u.push({walletType:r,eagerConnect:a.eagerConnect.bind(a)})}});let p=await Promise.allSettled(u.map(async({eagerConnect:r})=>r())),d=[];p.forEach((r,i)=>{let{status:a}=r;a==="rejected"&&d.push(u[i].walletType)}),d.length&&o.removeWallets(d)}}c(te,"autoConnect");import{LegacyWallet as Ae}from"@rango-dev/wallets-core/legacy";import{useContext as Ie,useRef as Se}from"react";function oe(t){let e=Se({});function o(s){let n=s.config.type;return typeof e.current[n]>"u"&&(e.current[n]=new Ae({config:s.config,handler:t},s.actions)),e.current[n]}return c(o,"updater"),o}c(oe,"useInitializers");function Le(){let t=Ie(x);if(!t)throw Error("useWallet can only be used within the Provider component");return t}c(Le,"useWallets");import{useEffect as Te,useRef as xe}from"react";function re(t){return!!t.allBlockChains?.length&&!!t.autoConnect}c(re,"shouldTryAutoConnect");function b(t){let e=xe(!1);Te(()=>{re(t)&&!e.current&&(e.current=!0,t.autoConnectHandler())},[t.autoConnect,t.allBlockChains])}c(b,"useAutoConnect");function j(t){let[e,o]=be(K,{}),s=oe(D(o,t.onUpdateState)),n=t.providers,u=X(n);b({allBlockChains:t.allBlockChains,autoConnect:t.autoConnect,autoConnectHandler:async()=>te(u,s)});let p={async connect(d,r){let i=u.get(d);if(!i)throw new Error(`You should add ${d} to provider first.`);let a;r&&r.length>0&&(a=r.find(f=>!!f.network)?.network);let m=await s(i).connect(a,r);return t.autoConnect&&Z({type:d,walletActions:i.actions,getState:p.state}),[m]},async disconnect(d){let r=u.get(d);if(!r)throw new Error(`You should add ${d} to provider first.`);await s(r).disconnect(),t.autoConnect&&ee({type:d,walletActions:r.actions})},async disconnectAll(){let d=[];return z(e).forEach(r=>{let i=u.get(r);if(i){let a=s(i);d.push(a.disconnect())}}),t.autoConnect&&O(),await Promise.allSettled(d)},async suggestAndConnect(d,r){let i=u.get(d);if(!i)throw new Error(`You should add ${d} to provider first.`);return await s(i).suggestAndConnect(r)},state(d){return e[d]||_},canSwitchNetworkTo(d,r){let i=u.get(d);if(!i)return!1;let a=s(i);return a.canSwitchNetworkTo?a.canSwitchNetworkTo(r,a.provider):!1},providers(){let d={};return J(e).forEach(r=>{let i=u.get(r);if(i){let a=s(i);d[r]=a.provider}}),d},getWalletInfo(d){let r=u.get(d);if(!r)throw new Error(`You should add ${d} to provider first.`);return r.actions.getWalletInfo(t.allBlockChains||[])},async getSigners(d){let r=u.get(d);if(!r)throw new Error(`You should add ${d} to provider first.`);let i=s(r),a=i.provider;return i.getSigners(a)}};return M(()=>{u.forEach(d=>{let r=s(d),i=c(()=>{r.onInit&&r.onInit()},"runOnInit"),a=c(l=>{l.target&&l.target.readyState==="complete"&&(i(),document.removeEventListener("readystatechange",a))},"initWhenPageIsReady");i(),document.addEventListener("readystatechange",a)})},[]),M(()=>{t.allBlockChains&&u.forEach(r=>{let i=s(r),a=i.getWalletInfo(t.allBlockChains||[]);i.setInfo({supportedBlockchains:a.supportedChains,isContractWallet:!!a.isContractWallet})})},[t.allBlockChains]),M(()=>{u.forEach(d=>{s(d).setHandler(D(o,t.onUpdateState))})},[t.onUpdateState]),p}c(j,"useLegacyProviders");import{legacyFormatAddressWithNetwork as Be}from"@rango-dev/wallets-core/legacy";import{CAIP_BITCOIN_CHAIN_ID as Re}from"@rango-dev/wallets-core/namespaces/utxo";import{CAIP as Fe}from"@rango-dev/wallets-core/utils";import{Err as U,Ok as ne}from"ts-results";function He(t){return typeof t=="string"?t:["solana"].includes(t.namespace.toLowerCase())?t.namespace.toUpperCase():t.namespace.toLowerCase()==="eip155"?"ETH":t.reference===Re?"BTC":t.namespace==="sui"?t.reference.toUpperCase():t.reference}c(He,"mapCaipNamespaceToLegacyNetworkName");function B(t){let{chainId:e,address:o}=Fe.AccountId.parse(t),s=He(e);return Be(o,s)}c(B,"fromAccountIdToLegacyAddressFormat");async function Y(t){return t.reduce(async(e,o)=>{let s=await e;try{let n=await o();return[...s,new ne(n)]}catch(n){return[...s,new U(n)]}},Promise.resolve([]))}c(Y,"runSequentiallyWithoutFailure");function ae(t){return typeof t=="object"&&!Array.isArray(t)}c(ae,"isConnectResultEvm");function se(t){return Array.isArray(t)}c(se,"isConnectResultSolana");function ce(t){let e=new Set,o=[],s=c((p,d)=>{o=o.filter(r=>r.key!==p?!0:(r.resolve(d),!1))},"removeKeyFromQueue"),n=c(async()=>{let p=o.find(a=>!e.has(a.key));if(!p)return;let{task:d,resolve:r,key:i}=p;e.add(i);try{let a=await d();r(new ne(a))}catch(a){t?.onError&&t.onError(a,{removeCurrentKeyFromQueue:()=>s(i,new U(a))}),r(new U(a))}finally{let a=o.findIndex(l=>l.key===i);a>=0&&o.splice(a,1),e.delete(i),n()}},"processQueue");return c(async(p,d)=>new Promise(r=>{o.push({task:p,resolve:r,key:d}),n()}),"queueTask")}c(ce,"createQueue");function $(t){let e="0.0.0",o="1.0.0",s=[],n=[];return t.forEach(u=>{try{let p=V(u,o);n.push(p[1])}catch{let p=V(u,e);s.push(p[1])}}),[s,n]}c($,"separateLegacyAndHubProviders");function S(t,e){return t.find(o=>o.id===e)}c(S,"findProviderByType");var De=new E(W);function q(t,e){return t.info()?.metadata.properties?.find(n=>n.name==="namespaces")?.value.data.flatMap(n=>n.getSupportedChains(e||[]))||[]}c(q,"getSupportedChainsFromProvider");function ie(t,e,o,s){let n=t.get(e.provider);if(!n)throw new Error("Currently all the events have assigned to a provider. The event doesn't include one.",{cause:e});let u=e.namespace,p=u?n.findByNamespace(u):void 0,d=null,r=null,i;if(p){let[f]=p.state();d=f().accounts,r=f().network,s.lastConnectAttemptParams[e.provider]&&(i=s.lastConnectAttemptParams[e.provider].find(g=>g.namespace===u)?.derivationPath)}let[a]=n.state(),l={connected:a().connected,connecting:a().connecting,installed:a().installed,accounts:d,network:r,reachable:!0,derivationPath:i},m={supportedBlockchains:q(n,s.allBlockChains),isContractWallet:!1,isHub:!0,namespace:u};switch(e.type){case"provider_detected":o(e.provider,A.INSTALLED,!0,l,m);break;case"provider_connecting":o(e.provider,A.CONNECTING,e.value,l,m);break;case"provider_connected":o(e.provider,A.CONNECTED,!0,l,m);break;case"provider_disconnected":o(e.provider,A.PROVIDER_DISCONNECTED,e.provider,l,m),o(e.provider,A.CONNECTED,!1,l,m),o(e.provider,A.ACCOUNTS,null,l,m);break;case"namespace_disconnected":De.removeNamespacesFromWallet(e.provider,[e.namespace]),o(e.provider,A.NAMESPACE_DISCONNECTED,e.namespace,l,{...m,namespace:e.namespace});break;case"namespace_connected":case"namespace_account_switched":{e.type==="namespace_account_switched"&&o(e.provider,A.NAMESPACE_DISCONNECTED,e.namespace,l,m);let f=e.accounts.map(B);o(e.provider,A.ACCOUNTS,f,l,{...m,namespace:e.namespace})}break;case"namespace_network_switched":o(e.provider,A.NETWORK,e.network,l,{...m,namespace:e.namespace});break}}c(ie,"mapHubEventsToLegacy");function le(t){let e="0.0.0",o=[];return t.forEach(s=>{let n=V(s,e);o.push(n[1])}),o}c(le,"getAllLegacyProviders");function de(t,e){let s=le(t).find(n=>n.config.type===e);if(!s)throw console.warn(`You have a provider that doesn't have legacy provider. It causes some problems since we need some legacy functionality. Provider Id: ${e}`),new Error(`You need to have legacy implementation to use some methods. Provider Id: ${e}`);return s}c(de,"getLegacyProvider");function G(t,e){if(!t.network)return;let o=e.filter(Oe);return _e(o)[t.network]}c(G,"convertNamespaceNetworkToEvmChainId");function pe(t,e){return G(t,e)||t.network}c(pe,"tryConvertNamespaceNetworkToChainInfo");function ue(t){return ae(t)?{accounts:t.accounts,network:t.network,provider:void 0}:se(t)?{accounts:t,network:null,provider:void 0}:{accounts:[t],network:null,provider:void 0}}c(ue,"transformHubResultToLegacyResult");function me(t,e){let o=t.getAll();e.filter(n=>!o.get(n.id)).forEach(n=>{t.add(n.id,n),n.init()}),o.forEach(n=>{e.some(p=>p.id===n.id)||t.remove(n.id)})}c(me,"synchronizeHubWithConfigProviders");function fe(t){return t.namespaceId==="Solana"}c(fe,"isSolanaNamespace");function R(t){return t.namespaceId==="EVM"}c(R,"isEvmNamespace");import{utils as Ge}from"@rango-dev/wallets-core/namespaces/evm";import"@rango-dev/wallets-shared";import{useEffect as he,useRef as we,useState as Qe}from"react";import{Ok as Ke,Result as ze}from"ts-results";import{Provider as Me}from"@rango-dev/wallets-core";import{legacyIsEvmNamespace as je}from"@rango-dev/wallets-core/legacy";import{Result as Ue}from"ts-results";var F=new E(W);async function Ye(t,e,o){let{getHub:s,allBlockChains:n}=o,u=s().get(t);if(!u)throw new Error(`You should add ${t} to provider first then call 'connect'.`);if(!e)throw new Error("Passing namespace to `connect` is required. ");let p=[];e.forEach(l=>{let m=l.namespace,f=u.findByNamespace(m);if(!f)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${l.namespace})`);p.push([l,f])});let d=p.map(([l,m])=>{let g=(je(l)?G(l,n||[]):void 0)||l.network;return async()=>await(R(m)?m.connect(g):m.connect()).catch(w=>{throw w instanceof Error?w:new Error(w)})}),r=await Y(d),i=p.filter((l,m)=>r[m].err).map(l=>l[0]);if(i.length>0&&F.removeNamespacesFromWallet(t,i.map(l=>l.namespace)),!r.some(l=>l.ok))throw new Error(`No namespace connected for ${t}`);return Ue.all(...r.filter(l=>l.ok)).unwrap()}c(Ye,"eagerConnect");async function Ve(t,e){let o=[],s=[],n=[],u=[];t.forEach(d=>{let r=e.findByNamespace(d.namespace);r?(o.push(d),u.push(async()=>await r.canEagerConnect())):n.push(d)});let p=await Y(u);return o.forEach((d,r)=>{p[r].ok&&p[r].val?s.push(d):n.push(d)}),{successNamespaces:s,failedNamespaces:n}}c(Ve,"tryRunCanEagerConnect");async function ge(t){let{getHub:e,allBlockChains:o,wallets:s}=t,n=F.list(),u=Object.keys(n),p=[];if(u.length){let d=[],r=s?.map(i=>typeof i=="string"?i:i instanceof Me?i.id:i.config.type);u.forEach(async i=>{if(r&&!r.includes(i)){console.warn("Trying to run auto connect for a wallet which is not included in config. Desired wallet:",i),p.push(i);return}let a=e().get(i),l=n[i].map(g=>({namespace:g.namespace,network:g.network}));if(!l.length||!a){p.push(i);return}let{successNamespaces:m,failedNamespaces:f}=await Ve(l,a);if(m.length)f.length&&F.removeNamespacesFromWallet(a.id,f.map(g=>g.namespace));else{p.push(i);return}d.push(Ye(i,m,{allBlockChains:o,getHub:e}).catch(g=>console.warn(g)))}),F.removeWallets(p),await Promise.all(d)}}c(ge,"autoConnect");import{createStore as $e,Hub as qe}from"@rango-dev/wallets-core";import{useRef as ye}from"react";function ve(t){let e=ye(null),o=ye(null);function s(){let p=new qe({store:n()});return t.forEach(d=>{p.add(d.id,d)}),o.current=p,p}c(s,"createHub");function n(){if(e.current!==null)return e.current;let p=$e();return e.current=p,p}c(n,"getStore");function u(){let p=o.current?.getAll();return!o.current||!p?s():(me(o.current,t),o.current)}return c(u,"getHub"),{getStore:n,getHub:u}}c(ve,"useHubRefs");function Q(t){let{getStore:e,getHub:o}=ve(t.providers),[,s]=Qe(0),n=we({onUpdateState:t.onUpdateState,allVersionedProviders:t.allVersionedProviders,allBlockChains:t.allBlockChains}),u=we({}),p=c((a,l)=>{u.current[a]=l||[]},"updateLastConnectAttemptParams"),d=ce({onError:(a,l)=>{Ge.isUserRejectionError(a)&&l.removeCurrentKeyFromQueue()}});he(()=>{n.current={onUpdateState:t.onUpdateState,allVersionedProviders:t.allVersionedProviders,allBlockChains:t.allBlockChains}},[t]),he(()=>{let a=c(()=>{o().init(),s(m=>m+1)},"runOnInit"),l=c(m=>{m.target&&m.target.readyState==="complete"&&(a(),document.removeEventListener("readystatechange",l))},"initHubWhenPageIsReady");a(),document.addEventListener("readystatechange",l),e().subscribe(m=>{if(n.current.onUpdateState)try{ie(o(),m,n.current.onUpdateState,{allBlockChains:n.current.allBlockChains,lastConnectAttemptParams:u.current})}catch(f){console.error(f)}s(f=>f+1)}).flushEvents()},[]),b({autoConnect:t.autoConnect,allBlockChains:t.allBlockChains,autoConnectHandler:()=>{ge({allBlockChains:t.allBlockChains,getHub:o,wallets:t.configs?.wallets})}});let r=new E(W);return{canSwitchNetworkTo(a,l,m){let f=o().get(a);if(!f)throw new Error(`You should add ${a} to provider first then call 'canSwitchNetworkTo'.`);if(!m)throw new Error("Passing namespace to `canSwitchNetworkTo` is required.");let g=f.findByNamespace(m.namespace);if(!g)throw new Error(`We couldn't find any matched namespace on your request provider. (requested namespace: ${m.namespace})`);if(!("canSwitchNetwork"in g))return!1;let P=f.info()?.metadata?.properties?.find(v=>v.name==="namespaces");if(!n.current.allBlockChains)throw new Error("Blockchains are not available");let w=P?.value.data.find(v=>v.value===m.namespace)?.getSupportedChains(n.current.allBlockChains);if(!w)throw new Error(`NamespaceMeta is not defined for requested namespace: ${m.namespace}`);return g.canSwitchNetwork({network:l,supportedChains:w})},async connect(a,l){let m=o().get(a);if(!m)throw new Error(`You should add ${a} to provider first then call 'connect'.`);if(!l)throw new Error("Passing namespace to `connect` is required.");p(a,l);let f=[];l.forEach(y=>{let C=y.namespace,k=m.findByNamespace(C);if(!k)throw new Error(`We couldn't find any provider matched with your request namespace. (requested namespace: ${y.namespace})`);f.push([y,k])});let g=f.map(async([y,C])=>{let k=pe(y,t.allBlockChains||[]),N;return fe(C)?N=c(async()=>C.connect({derivationPath:y.derivationPath}),"connectNamespacePromise"):R(C)?N=c(async()=>C.connect(k,{derivationPath:y.derivationPath}),"connectNamespacePromise"):N=c(async()=>C.connect(),"connectNamespacePromise"),d(c(async()=>N().then(ue).then(H=>({response:H,input:{namespace:y.namespace,network:y.network,supportsEagerConnect:"canEagerConnect"in C}})),"connectNamespaceProcess"),a)}),P=await Promise.all(g),w=P.filter(y=>y.ok).filter(y=>y.val.input.supportsEagerConnect).map(y=>({namespace:y.val.input.namespace,network:y.val.input.network}));w.length>0&&r.addWallet(a,w);let v=P.map(y=>y.andThen(C=>new Ke(C.response))),L=ze.all(...v);if(L.err)throw L.val;return L.unwrap()},async disconnect(a,l){let m=o().get(a);if(!m)throw new Error(`You should add ${a} to provider first then call 'disconnect'.`);m.getAll().forEach(f=>{let g=!l||l.includes(f.namespaceId),P=f.state()[0]().connected;if(g&&P)return f.disconnect()}),t.autoConnect&&(l?r.removeNamespacesFromWallet(a,l):r.removeWallets([a]))},async disconnectAll(){let a=Array.from(o().getAll().values()).map(async l=>this.disconnect(l.id));return await Promise.allSettled(a)},async getSigners(a){let l=o().get(a);if(!l)throw new Error(`You should add ${a} to provider first.`);let m=l.info();if(!m)throw new Error("Your provider should have required `info`.");let g=m.metadata.properties?.find(P=>P.name==="signers");if(!g)throw new Error("Your provider should contain signers property.");return g.value.getSigners()},getWalletInfo(a){let l=o().get(a);if(!l)throw new Error(`You should add ${a} to provider first.`);let m=l.info();if(!m)throw new Error("Your provider should have required `info`.");let f={DEFAULT:""},{metadata:g,deepLink:P}=m,{extensions:w}=g;Object.keys(w).forEach(k=>{let N=k;if(N==="homepage"&&(f.DEFAULT=w[N]||""),["firefox","chrome","brave","edge"].includes(N)){let H=N.toUpperCase();f[H]=w[N]||""}});let v=g.properties,L=v?.find(k=>k.name==="namespaces"),y=v?.find(k=>k.name==="derivationPath"),C=v?.find(k=>k.name==="details");return{name:g.name,img:g.icon,installLink:f,color:"red",supportedChains:q(l,n.current.allBlockChains),isContractWallet:C?.value?.isContractWallet,mobileWallet:C?.value?.mobileWallet,showOnMobile:C?.value?.showOnMobile,needsNamespace:L?.value,needsDerivationPath:y?.value,generateDeepLink:P,isHub:!0,properties:g.properties}},providers(){let a={};return Array.from(o().getAll().keys()).forEach(l=>{try{let m=de(t.allVersionedProviders,l);a[l]=m.getInstance()}catch(m){console.warn(m)}}),a},state(a){let l=o().state(),m=o().get(a),f=l[a];if(!f||!m)throw new Error(`It seems your requested provider doesn't exist in hub. Provider Id: ${a}`);let g=f.namespaces.filter(v=>v.connected).flatMap(v=>v.accounts?.map(B)).filter(v=>!!v),P=new Map(Array.from(m.getAll(),([v,L])=>[L.namespaceId,L.state()[0]()]));return{connected:f.connected,connecting:f.connecting,installed:f.installed,reachable:!0,accounts:g,network:null,namespaces:P}},suggestAndConnect(a,l){throw new Error("`suggestAndConnect` is not implemented")}}}c(Q,"useHubAdapter");function Ce(t){let{providers:e,...o}=t,[s,n]=$(e),u=j({...o,providers:s}),p=Q({...o,providers:n,allVersionedProviders:e});return{canSwitchNetworkTo(r,i,a){return S(n,r)?p.canSwitchNetworkTo(r,i,a):u.canSwitchNetworkTo(r,i)},async connect(r,i){return S(n,r)?await p.connect(r,i):await u.connect(r,i)},async disconnect(r,i){return S(n,r)?await p.disconnect(r,i):await u.disconnect(r)},async disconnectAll(){return await Promise.allSettled([p.disconnectAll(),u.disconnectAll()])},async getSigners(r){return S(n,r)?p.getSigners(r):u.getSigners(r)},getWalletInfo(r){return S(n,r)?p.getWalletInfo(r):u.getWalletInfo(r)},providers(){let r={};return n.length>0&&(r={...r,...p.providers()}),s.length>0&&(r={...r,...u.providers()}),r},state(r){return S(n,r)?p.state(r):u.state(r)},async suggestAndConnect(r,i){return S(n,r)?p.suggestAndConnect(r,i):await u.suggestAndConnect(r,i)}}}c(Ce,"useProviders");function Xe(t){let e=Ce(t);return Je.createElement(x.Provider,{value:e},t.children)}c(Xe,"Provider");var Ze=Xe;import{LegacyEvents as $o}from"@rango-dev/wallets-core/legacy";export{$o as Events,Ze as Provider,J as availableWallets,X as checkWalletProviders,lt as choose,O as clearPersistance,z as connectedWallets,_ as defaultWalletState,dt as isAsync,D as makeEventHandler,pt as needsCheckInstallation,K as stateReducer,Z as tryPersistWallet,ee as tryRemoveWalletFromPersistance,Le as useWallets};
2
2
  //# sourceMappingURL=index.js.map