@kheopskit/core 6.0.0-rc.0 → 6.0.0-rc.2
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 +18 -0
- package/MIGRATING_TO_V6.md +56 -39
- package/README.md +48 -35
- package/dist/ethereum.d.mts +2 -1
- package/dist/ethereum.d.ts +2 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +21 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -17
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/polkadot.d.mts +1 -1
- package/dist/polkadot.d.ts +1 -1
- package/dist/polkadot.js +24 -41
- package/dist/polkadot.js.map +1 -1
- package/dist/polkadot.mjs +25 -42
- package/dist/polkadot.mjs.map +1 -1
- package/dist/registryReads-BpHsWLd7.js +38 -0
- package/dist/registryReads-BpHsWLd7.js.map +1 -0
- package/dist/{pageLoad-BZ7o8p5R.mjs → registryReads-BvtznSo3.mjs} +12 -3
- package/dist/registryReads-BvtznSo3.mjs.map +1 -0
- package/dist/solana.d.mts +2 -1
- package/dist/solana.d.ts +2 -1
- package/dist/solana.js +1 -0
- package/dist/solana.js.map +1 -1
- package/dist/solana.mjs +1 -0
- package/dist/solana.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/types-BWHvNFlN.js.map +1 -1
- package/dist/{types-Dkyt9bf4.d.ts → types-DCaL9bIc.d.mts} +45 -29
- package/dist/{types-Dkyt9bf4.d.mts → types-DCaL9bIc.d.ts} +45 -29
- package/dist/types-Yor672md.mjs.map +1 -1
- package/dist/walletconnect.d.mts +1 -1
- package/dist/walletconnect.d.ts +1 -1
- package/package.json +1 -1
- package/dist/pageLoad-BZ7o8p5R.mjs.map +0 -1
- package/dist/pageLoad-D1wLeuFG.js +0 -28
- package/dist/pageLoad-D1wLeuFG.js.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["PLATFORM_ORDER"],"sources":["../src/api/config.ts","../src/utils/sortAccounts.ts","../src/utils/sortWallets.ts","../src/api/platform.ts","../src/api/reconnectPolicy.ts","../src/api/hydration.ts","../src/utils/createHydrationBuffer.ts","../src/utils/logObservable.ts","../src/api/accounts.ts","../src/utils/createStore.ts","../src/api/compactStore.ts","../src/api/store.ts","../src/api/wallets.ts","../src/api/kheopskit.ts"],"sourcesContent":["import { KheopskitError } from \"./errors\";\nimport type { KheopskitConfig, KheopskitPlatform } from \"./types\";\n\n/**\n * Default storage key for persisting wallet connection state.\n * Can be overridden via config.storageKey to avoid conflicts\n * when running multiple dapps on the same domain.\n */\nexport const DEFAULT_STORAGE_KEY = \"kheopskit\";\n\nconst DEFAULTS = {\n\tautoReconnect: true,\n\tdebug: false,\n\tstorageKey: DEFAULT_STORAGE_KEY,\n\thydrationGracePeriod: 500,\n\thydrationTimeout: 3000,\n} satisfies Omit<KheopskitConfig, \"platforms\" | \"walletConnect\">;\n\nexport const resolveConfig = <\n\tconst P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n>(\n\tconfig?: Partial<KheopskitConfig<P>>,\n): KheopskitConfig<P> => {\n\tconst platforms = (config?.platforms ?? []) as P;\n\n\t// Guard the v4 breaking change: platforms are plugin instances, not strings.\n\t// Catches JS callers (no tsc) and gives agents a fix that names the doc.\n\tconst invalidPlatforms = (platforms as readonly unknown[]).filter(\n\t\t(p) =>\n\t\t\ttypeof p !== \"object\" ||\n\t\t\tp === null ||\n\t\t\ttypeof (p as { getWallets$?: unknown }).getWallets$ !== \"function\",\n\t);\n\tif (invalidPlatforms.length > 0) {\n\t\tthrow new Error(\n\t\t\t\"[kheopskit] config.platforms must contain plugin instances created by the \" +\n\t\t\t\t\"per-platform factories (e.g. platforms: [polkadot(), ethereum(), solana()] \" +\n\t\t\t\t'imported from \"@kheopskit/core/<platform>\"). ' +\n\t\t\t\t`Invalid entries: ${JSON.stringify(invalidPlatforms)}. ` +\n\t\t\t\t'String platform names like \"polkadot\" were removed in v4 — see MIGRATING_TO_V4.md.',\n\t\t);\n\t}\n\n\tif (\n\t\tconfig?.walletConnect !== undefined &&\n\t\ttypeof (config.walletConnect as { getWallet$?: unknown } | null)\n\t\t\t?.getWallet$ !== \"function\"\n\t) {\n\t\tthrow new KheopskitError(\n\t\t\t\"INVALID_CONFIG\",\n\t\t\t\"config.walletConnect must be created by walletConnect() imported from \" +\n\t\t\t\t'\"@kheopskit/core/walletconnect\", e.g. walletConnect: walletConnect({ projectId, metadata, networks }). ' +\n\t\t\t\t\"Raw WalletConnect options were removed in v6, see MIGRATING_TO_V6.md.\",\n\t\t);\n\t}\n\n\tif (platforms.length === 0) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] No platforms configured; wallets and accounts will be empty. \" +\n\t\t\t\t'Pass e.g. platforms: [polkadot()] from \"@kheopskit/core/polkadot\".',\n\t\t);\n\t}\n\n\treturn Object.assign({}, DEFAULTS, config, { platforms });\n};\n","import type { BaseWalletAccount, WalletPlatform } from \"../api/types\";\n\nconst PLATFORM_ORDER: Record<WalletPlatform, number> = {\n\tpolkadot: 0,\n\tethereum: 1,\n\tsolana: 2,\n};\n\nconst byPlatform = (a1: BaseWalletAccount, a2: BaseWalletAccount) =>\n\tPLATFORM_ORDER[a1.platform] - PLATFORM_ORDER[a2.platform];\n\n// Group accounts by wallet, surfacing Talisman first (case-insensitive).\nconst byWalletName = (a1: BaseWalletAccount, a2: BaseWalletAccount) => {\n\tif (a1.walletName === a2.walletName) return 0;\n\tif (a1.walletName.toLowerCase() === \"talisman\") return -1;\n\tif (a2.walletName.toLowerCase() === \"talisman\") return 1;\n\treturn a1.walletName.localeCompare(a2.walletName);\n};\n\nexport const sortAccounts = (a1: BaseWalletAccount, a2: BaseWalletAccount) =>\n\tbyPlatform(a1, a2) || byWalletName(a1, a2);\n","import {\n\ttype BaseWallet,\n\tisWalletConnectWallet,\n\ttype WalletConnectWallet,\n\ttype WalletPlatform,\n} from \"../api/types\";\n\nconst PLATFORM_ORDER: Record<WalletPlatform, number> = {\n\tpolkadot: 0,\n\tethereum: 1,\n\tsolana: 2,\n};\n\n// The platform-less WalletConnect connector sorts after all platform wallets.\nconst orderOf = (wallet: BaseWallet | WalletConnectWallet) =>\n\tisWalletConnectWallet(wallet) ? 3 : PLATFORM_ORDER[wallet.platform];\n\nexport const sortWallets = (\n\tw1: BaseWallet | WalletConnectWallet,\n\tw2: BaseWallet | WalletConnectWallet,\n) => {\n\t// Sort by platform first: polkadot, then ethereum, then solana, then WC\n\tconst o1 = orderOf(w1);\n\tconst o2 = orderOf(w2);\n\tif (o1 !== o2) return o1 - o2;\n\n\t// Sort by name, but Talisman first\n\tif (w1.name.toLowerCase() === \"talisman\") return -1;\n\tif (w2.name.toLowerCase() === \"talisman\") return 1;\n\n\treturn w1.name.localeCompare(w2.name);\n};\n","import type { CachedAccount, KheopskitPlatform } from \"./types\";\n\n/**\n * Whether a cached account should survive SSR hydration, per its platform\n * plugin's `acceptsCachedAccount` hook. Plugins without the hook (and platforms\n * with no enabled plugin) accept all — matching the pre-plugin behavior where\n * only Polkadot accounts were filtered (by key type).\n */\nexport const acceptsCachedAccount = (\n\tcached: CachedAccount,\n\tplatforms: readonly KheopskitPlatform[],\n): boolean => {\n\tconst plugin = platforms.find((p) => p.platform === cached.platform);\n\treturn plugin?.acceptsCachedAccount?.(cached) ?? true;\n};\n","import type { BaseWallet, KheopskitConfig } from \"./types\";\n\n// `maxAttempts` caps retries: wallets$ re-emits on every discovery change, so a\n// connect that always rejects would otherwise be re-attempted on each one.\nexport type ReconnectPolicyOptions = {\n\t/** @default 3 */\n\tmaxAttempts?: number;\n};\n\ntype ReconnectAttemptState =\n\t| { kind: \"pending\" }\n\t| { kind: \"reconnected\" }\n\t| { kind: \"settled\" }\n\t| { kind: \"failed\"; attempts: number };\n\nexport const createReconnectPolicy = ({\n\tmaxAttempts = 3,\n}: ReconnectPolicyOptions = {}) => {\n\tconst states = new Map<string, ReconnectAttemptState>();\n\n\tconst shouldAttempt = (walletId: string): boolean => {\n\t\tconst state = states.get(walletId);\n\t\tif (!state) return true;\n\t\treturn state.kind === \"failed\" && state.attempts < maxAttempts;\n\t};\n\n\tconst attempt = async (\n\t\twalletId: string,\n\t\tconnect: () => Promise<unknown>,\n\t): Promise<boolean> => {\n\t\tif (!shouldAttempt(walletId)) return false;\n\n\t\tconst before = states.get(walletId);\n\t\tstates.set(walletId, { kind: \"pending\" });\n\t\tconst recordOutcome = (outcome: ReconnectAttemptState) => {\n\t\t\tif (states.get(walletId)?.kind !== \"settled\")\n\t\t\t\tstates.set(walletId, outcome);\n\t\t};\n\t\ttry {\n\t\t\tawait connect();\n\t\t\trecordOutcome({ kind: \"reconnected\" });\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tconst attempts = before?.kind === \"failed\" ? before.attempts + 1 : 1;\n\t\t\trecordOutcome({ kind: \"failed\", attempts });\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst settle = (walletId: string) => {\n\t\tstates.set(walletId, { kind: \"settled\" });\n\t};\n\n\treturn { shouldAttempt, attempt, settle };\n};\n\n// Shared by the first-frame snapshot and the live attempt: both must evaluate\n// `autoReconnect` identically or the server and client markup diverge.\nexport const reconnectAccepts = (\n\tautoReconnect: KheopskitConfig[\"autoReconnect\"],\n\twallet: BaseWallet,\n): boolean =>\n\ttypeof autoReconnect === \"function\" ? autoReconnect(wallet) : autoReconnect;\n","import { hydrateAccount, hydrateWallet } from \"../utils/hydrateState\";\nimport { getCachedIcon } from \"../utils/iconCache\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport { acceptsCachedAccount } from \"./platform\";\nimport { reconnectAccepts } from \"./reconnectPolicy\";\nimport type { KheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tKheopskitConfig,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet } from \"./types\";\n\n/** Result of {@link getHydratedSnapshot}: placeholder wallets and accounts built from the cache. */\nexport type HydratedSnapshot = {\n\twallets: (BaseWallet | WalletConnectWallet)[];\n\taccounts: BaseWalletAccount[];\n};\n\nexport type GetHydratedSnapshotOptions = {\n\t/**\n\t * Enrich wallets that have no icon from the localStorage icon cache.\n\t *\n\t * Must stay `false` for any snapshot that has to match server-rendered markup\n\t * (React's `getServerSnapshot` runs on the client during hydration, where the\n\t * icon cache is populated — enriching there would diverge from the server,\n\t * which always sees an empty cache).\n\t */\n\ticons?: boolean;\n};\n\n/**\n * Builds the cached-state snapshot every consumer must agree on: read the\n * store's cached state, hydrate wallets/accounts into placeholders, apply the\n * `autoReconnect` rule (a cached connected wallet it rejects becomes\n * `disconnected` and loses its cached accounts), filter accounts through each\n * platform plugin's `acceptsCachedAccount` hook, and sort with the same\n * comparators the live pipeline uses.\n *\n * This is the single implementation behind the observable's initial seed and\n * both React snapshot sources (`serverValue`/`initialValue`). They must produce\n * the same shape in the same order or the UI flickers/reorders on reload — by\n * sharing this helper, that agreement holds by construction.\n */\nexport const getHydratedSnapshot = (\n\tstore: KheopskitStore,\n\tconfig: Pick<KheopskitConfig, \"platforms\" | \"autoReconnect\">,\n\toptions: GetHydratedSnapshotOptions = {},\n): HydratedSnapshot => {\n\tconst cached = store.getCachedState();\n\n\tconst wallets = cached.wallets\n\t\t.map(hydrateWallet)\n\t\t.map((wallet) =>\n\t\t\twallet.status === \"connecting\" &&\n\t\t\tisInjectedWallet(wallet) &&\n\t\t\t!reconnectAccepts(config.autoReconnect, wallet)\n\t\t\t\t? { ...wallet, status: \"disconnected\" as const }\n\t\t\t\t: wallet,\n\t\t)\n\t\t.map((wallet) => {\n\t\t\t// Some wallets (e.g. Ethereum) have no SSR-safe icon; optionally fill it\n\t\t\t// from the localStorage cache.\n\t\t\tif (!options.icons || wallet.icon) return wallet;\n\t\t\tconst icon = getCachedIcon(wallet.id);\n\t\t\treturn icon ? { ...wallet, icon } : wallet;\n\t\t})\n\t\t.sort(sortWallets);\n\n\tconst disconnected = new Set(\n\t\twallets.filter((w) => w.status === \"disconnected\").map((w) => w.id),\n\t);\n\n\tconst accounts = cached.accounts\n\t\t.filter((account) => !disconnected.has(account.walletId))\n\t\t.filter((account) => acceptsCachedAccount(account, config.platforms))\n\t\t.map(hydrateAccount)\n\t\t.sort(sortAccounts);\n\n\treturn { wallets, accounts };\n};\n","import {\n\tBehaviorSubject,\n\tcombineLatest,\n\tfilter,\n\tmap,\n\tObservable,\n\tSubscription,\n\tstartWith,\n\ttake,\n\ttimer,\n} from \"rxjs\";\n\ntype HydrationBufferResult<T> = {\n\titems: T[];\n\tisHydrating: boolean;\n};\n\nconst createBufferCore = <L, C>(\n\tcachedItems: C[],\n\tliveItems$: Observable<L[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tmergeFn: (liveItems: L[], cachedItems: C[]) => (L | C)[],\n\tsettled$?: Observable<boolean>,\n): Observable<HydrationBufferResult<L | C>> => {\n\tif (gracePeriodMs <= 0 || cachedItems.length === 0) {\n\t\treturn liveItems$.pipe(map((items) => ({ items, isHydrating: false })));\n\t}\n\n\treturn new Observable<HydrationBufferResult<L | C>>((subscriber) => {\n\t\tconst subscriptions = new Subscription();\n\t\tconst isHydrating$ = new BehaviorSubject(true);\n\t\tconst endHydration = () => {\n\t\t\tif (isHydrating$.value) isHydrating$.next(false);\n\t\t};\n\n\t\tconst graceElapsed$ = timer(gracePeriodMs).pipe(\n\t\t\tmap(() => true),\n\t\t\tstartWith(false),\n\t\t);\n\t\tconst ended$: Observable<unknown> = settled$\n\t\t\t? combineLatest([graceElapsed$, settled$]).pipe(\n\t\t\t\t\tfilter(([graceElapsed, settled]) => graceElapsed && settled),\n\t\t\t\t\ttake(1),\n\t\t\t\t)\n\t\t\t: timer(gracePeriodMs);\n\t\tsubscriptions.add(ended$.subscribe(endHydration));\n\t\tsubscriptions.add(timer(timeoutMs).subscribe(endHydration));\n\n\t\tsubscriptions.add(\n\t\t\tcombineLatest([liveItems$.pipe(startWith([] as L[])), isHydrating$])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([liveItems, isHydrating]) =>\n\t\t\t\t\t\tisHydrating\n\t\t\t\t\t\t\t? { items: mergeFn(liveItems, cachedItems), isHydrating }\n\t\t\t\t\t\t\t: { items: liveItems, isHydrating },\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber),\n\t\t);\n\n\t\treturn () => {\n\t\t\tsubscriptions.unsubscribe();\n\t\t\tisHydrating$.complete();\n\t\t};\n\t});\n};\n\n/**\n * Creates a hydration buffer that merges cached items with live items.\n *\n * During hydration, cached items take precedence over live items with the same key.\n * This preserves the cached connected state (e.g., isConnected: true) while\n * auto-reconnect is still in progress. New live items not in the cache are added.\n *\n * @param cachedItems - Initial cached items from storage\n * @param liveItems$ - Observable of live items as they become available\n * @param gracePeriodMs - Minimum time in ms the cached items are shown\n * @param timeoutMs - Upper bound in ms on hydration\n * @param getKey - Function to extract a unique key from an item\n * @param settled$ - Whether the live state has caught up with the cache\n * @param mergeItem - Optional function to merge a live item with its cached counterpart\n * @param transformCachedOnly - Optional function to transform cached items not yet in the live stream\n */\nexport const createHydrationBuffer = <L, C>(\n\tcachedItems: C[],\n\tliveItems$: Observable<L[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tgetKey: (item: L | C) => string,\n\tsettled$?: Observable<boolean>,\n\tmergeItem?: (liveItem: L, cachedItem: C) => L | C,\n\ttransformCachedOnly?: (cachedItem: C) => C,\n): Observable<HydrationBufferResult<L | C>> => {\n\treturn createBufferCore(\n\t\tcachedItems,\n\t\tliveItems$,\n\t\tgracePeriodMs,\n\t\ttimeoutMs,\n\t\t(liveItems, cached) => {\n\t\t\tconst cachedByKey = new Map(cached.map((item) => [getKey(item), item]));\n\t\t\tconst liveKeys = new Set(liveItems.map(getKey));\n\n\t\t\t// For items in both live and cached, prefer cached (preserves connected state)\n\t\t\t// but allow mergeItem to customize how they're combined\n\t\t\t// For items only in live (newly discovered), use the live version\n\t\t\tconst mergedItems: (L | C)[] = liveItems.map((liveItem) => {\n\t\t\t\tconst key = getKey(liveItem);\n\t\t\t\tconst cachedItem = cachedByKey.get(key);\n\t\t\t\tif (!cachedItem) return liveItem;\n\t\t\t\treturn mergeItem ? mergeItem(liveItem, cachedItem) : cachedItem;\n\t\t\t});\n\n\t\t\t// Add cached items not yet in the live stream (e.g., extensions not yet detected)\n\t\t\tfor (const cachedItem of cached) {\n\t\t\t\tif (!liveKeys.has(getKey(cachedItem))) {\n\t\t\t\t\tconst transformed = transformCachedOnly\n\t\t\t\t\t\t? transformCachedOnly(cachedItem)\n\t\t\t\t\t\t: cachedItem;\n\t\t\t\t\tmergedItems.push(transformed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mergedItems;\n\t\t},\n\t\tsettled$,\n\t);\n};\n\n/**\n * Creates a hydration buffer specifically for accounts, which need special handling.\n *\n * Accounts are grouped by wallet - when a wallet provides its account list,\n * we replace all cached accounts for that wallet with the live ones.\n * Cached accounts for wallets that haven't provided accounts yet are preserved.\n *\n * @param cachedAccounts - Initial cached accounts from storage\n * @param liveAccounts$ - Observable of live accounts as they become available\n * @param gracePeriodMs - Minimum time in ms the cached accounts are shown\n * @param timeoutMs - Upper bound in ms on hydration\n * @param getWalletId - Function to extract the wallet ID from an account\n * @param settled$ - Whether the live state has caught up with the cache\n */\nexport const createAccountHydrationBuffer = <T>(\n\tcachedAccounts: T[],\n\tliveAccounts$: Observable<T[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tgetWalletId: (account: T) => string,\n\tsettled$?: Observable<boolean>,\n): Observable<HydrationBufferResult<T>> => {\n\treturn createBufferCore(\n\t\tcachedAccounts,\n\t\tliveAccounts$,\n\t\tgracePeriodMs,\n\t\ttimeoutMs,\n\t\t(liveAccounts, cached) => {\n\t\t\tconst walletsWithLiveAccounts = new Set(liveAccounts.map(getWalletId));\n\t\t\tconst mergedAccounts: T[] = [...liveAccounts];\n\n\t\t\tfor (const cachedAccount of cached) {\n\t\t\t\tif (!walletsWithLiveAccounts.has(getWalletId(cachedAccount))) {\n\t\t\t\t\tmergedAccounts.push(cachedAccount);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mergedAccounts;\n\t\t},\n\t\tsettled$,\n\t);\n};\n","import { type MonoTypeOperatorFunction, tap } from \"rxjs\";\n\ntype Opts = {\n\tprintValue?: boolean;\n\tenabled?: boolean;\n};\n\nexport const logObservable = <T>(\n\tlabel: string,\n\topts?: Opts,\n): MonoTypeOperatorFunction<T> =>\n\ttap((value) => {\n\t\tconst { printValue = false, enabled = true } = opts || {};\n\n\t\tif (!label || !enabled) return;\n\n\t\tconst text = `[kheopskit] observable ${label} emit`;\n\n\t\tif (printValue) console.debug(text, value);\n\t\telse console.debug(text);\n\t});\n","import { combineLatest, map, Observable, of, shareReplay } from \"rxjs\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { framesOf, type PlatformAccountsFrame } from \"./platformAccounts\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tKheopskitConfig,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isWalletConnectWallet } from \"./types\";\n\nexport type AccountsFrame = PlatformAccountsFrame<BaseWalletAccount>;\n\nexport const getAccounts$ = (\n\tconfig: KheopskitConfig,\n\twallets: Observable<(BaseWallet | WalletConnectWallet)[]>,\n) => {\n\treturn new Observable<AccountsFrame>((subscriber) => {\n\t\t// Each plugin gets its own platform's (injected) wallets plus the shared\n\t\t// WalletConnect connector; it derives WC accounts only for the namespaces\n\t\t// the session carries.\n\t\tconst sources = config.platforms.map((plugin) =>\n\t\t\tframesOf(\n\t\t\t\tplugin.getAccounts$(\n\t\t\t\t\twallets.pipe(\n\t\t\t\t\t\tmap((ws) =>\n\t\t\t\t\t\t\tws.filter(\n\t\t\t\t\t\t\t\t(w) =>\n\t\t\t\t\t\t\t\t\tisWalletConnectWallet(w) || w.platform === plugin.platform,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\tconst frames$ = sources.length\n\t\t\t? combineLatest(sources).pipe(\n\t\t\t\t\tmap((frames) => ({\n\t\t\t\t\t\taccounts: frames\n\t\t\t\t\t\t\t.flatMap((frame) => frame.accounts)\n\t\t\t\t\t\t\t.sort(sortAccounts),\n\t\t\t\t\t\tanswered: frames.flatMap((frame) => frame.answered),\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t: of<AccountsFrame>({ accounts: [], answered: [] });\n\n\t\tconst sub = frames$.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n};\n","import { BehaviorSubject, Observable } from \"rxjs\";\nimport { type SyncableStorage, safeLocalStorage } from \"./storage\";\n\nexport const createStore = <T>(\n\tkey: string,\n\tdefaultValue: T,\n\tstorage: SyncableStorage = safeLocalStorage,\n\tnormalize: (value: T) => T = (value) => value,\n) => {\n\tconst read = (str: string | null) => normalize(parseData(str, defaultValue));\n\tconst syncsAcrossTabs =\n\t\ttypeof window !== \"undefined\" && storage.subscribe !== undefined;\n\tconst subject = new BehaviorSubject<T>(read(storage.getItem(key)));\n\tlet observers = 0;\n\tlet stopSync: (() => void) | undefined;\n\n\tconst latestValue = () => {\n\t\tif (syncsAcrossTabs && observers === 0)\n\t\t\tsubject.next(read(storage.getItem(key)));\n\t\treturn subject.getValue();\n\t};\n\n\tconst observable = new Observable<T>((subscriber) => {\n\t\tif (observers === 0 && syncsAcrossTabs) {\n\t\t\tlatestValue();\n\t\t\tstopSync = storage.subscribe?.(key, (newValue) => {\n\t\t\t\tsubject.next(read(newValue));\n\t\t\t});\n\t\t}\n\t\tobservers++;\n\t\tconst subscription = subject.subscribe(subscriber);\n\t\treturn () => {\n\t\t\tsubscription.unsubscribe();\n\t\t\tobservers--;\n\t\t\tif (observers === 0) stopSync?.();\n\t\t};\n\t});\n\n\tconst update = (val: T) => {\n\t\tpersistBestEffort(key, val, storage);\n\t\tsubject.next(val);\n\t};\n\n\treturn {\n\t\tobservable,\n\t\tset: (val: T) => update(val),\n\t\tmutate: (transform: (prev: T) => T) => update(transform(latestValue())),\n\t\tget: () => structuredClone(latestValue()),\n\t\tdestroy: () => subject.complete(),\n\t};\n};\n\nconst parseData = <T>(str: string | null, defaultValue: T): T => {\n\ttry {\n\t\tif (str) return JSON.parse(str);\n\t} catch {\n\t\t// invalid data\n\t}\n\treturn defaultValue;\n};\n\nconst persistBestEffort = <T>(\n\tkey: string,\n\tval: T,\n\tstorage: SyncableStorage,\n) => {\n\tconst str = JSON.stringify(val);\n\ttry {\n\t\tstorage.setItem(key, str);\n\t} catch {}\n};\n","import { isWalletPlatform } from \"../utils/isWalletPlatform\";\nimport { cookieStorage } from \"../utils/storage\";\nimport { getWalletAccountId } from \"../utils/WalletAccountId\";\nimport {\n\tisValidWalletId,\n\tparseWalletId,\n\tWALLET_CONNECT_WALLET_ID,\n\ttype WalletId,\n} from \"../utils/WalletId\";\nimport type {\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitStoreData,\n\tWalletPlatform,\n} from \"./types\";\n\n/**\n * Compact wire format for the cookie-persisted store (`CompactStoreV1`).\n *\n * Cookies are size-constrained (~4KB per cookie, sent on every request), so the\n * persisted {@link KheopskitStoreData} is encoded as terse tuples with\n * single-letter keys instead of raw JSON. This module owns that format: the\n * encoder, the defensive decoder, and the lazy migration from the legacy\n * verbose-JSON cookies written by older versions.\n *\n * Any change here is a compatibility question — new fields must be optional and\n * decoding must keep accepting everything older versions wrote (or degrade to\n * \"start fresh\", never throw).\n */\n\n// wallet type: 0=injected, 1=walletconnect\ntype CompactWalletEntry = [WalletId, string, 0 | 1, 0 | 1];\ntype CompactPolkadotAccountType = 0 | 1 | 2 | 3;\n// platform: 0=polkadot, 1=ethereum, 2=solana\ntype CompactPlatformCode = 0 | 1 | 2;\ntype CompactAccountEntry = [\n\tWalletId,\n\tstring,\n\tstring | null,\n\tnumber | null,\n\tCompactPolkadotAccountType | null,\n\t// Platform code. Newly written entries always include it (the WalletConnect\n\t// connector's walletId is platform-less, so platform can't be derived from\n\t// it); absent in entries written by older versions, where it's derived from\n\t// the walletId instead.\n\t(CompactPlatformCode | null)?,\n];\n\ntype CompactStoreV1 = {\n\tv: 1;\n\t// remembered\n\tr?: WalletId[];\n\t// wallets: [id, name, isConnected(0|1), type(0=injected,1=walletconnect)?]\n\tw?: CompactWalletEntry[];\n\t// accounts: [walletId, address, name?, chainId?, polkadotType?, platform?]\n\ta?: CompactAccountEntry[];\n};\n\nconst EMPTY_STORE_DATA: KheopskitStoreData = {};\n\ntype PreV6StoreData = KheopskitStoreData & { autoReconnect?: unknown };\n\nexport const migratePreV6StoreData = (\n\tdata: PreV6StoreData,\n): KheopskitStoreData => {\n\tif (data?.autoReconnect === undefined) return data;\n\tconst { autoReconnect, ...rest } = data;\n\treturn rest.remembered === undefined && Array.isArray(autoReconnect)\n\t\t? { ...rest, remembered: autoReconnect }\n\t\t: rest;\n};\n\nconst toCompactPolkadotAccountType = (\n\ttype: CachedAccount[\"polkadotAccountType\"],\n): CompactPolkadotAccountType | null => {\n\tswitch (type) {\n\t\tcase \"sr25519\":\n\t\t\treturn 0;\n\t\tcase \"ed25519\":\n\t\t\treturn 1;\n\t\tcase \"ecdsa\":\n\t\t\treturn 2;\n\t\tcase \"ethereum\":\n\t\t\treturn 3;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n};\n\nconst fromCompactPolkadotAccountType = (\n\ttype: CompactPolkadotAccountType | null | undefined,\n): CachedAccount[\"polkadotAccountType\"] => {\n\tswitch (type) {\n\t\tcase 0:\n\t\t\treturn \"sr25519\";\n\t\tcase 1:\n\t\t\treturn \"ed25519\";\n\t\tcase 2:\n\t\t\treturn \"ecdsa\";\n\t\tcase 3:\n\t\t\treturn \"ethereum\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst toCompactPlatform = (platform: WalletPlatform): CompactPlatformCode => {\n\tswitch (platform) {\n\t\tcase \"polkadot\":\n\t\t\treturn 0;\n\t\tcase \"ethereum\":\n\t\t\treturn 1;\n\t\tcase \"solana\":\n\t\t\treturn 2;\n\t}\n};\n\nconst fromCompactPlatform = (\n\tcode: CompactPlatformCode | null | undefined,\n): WalletPlatform | undefined => {\n\tswitch (code) {\n\t\tcase 0:\n\t\t\treturn \"polkadot\";\n\t\tcase 1:\n\t\t\treturn \"ethereum\";\n\t\tcase 2:\n\t\t\treturn \"solana\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst isCompactStore = (value: unknown): value is CompactStoreV1 => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tif (\"cachedWallets\" in value || \"cachedAccounts\" in value) return false;\n\treturn \"v\" in value || \"w\" in value || \"a\" in value || \"r\" in value;\n};\n\nconst toCompactStore = (data: KheopskitStoreData): CompactStoreV1 => {\n\tconst wallets = data.cachedWallets?.map(\n\t\t(wallet): CompactWalletEntry => [\n\t\t\twallet.id,\n\t\t\twallet.name,\n\t\t\twallet.isConnected ? 1 : 0,\n\t\t\twallet.type === \"walletconnect\" ? 1 : 0,\n\t\t],\n\t);\n\n\tconst accounts = data.cachedAccounts?.map(\n\t\t(account): CompactAccountEntry => [\n\t\t\taccount.walletId,\n\t\t\taccount.address,\n\t\t\taccount.name ?? null,\n\t\t\taccount.chainId ?? null,\n\t\t\ttoCompactPolkadotAccountType(account.polkadotAccountType),\n\t\t\ttoCompactPlatform(account.platform),\n\t\t],\n\t);\n\n\treturn {\n\t\tv: 1,\n\t\tr: data.remembered,\n\t\tw: wallets?.length ? wallets : undefined,\n\t\ta: accounts?.length ? accounts : undefined,\n\t};\n};\n\nconst fromCompactStore = (data: CompactStoreV1): KheopskitStoreData => {\n\tconst walletNameMap = new Map<WalletId, string>();\n\n\t// Decode defensively: a compact payload may be malformed (older/corrupt\n\t// cookie, hand-edited). Skip entries with an unparseable wallet id rather\n\t// than throwing, which would crash store initialisation.\n\tconst wallets: CachedWallet[] = [];\n\tfor (const item of Array.isArray(data.w) ? data.w : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [id, name, isConnected, type] = item;\n\t\tif (!isValidWalletId(id)) continue;\n\t\tconst isWalletConnect = id === WALLET_CONNECT_WALLET_ID;\n\t\tconst walletType = type === 1 ? \"walletconnect\" : \"injected\";\n\t\t// Keep id/type consistent: the platform-less connector uses the fixed WC\n\t\t// id; everything else is a platform-prefixed injected wallet. Drop stale\n\t\t// mismatches (e.g. per-platform WC ids from older versions).\n\t\tif (isWalletConnect !== (walletType === \"walletconnect\")) continue;\n\t\twalletNameMap.set(id, name);\n\t\twallets.push({\n\t\t\tid,\n\t\t\tplatform: isWalletConnect ? undefined : parseWalletId(id).platform,\n\t\t\ttype: walletType,\n\t\t\tname,\n\t\t\tisConnected: isConnected === 1,\n\t\t});\n\t}\n\n\tconst accounts: CachedAccount[] = [];\n\tfor (const item of Array.isArray(data.a) ? data.a : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [\n\t\t\twalletId,\n\t\t\taddress,\n\t\t\tname,\n\t\t\tchainId,\n\t\t\tpolkadotAccountType,\n\t\t\tplatformCode,\n\t\t] = item;\n\t\tif (!isValidWalletId(walletId) || typeof address !== \"string\" || !address)\n\t\t\tcontinue;\n\t\t// Prefer the explicit platform code; fall back to deriving it from the\n\t\t// walletId for entries written before the code existed (never WC ones).\n\t\tconst platform =\n\t\t\tplatformCode != null\n\t\t\t\t? fromCompactPlatform(platformCode)\n\t\t\t\t: walletId === WALLET_CONNECT_WALLET_ID\n\t\t\t\t\t? undefined\n\t\t\t\t\t: parseWalletId(walletId).platform;\n\t\tif (!isWalletPlatform(platform)) continue;\n\t\taccounts.push({\n\t\t\tid: getWalletAccountId(walletId, address),\n\t\t\tplatform,\n\t\t\taddress,\n\t\t\tname: name ?? undefined,\n\t\t\tchainId: chainId ?? undefined,\n\t\t\tpolkadotAccountType:\n\t\t\t\tplatform === \"polkadot\"\n\t\t\t\t\t? fromCompactPolkadotAccountType(polkadotAccountType)\n\t\t\t\t\t: undefined,\n\t\t\twalletId,\n\t\t\twalletName: walletNameMap.get(walletId) ?? walletId,\n\t\t});\n\t}\n\n\treturn {\n\t\tremembered: data.r,\n\t\tcachedWallets: wallets,\n\t\tcachedAccounts: accounts,\n\t};\n};\n\nconst decodeStore = (raw: string, fallback: KheopskitStoreData) => {\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\tif (isCompactStore(parsed)) return fromCompactStore(parsed);\n\t\treturn migratePreV6StoreData(parsed as PreV6StoreData);\n\t} catch {\n\t\treturn fallback;\n\t}\n};\n\nconst encodeStore = (data: KheopskitStoreData): string =>\n\tJSON.stringify(toCompactStore(data));\n\n/**\n * Cookie storage that transparently encodes/decodes {@link CompactStoreV1},\n * migrating legacy verbose-JSON cookies to the compact format on first read.\n */\nexport const createCompactCookieStorage = (initialCookies?: string) => {\n\tconst base = cookieStorage(initialCookies);\n\n\treturn {\n\t\tgetItem: (key: string) => {\n\t\t\tconst raw = base.getItem(key);\n\t\t\tif (!raw) return null;\n\t\t\tconst expanded = decodeStore(raw, EMPTY_STORE_DATA);\n\t\t\tif (typeof document !== \"undefined\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\t\t\t\tif (!isCompactStore(parsed)) {\n\t\t\t\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore malformed cookie during migration\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn JSON.stringify(expanded);\n\t\t},\n\t\tsetItem: (key: string, value: string) => {\n\t\t\tconst expanded = decodeStore(value, EMPTY_STORE_DATA);\n\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t},\n\t\tremoveItem: base.removeItem,\n\t\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\t\tconst unsubscribe = base.subscribe?.(key, (value) => {\n\t\t\t\tif (!value) {\n\t\t\t\t\tcallback(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst expanded = decodeStore(value, EMPTY_STORE_DATA);\n\t\t\t\tcallback(JSON.stringify(expanded));\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tunsubscribe?.();\n\t\t\t};\n\t\t},\n\t};\n};\n","import { uniq } from \"lodash-es\";\nimport { createStore } from \"../utils/createStore\";\nimport { isWalletPlatform } from \"../utils/isWalletPlatform\";\nimport { type SyncableStorage, safeLocalStorage } from \"../utils/storage\";\nimport {\n\tisValidWalletId,\n\tparseWalletId,\n\tWALLET_CONNECT_WALLET_ID,\n\ttype WalletId,\n} from \"../utils/WalletId\";\nimport {\n\tcreateCompactCookieStorage,\n\tmigratePreV6StoreData,\n} from \"./compactStore\";\nimport { DEFAULT_STORAGE_KEY } from \"./config\";\nimport type {\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitStore,\n\tKheopskitStoreData,\n} from \"./types\";\n\nexport type { KheopskitStore } from \"./types\";\n\nconst DEFAULT_SETTINGS: KheopskitStoreData = {};\n\n/**\n * Validates a cached wallet read from persisted storage. Cached state may have\n * been written by an older (or corrupted) version with a different shape, so we\n * drop anything that wouldn't survive hydration/sort rather than letting it\n * throw at render time. Only the fields downstream code relies on are checked.\n */\nconst isValidCachedWallet = (value: unknown): value is CachedWallet => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst w = value as Record<string, unknown>;\n\tif (!isValidWalletId(w.id)) return false;\n\tif (typeof w.name !== \"string\" || typeof w.isConnected !== \"boolean\")\n\t\treturn false;\n\t// The WalletConnect connector is platform-less with a fixed id; drop stale\n\t// per-platform WC entries written by older versions.\n\tif (w.type === \"walletconnect\")\n\t\treturn w.id === WALLET_CONNECT_WALLET_ID && w.platform === undefined;\n\treturn w.type === \"injected\" && isWalletPlatform(w.platform);\n};\n\n/** Validates a cached account read from persisted storage. See {@link isValidCachedWallet}. */\nconst isValidCachedAccount = (value: unknown): value is CachedAccount => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst a = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof a.id === \"string\" &&\n\t\t!!a.id &&\n\t\tisWalletPlatform(a.platform) &&\n\t\ttypeof a.address === \"string\" &&\n\t\t!!a.address &&\n\t\tisValidWalletId(a.walletId) &&\n\t\ttypeof a.walletName === \"string\"\n\t);\n};\n\ntype CreateKheopskitStoreOptions = {\n\t/**\n\t * Storage backend to persist into. When provided, it takes precedence over\n\t * `ssrCookies` and localStorage.\n\t */\n\tstorage?: SyncableStorage;\n\t/**\n\t * Cookie string for SSR hydration.\n\t * When provided, uses cookieStorage instead of localStorage.\n\t */\n\tssrCookies?: string;\n\t/**\n\t * Custom storage key to namespace the stored data.\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey?: string;\n};\n\n/**\n * Creates a kheopskit store with the appropriate storage backend.\n * Uses the given `storage` when provided, else cookieStorage when ssrCookies is\n * provided (for SSR hydration), otherwise safeLocalStorage.\n *\n * @param options - Configuration options for the store\n */\nexport const createKheopskitStore = (\n\toptions: CreateKheopskitStoreOptions = {},\n): KheopskitStore => {\n\tconst { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;\n\tconst storage =\n\t\toptions.storage ??\n\t\t(ssrCookies !== undefined\n\t\t\t? createCompactCookieStorage(ssrCookies)\n\t\t\t: safeLocalStorage);\n\tconst store = createStore(\n\t\tstorageKey,\n\t\tDEFAULT_SETTINGS,\n\t\tstorage,\n\t\tmigratePreV6StoreData,\n\t);\n\n\tconst rememberWallet = (walletId: WalletId) => {\n\t\tparseWalletId(walletId); // validate walletId\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tremembered: uniq((prev.remembered ?? []).concat(walletId)),\n\t\t}));\n\t};\n\n\tconst forgetWallet = (walletId: WalletId) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tremembered: uniq((prev.remembered ?? []).filter((id) => id !== walletId)),\n\t\t}));\n\t};\n\n\tconst getCachedState = () => {\n\t\t// `store.get()` returns whatever JSON was persisted — it may be from an\n\t\t// older version, a different shape, or outright corrupt. Read defensively:\n\t\t// coerce non-objects/arrays to empty and drop any entry that fails\n\t\t// validation, so stale cache degrades to \"start fresh\" instead of throwing\n\t\t// during hydration (which renders eagerly, so a throw blanks the dapp).\n\t\tconst data = store.get() as Partial<KheopskitStoreData> | null | undefined;\n\t\tconst cachedWallets = Array.isArray(data?.cachedWallets)\n\t\t\t? data.cachedWallets\n\t\t\t: [];\n\t\tconst cachedAccounts = Array.isArray(data?.cachedAccounts)\n\t\t\t? data.cachedAccounts\n\t\t\t: [];\n\t\treturn {\n\t\t\twallets: cachedWallets.filter(isValidCachedWallet),\n\t\t\taccounts: cachedAccounts.filter(isValidCachedAccount),\n\t\t};\n\t};\n\n\tconst setCachedState = (\n\t\twallets: CachedWallet[],\n\t\taccounts: CachedAccount[],\n\t) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tcachedWallets: wallets,\n\t\t\tcachedAccounts: accounts,\n\t\t}));\n\t};\n\n\treturn {\n\t\tobservable: store.observable,\n\t\trememberWallet,\n\t\tforgetWallet,\n\t\tgetCachedState,\n\t\tsetCachedState,\n\t\tdestroy: store.destroy,\n\t};\n};\n\n/**\n * Cached default store instance, anchored on globalThis so it stays a single\n * instance even if this module is duplicated across bundle chunks (e.g. CJS\n * subpath entries). Lazily initialized on first access to be SSR-safe.\n */\nconst DEFAULT_STORE_SYMBOL = Symbol.for(\"kheopskit.defaultStore\");\n\n/**\n * Gets the default store, creating it on first access.\n * Uses localStorage on client, noop on server.\n * Lazily initialized to avoid SSR issues with module-level code.\n */\nexport const getDefaultStore = (): KheopskitStore => {\n\tconst g = globalThis as unknown as Record<symbol, KheopskitStore | undefined>;\n\tif (!g[DEFAULT_STORE_SYMBOL]) {\n\t\tg[DEFAULT_STORE_SYMBOL] = createKheopskitStore();\n\t}\n\treturn g[DEFAULT_STORE_SYMBOL];\n};\n","import {\n\tcombineLatest,\n\tfilter,\n\tmap,\n\tmergeMap,\n\tObservable,\n\tof,\n\tshareReplay,\n\ttake,\n\ttap,\n} from \"rxjs\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport { KheopskitError } from \"./errors\";\nimport { createReconnectPolicy, reconnectAccepts } from \"./reconnectPolicy\";\nimport type { KheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tConnectOptions,\n\tKheopskitConfig,\n\tPlatformContext,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet } from \"./types\";\n\nexport const getWallets$ = (config: KheopskitConfig, store: KheopskitStore) => {\n\t// lock the list of wallets to auto reconnect on first call\n\tconst rememberedWalletIds$ = store.observable.pipe(\n\t\tmap((s) => s.remembered ?? []),\n\t\ttake(1),\n\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t);\n\n\treturn new Observable<(BaseWallet | WalletConnectWallet)[]>((subscriber) => {\n\t\tconst ctx: PlatformContext = { config, store };\n\t\tconst observables = config.platforms.map((plugin) =>\n\t\t\tplugin.getWallets$(ctx),\n\t\t);\n\n\t\tconst reconnectPolicy = createReconnectPolicy();\n\n\t\tconst settleOnUserCall = <W extends BaseWallet>(wallet: W): W => ({\n\t\t\t...wallet,\n\t\t\tconnect: (options?: ConnectOptions) => {\n\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\treturn wallet.connect(options);\n\t\t\t},\n\t\t\tdisconnect: () => {\n\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\treturn wallet.disconnect();\n\t\t\t},\n\t\t});\n\n\t\tconst platformWallets$ = observables.length\n\t\t\t? combineLatest(observables).pipe(map((wallets) => wallets.flat()))\n\t\t\t: of<BaseWallet[]>([]);\n\n\t\t// The single, platform-less WalletConnect connector is appended here (not\n\t\t// emitted per platform). It sorts last (see sortWallets).\n\t\tconst walletConnect$ = config.walletConnect?.getWallet$(ctx);\n\t\tconst unsortedWallets$: Observable<(BaseWallet | WalletConnectWallet)[]> =\n\t\t\twalletConnect$\n\t\t\t\t? combineLatest([platformWallets$, walletConnect$]).pipe(\n\t\t\t\t\t\tmap(([platformWallets, walletConnect]) =>\n\t\t\t\t\t\t\twalletConnect\n\t\t\t\t\t\t\t\t? [...platformWallets, walletConnect]\n\t\t\t\t\t\t\t\t: platformWallets,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: platformWallets$;\n\t\tconst rawWallets$ = unsortedWallets$.pipe(\n\t\t\tmap((all) => all.sort(sortWallets)),\n\t\t);\n\n\t\tconst wallets$ = rawWallets$.pipe(\n\t\t\tmap((wallets) =>\n\t\t\t\twallets.map((wallet) =>\n\t\t\t\t\tisInjectedWallet(wallet) ? settleOnUserCall(wallet) : wallet,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\tconst reconnect = async (wallet: BaseWallet) => {\n\t\t\ttry {\n\t\t\t\tawait reconnectPolicy.attempt(wallet.id, () => wallet.connect());\n\t\t\t} catch (err) {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tif (err instanceof KheopskitError) {\n\t\t\t\t\tif (err.code === \"USER_REJECTED\") store.forgetWallet(wallet.id);\n\t\t\t\t\tif (err.code === \"USER_REJECTED\" || err.code === \"ABORTED\")\n\t\t\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\t}\n\t\t\t\tif (config.debug)\n\t\t\t\t\tconsole.debug(\"[kheopskit] reconnect of %s failed\", wallet.id, err);\n\t\t\t}\n\t\t};\n\n\t\tconst subWallets = wallets$.subscribe(subscriber);\n\t\tif (subscriber.closed) return subWallets;\n\n\t\tconst subAutoReconnect = combineLatest([rawWallets$, rememberedWalletIds$])\n\t\t\t.pipe(\n\t\t\t\tfilter(\n\t\t\t\t\t([, walletIds]) =>\n\t\t\t\t\t\tconfig.autoReconnect !== false && walletIds.length > 0,\n\t\t\t\t),\n\t\t\t\tmergeMap(([wallets, walletIds]) =>\n\t\t\t\t\twallets\n\t\t\t\t\t\t.filter(isInjectedWallet)\n\t\t\t\t\t\t.filter((wallet) => walletIds.includes(wallet.id)),\n\t\t\t\t),\n\t\t\t\ttap((wallet) => {\n\t\t\t\t\tif (wallet.status === \"connected\") reconnectPolicy.settle(wallet.id);\n\t\t\t\t}),\n\t\t\t\tfilter(\n\t\t\t\t\t(wallet) =>\n\t\t\t\t\t\twallet.status === \"disconnected\" &&\n\t\t\t\t\t\treconnectAccepts(config.autoReconnect, wallet),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(reconnect);\n\n\t\treturn () => {\n\t\t\tsubAutoReconnect.unsubscribe();\n\t\t\tsubWallets.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n};\n","import {\n\tasapScheduler,\n\tcombineLatest,\n\tdebounceTime,\n\tdistinctUntilChanged,\n\tfilter,\n\tmap,\n\tObservable,\n\tof,\n\tshareReplay,\n\tstartWith,\n\tswitchMap,\n\ttake,\n\ttap,\n} from \"rxjs\";\nimport {\n\tcreateAccountHydrationBuffer,\n\tcreateHydrationBuffer,\n} from \"../utils/createHydrationBuffer\";\nimport { serializeAccount, serializeWallet } from \"../utils/hydrateState\";\nimport { getCachedIcon, setCachedIcons } from \"../utils/iconCache\";\nimport { logObservable } from \"../utils/logObservable\";\nimport { pageLoaded$ } from \"../utils/pageLoad\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport { type AccountsFrame, getAccounts$ } from \"./accounts\";\nimport { resolveConfig } from \"./config\";\nimport { abortedError, walletPendingError } from \"./errors\";\nimport { getHydratedSnapshot } from \"./hydration\";\nimport { createKheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitConfig,\n\tKheopskitPlatform,\n\tKheopskitState,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet, isWalletConnectWallet } from \"./types\";\nimport { getWallets$ } from \"./wallets\";\n\nexport type { KheopskitConfig, KheopskitState } from \"./types\";\n\n/** Options for {@link getKheopskit$}. */\nexport type GetKheopskitOptions = {\n\t/**\n\t * Cookie string for SSR hydration. When provided, state is read from cookies\n\t * instead of localStorage so the server can hydrate without a flash. Pass the\n\t * request's `cookie` header.\n\t */\n\tssrCookies?: string;\n\t/**\n\t * An existing store to reuse instead of creating one.\n\t */\n\tstore?: ReturnType<typeof createKheopskitStore>;\n};\n\nexport const getKheopskit$ = <\n\tconst P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n>(\n\tconfig?: Partial<KheopskitConfig<P>>,\n\toptions: GetKheopskitOptions = {},\n): Observable<KheopskitState<P>> => {\n\tconst { ssrCookies, store: existingStore } = options;\n\tconst kc = resolveConfig(config);\n\tconst store =\n\t\texistingStore ??\n\t\tcreateKheopskitStore({ ssrCookies, storageKey: kc.storageKey });\n\n\tif (kc.debug) console.debug(\"[kheopskit] config\", kc);\n\n\t// Warn about SSR environment without cookies\n\tif (kc.debug && typeof window === \"undefined\" && ssrCookies === undefined) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] Running on server without `ssrCookies`. \" +\n\t\t\t\t\"Wallet state will not be hydrated. Pass cookies for SSR support.\",\n\t\t);\n\t}\n\n\t// Get cached state for hydration (same snapshot the React provider builds)\n\tconst { wallets: cachedWallets, accounts: cachedAccounts } =\n\t\tgetHydratedSnapshot(store, kc, { icons: true });\n\n\tif (kc.debug && cachedWallets.length > 0) {\n\t\tconsole.debug(\"[kheopskit] hydrating from cache:\", {\n\t\t\twallets: cachedWallets.length,\n\t\t\taccounts: cachedAccounts.length,\n\t\t});\n\t}\n\n\treturn new Observable<KheopskitState>((subscriber) => {\n\t\tlet latest: KheopskitState | undefined;\n\t\tlet closed = false;\n\t\tconst waiters = new Set<StateWaiter>();\n\t\tconst liveWaiters = new Set<(state: KheopskitState | undefined) => void>();\n\t\tconst wrapped = new WeakMap<\n\t\t\tBaseWallet | WalletConnectWallet,\n\t\t\tBaseWallet | WalletConnectWallet\n\t\t>();\n\n\t\tconst abandon = (waiter: StateWaiter) => {\n\t\t\twaiters.delete(waiter);\n\t\t\tif (waiter.isConnected)\n\t\t\t\twaiter.reject(abortedError(waiter.walletId, \"connect\"));\n\t\t\telse waiter.resolve();\n\t\t};\n\n\t\tconst settleIn = (waiter: StateWaiter, state: KheopskitState) => {\n\t\t\tconst wallet = state.wallets.find((w) => w.id === waiter.walletId);\n\t\t\tif (!wallet || wallet.isConnected === waiter.isConnected) {\n\t\t\t\twaiters.delete(waiter);\n\t\t\t\twaiter.resolve();\n\t\t\t}\n\t\t};\n\n\t\tconst supersede = (walletId: WalletId, isConnected: boolean) => {\n\t\t\tfor (const waiter of waiters)\n\t\t\t\tif (waiter.walletId === walletId && waiter.isConnected !== isConnected)\n\t\t\t\t\tabandon(waiter);\n\t\t};\n\n\t\tconst whenState = (walletId: WalletId, isConnected: boolean) =>\n\t\t\tnew Promise<void>((resolve, reject) => {\n\t\t\t\tconst waiter = { walletId, isConnected, resolve, reject };\n\t\t\t\twaiters.add(waiter);\n\t\t\t\tif (latest) settleIn(waiter, latest);\n\t\t\t\tif (closed && waiters.has(waiter)) abandon(waiter);\n\t\t\t});\n\n\t\tconst whenLive = (walletId: WalletId, signal: AbortSignal | undefined) =>\n\t\t\tnew Promise<BaseWallet | WalletConnectWallet>((resolve, reject) => {\n\t\t\t\tconst settle = (finish: () => void) => {\n\t\t\t\t\tliveWaiters.delete(check);\n\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\tconst onAbort = () =>\n\t\t\t\t\tsettle(() => reject(abortedError(walletId, \"connect\")));\n\t\t\t\tconst check = (state: KheopskitState | undefined) => {\n\t\t\t\t\tif (!state) return onAbort();\n\t\t\t\t\tconst live = state.wallets.find(\n\t\t\t\t\t\t(w) => w.id === walletId && !w.isPlaceholder,\n\t\t\t\t\t);\n\t\t\t\t\tif (live) settle(() => resolve(live));\n\t\t\t\t\telse if (!state.isHydrating)\n\t\t\t\t\t\tsettle(() => reject(walletPendingError(walletId)));\n\t\t\t\t};\n\t\t\t\tif (closed || signal?.aborted) return onAbort();\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\tliveWaiters.add(check);\n\t\t\t\tif (latest) check(latest);\n\t\t\t});\n\n\t\tconst deferToLive = (\n\t\t\tplaceholder: BaseWallet | WalletConnectWallet,\n\t\t): BaseWallet | WalletConnectWallet => ({\n\t\t\t...placeholder,\n\t\t\tconnect: async (options) => {\n\t\t\t\tconst live = await whenLive(placeholder.id, options?.signal);\n\t\t\t\tif (closed) throw abortedError(placeholder.id, \"connect\");\n\t\t\t\tawait live.connect(options);\n\t\t\t},\n\t\t});\n\n\t\tconst settleWithState = (\n\t\t\twallet: BaseWallet | WalletConnectWallet,\n\t\t): BaseWallet | WalletConnectWallet => {\n\t\t\tconst existing = wrapped.get(wallet);\n\t\t\tif (existing) return existing;\n\t\t\tif (wallet.isPlaceholder) {\n\t\t\t\tconst deferred = deferToLive(wallet);\n\t\t\t\twrapped.set(wallet, deferred);\n\t\t\t\treturn deferred;\n\t\t\t}\n\t\t\tif (!isInjectedWallet(wallet)) return wallet;\n\t\t\tconst settled: BaseWallet = {\n\t\t\t\t...wallet,\n\t\t\t\tconnect: async (options) => {\n\t\t\t\t\tif (closed) throw abortedError(wallet.id, \"connect\");\n\t\t\t\t\tawait wallet.connect(options);\n\t\t\t\t\tsupersede(wallet.id, true);\n\t\t\t\t\tawait whenState(wallet.id, true);\n\t\t\t\t},\n\t\t\t\tdisconnect: async () => {\n\t\t\t\t\tif (closed) throw abortedError(wallet.id, \"disconnect\");\n\t\t\t\t\tawait wallet.disconnect();\n\t\t\t\t\tsupersede(wallet.id, false);\n\t\t\t\t\tawait whenState(wallet.id, false);\n\t\t\t\t},\n\t\t\t};\n\t\t\twrapped.set(wallet, settled);\n\t\t\treturn settled;\n\t\t};\n\n\t\t// Get live wallets and accounts\n\t\tconst liveWallets$ = getWallets$(kc, store);\n\t\tconst accountFrames$ = getAccounts$(kc, liveWallets$);\n\t\tconst liveAccounts$ = accountFrames$.pipe(\n\t\t\tmap(({ accounts }) => accounts.map(asLive)),\n\t\t);\n\n\t\tconst isDiscovering$ = pageLoaded$.pipe(\n\t\t\tswitchMap((loaded) =>\n\t\t\t\tloaded\n\t\t\t\t\t? liveWallets$.pipe(\n\t\t\t\t\t\t\ttake(1),\n\t\t\t\t\t\t\tmap(() => false),\n\t\t\t\t\t\t)\n\t\t\t\t\t: of(true),\n\t\t\t),\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\n\t\tconst reconnecting = cachedWallets.filter((w) => w.status === \"connecting\");\n\t\tconst hydrationSettled$ = combineLatest([\n\t\t\tliveWallets$,\n\t\t\taccountFrames$.pipe(startWith(noAnswerYet)),\n\t\t\tisDiscovering$,\n\t\t\tstore.observable.pipe(\n\t\t\t\tmap((s) => s.remembered ?? []),\n\t\t\t\ttake(1),\n\t\t\t),\n\t\t]).pipe(\n\t\t\tmap(\n\t\t\t\t([wallets, { accounts, answered }, isDiscovering, remembered]) =>\n\t\t\t\t\t!isDiscovering &&\n\t\t\t\t\treconnecting.every((cached) =>\n\t\t\t\t\t\treconnectSettled(cached, {\n\t\t\t\t\t\t\twallets,\n\t\t\t\t\t\t\taccounts,\n\t\t\t\t\t\t\tanswered,\n\t\t\t\t\t\t\tcachedAccounts,\n\t\t\t\t\t\t\tremembered,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t),\n\t\t\tdebounceTime(0, asapScheduler),\n\t\t\tdistinctUntilChanged(),\n\t\t);\n\n\t\t// Apply hydration buffer to wallets\n\t\tconst bufferedWallets$ = createHydrationBuffer(\n\t\t\tcachedWallets,\n\t\t\tliveWallets$.pipe(map((wallets) => wallets.map(asLive))),\n\t\t\tkc.hydrationGracePeriod,\n\t\t\tkc.hydrationTimeout,\n\t\t\t(w) => w.id,\n\t\t\thydrationSettled$,\n\t\t\t(live, cached) => {\n\t\t\t\tconst status = sessionRestoring(live, cached)\n\t\t\t\t\t? \"connecting\"\n\t\t\t\t\t: live.status;\n\t\t\t\treturn {\n\t\t\t\t\t...live,\n\t\t\t\t\tstatus,\n\t\t\t\t\tisConnected: status === \"connected\",\n\t\t\t\t\ticon: cached.icon || getCachedIcon(cached.id) || live.icon,\n\t\t\t\t};\n\t\t\t},\n\t\t\t// Transform cached-only items: add icon from localStorage cache\n\t\t\t(cached) => ({\n\t\t\t\t...cached,\n\t\t\t\ticon: cached.icon || getCachedIcon(cached.id) || \"\",\n\t\t\t}),\n\t\t);\n\n\t\t// Apply hydration buffer to accounts\n\t\tconst bufferedAccounts$ = createAccountHydrationBuffer(\n\t\t\tcachedAccounts,\n\t\t\tliveAccounts$,\n\t\t\tkc.hydrationGracePeriod,\n\t\t\tkc.hydrationTimeout,\n\t\t\t(a) => a.walletId,\n\t\t\thydrationSettled$,\n\t\t);\n\n\t\t// Share the buffered streams so the main and persistence subscriptions\n\t\t// below reuse a single hydration pipeline (timers, isHydrating state)\n\t\t// instead of running the buffering twice.\n\t\tconst sharedWallets$ = bufferedWallets$.pipe(\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\t\tconst sharedAccounts$ = bufferedAccounts$.pipe(\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\n\t\t// Combine buffered wallets and accounts\n\t\tconst subscription = combineLatest({\n\t\t\twallets: sharedWallets$,\n\t\t\taccounts: sharedAccounts$,\n\t\t\tisDiscovering: isDiscovering$,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tmap(({ wallets, accounts, isDiscovering }) => {\n\t\t\t\t\tif (kc.debug) {\n\t\t\t\t\t\tconsole.debug(\"[kheopskit] hydration state\", {\n\t\t\t\t\t\t\twalletsHydrating: wallets.isHydrating,\n\t\t\t\t\t\t\taccountsHydrating: accounts.isHydrating,\n\t\t\t\t\t\t\tisDiscovering,\n\t\t\t\t\t\t\twalletsConnected: wallets.items.filter((w) => w.isConnected)\n\t\t\t\t\t\t\t\t.length,\n\t\t\t\t\t\t\twalletsTotal: wallets.items.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Sort on every emission with the same comparators used for the\n\t\t\t\t\t// cached initial snapshot. The hydration buffers append cached-only\n\t\t\t\t\t// items after live ones (and reconnects land out of order), so\n\t\t\t\t\t// without this the list visibly reorders as wallets come back.\n\t\t\t\t\treturn {\n\t\t\t\t\t\tconfig: kc,\n\t\t\t\t\t\twallets: [...wallets.items].sort(sortWallets).map(settleWithState),\n\t\t\t\t\t\taccounts: [...accounts.items].sort(sortAccounts),\n\t\t\t\t\t\tisHydrating: wallets.isHydrating || accounts.isHydrating,\n\t\t\t\t\t\tisDiscovering,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t\tdebounceTime(0, asapScheduler),\n\t\t\t\tdistinctUntilChanged(statesEqual),\n\t\t\t\ttap((state) => {\n\t\t\t\t\tlatest = state;\n\t\t\t\t\tfor (const check of liveWaiters) check(state);\n\t\t\t\t\tfor (const waiter of waiters) settleIn(waiter, state);\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\t// Persist state snapshot when hydration completes and state stabilizes\n\t\tconst persistSub = combineLatest({\n\t\t\twallets: sharedWallets$,\n\t\t\taccounts: sharedAccounts$,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\t// Wait for hydration to complete\n\t\t\t\tfilter(\n\t\t\t\t\t({ wallets, accounts }) =>\n\t\t\t\t\t\t!wallets.isHydrating && !accounts.isHydrating,\n\t\t\t\t),\n\t\t\t\t// Debounce to avoid excessive writes\n\t\t\t\tdebounceTime(1000),\n\t\t\t\t// Only persist if the serialized snapshot would actually change.\n\t\t\t\t// Compare the persisted fields (not just ids): an Ethereum chain switch\n\t\t\t\t// keeps the same account id but changes the cached chainId, so an\n\t\t\t\t// id-only comparator would skip persisting it.\n\t\t\t\tdistinctUntilChanged((prev, curr) => {\n\t\t\t\t\tconst prevWalletKeys = prev.wallets.items.map(persistedWalletKey);\n\t\t\t\t\tconst currWalletKeys = curr.wallets.items.map(persistedWalletKey);\n\t\t\t\t\tconst prevAccountKeys = prev.accounts.items.map(accountChangeKey);\n\t\t\t\t\tconst currAccountKeys = curr.accounts.items.map(accountChangeKey);\n\t\t\t\t\treturn (\n\t\t\t\t\t\tarraysEqual(prevWalletKeys, currWalletKeys) &&\n\t\t\t\t\t\tarraysEqual(prevAccountKeys, currAccountKeys)\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe(({ wallets, accounts }) => {\n\t\t\t\tconst snapshot = persistedSnapshot(\n\t\t\t\t\twallets.items,\n\t\t\t\t\taccounts.items,\n\t\t\t\t\tstore.getCachedState(),\n\t\t\t\t);\n\n\t\t\t\tif (kc.debug) {\n\t\t\t\t\tconsole.debug(\"[kheopskit] persisting state snapshot:\", {\n\t\t\t\t\t\twallets: snapshot.wallets.length,\n\t\t\t\t\t\taccounts: snapshot.accounts.length,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tstore.setCachedState(snapshot.wallets, snapshot.accounts);\n\n\t\t\t\t// Cache wallet icons in localStorage (separate from cookies for size)\n\t\t\t\tconst icons: Record<string, string> = {};\n\t\t\t\tfor (const wallet of wallets.items) {\n\t\t\t\t\tif (wallet.icon) {\n\t\t\t\t\t\ticons[wallet.id] = wallet.icon;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsetCachedIcons(icons);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tsubscription.unsubscribe();\n\t\t\tpersistSub.unsubscribe();\n\t\t\tclosed = true;\n\t\t\tfor (const waiter of waiters) abandon(waiter);\n\t\t\tfor (const check of liveWaiters) check(undefined);\n\t\t};\n\t}).pipe(\n\t\tlogObservable(\"kheopskit$\", { enabled: kc.debug, printValue: true }),\n\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t// The runtime objects are the concrete per-plugin wallet/account types;\n\t\t// recover the precise KheopskitState<P> the caller's plugins imply.\n\t) as unknown as Observable<KheopskitState<P>>;\n};\n\ntype StateWaiter = {\n\twalletId: WalletId;\n\tisConnected: boolean;\n\tresolve: () => void;\n\treject: (error: unknown) => void;\n};\n\n// AppKit restores a cached WalletConnect session on its own and reports nothing\n// until it has; an injected wallet reports its attempt from its first emission.\nconst sessionRestoring = (\n\tlive: BaseWallet | WalletConnectWallet,\n\tcached: BaseWallet | WalletConnectWallet,\n): boolean =>\n\tisWalletConnectWallet(live) &&\n\tlive.status === \"disconnected\" &&\n\tcached.status === \"connecting\";\n\nconst flagged = new WeakMap<object, object>();\n\nconst asLive = <T extends object>(item: T): T & { isPlaceholder: false } => {\n\tconst existing = flagged.get(item);\n\tif (existing) return existing as T & { isPlaceholder: false };\n\tconst live = { ...item, isPlaceholder: false as const };\n\tflagged.set(item, live);\n\treturn live;\n};\n\nconst noAnswerYet: AccountsFrame = { accounts: [], answered: [] };\n\n/**\n * A remembered wallet that reads disconnected without an error is still\n * waiting for its reconnect: getWallets$ emits the wallet list before its\n * connect() flips the status to connecting.\n */\nconst reconnectSettled = (\n\tcached: BaseWallet | WalletConnectWallet,\n\tlive: AccountsFrame & {\n\t\twallets: (BaseWallet | WalletConnectWallet)[];\n\t\tcachedAccounts: BaseWalletAccount[];\n\t\tremembered: WalletId[];\n\t},\n): boolean => {\n\tconst wallet = live.wallets.find((w) => w.id === cached.id);\n\tif (!wallet) return true;\n\tconst status = sessionRestoring(wallet, cached)\n\t\t? \"connecting\"\n\t\t: wallet.status;\n\tif (status === \"connecting\") return false;\n\tif (status === \"disconnected\")\n\t\treturn wallet.error !== undefined || !live.remembered.includes(cached.id);\n\treturn (\n\t\tlive.answered.includes(cached.id) ||\n\t\t!live.cachedAccounts.some((a) => a.walletId === cached.id) ||\n\t\tlive.accounts.some((a) => a.walletId === cached.id)\n\t);\n};\n\n/**\n * A wallet still connecting keeps its previous cache entry and accounts:\n * written live it would read isConnected: false with no accounts, and the\n * next load would hydrate it as disconnected without placeholders while its\n * reconnect runs.\n */\nconst persistedSnapshot = (\n\twallets: (BaseWallet | WalletConnectWallet)[],\n\taccounts: BaseWalletAccount[],\n\tprevious: { wallets: CachedWallet[]; accounts: CachedAccount[] },\n): { wallets: CachedWallet[]; accounts: CachedAccount[] } => {\n\tconst connecting = new Set(\n\t\twallets.filter((w) => w.status === \"connecting\").map((w) => w.id),\n\t);\n\tconst connected = new Set(\n\t\twallets.filter((w) => w.isConnected).map((w) => w.id),\n\t);\n\tconst previousWallets = new Map(previous.wallets.map((w) => [w.id, w]));\n\treturn {\n\t\twallets: wallets.map(\n\t\t\t(w) =>\n\t\t\t\t(connecting.has(w.id) && previousWallets.get(w.id)) ||\n\t\t\t\tserializeWallet(w),\n\t\t),\n\t\taccounts: [\n\t\t\t...accounts\n\t\t\t\t.filter((a) => connected.has(a.walletId))\n\t\t\t\t.map(serializeAccount),\n\t\t\t...previous.accounts.filter((a) => connecting.has(a.walletId)),\n\t\t],\n\t};\n};\n\nconst arraysEqual = (a: string[], b: string[]) =>\n\ta.length === b.length && a.every((v, i) => v === b[i]);\n\n// Mutable per-platform account fields that can change without the account id\n// changing. Declared locally (not imported from the platform packages) so this\n// core entry stays free of platform SDK types — see check:isolation.\ntype EthereumAccountFields = { chainId?: number };\ntype PolkadotAccountFields = { type?: string };\ntype SolanaAccountFields = { chains?: string[] };\n\n/**\n * A signature of an account covering its id, its name, plus the\n * platform-specific fields that can change without the id changing (Ethereum\n * chainId, Polkadot key type, Solana clusters). Used to detect both UI-relevant\n * changes and changes worth re-persisting, so the two comparators can't drift\n * apart.\n */\nconst accountChangeKey = (account: BaseWalletAccount): string =>\n\t`${account.name ?? \"\"}|${accountPlatformKey(account)}`;\n\nconst accountPlatformKey = (account: BaseWalletAccount): string => {\n\tswitch (account.platform) {\n\t\tcase \"ethereum\":\n\t\t\treturn `${account.id}|${(account as EthereumAccountFields).chainId ?? \"\"}`;\n\t\tcase \"polkadot\":\n\t\t\treturn `${account.id}|${(account as PolkadotAccountFields).type ?? \"\"}`;\n\t\tcase \"solana\":\n\t\t\treturn `${account.id}|${((account as SolanaAccountFields).chains ?? []).join(\",\")}`;\n\t\tdefault:\n\t\t\treturn account.id;\n\t}\n};\n\n/** Platforms a wallet's live session carries (only the WalletConnect connector). */\nconst walletPlatforms = (wallet: BaseWallet | WalletConnectWallet): string =>\n\tisWalletConnectWallet(wallet) ? wallet.platforms.join(\",\") : \"\";\n\n/** Fields persisted to the cache for a wallet (icon is stored separately). */\nconst walletPersistKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${wallet.id}|${wallet.isConnected ? 1 : 0}|${wallet.name}`;\n\n/**\n * What decides a cache write: the persisted fields plus `status`, because a\n * wallet whose kept entry was written while connecting must be rewritten live\n * once its reconnect fails, and `isConnected` reads false on both sides.\n */\nconst persistedWalletKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${walletPersistKey(wallet)}|${wallet.status}`;\n\n/**\n * UI-significant signature of a wallet: the persisted fields plus icon and the\n * WalletConnect connector's `platforms` array, which drive what the UI shows but\n * aren't part of the id (icon and platforms can arrive asynchronously after\n * connect without isConnected flipping).\n */\nconst walletUiKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${walletPersistKey(wallet)}|${wallet.status}|${wallet.error?.code ?? \"\"}|${wallet.icon}|${walletPlatforms(wallet)}`;\n\n/**\n * Equality check for KheopskitState to prevent unnecessary emissions. Compares\n * the UI-significant signature of every wallet and account, in order.\n */\nconst statesEqual = (a: KheopskitState, b: KheopskitState): boolean =>\n\ta.isHydrating === b.isHydrating &&\n\ta.isDiscovering === b.isDiscovering &&\n\ta.wallets.length === b.wallets.length &&\n\ta.accounts.length === b.accounts.length &&\n\ta.wallets.every((w, i) => {\n\t\tconst other = b.wallets[i];\n\t\treturn (\n\t\t\t!!other &&\n\t\t\tw.isPlaceholder === other.isPlaceholder &&\n\t\t\twalletUiKey(w) === walletUiKey(other)\n\t\t);\n\t}) &&\n\ta.accounts.every((acc, i) => {\n\t\tconst other = b.accounts[i];\n\t\treturn (\n\t\t\t!!other &&\n\t\t\tacc.isPlaceholder === other.isPlaceholder &&\n\t\t\taccountChangeKey(acc) === accountChangeKey(other)\n\t\t);\n\t});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["PLATFORM_ORDER"],"sources":["../src/api/config.ts","../src/utils/sortAccounts.ts","../src/utils/sortWallets.ts","../src/api/platform.ts","../src/api/reconnectPolicy.ts","../src/api/hydration.ts","../src/utils/createHydrationBuffer.ts","../src/utils/logObservable.ts","../src/api/accounts.ts","../src/utils/createStore.ts","../src/api/compactStore.ts","../src/api/store.ts","../src/api/wallets.ts","../src/api/kheopskit.ts"],"sourcesContent":["import { KheopskitError } from \"./errors\";\nimport type { KheopskitConfig, KheopskitPlatform } from \"./types\";\n\n/**\n * Default storage key for persisting wallet connection state.\n * Can be overridden via config.storageKey to avoid conflicts\n * when running multiple dapps on the same domain.\n */\nexport const DEFAULT_STORAGE_KEY = \"kheopskit\";\n\nconst DEFAULTS = {\n\tautoReconnect: true,\n\tdebug: false,\n\tstorageKey: DEFAULT_STORAGE_KEY,\n\thydrationGracePeriod: 500,\n\thydrationTimeout: 3000,\n} satisfies Omit<KheopskitConfig, \"platforms\" | \"walletConnect\">;\n\nexport const resolveConfig = <\n\tconst P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n>(\n\tconfig?: Partial<KheopskitConfig<P>>,\n): KheopskitConfig<P> => {\n\tconst platforms = (config?.platforms ?? []) as P;\n\n\t// Guard the v4 breaking change: platforms are plugin instances, not strings.\n\t// Catches JS callers (no tsc) and gives agents a fix that names the doc.\n\tconst invalidPlatforms = (platforms as readonly unknown[]).filter(\n\t\t(p) =>\n\t\t\ttypeof p !== \"object\" ||\n\t\t\tp === null ||\n\t\t\ttypeof (p as { getWallets$?: unknown }).getWallets$ !== \"function\",\n\t);\n\tif (invalidPlatforms.length > 0) {\n\t\tthrow new Error(\n\t\t\t\"[kheopskit] config.platforms must contain plugin instances created by the \" +\n\t\t\t\t\"per-platform factories (e.g. platforms: [polkadot(), ethereum(), solana()] \" +\n\t\t\t\t'imported from \"@kheopskit/core/<platform>\"). ' +\n\t\t\t\t`Invalid entries: ${JSON.stringify(invalidPlatforms)}. ` +\n\t\t\t\t'String platform names like \"polkadot\" were removed in v4 — see MIGRATING_TO_V4.md.',\n\t\t);\n\t}\n\n\tif (\n\t\tconfig?.walletConnect !== undefined &&\n\t\ttypeof (config.walletConnect as { getWallet$?: unknown } | null)\n\t\t\t?.getWallet$ !== \"function\"\n\t) {\n\t\tthrow new KheopskitError(\n\t\t\t\"INVALID_CONFIG\",\n\t\t\t\"config.walletConnect must be created by walletConnect() imported from \" +\n\t\t\t\t'\"@kheopskit/core/walletconnect\", e.g. walletConnect: walletConnect({ projectId, metadata, networks }). ' +\n\t\t\t\t\"Raw WalletConnect options were removed in v6, see MIGRATING_TO_V6.md.\",\n\t\t);\n\t}\n\n\tif (platforms.length === 0) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] No platforms configured; wallets and accounts will be empty. \" +\n\t\t\t\t'Pass e.g. platforms: [polkadot()] from \"@kheopskit/core/polkadot\".',\n\t\t);\n\t}\n\n\treturn Object.assign({}, DEFAULTS, config, { platforms });\n};\n","import type { BaseWalletAccount, WalletPlatform } from \"../api/types\";\n\nconst PLATFORM_ORDER: Record<WalletPlatform, number> = {\n\tpolkadot: 0,\n\tethereum: 1,\n\tsolana: 2,\n};\n\nconst byPlatform = (a1: BaseWalletAccount, a2: BaseWalletAccount) =>\n\tPLATFORM_ORDER[a1.platform] - PLATFORM_ORDER[a2.platform];\n\n// Group accounts by wallet, surfacing Talisman first (case-insensitive).\nconst byWalletName = (a1: BaseWalletAccount, a2: BaseWalletAccount) => {\n\tif (a1.walletName === a2.walletName) return 0;\n\tif (a1.walletName.toLowerCase() === \"talisman\") return -1;\n\tif (a2.walletName.toLowerCase() === \"talisman\") return 1;\n\treturn a1.walletName.localeCompare(a2.walletName);\n};\n\nexport const sortAccounts = (a1: BaseWalletAccount, a2: BaseWalletAccount) =>\n\tbyPlatform(a1, a2) || byWalletName(a1, a2);\n","import {\n\ttype BaseWallet,\n\tisWalletConnectWallet,\n\ttype WalletConnectWallet,\n\ttype WalletPlatform,\n} from \"../api/types\";\n\nconst PLATFORM_ORDER: Record<WalletPlatform, number> = {\n\tpolkadot: 0,\n\tethereum: 1,\n\tsolana: 2,\n};\n\n// The platform-less WalletConnect connector sorts after all platform wallets.\nconst orderOf = (wallet: BaseWallet | WalletConnectWallet) =>\n\tisWalletConnectWallet(wallet) ? 3 : PLATFORM_ORDER[wallet.platform];\n\nexport const sortWallets = (\n\tw1: BaseWallet | WalletConnectWallet,\n\tw2: BaseWallet | WalletConnectWallet,\n) => {\n\t// Sort by platform first: polkadot, then ethereum, then solana, then WC\n\tconst o1 = orderOf(w1);\n\tconst o2 = orderOf(w2);\n\tif (o1 !== o2) return o1 - o2;\n\n\t// Sort by name, but Talisman first\n\tif (w1.name.toLowerCase() === \"talisman\") return -1;\n\tif (w2.name.toLowerCase() === \"talisman\") return 1;\n\n\treturn w1.name.localeCompare(w2.name);\n};\n","import type { CachedAccount, KheopskitPlatform } from \"./types\";\n\n/**\n * Whether a cached account should survive SSR hydration, per its platform\n * plugin's `acceptsCachedAccount` hook. Plugins without the hook (and platforms\n * with no enabled plugin) accept all — matching the pre-plugin behavior where\n * only Polkadot accounts were filtered (by key type).\n */\nexport const acceptsCachedAccount = (\n\tcached: CachedAccount,\n\tplatforms: readonly KheopskitPlatform[],\n): boolean => {\n\tconst plugin = platforms.find((p) => p.platform === cached.platform);\n\treturn plugin?.acceptsCachedAccount?.(cached) ?? true;\n};\n","import type { BaseWallet, KheopskitConfig } from \"./types\";\n\n// `maxAttempts` caps retries: wallets$ re-emits on every discovery change, so a\n// connect that always rejects would otherwise be re-attempted on each one.\nexport type ReconnectPolicyOptions = {\n\t/** @default 3 */\n\tmaxAttempts?: number;\n};\n\ntype ReconnectAttemptState =\n\t| { kind: \"pending\" }\n\t| { kind: \"reconnected\" }\n\t| { kind: \"settled\" }\n\t| { kind: \"failed\"; attempts: number };\n\nexport const createReconnectPolicy = ({\n\tmaxAttempts = 3,\n}: ReconnectPolicyOptions = {}) => {\n\tconst states = new Map<string, ReconnectAttemptState>();\n\n\tconst shouldAttempt = (walletId: string): boolean => {\n\t\tconst state = states.get(walletId);\n\t\tif (!state) return true;\n\t\treturn state.kind === \"failed\" && state.attempts < maxAttempts;\n\t};\n\n\tconst attempt = async (\n\t\twalletId: string,\n\t\tconnect: () => Promise<unknown>,\n\t): Promise<boolean> => {\n\t\tif (!shouldAttempt(walletId)) return false;\n\n\t\tconst before = states.get(walletId);\n\t\tstates.set(walletId, { kind: \"pending\" });\n\t\tconst recordOutcome = (outcome: ReconnectAttemptState) => {\n\t\t\tif (states.get(walletId)?.kind !== \"settled\")\n\t\t\t\tstates.set(walletId, outcome);\n\t\t};\n\t\ttry {\n\t\t\tawait connect();\n\t\t\trecordOutcome({ kind: \"reconnected\" });\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tconst attempts = before?.kind === \"failed\" ? before.attempts + 1 : 1;\n\t\t\trecordOutcome({ kind: \"failed\", attempts });\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst settle = (walletId: string) => {\n\t\tstates.set(walletId, { kind: \"settled\" });\n\t};\n\n\treturn { shouldAttempt, attempt, settle };\n};\n\n// Shared by the first-frame snapshot and the live attempt: both must evaluate\n// `autoReconnect` identically or the server and client markup diverge.\nexport const reconnectAccepts = (\n\tautoReconnect: KheopskitConfig[\"autoReconnect\"],\n\twallet: BaseWallet,\n): boolean =>\n\ttypeof autoReconnect === \"function\" ? autoReconnect(wallet) : autoReconnect;\n","import { hydrateAccount, hydrateWallet } from \"../utils/hydrateState\";\nimport { getCachedIcon } from \"../utils/iconCache\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport { acceptsCachedAccount } from \"./platform\";\nimport { reconnectAccepts } from \"./reconnectPolicy\";\nimport type { KheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tKheopskitConfig,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet } from \"./types\";\n\n/** Result of {@link getHydratedSnapshot}: placeholder wallets and accounts built from the cache. */\nexport type HydratedSnapshot = {\n\twallets: (BaseWallet | WalletConnectWallet)[];\n\taccounts: BaseWalletAccount[];\n};\n\nexport type GetHydratedSnapshotOptions = {\n\t/**\n\t * Enrich wallets that have no icon from the localStorage icon cache.\n\t *\n\t * Must stay `false` for any snapshot that has to match server-rendered markup\n\t * (React's `getServerSnapshot` runs on the client during hydration, where the\n\t * icon cache is populated — enriching there would diverge from the server,\n\t * which always sees an empty cache).\n\t */\n\ticons?: boolean;\n};\n\n/**\n * Builds the cached-state snapshot every consumer must agree on: read the\n * store's cached state, hydrate wallets/accounts into placeholders, apply the\n * `autoReconnect` rule (a cached connected wallet it rejects becomes\n * `disconnected` and loses its cached accounts), filter accounts through each\n * platform plugin's `acceptsCachedAccount` hook, and sort with the same\n * comparators the live pipeline uses.\n *\n * This is the single implementation behind the observable's initial seed and\n * both React snapshot sources (`serverValue`/`initialValue`). They must produce\n * the same shape in the same order or the UI flickers/reorders on reload — by\n * sharing this helper, that agreement holds by construction.\n */\nexport const getHydratedSnapshot = (\n\tstore: KheopskitStore,\n\tconfig: Pick<KheopskitConfig, \"platforms\" | \"autoReconnect\">,\n\toptions: GetHydratedSnapshotOptions = {},\n): HydratedSnapshot => {\n\tconst cached = store.getCachedState();\n\n\tconst wallets = cached.wallets\n\t\t.map(hydrateWallet)\n\t\t.map((wallet) =>\n\t\t\twallet.status === \"connecting\" &&\n\t\t\tisInjectedWallet(wallet) &&\n\t\t\t!reconnectAccepts(config.autoReconnect, wallet)\n\t\t\t\t? { ...wallet, status: \"disconnected\" as const }\n\t\t\t\t: wallet,\n\t\t)\n\t\t.map((wallet) => {\n\t\t\t// Some wallets (e.g. Ethereum) have no SSR-safe icon; optionally fill it\n\t\t\t// from the localStorage cache.\n\t\t\tif (!options.icons || wallet.icon) return wallet;\n\t\t\tconst icon = getCachedIcon(wallet.id);\n\t\t\treturn icon ? { ...wallet, icon } : wallet;\n\t\t})\n\t\t.sort(sortWallets);\n\n\tconst disconnected = new Set(\n\t\twallets.filter((w) => w.status === \"disconnected\").map((w) => w.id),\n\t);\n\n\tconst accounts = cached.accounts\n\t\t.filter((account) => !disconnected.has(account.walletId))\n\t\t.filter((account) => acceptsCachedAccount(account, config.platforms))\n\t\t.map(hydrateAccount)\n\t\t.sort(sortAccounts);\n\n\treturn { wallets, accounts };\n};\n","import {\n\tBehaviorSubject,\n\tcombineLatest,\n\tfilter,\n\tmap,\n\tObservable,\n\tSubscription,\n\tstartWith,\n\ttake,\n\ttimer,\n} from \"rxjs\";\n\ntype HydrationBufferResult<T> = {\n\titems: T[];\n\tisHydrating: boolean;\n};\n\nconst createBufferCore = <L, C>(\n\tcachedItems: C[],\n\tliveItems$: Observable<L[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tmergeFn: (liveItems: L[], cachedItems: C[]) => (L | C)[],\n\tsettled$?: Observable<boolean>,\n): Observable<HydrationBufferResult<L | C>> => {\n\tif (gracePeriodMs <= 0 || cachedItems.length === 0) {\n\t\treturn liveItems$.pipe(map((items) => ({ items, isHydrating: false })));\n\t}\n\n\treturn new Observable<HydrationBufferResult<L | C>>((subscriber) => {\n\t\tconst subscriptions = new Subscription();\n\t\tconst isHydrating$ = new BehaviorSubject(true);\n\t\tconst endHydration = () => {\n\t\t\tif (isHydrating$.value) isHydrating$.next(false);\n\t\t};\n\n\t\tconst graceElapsed$ = timer(gracePeriodMs).pipe(\n\t\t\tmap(() => true),\n\t\t\tstartWith(false),\n\t\t);\n\t\tconst ended$: Observable<unknown> = settled$\n\t\t\t? combineLatest([graceElapsed$, settled$]).pipe(\n\t\t\t\t\tfilter(([graceElapsed, settled]) => graceElapsed && settled),\n\t\t\t\t\ttake(1),\n\t\t\t\t)\n\t\t\t: timer(gracePeriodMs);\n\t\tsubscriptions.add(ended$.subscribe(endHydration));\n\t\tsubscriptions.add(timer(timeoutMs).subscribe(endHydration));\n\n\t\tsubscriptions.add(\n\t\t\tcombineLatest([liveItems$.pipe(startWith([] as L[])), isHydrating$])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([liveItems, isHydrating]) =>\n\t\t\t\t\t\tisHydrating\n\t\t\t\t\t\t\t? { items: mergeFn(liveItems, cachedItems), isHydrating }\n\t\t\t\t\t\t\t: { items: liveItems, isHydrating },\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber),\n\t\t);\n\n\t\treturn () => {\n\t\t\tsubscriptions.unsubscribe();\n\t\t\tisHydrating$.complete();\n\t\t};\n\t});\n};\n\n/**\n * Creates a hydration buffer that merges cached items with live items.\n *\n * During hydration, cached items take precedence over live items with the same key.\n * This preserves the cached connected state (e.g., isConnected: true) while\n * auto-reconnect is still in progress. New live items not in the cache are added.\n *\n * @param cachedItems - Initial cached items from storage\n * @param liveItems$ - Observable of live items as they become available\n * @param gracePeriodMs - Minimum time in ms the cached items are shown\n * @param timeoutMs - Upper bound in ms on hydration\n * @param getKey - Function to extract a unique key from an item\n * @param settled$ - Whether the live state has caught up with the cache\n * @param mergeItem - Optional function to merge a live item with its cached counterpart\n * @param transformCachedOnly - Optional function to transform cached items not yet in the live stream\n */\nexport const createHydrationBuffer = <L, C>(\n\tcachedItems: C[],\n\tliveItems$: Observable<L[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tgetKey: (item: L | C) => string,\n\tsettled$?: Observable<boolean>,\n\tmergeItem?: (liveItem: L, cachedItem: C) => L | C,\n\ttransformCachedOnly?: (cachedItem: C) => C,\n): Observable<HydrationBufferResult<L | C>> => {\n\treturn createBufferCore(\n\t\tcachedItems,\n\t\tliveItems$,\n\t\tgracePeriodMs,\n\t\ttimeoutMs,\n\t\t(liveItems, cached) => {\n\t\t\tconst cachedByKey = new Map(cached.map((item) => [getKey(item), item]));\n\t\t\tconst liveKeys = new Set(liveItems.map(getKey));\n\n\t\t\t// For items in both live and cached, prefer cached (preserves connected state)\n\t\t\t// but allow mergeItem to customize how they're combined\n\t\t\t// For items only in live (newly discovered), use the live version\n\t\t\tconst mergedItems: (L | C)[] = liveItems.map((liveItem) => {\n\t\t\t\tconst key = getKey(liveItem);\n\t\t\t\tconst cachedItem = cachedByKey.get(key);\n\t\t\t\tif (!cachedItem) return liveItem;\n\t\t\t\treturn mergeItem ? mergeItem(liveItem, cachedItem) : cachedItem;\n\t\t\t});\n\n\t\t\t// Add cached items not yet in the live stream (e.g., extensions not yet detected)\n\t\t\tfor (const cachedItem of cached) {\n\t\t\t\tif (!liveKeys.has(getKey(cachedItem))) {\n\t\t\t\t\tconst transformed = transformCachedOnly\n\t\t\t\t\t\t? transformCachedOnly(cachedItem)\n\t\t\t\t\t\t: cachedItem;\n\t\t\t\t\tmergedItems.push(transformed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mergedItems;\n\t\t},\n\t\tsettled$,\n\t);\n};\n\n/**\n * Creates a hydration buffer specifically for accounts, which need special handling.\n *\n * Accounts are grouped by wallet - when a wallet provides its account list,\n * we replace all cached accounts for that wallet with the live ones.\n * Cached accounts for wallets that haven't provided accounts yet are preserved.\n *\n * @param cachedAccounts - Initial cached accounts from storage\n * @param liveAccounts$ - Observable of live accounts as they become available\n * @param gracePeriodMs - Minimum time in ms the cached accounts are shown\n * @param timeoutMs - Upper bound in ms on hydration\n * @param getWalletId - Function to extract the wallet ID from an account\n * @param settled$ - Whether the live state has caught up with the cache\n */\nexport const createAccountHydrationBuffer = <T>(\n\tcachedAccounts: T[],\n\tliveAccounts$: Observable<T[]>,\n\tgracePeriodMs: number,\n\ttimeoutMs: number,\n\tgetWalletId: (account: T) => string,\n\tsettled$?: Observable<boolean>,\n): Observable<HydrationBufferResult<T>> => {\n\treturn createBufferCore(\n\t\tcachedAccounts,\n\t\tliveAccounts$,\n\t\tgracePeriodMs,\n\t\ttimeoutMs,\n\t\t(liveAccounts, cached) => {\n\t\t\tconst walletsWithLiveAccounts = new Set(liveAccounts.map(getWalletId));\n\t\t\tconst mergedAccounts: T[] = [...liveAccounts];\n\n\t\t\tfor (const cachedAccount of cached) {\n\t\t\t\tif (!walletsWithLiveAccounts.has(getWalletId(cachedAccount))) {\n\t\t\t\t\tmergedAccounts.push(cachedAccount);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn mergedAccounts;\n\t\t},\n\t\tsettled$,\n\t);\n};\n","import { type MonoTypeOperatorFunction, tap } from \"rxjs\";\n\ntype Opts = {\n\tprintValue?: boolean;\n\tenabled?: boolean;\n};\n\nexport const logObservable = <T>(\n\tlabel: string,\n\topts?: Opts,\n): MonoTypeOperatorFunction<T> =>\n\ttap((value) => {\n\t\tconst { printValue = false, enabled = true } = opts || {};\n\n\t\tif (!label || !enabled) return;\n\n\t\tconst text = `[kheopskit] observable ${label} emit`;\n\n\t\tif (printValue) console.debug(text, value);\n\t\telse console.debug(text);\n\t});\n","import { combineLatest, map, Observable, of, shareReplay } from \"rxjs\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { framesOf, type PlatformAccountsFrame } from \"./platformAccounts\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tKheopskitConfig,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isWalletConnectWallet } from \"./types\";\n\nexport type AccountsFrame = PlatformAccountsFrame<BaseWalletAccount>;\n\nexport const getAccounts$ = (\n\tconfig: KheopskitConfig,\n\twallets: Observable<(BaseWallet | WalletConnectWallet)[]>,\n) => {\n\treturn new Observable<AccountsFrame>((subscriber) => {\n\t\t// Each plugin gets its own platform's (injected) wallets plus the shared\n\t\t// WalletConnect connector; it derives WC accounts only for the namespaces\n\t\t// the session carries.\n\t\tconst sources = config.platforms.map((plugin) =>\n\t\t\tframesOf(\n\t\t\t\tplugin.getAccounts$(\n\t\t\t\t\twallets.pipe(\n\t\t\t\t\t\tmap((ws) =>\n\t\t\t\t\t\t\tws.filter(\n\t\t\t\t\t\t\t\t(w) =>\n\t\t\t\t\t\t\t\t\tisWalletConnectWallet(w) || w.platform === plugin.platform,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\tconst frames$ = sources.length\n\t\t\t? combineLatest(sources).pipe(\n\t\t\t\t\tmap((frames) => ({\n\t\t\t\t\t\taccounts: frames\n\t\t\t\t\t\t\t.flatMap((frame) => frame.accounts)\n\t\t\t\t\t\t\t.sort(sortAccounts),\n\t\t\t\t\t\tanswered: frames.flatMap((frame) => frame.answered),\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t: of<AccountsFrame>({ accounts: [], answered: [] });\n\n\t\tconst sub = frames$.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n};\n","import { BehaviorSubject, Observable } from \"rxjs\";\nimport { type SyncableStorage, safeLocalStorage } from \"./storage\";\n\nexport const createStore = <T>(\n\tkey: string,\n\tdefaultValue: T,\n\tstorage: SyncableStorage = safeLocalStorage,\n\tnormalize: (value: T) => T = (value) => value,\n) => {\n\tconst read = (str: string | null) => normalize(parseData(str, defaultValue));\n\tconst syncsAcrossTabs =\n\t\ttypeof window !== \"undefined\" && storage.subscribe !== undefined;\n\tconst subject = new BehaviorSubject<T>(read(storage.getItem(key)));\n\tlet observers = 0;\n\tlet stopSync: (() => void) | undefined;\n\n\tconst latestValue = () => {\n\t\tif (syncsAcrossTabs && observers === 0)\n\t\t\tsubject.next(read(storage.getItem(key)));\n\t\treturn subject.getValue();\n\t};\n\n\tconst observable = new Observable<T>((subscriber) => {\n\t\tif (observers === 0 && syncsAcrossTabs) {\n\t\t\tlatestValue();\n\t\t\tstopSync = storage.subscribe?.(key, (newValue) => {\n\t\t\t\tsubject.next(read(newValue));\n\t\t\t});\n\t\t}\n\t\tobservers++;\n\t\tconst subscription = subject.subscribe(subscriber);\n\t\treturn () => {\n\t\t\tsubscription.unsubscribe();\n\t\t\tobservers--;\n\t\t\tif (observers === 0) stopSync?.();\n\t\t};\n\t});\n\n\tconst update = (val: T) => {\n\t\tpersistBestEffort(key, val, storage);\n\t\tsubject.next(val);\n\t};\n\n\treturn {\n\t\tobservable,\n\t\tset: (val: T) => update(val),\n\t\tmutate: (transform: (prev: T) => T) => update(transform(latestValue())),\n\t\tget: () => structuredClone(latestValue()),\n\t\tdestroy: () => subject.complete(),\n\t};\n};\n\nconst parseData = <T>(str: string | null, defaultValue: T): T => {\n\ttry {\n\t\tif (str) return JSON.parse(str);\n\t} catch {\n\t\t// invalid data\n\t}\n\treturn defaultValue;\n};\n\nconst persistBestEffort = <T>(\n\tkey: string,\n\tval: T,\n\tstorage: SyncableStorage,\n) => {\n\tconst str = JSON.stringify(val);\n\ttry {\n\t\tstorage.setItem(key, str);\n\t} catch {}\n};\n","import { isWalletPlatform } from \"../utils/isWalletPlatform\";\nimport { cookieStorage } from \"../utils/storage\";\nimport { getWalletAccountId } from \"../utils/WalletAccountId\";\nimport {\n\tisValidWalletId,\n\tparseWalletId,\n\tWALLET_CONNECT_WALLET_ID,\n\ttype WalletId,\n} from \"../utils/WalletId\";\nimport type {\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitStoreData,\n\tWalletPlatform,\n} from \"./types\";\n\n/**\n * Compact wire format for the cookie-persisted store (`CompactStoreV1`).\n *\n * Cookies are size-constrained (~4KB per cookie, sent on every request), so the\n * persisted {@link KheopskitStoreData} is encoded as terse tuples with\n * single-letter keys instead of raw JSON. This module owns that format: the\n * encoder, the defensive decoder, and the lazy migration from the legacy\n * verbose-JSON cookies written by older versions.\n *\n * Any change here is a compatibility question — new fields must be optional and\n * decoding must keep accepting everything older versions wrote (or degrade to\n * \"start fresh\", never throw).\n */\n\n// wallet type: 0=injected, 1=walletconnect\ntype CompactWalletEntry = [WalletId, string, 0 | 1, 0 | 1];\ntype CompactPolkadotAccountType = 0 | 1 | 2 | 3;\n// platform: 0=polkadot, 1=ethereum, 2=solana\ntype CompactPlatformCode = 0 | 1 | 2;\ntype CompactAccountEntry = [\n\tWalletId,\n\tstring,\n\tstring | null,\n\tnumber | null,\n\tCompactPolkadotAccountType | null,\n\t// Platform code. Newly written entries always include it (the WalletConnect\n\t// connector's walletId is platform-less, so platform can't be derived from\n\t// it); absent in entries written by older versions, where it's derived from\n\t// the walletId instead.\n\t(CompactPlatformCode | null)?,\n];\n\ntype CompactStoreV1 = {\n\tv: 1;\n\t// remembered\n\tr?: WalletId[];\n\t// wallets: [id, name, isConnected(0|1), type(0=injected,1=walletconnect)?]\n\tw?: CompactWalletEntry[];\n\t// accounts: [walletId, address, name?, chainId?, polkadotType?, platform?]\n\ta?: CompactAccountEntry[];\n};\n\nconst EMPTY_STORE_DATA: KheopskitStoreData = {};\n\ntype PreV6StoreData = KheopskitStoreData & { autoReconnect?: unknown };\n\nexport const migratePreV6StoreData = (\n\tdata: PreV6StoreData,\n): KheopskitStoreData => {\n\tif (data?.autoReconnect === undefined) return data;\n\tconst { autoReconnect, ...rest } = data;\n\treturn rest.remembered === undefined && Array.isArray(autoReconnect)\n\t\t? { ...rest, remembered: autoReconnect }\n\t\t: rest;\n};\n\nconst toCompactPolkadotAccountType = (\n\ttype: CachedAccount[\"polkadotAccountType\"],\n): CompactPolkadotAccountType | null => {\n\tswitch (type) {\n\t\tcase \"sr25519\":\n\t\t\treturn 0;\n\t\tcase \"ed25519\":\n\t\t\treturn 1;\n\t\tcase \"ecdsa\":\n\t\t\treturn 2;\n\t\tcase \"ethereum\":\n\t\t\treturn 3;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n};\n\nconst fromCompactPolkadotAccountType = (\n\ttype: CompactPolkadotAccountType | null | undefined,\n): CachedAccount[\"polkadotAccountType\"] => {\n\tswitch (type) {\n\t\tcase 0:\n\t\t\treturn \"sr25519\";\n\t\tcase 1:\n\t\t\treturn \"ed25519\";\n\t\tcase 2:\n\t\t\treturn \"ecdsa\";\n\t\tcase 3:\n\t\t\treturn \"ethereum\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst toCompactPlatform = (platform: WalletPlatform): CompactPlatformCode => {\n\tswitch (platform) {\n\t\tcase \"polkadot\":\n\t\t\treturn 0;\n\t\tcase \"ethereum\":\n\t\t\treturn 1;\n\t\tcase \"solana\":\n\t\t\treturn 2;\n\t}\n};\n\nconst fromCompactPlatform = (\n\tcode: CompactPlatformCode | null | undefined,\n): WalletPlatform | undefined => {\n\tswitch (code) {\n\t\tcase 0:\n\t\t\treturn \"polkadot\";\n\t\tcase 1:\n\t\t\treturn \"ethereum\";\n\t\tcase 2:\n\t\t\treturn \"solana\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst isCompactStore = (value: unknown): value is CompactStoreV1 => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tif (\"cachedWallets\" in value || \"cachedAccounts\" in value) return false;\n\treturn \"v\" in value || \"w\" in value || \"a\" in value || \"r\" in value;\n};\n\nconst toCompactStore = (data: KheopskitStoreData): CompactStoreV1 => {\n\tconst wallets = data.cachedWallets?.map(\n\t\t(wallet): CompactWalletEntry => [\n\t\t\twallet.id,\n\t\t\twallet.name,\n\t\t\twallet.isConnected ? 1 : 0,\n\t\t\twallet.type === \"walletconnect\" ? 1 : 0,\n\t\t],\n\t);\n\n\tconst accounts = data.cachedAccounts?.map(\n\t\t(account): CompactAccountEntry => [\n\t\t\taccount.walletId,\n\t\t\taccount.address,\n\t\t\taccount.name ?? null,\n\t\t\taccount.chainId ?? null,\n\t\t\ttoCompactPolkadotAccountType(account.polkadotAccountType),\n\t\t\ttoCompactPlatform(account.platform),\n\t\t],\n\t);\n\n\treturn {\n\t\tv: 1,\n\t\tr: data.remembered,\n\t\tw: wallets?.length ? wallets : undefined,\n\t\ta: accounts?.length ? accounts : undefined,\n\t};\n};\n\nconst fromCompactStore = (data: CompactStoreV1): KheopskitStoreData => {\n\tconst walletNameMap = new Map<WalletId, string>();\n\n\t// Decode defensively: a compact payload may be malformed (older/corrupt\n\t// cookie, hand-edited). Skip entries with an unparseable wallet id rather\n\t// than throwing, which would crash store initialisation.\n\tconst wallets: CachedWallet[] = [];\n\tfor (const item of Array.isArray(data.w) ? data.w : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [id, name, isConnected, type] = item;\n\t\tif (!isValidWalletId(id)) continue;\n\t\tconst isWalletConnect = id === WALLET_CONNECT_WALLET_ID;\n\t\tconst walletType = type === 1 ? \"walletconnect\" : \"injected\";\n\t\t// Keep id/type consistent: the platform-less connector uses the fixed WC\n\t\t// id; everything else is a platform-prefixed injected wallet. Drop stale\n\t\t// mismatches (e.g. per-platform WC ids from older versions).\n\t\tif (isWalletConnect !== (walletType === \"walletconnect\")) continue;\n\t\twalletNameMap.set(id, name);\n\t\twallets.push({\n\t\t\tid,\n\t\t\tplatform: isWalletConnect ? undefined : parseWalletId(id).platform,\n\t\t\ttype: walletType,\n\t\t\tname,\n\t\t\tisConnected: isConnected === 1,\n\t\t});\n\t}\n\n\tconst accounts: CachedAccount[] = [];\n\tfor (const item of Array.isArray(data.a) ? data.a : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [\n\t\t\twalletId,\n\t\t\taddress,\n\t\t\tname,\n\t\t\tchainId,\n\t\t\tpolkadotAccountType,\n\t\t\tplatformCode,\n\t\t] = item;\n\t\tif (!isValidWalletId(walletId) || typeof address !== \"string\" || !address)\n\t\t\tcontinue;\n\t\t// Prefer the explicit platform code; fall back to deriving it from the\n\t\t// walletId for entries written before the code existed (never WC ones).\n\t\tconst platform =\n\t\t\tplatformCode != null\n\t\t\t\t? fromCompactPlatform(platformCode)\n\t\t\t\t: walletId === WALLET_CONNECT_WALLET_ID\n\t\t\t\t\t? undefined\n\t\t\t\t\t: parseWalletId(walletId).platform;\n\t\tif (!isWalletPlatform(platform)) continue;\n\t\taccounts.push({\n\t\t\tid: getWalletAccountId(walletId, address),\n\t\t\tplatform,\n\t\t\taddress,\n\t\t\tname: name ?? undefined,\n\t\t\tchainId: chainId ?? undefined,\n\t\t\tpolkadotAccountType:\n\t\t\t\tplatform === \"polkadot\"\n\t\t\t\t\t? fromCompactPolkadotAccountType(polkadotAccountType)\n\t\t\t\t\t: undefined,\n\t\t\twalletId,\n\t\t\twalletName: walletNameMap.get(walletId) ?? walletId,\n\t\t});\n\t}\n\n\treturn {\n\t\tremembered: data.r,\n\t\tcachedWallets: wallets,\n\t\tcachedAccounts: accounts,\n\t};\n};\n\nconst decodeStore = (raw: string, fallback: KheopskitStoreData) => {\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\tif (isCompactStore(parsed)) return fromCompactStore(parsed);\n\t\treturn migratePreV6StoreData(parsed as PreV6StoreData);\n\t} catch {\n\t\treturn fallback;\n\t}\n};\n\nconst encodeStore = (data: KheopskitStoreData): string =>\n\tJSON.stringify(toCompactStore(data));\n\n/**\n * Cookie storage that transparently encodes/decodes {@link CompactStoreV1},\n * migrating legacy verbose-JSON cookies to the compact format on first read.\n */\nexport const createCompactCookieStorage = (initialCookies?: string) => {\n\tconst base = cookieStorage(initialCookies);\n\n\treturn {\n\t\tgetItem: (key: string) => {\n\t\t\tconst raw = base.getItem(key);\n\t\t\tif (!raw) return null;\n\t\t\tconst expanded = decodeStore(raw, EMPTY_STORE_DATA);\n\t\t\tif (typeof document !== \"undefined\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\t\t\t\tif (!isCompactStore(parsed)) {\n\t\t\t\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore malformed cookie during migration\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn JSON.stringify(expanded);\n\t\t},\n\t\tsetItem: (key: string, value: string) => {\n\t\t\tconst expanded = decodeStore(value, EMPTY_STORE_DATA);\n\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t},\n\t\tremoveItem: base.removeItem,\n\t\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\t\tconst unsubscribe = base.subscribe?.(key, (value) => {\n\t\t\t\tif (!value) {\n\t\t\t\t\tcallback(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst expanded = decodeStore(value, EMPTY_STORE_DATA);\n\t\t\t\tcallback(JSON.stringify(expanded));\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tunsubscribe?.();\n\t\t\t};\n\t\t},\n\t};\n};\n","import { uniq } from \"lodash-es\";\nimport { createStore } from \"../utils/createStore\";\nimport { isWalletPlatform } from \"../utils/isWalletPlatform\";\nimport { type SyncableStorage, safeLocalStorage } from \"../utils/storage\";\nimport {\n\tisValidWalletId,\n\tparseWalletId,\n\tWALLET_CONNECT_WALLET_ID,\n\ttype WalletId,\n} from \"../utils/WalletId\";\nimport {\n\tcreateCompactCookieStorage,\n\tmigratePreV6StoreData,\n} from \"./compactStore\";\nimport { DEFAULT_STORAGE_KEY } from \"./config\";\nimport type {\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitStore,\n\tKheopskitStoreData,\n} from \"./types\";\n\nexport type { KheopskitStore } from \"./types\";\n\nconst DEFAULT_SETTINGS: KheopskitStoreData = {};\n\n/**\n * Validates a cached wallet read from persisted storage. Cached state may have\n * been written by an older (or corrupted) version with a different shape, so we\n * drop anything that wouldn't survive hydration/sort rather than letting it\n * throw at render time. Only the fields downstream code relies on are checked.\n */\nconst isValidCachedWallet = (value: unknown): value is CachedWallet => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst w = value as Record<string, unknown>;\n\tif (!isValidWalletId(w.id)) return false;\n\tif (typeof w.name !== \"string\" || typeof w.isConnected !== \"boolean\")\n\t\treturn false;\n\t// The WalletConnect connector is platform-less with a fixed id; drop stale\n\t// per-platform WC entries written by older versions.\n\tif (w.type === \"walletconnect\")\n\t\treturn w.id === WALLET_CONNECT_WALLET_ID && w.platform === undefined;\n\treturn w.type === \"injected\" && isWalletPlatform(w.platform);\n};\n\n/** Validates a cached account read from persisted storage. See {@link isValidCachedWallet}. */\nconst isValidCachedAccount = (value: unknown): value is CachedAccount => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst a = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof a.id === \"string\" &&\n\t\t!!a.id &&\n\t\tisWalletPlatform(a.platform) &&\n\t\ttypeof a.address === \"string\" &&\n\t\t!!a.address &&\n\t\tisValidWalletId(a.walletId) &&\n\t\ttypeof a.walletName === \"string\"\n\t);\n};\n\ntype CreateKheopskitStoreOptions = {\n\t/**\n\t * Storage backend to persist into. When provided, it takes precedence over\n\t * `ssrCookies` and localStorage.\n\t */\n\tstorage?: SyncableStorage;\n\t/**\n\t * Cookie string for SSR hydration.\n\t * When provided, uses cookieStorage instead of localStorage.\n\t */\n\tssrCookies?: string;\n\t/**\n\t * Custom storage key to namespace the stored data.\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey?: string;\n};\n\n/**\n * Creates a kheopskit store with the appropriate storage backend.\n * Uses the given `storage` when provided, else cookieStorage when ssrCookies is\n * provided (for SSR hydration), otherwise safeLocalStorage.\n *\n * @param options - Configuration options for the store\n */\nexport const createKheopskitStore = (\n\toptions: CreateKheopskitStoreOptions = {},\n): KheopskitStore => {\n\tconst { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;\n\tconst storage =\n\t\toptions.storage ??\n\t\t(ssrCookies !== undefined\n\t\t\t? createCompactCookieStorage(ssrCookies)\n\t\t\t: safeLocalStorage);\n\tconst store = createStore(\n\t\tstorageKey,\n\t\tDEFAULT_SETTINGS,\n\t\tstorage,\n\t\tmigratePreV6StoreData,\n\t);\n\n\tconst rememberWallet = (walletId: WalletId) => {\n\t\tparseWalletId(walletId); // validate walletId\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tremembered: uniq((prev.remembered ?? []).concat(walletId)),\n\t\t}));\n\t};\n\n\tconst forgetWallet = (walletId: WalletId) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tremembered: uniq((prev.remembered ?? []).filter((id) => id !== walletId)),\n\t\t}));\n\t};\n\n\tconst getCachedState = () => {\n\t\t// `store.get()` returns whatever JSON was persisted — it may be from an\n\t\t// older version, a different shape, or outright corrupt. Read defensively:\n\t\t// coerce non-objects/arrays to empty and drop any entry that fails\n\t\t// validation, so stale cache degrades to \"start fresh\" instead of throwing\n\t\t// during hydration (which renders eagerly, so a throw blanks the dapp).\n\t\tconst data = store.get() as Partial<KheopskitStoreData> | null | undefined;\n\t\tconst cachedWallets = Array.isArray(data?.cachedWallets)\n\t\t\t? data.cachedWallets\n\t\t\t: [];\n\t\tconst cachedAccounts = Array.isArray(data?.cachedAccounts)\n\t\t\t? data.cachedAccounts\n\t\t\t: [];\n\t\treturn {\n\t\t\twallets: cachedWallets.filter(isValidCachedWallet),\n\t\t\taccounts: cachedAccounts.filter(isValidCachedAccount),\n\t\t};\n\t};\n\n\tconst setCachedState = (\n\t\twallets: CachedWallet[],\n\t\taccounts: CachedAccount[],\n\t) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tcachedWallets: wallets,\n\t\t\tcachedAccounts: accounts,\n\t\t}));\n\t};\n\n\treturn {\n\t\tobservable: store.observable,\n\t\trememberWallet,\n\t\tforgetWallet,\n\t\tgetCachedState,\n\t\tsetCachedState,\n\t\tdestroy: store.destroy,\n\t};\n};\n\n/**\n * Cached default store instance, anchored on globalThis so it stays a single\n * instance even if this module is duplicated across bundle chunks (e.g. CJS\n * subpath entries). Lazily initialized on first access to be SSR-safe.\n */\nconst DEFAULT_STORE_SYMBOL = Symbol.for(\"kheopskit.defaultStore\");\n\n/**\n * Gets the default store, creating it on first access.\n * Uses localStorage on client, noop on server.\n * Lazily initialized to avoid SSR issues with module-level code.\n */\nexport const getDefaultStore = (): KheopskitStore => {\n\tconst g = globalThis as unknown as Record<symbol, KheopskitStore | undefined>;\n\tif (!g[DEFAULT_STORE_SYMBOL]) {\n\t\tg[DEFAULT_STORE_SYMBOL] = createKheopskitStore();\n\t}\n\treturn g[DEFAULT_STORE_SYMBOL];\n};\n","import {\n\tcombineLatest,\n\tfilter,\n\tmap,\n\tmergeMap,\n\tObservable,\n\tof,\n\tshareReplay,\n\ttake,\n\ttap,\n} from \"rxjs\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport { KheopskitError } from \"./errors\";\nimport { createReconnectPolicy, reconnectAccepts } from \"./reconnectPolicy\";\nimport type { KheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tConnectOptions,\n\tKheopskitConfig,\n\tPlatformContext,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet } from \"./types\";\n\nexport const getWallets$ = (\n\tconfig: KheopskitConfig,\n\tstore: KheopskitStore,\n\tregistryReads$?: Observable<void>,\n) => {\n\t// lock the list of wallets to auto reconnect on first call\n\tconst rememberedWalletIds$ = store.observable.pipe(\n\t\tmap((s) => s.remembered ?? []),\n\t\ttake(1),\n\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t);\n\n\treturn new Observable<(BaseWallet | WalletConnectWallet)[]>((subscriber) => {\n\t\tconst ctx: PlatformContext = { config, store, registryReads$ };\n\t\tconst observables = config.platforms.map((plugin) =>\n\t\t\tplugin.getWallets$(ctx),\n\t\t);\n\n\t\tconst reconnectPolicy = createReconnectPolicy();\n\n\t\tconst settleOnUserCall = <W extends BaseWallet>(wallet: W): W => ({\n\t\t\t...wallet,\n\t\t\tconnect: (options?: ConnectOptions) => {\n\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\treturn wallet.connect(options);\n\t\t\t},\n\t\t\tdisconnect: () => {\n\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\treturn wallet.disconnect();\n\t\t\t},\n\t\t});\n\n\t\tconst platformWallets$ = observables.length\n\t\t\t? combineLatest(observables).pipe(map((wallets) => wallets.flat()))\n\t\t\t: of<BaseWallet[]>([]);\n\n\t\t// The single, platform-less WalletConnect connector is appended here (not\n\t\t// emitted per platform). It sorts last (see sortWallets).\n\t\tconst walletConnect$ = config.walletConnect?.getWallet$(ctx);\n\t\tconst unsortedWallets$: Observable<(BaseWallet | WalletConnectWallet)[]> =\n\t\t\twalletConnect$\n\t\t\t\t? combineLatest([platformWallets$, walletConnect$]).pipe(\n\t\t\t\t\t\tmap(([platformWallets, walletConnect]) =>\n\t\t\t\t\t\t\twalletConnect\n\t\t\t\t\t\t\t\t? [...platformWallets, walletConnect]\n\t\t\t\t\t\t\t\t: platformWallets,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: platformWallets$;\n\t\tconst rawWallets$ = unsortedWallets$.pipe(\n\t\t\tmap((all) => all.sort(sortWallets)),\n\t\t);\n\n\t\tconst wallets$ = rawWallets$.pipe(\n\t\t\tmap((wallets) =>\n\t\t\t\twallets.map((wallet) =>\n\t\t\t\t\tisInjectedWallet(wallet) ? settleOnUserCall(wallet) : wallet,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\tconst reconnect = async (wallet: BaseWallet) => {\n\t\t\ttry {\n\t\t\t\tawait reconnectPolicy.attempt(wallet.id, () => wallet.connect());\n\t\t\t} catch (err) {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tif (err instanceof KheopskitError) {\n\t\t\t\t\tif (err.code === \"USER_REJECTED\") store.forgetWallet(wallet.id);\n\t\t\t\t\tif (err.code === \"USER_REJECTED\" || err.code === \"ABORTED\")\n\t\t\t\t\t\treconnectPolicy.settle(wallet.id);\n\t\t\t\t}\n\t\t\t\tif (config.debug)\n\t\t\t\t\tconsole.debug(\"[kheopskit] reconnect of %s failed\", wallet.id, err);\n\t\t\t}\n\t\t};\n\n\t\tconst subWallets = wallets$.subscribe(subscriber);\n\t\tif (subscriber.closed) return subWallets;\n\n\t\tconst subAutoReconnect = combineLatest([rawWallets$, rememberedWalletIds$])\n\t\t\t.pipe(\n\t\t\t\tfilter(\n\t\t\t\t\t([, walletIds]) =>\n\t\t\t\t\t\tconfig.autoReconnect !== false && walletIds.length > 0,\n\t\t\t\t),\n\t\t\t\tmergeMap(([wallets, walletIds]) =>\n\t\t\t\t\twallets\n\t\t\t\t\t\t.filter(isInjectedWallet)\n\t\t\t\t\t\t.filter((wallet) => walletIds.includes(wallet.id)),\n\t\t\t\t),\n\t\t\t\ttap((wallet) => {\n\t\t\t\t\tif (wallet.status === \"connected\") reconnectPolicy.settle(wallet.id);\n\t\t\t\t}),\n\t\t\t\tfilter(\n\t\t\t\t\t(wallet) =>\n\t\t\t\t\t\twallet.status === \"disconnected\" &&\n\t\t\t\t\t\treconnectAccepts(config.autoReconnect, wallet),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(reconnect);\n\n\t\treturn () => {\n\t\t\tsubAutoReconnect.unsubscribe();\n\t\t\tsubWallets.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n};\n","import {\n\tasapScheduler,\n\tcombineLatest,\n\tconcat,\n\tdebounceTime,\n\tdistinctUntilChanged,\n\tfilter,\n\tignoreElements,\n\tmap,\n\tObservable,\n\tof,\n\tshareReplay,\n\tstartWith,\n\ttake,\n\ttap,\n} from \"rxjs\";\nimport {\n\tcreateAccountHydrationBuffer,\n\tcreateHydrationBuffer,\n} from \"../utils/createHydrationBuffer\";\nimport { serializeAccount, serializeWallet } from \"../utils/hydrateState\";\nimport { getCachedIcon, setCachedIcons } from \"../utils/iconCache\";\nimport { logObservable } from \"../utils/logObservable\";\nimport { createRegistryReads$ } from \"../utils/registryReads\";\nimport { sortAccounts } from \"../utils/sortAccounts\";\nimport { sortWallets } from \"../utils/sortWallets\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport { type AccountsFrame, getAccounts$ } from \"./accounts\";\nimport { resolveConfig } from \"./config\";\nimport { abortedError, walletPendingError } from \"./errors\";\nimport { getHydratedSnapshot } from \"./hydration\";\nimport { createKheopskitStore } from \"./store\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tCachedAccount,\n\tCachedWallet,\n\tKheopskitConfig,\n\tKheopskitPlatform,\n\tKheopskitState,\n\tWalletConnectWallet,\n} from \"./types\";\nimport { isInjectedWallet, isWalletConnectWallet } from \"./types\";\nimport { getWallets$ } from \"./wallets\";\n\nexport type { KheopskitConfig, KheopskitState } from \"./types\";\n\n/** Options for {@link getKheopskit$}. */\nexport type GetKheopskitOptions = {\n\t/**\n\t * Cookie string for SSR hydration. When provided, state is read from cookies\n\t * instead of localStorage so the server can hydrate without a flash. Pass the\n\t * request's `cookie` header.\n\t */\n\tssrCookies?: string;\n\t/**\n\t * An existing store to reuse instead of creating one.\n\t */\n\tstore?: ReturnType<typeof createKheopskitStore>;\n};\n\nexport const getKheopskit$ = <\n\tconst P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n>(\n\tconfig?: Partial<KheopskitConfig<P>>,\n\toptions: GetKheopskitOptions = {},\n): Observable<KheopskitState<P>> => {\n\tconst { ssrCookies, store: existingStore } = options;\n\tconst kc = resolveConfig(config);\n\tconst store =\n\t\texistingStore ??\n\t\tcreateKheopskitStore({ ssrCookies, storageKey: kc.storageKey });\n\n\tif (kc.debug) console.debug(\"[kheopskit] config\", kc);\n\n\t// Warn about SSR environment without cookies\n\tif (kc.debug && typeof window === \"undefined\" && ssrCookies === undefined) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] Running on server without `ssrCookies`. \" +\n\t\t\t\t\"Wallet state will not be hydrated. Pass cookies for SSR support.\",\n\t\t);\n\t}\n\n\t// Get cached state for hydration (same snapshot the React provider builds)\n\tconst { wallets: cachedWallets, accounts: cachedAccounts } =\n\t\tgetHydratedSnapshot(store, kc, { icons: true });\n\n\tif (kc.debug && cachedWallets.length > 0) {\n\t\tconsole.debug(\"[kheopskit] hydrating from cache:\", {\n\t\t\twallets: cachedWallets.length,\n\t\t\taccounts: cachedAccounts.length,\n\t\t});\n\t}\n\n\treturn new Observable<KheopskitState>((subscriber) => {\n\t\tlet latest: KheopskitState | undefined;\n\t\tlet closed = false;\n\t\tconst waiters = new Set<StateWaiter>();\n\t\tconst liveWaiters = new Set<(state: KheopskitState | undefined) => void>();\n\t\tconst wrapped = new WeakMap<\n\t\t\tBaseWallet | WalletConnectWallet,\n\t\t\tBaseWallet | WalletConnectWallet\n\t\t>();\n\n\t\tconst abandon = (waiter: StateWaiter) => {\n\t\t\twaiters.delete(waiter);\n\t\t\tif (waiter.isConnected)\n\t\t\t\twaiter.reject(abortedError(waiter.walletId, \"connect\"));\n\t\t\telse waiter.resolve();\n\t\t};\n\n\t\tconst settleIn = (waiter: StateWaiter, state: KheopskitState) => {\n\t\t\tconst wallet = state.wallets.find((w) => w.id === waiter.walletId);\n\t\t\tif (!wallet || wallet.isConnected === waiter.isConnected) {\n\t\t\t\twaiters.delete(waiter);\n\t\t\t\twaiter.resolve();\n\t\t\t}\n\t\t};\n\n\t\tconst supersede = (walletId: WalletId, isConnected: boolean) => {\n\t\t\tfor (const waiter of waiters)\n\t\t\t\tif (waiter.walletId === walletId && waiter.isConnected !== isConnected)\n\t\t\t\t\tabandon(waiter);\n\t\t};\n\n\t\tconst whenState = (walletId: WalletId, isConnected: boolean) =>\n\t\t\tnew Promise<void>((resolve, reject) => {\n\t\t\t\tconst waiter = { walletId, isConnected, resolve, reject };\n\t\t\t\twaiters.add(waiter);\n\t\t\t\tif (latest) settleIn(waiter, latest);\n\t\t\t\tif (closed && waiters.has(waiter)) abandon(waiter);\n\t\t\t});\n\n\t\tconst whenLive = (walletId: WalletId, signal: AbortSignal | undefined) =>\n\t\t\tnew Promise<BaseWallet | WalletConnectWallet>((resolve, reject) => {\n\t\t\t\tconst settle = (finish: () => void) => {\n\t\t\t\t\tliveWaiters.delete(check);\n\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\tconst onAbort = () =>\n\t\t\t\t\tsettle(() => reject(abortedError(walletId, \"connect\")));\n\t\t\t\tconst check = (state: KheopskitState | undefined) => {\n\t\t\t\t\tif (!state) return onAbort();\n\t\t\t\t\tconst live = state.wallets.find(\n\t\t\t\t\t\t(w) => w.id === walletId && !w.isPlaceholder,\n\t\t\t\t\t);\n\t\t\t\t\tif (live) settle(() => resolve(live));\n\t\t\t\t\telse if (!state.isHydrating)\n\t\t\t\t\t\tsettle(() => reject(walletPendingError(walletId)));\n\t\t\t\t};\n\t\t\t\tif (closed || signal?.aborted) return onAbort();\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\tliveWaiters.add(check);\n\t\t\t\tif (latest) check(latest);\n\t\t\t});\n\n\t\tconst deferToLive = (\n\t\t\tplaceholder: BaseWallet | WalletConnectWallet,\n\t\t): BaseWallet | WalletConnectWallet => ({\n\t\t\t...placeholder,\n\t\t\tconnect: async (options) => {\n\t\t\t\tconst live = await whenLive(placeholder.id, options?.signal);\n\t\t\t\tif (closed) throw abortedError(placeholder.id, \"connect\");\n\t\t\t\tawait live.connect(options);\n\t\t\t},\n\t\t});\n\n\t\tconst settleWithState = (\n\t\t\twallet: BaseWallet | WalletConnectWallet,\n\t\t): BaseWallet | WalletConnectWallet => {\n\t\t\tconst existing = wrapped.get(wallet);\n\t\t\tif (existing) return existing;\n\t\t\tif (wallet.isPlaceholder) {\n\t\t\t\tconst deferred = deferToLive(wallet);\n\t\t\t\twrapped.set(wallet, deferred);\n\t\t\t\treturn deferred;\n\t\t\t}\n\t\t\tif (!isInjectedWallet(wallet)) return wallet;\n\t\t\tconst settled: BaseWallet = {\n\t\t\t\t...wallet,\n\t\t\t\tconnect: async (options) => {\n\t\t\t\t\tif (closed) throw abortedError(wallet.id, \"connect\");\n\t\t\t\t\tawait wallet.connect(options);\n\t\t\t\t\tsupersede(wallet.id, true);\n\t\t\t\t\tawait whenState(wallet.id, true);\n\t\t\t\t},\n\t\t\t\tdisconnect: async () => {\n\t\t\t\t\tif (closed) throw abortedError(wallet.id, \"disconnect\");\n\t\t\t\t\tawait wallet.disconnect();\n\t\t\t\t\tsupersede(wallet.id, false);\n\t\t\t\t\tawait whenState(wallet.id, false);\n\t\t\t\t},\n\t\t\t};\n\t\t\twrapped.set(wallet, settled);\n\t\t\treturn settled;\n\t\t};\n\n\t\tconst registryReads$ = createRegistryReads$().pipe(\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\t\tconst liveWallets$ = getWallets$(kc, store, registryReads$);\n\t\tconst accountFrames$ = getAccounts$(kc, liveWallets$);\n\t\tconst liveAccounts$ = accountFrames$.pipe(\n\t\t\tmap(({ accounts }) => accounts.map(asLive)),\n\t\t);\n\n\t\tconst isDiscovering$ = concat(\n\t\t\tof(true),\n\t\t\tregistryReads$.pipe(ignoreElements()),\n\t\t\tliveWallets$.pipe(\n\t\t\t\ttake(1),\n\t\t\t\tmap(() => false),\n\t\t\t),\n\t\t).pipe(shareReplay({ bufferSize: 1, refCount: true }));\n\n\t\tconst hydrationSettled$ = combineLatest([\n\t\t\tliveWallets$,\n\t\t\taccountFrames$.pipe(startWith(noAnswerYet)),\n\t\t\tisDiscovering$,\n\t\t\tstore.observable.pipe(\n\t\t\t\tmap((s) => s.remembered ?? []),\n\t\t\t\ttake(1),\n\t\t\t),\n\t\t]).pipe(\n\t\t\tmap(([wallets, { accounts, answered }, isDiscovering, remembered]) =>\n\t\t\t\tcachedWallets.every((cached) => {\n\t\t\t\t\tconst wallet = wallets.find((w) => w.id === cached.id);\n\t\t\t\t\tif (!wallet) return !isDiscovering;\n\t\t\t\t\treturn (\n\t\t\t\t\t\tcached.status !== \"connecting\" ||\n\t\t\t\t\t\treconnectSettled(cached, wallet, {\n\t\t\t\t\t\t\taccounts,\n\t\t\t\t\t\t\tanswered,\n\t\t\t\t\t\t\tcachedAccounts,\n\t\t\t\t\t\t\tremembered,\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t),\n\t\t\tdebounceTime(0, asapScheduler),\n\t\t\tdistinctUntilChanged(),\n\t\t);\n\n\t\t// Apply hydration buffer to wallets\n\t\tconst bufferedWallets$ = createHydrationBuffer(\n\t\t\tcachedWallets,\n\t\t\tliveWallets$.pipe(map((wallets) => wallets.map(asLive))),\n\t\t\tkc.hydrationGracePeriod,\n\t\t\tkc.hydrationTimeout,\n\t\t\t(w) => w.id,\n\t\t\thydrationSettled$,\n\t\t\t(live, cached) => {\n\t\t\t\tconst status = sessionRestoring(live, cached)\n\t\t\t\t\t? \"connecting\"\n\t\t\t\t\t: live.status;\n\t\t\t\treturn {\n\t\t\t\t\t...live,\n\t\t\t\t\tstatus,\n\t\t\t\t\tisConnected: status === \"connected\",\n\t\t\t\t\ticon: cached.icon || getCachedIcon(cached.id) || live.icon,\n\t\t\t\t};\n\t\t\t},\n\t\t\t// Transform cached-only items: add icon from localStorage cache\n\t\t\t(cached) => ({\n\t\t\t\t...cached,\n\t\t\t\ticon: cached.icon || getCachedIcon(cached.id) || \"\",\n\t\t\t}),\n\t\t);\n\n\t\t// Apply hydration buffer to accounts\n\t\tconst bufferedAccounts$ = createAccountHydrationBuffer(\n\t\t\tcachedAccounts,\n\t\t\tliveAccounts$,\n\t\t\tkc.hydrationGracePeriod,\n\t\t\tkc.hydrationTimeout,\n\t\t\t(a) => a.walletId,\n\t\t\thydrationSettled$,\n\t\t);\n\n\t\t// Share the buffered streams so the main and persistence subscriptions\n\t\t// below reuse a single hydration pipeline (timers, isHydrating state)\n\t\t// instead of running the buffering twice.\n\t\tconst sharedWallets$ = bufferedWallets$.pipe(\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\t\tconst sharedAccounts$ = bufferedAccounts$.pipe(\n\t\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t);\n\n\t\t// Combine buffered wallets and accounts\n\t\tconst subscription = combineLatest({\n\t\t\twallets: sharedWallets$,\n\t\t\taccounts: sharedAccounts$,\n\t\t\tisDiscovering: isDiscovering$,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\tmap(({ wallets, accounts, isDiscovering }) => {\n\t\t\t\t\tif (kc.debug) {\n\t\t\t\t\t\tconsole.debug(\"[kheopskit] hydration state\", {\n\t\t\t\t\t\t\twalletsHydrating: wallets.isHydrating,\n\t\t\t\t\t\t\taccountsHydrating: accounts.isHydrating,\n\t\t\t\t\t\t\tisDiscovering,\n\t\t\t\t\t\t\twalletsConnected: wallets.items.filter((w) => w.isConnected)\n\t\t\t\t\t\t\t\t.length,\n\t\t\t\t\t\t\twalletsTotal: wallets.items.length,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Sort on every emission with the same comparators used for the\n\t\t\t\t\t// cached initial snapshot. The hydration buffers append cached-only\n\t\t\t\t\t// items after live ones (and reconnects land out of order), so\n\t\t\t\t\t// without this the list visibly reorders as wallets come back.\n\t\t\t\t\treturn {\n\t\t\t\t\t\tconfig: kc,\n\t\t\t\t\t\twallets: [...wallets.items].sort(sortWallets).map(settleWithState),\n\t\t\t\t\t\taccounts: [...accounts.items].sort(sortAccounts),\n\t\t\t\t\t\tisHydrating: wallets.isHydrating || accounts.isHydrating,\n\t\t\t\t\t\tisDiscovering,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t\tdebounceTime(0, asapScheduler),\n\t\t\t\tdistinctUntilChanged(statesEqual),\n\t\t\t\ttap((state) => {\n\t\t\t\t\tlatest = state;\n\t\t\t\t\tfor (const check of liveWaiters) check(state);\n\t\t\t\t\tfor (const waiter of waiters) settleIn(waiter, state);\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\t// Persist state snapshot when hydration completes and state stabilizes\n\t\tconst persistSub = combineLatest({\n\t\t\twallets: sharedWallets$,\n\t\t\taccounts: sharedAccounts$,\n\t\t})\n\t\t\t.pipe(\n\t\t\t\t// Wait for hydration to complete\n\t\t\t\tfilter(\n\t\t\t\t\t({ wallets, accounts }) =>\n\t\t\t\t\t\t!wallets.isHydrating && !accounts.isHydrating,\n\t\t\t\t),\n\t\t\t\t// Debounce to avoid excessive writes\n\t\t\t\tdebounceTime(1000),\n\t\t\t\t// Only persist if the serialized snapshot would actually change.\n\t\t\t\t// Compare the persisted fields (not just ids): an Ethereum chain switch\n\t\t\t\t// keeps the same account id but changes the cached chainId, so an\n\t\t\t\t// id-only comparator would skip persisting it.\n\t\t\t\tdistinctUntilChanged((prev, curr) => {\n\t\t\t\t\tconst prevWalletKeys = prev.wallets.items.map(persistedWalletKey);\n\t\t\t\t\tconst currWalletKeys = curr.wallets.items.map(persistedWalletKey);\n\t\t\t\t\tconst prevAccountKeys = prev.accounts.items.map(accountChangeKey);\n\t\t\t\t\tconst currAccountKeys = curr.accounts.items.map(accountChangeKey);\n\t\t\t\t\treturn (\n\t\t\t\t\t\tarraysEqual(prevWalletKeys, currWalletKeys) &&\n\t\t\t\t\t\tarraysEqual(prevAccountKeys, currAccountKeys)\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe(({ wallets, accounts }) => {\n\t\t\t\tconst snapshot = persistedSnapshot(\n\t\t\t\t\twallets.items,\n\t\t\t\t\taccounts.items,\n\t\t\t\t\tstore.getCachedState(),\n\t\t\t\t);\n\n\t\t\t\tif (kc.debug) {\n\t\t\t\t\tconsole.debug(\"[kheopskit] persisting state snapshot:\", {\n\t\t\t\t\t\twallets: snapshot.wallets.length,\n\t\t\t\t\t\taccounts: snapshot.accounts.length,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tstore.setCachedState(snapshot.wallets, snapshot.accounts);\n\n\t\t\t\t// Cache wallet icons in localStorage (separate from cookies for size)\n\t\t\t\tconst icons: Record<string, string> = {};\n\t\t\t\tfor (const wallet of wallets.items) {\n\t\t\t\t\tif (wallet.icon) {\n\t\t\t\t\t\ticons[wallet.id] = wallet.icon;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsetCachedIcons(icons);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tsubscription.unsubscribe();\n\t\t\tpersistSub.unsubscribe();\n\t\t\tclosed = true;\n\t\t\tfor (const waiter of waiters) abandon(waiter);\n\t\t\tfor (const check of liveWaiters) check(undefined);\n\t\t};\n\t}).pipe(\n\t\tlogObservable(\"kheopskit$\", { enabled: kc.debug, printValue: true }),\n\t\tshareReplay({ bufferSize: 1, refCount: true }),\n\t\t// The runtime objects are the concrete per-plugin wallet/account types;\n\t\t// recover the precise KheopskitState<P> the caller's plugins imply.\n\t) as unknown as Observable<KheopskitState<P>>;\n};\n\ntype StateWaiter = {\n\twalletId: WalletId;\n\tisConnected: boolean;\n\tresolve: () => void;\n\treject: (error: unknown) => void;\n};\n\n// AppKit restores a cached WalletConnect session on its own and reports nothing\n// until it has; an injected wallet reports its attempt from its first emission.\nconst sessionRestoring = (\n\tlive: BaseWallet | WalletConnectWallet,\n\tcached: BaseWallet | WalletConnectWallet,\n): boolean =>\n\tisWalletConnectWallet(live) &&\n\tlive.status === \"disconnected\" &&\n\tcached.status === \"connecting\";\n\nconst flagged = new WeakMap<object, object>();\n\nconst asLive = <T extends object>(item: T): T & { isPlaceholder: false } => {\n\tconst existing = flagged.get(item);\n\tif (existing) return existing as T & { isPlaceholder: false };\n\tconst live = { ...item, isPlaceholder: false as const };\n\tflagged.set(item, live);\n\treturn live;\n};\n\nconst noAnswerYet: AccountsFrame = { accounts: [], answered: [] };\n\n/**\n * A remembered wallet that reads disconnected without an error is still\n * waiting for its reconnect: getWallets$ emits the wallet list before its\n * connect() flips the status to connecting.\n */\nconst reconnectSettled = (\n\tcached: BaseWallet | WalletConnectWallet,\n\twallet: BaseWallet | WalletConnectWallet,\n\tlive: AccountsFrame & {\n\t\tcachedAccounts: BaseWalletAccount[];\n\t\tremembered: WalletId[];\n\t},\n): boolean => {\n\tconst status = sessionRestoring(wallet, cached)\n\t\t? \"connecting\"\n\t\t: wallet.status;\n\tif (status === \"connecting\") return false;\n\tif (status === \"disconnected\")\n\t\treturn wallet.error !== undefined || !live.remembered.includes(cached.id);\n\treturn (\n\t\tlive.answered.includes(cached.id) ||\n\t\t!live.cachedAccounts.some((a) => a.walletId === cached.id) ||\n\t\tlive.accounts.some((a) => a.walletId === cached.id)\n\t);\n};\n\n/**\n * A wallet still connecting keeps its previous cache entry and accounts:\n * written live it would read isConnected: false with no accounts, and the\n * next load would hydrate it as disconnected without placeholders while its\n * reconnect runs.\n */\nconst persistedSnapshot = (\n\twallets: (BaseWallet | WalletConnectWallet)[],\n\taccounts: BaseWalletAccount[],\n\tprevious: { wallets: CachedWallet[]; accounts: CachedAccount[] },\n): { wallets: CachedWallet[]; accounts: CachedAccount[] } => {\n\tconst connecting = new Set(\n\t\twallets.filter((w) => w.status === \"connecting\").map((w) => w.id),\n\t);\n\tconst connected = new Set(\n\t\twallets.filter((w) => w.isConnected).map((w) => w.id),\n\t);\n\tconst previousWallets = new Map(previous.wallets.map((w) => [w.id, w]));\n\treturn {\n\t\twallets: wallets.map(\n\t\t\t(w) =>\n\t\t\t\t(connecting.has(w.id) && previousWallets.get(w.id)) ||\n\t\t\t\tserializeWallet(w),\n\t\t),\n\t\taccounts: [\n\t\t\t...accounts\n\t\t\t\t.filter((a) => connected.has(a.walletId))\n\t\t\t\t.map(serializeAccount),\n\t\t\t...previous.accounts.filter((a) => connecting.has(a.walletId)),\n\t\t],\n\t};\n};\n\nconst arraysEqual = (a: string[], b: string[]) =>\n\ta.length === b.length && a.every((v, i) => v === b[i]);\n\n// Mutable per-platform account fields that can change without the account id\n// changing. Declared locally (not imported from the platform packages) so this\n// core entry stays free of platform SDK types — see check:isolation.\ntype EthereumAccountFields = { chainId?: number };\ntype PolkadotAccountFields = { type?: string };\ntype SolanaAccountFields = { chains?: string[] };\n\n/**\n * A signature of an account covering its id, its name, plus the\n * platform-specific fields that can change without the id changing (Ethereum\n * chainId, Polkadot key type, Solana clusters). Used to detect both UI-relevant\n * changes and changes worth re-persisting, so the two comparators can't drift\n * apart.\n */\nconst accountChangeKey = (account: BaseWalletAccount): string =>\n\t`${account.name ?? \"\"}|${accountPlatformKey(account)}`;\n\nconst accountPlatformKey = (account: BaseWalletAccount): string => {\n\tswitch (account.platform) {\n\t\tcase \"ethereum\":\n\t\t\treturn `${account.id}|${(account as EthereumAccountFields).chainId ?? \"\"}`;\n\t\tcase \"polkadot\":\n\t\t\treturn `${account.id}|${(account as PolkadotAccountFields).type ?? \"\"}`;\n\t\tcase \"solana\":\n\t\t\treturn `${account.id}|${((account as SolanaAccountFields).chains ?? []).join(\",\")}`;\n\t\tdefault:\n\t\t\treturn account.id;\n\t}\n};\n\n/** Platforms a wallet's live session carries (only the WalletConnect connector). */\nconst walletPlatforms = (wallet: BaseWallet | WalletConnectWallet): string =>\n\tisWalletConnectWallet(wallet) ? wallet.platforms.join(\",\") : \"\";\n\n/** Fields persisted to the cache for a wallet (icon is stored separately). */\nconst walletPersistKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${wallet.id}|${wallet.isConnected ? 1 : 0}|${wallet.name}`;\n\n/**\n * What decides a cache write: the persisted fields plus `status`, because a\n * wallet whose kept entry was written while connecting must be rewritten live\n * once its reconnect fails, and `isConnected` reads false on both sides.\n */\nconst persistedWalletKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${walletPersistKey(wallet)}|${wallet.status}`;\n\n/**\n * UI-significant signature of a wallet: the persisted fields plus icon and the\n * WalletConnect connector's `platforms` array, which drive what the UI shows but\n * aren't part of the id (icon and platforms can arrive asynchronously after\n * connect without isConnected flipping).\n */\nconst walletUiKey = (wallet: BaseWallet | WalletConnectWallet): string =>\n\t`${walletPersistKey(wallet)}|${wallet.status}|${wallet.error?.code ?? \"\"}|${wallet.icon}|${walletPlatforms(wallet)}`;\n\n/**\n * Equality check for KheopskitState to prevent unnecessary emissions. Compares\n * the UI-significant signature of every wallet and account, in order.\n */\nconst statesEqual = (a: KheopskitState, b: KheopskitState): boolean =>\n\ta.isHydrating === b.isHydrating &&\n\ta.isDiscovering === b.isDiscovering &&\n\ta.wallets.length === b.wallets.length &&\n\ta.accounts.length === b.accounts.length &&\n\ta.wallets.every((w, i) => {\n\t\tconst other = b.wallets[i];\n\t\treturn (\n\t\t\t!!other &&\n\t\t\tw.isPlaceholder === other.isPlaceholder &&\n\t\t\twalletUiKey(w) === walletUiKey(other)\n\t\t);\n\t}) &&\n\ta.accounts.every((acc, i) => {\n\t\tconst other = b.accounts[i];\n\t\treturn (\n\t\t\t!!other &&\n\t\t\tacc.isPlaceholder === other.isPlaceholder &&\n\t\t\taccountChangeKey(acc) === accountChangeKey(other)\n\t\t);\n\t});\n"],"mappings":";;;;;;;;;;;;AAQA,MAAa,sBAAsB;AAEnC,MAAM,WAAW;CAChB,eAAe;CACf,OAAO;CACP,YAAY;CACZ,sBAAsB;CACtB,kBAAkB;AACnB;AAEA,MAAa,iBAGZ,WACwB;CACxB,MAAM,YAAa,QAAQ,aAAa,CAAC;CAIzC,MAAM,mBAAoB,UAAiC,QACzD,MACA,OAAO,MAAM,YACb,MAAM,QACN,OAAQ,EAAgC,gBAAgB,UAC1D;CACA,IAAI,iBAAiB,SAAS,GAC7B,MAAM,IAAI,MACT,sNAGqB,KAAK,UAAU,gBAAgB,EAAE,qFAEvD;CAGD,IACC,QAAQ,kBAAkB,KAAA,KAC1B,OAAQ,OAAO,eACZ,eAAe,YAElB,MAAM,IAAI,eACT,kBACA,sPAGD;CAGD,IAAI,UAAU,WAAW,GACxB,QAAQ,KACP,+IAED;CAGD,OAAO,OAAO,OAAO,CAAC,GAAG,UAAU,QAAQ,EAAE,UAAU,CAAC;AACzD;;;AC9DA,MAAMA,mBAAiD;CACtD,UAAU;CACV,UAAU;CACV,QAAQ;AACT;AAEA,MAAM,cAAc,IAAuB,OAC1CA,iBAAe,GAAG,YAAYA,iBAAe,GAAG;AAGjD,MAAM,gBAAgB,IAAuB,OAA0B;CACtE,IAAI,GAAG,eAAe,GAAG,YAAY,OAAO;CAC5C,IAAI,GAAG,WAAW,YAAY,MAAM,YAAY,OAAO;CACvD,IAAI,GAAG,WAAW,YAAY,MAAM,YAAY,OAAO;CACvD,OAAO,GAAG,WAAW,cAAc,GAAG,UAAU;AACjD;AAEA,MAAa,gBAAgB,IAAuB,OACnD,WAAW,IAAI,EAAE,KAAK,aAAa,IAAI,EAAE;;;ACb1C,MAAM,iBAAiD;CACtD,UAAU;CACV,UAAU;CACV,QAAQ;AACT;AAGA,MAAM,WAAW,WAChB,sBAAsB,MAAM,IAAI,IAAI,eAAe,OAAO;AAE3D,MAAa,eACZ,IACA,OACI;CAEJ,MAAM,KAAK,QAAQ,EAAE;CACrB,MAAM,KAAK,QAAQ,EAAE;CACrB,IAAI,OAAO,IAAI,OAAO,KAAK;CAG3B,IAAI,GAAG,KAAK,YAAY,MAAM,YAAY,OAAO;CACjD,IAAI,GAAG,KAAK,YAAY,MAAM,YAAY,OAAO;CAEjD,OAAO,GAAG,KAAK,cAAc,GAAG,IAAI;AACrC;;;;;;;;;ACvBA,MAAa,wBACZ,QACA,cACa;CAEb,OADe,UAAU,MAAM,MAAM,EAAE,aAAa,OAAO,QAC/C,CAAC,EAAE,uBAAuB,MAAM,KAAK;AAClD;;;ACCA,MAAa,yBAAyB,EACrC,cAAc,MACa,CAAC,MAAM;CAClC,MAAM,yBAAS,IAAI,IAAmC;CAEtD,MAAM,iBAAiB,aAA8B;EACpD,MAAM,QAAQ,OAAO,IAAI,QAAQ;EACjC,IAAI,CAAC,OAAO,OAAO;EACnB,OAAO,MAAM,SAAS,YAAY,MAAM,WAAW;CACpD;CAEA,MAAM,UAAU,OACf,UACA,YACsB;EACtB,IAAI,CAAC,cAAc,QAAQ,GAAG,OAAO;EAErC,MAAM,SAAS,OAAO,IAAI,QAAQ;EAClC,OAAO,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;EACxC,MAAM,iBAAiB,YAAmC;GACzD,IAAI,OAAO,IAAI,QAAQ,CAAC,EAAE,SAAS,WAClC,OAAO,IAAI,UAAU,OAAO;EAC9B;EACA,IAAI;GACH,MAAM,QAAQ;GACd,cAAc,EAAE,MAAM,cAAc,CAAC;GACrC,OAAO;EACR,SAAS,KAAK;GAEb,cAAc;IAAE,MAAM;IAAU,UADf,QAAQ,SAAS,WAAW,OAAO,WAAW,IAAI;GAC1B,CAAC;GAC1C,MAAM;EACP;CACD;CAEA,MAAM,UAAU,aAAqB;EACpC,OAAO,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;CACzC;CAEA,OAAO;EAAE;EAAe;EAAS;CAAO;AACzC;AAIA,MAAa,oBACZ,eACA,WAEA,OAAO,kBAAkB,aAAa,cAAc,MAAM,IAAI;;;;;;;;;;;;;;;;AChB/D,MAAa,uBACZ,OACA,QACA,UAAsC,CAAC,MACjB;CACtB,MAAM,SAAS,MAAM,eAAe;CAEpC,MAAM,UAAU,OAAO,QACrB,IAAI,aAAa,CAAC,CAClB,KAAK,WACL,OAAO,WAAW,gBAClB,iBAAiB,MAAM,KACvB,CAAC,iBAAiB,OAAO,eAAe,MAAM,IAC3C;EAAE,GAAG;EAAQ,QAAQ;CAAwB,IAC7C,MACJ,CAAC,CACA,KAAK,WAAW;EAGhB,IAAI,CAAC,QAAQ,SAAS,OAAO,MAAM,OAAO;EAC1C,MAAM,OAAO,cAAc,OAAO,EAAE;EACpC,OAAO,OAAO;GAAE,GAAG;GAAQ;EAAK,IAAI;CACrC,CAAC,CAAC,CACD,KAAK,WAAW;CAElB,MAAM,eAAe,IAAI,IACxB,QAAQ,QAAQ,MAAM,EAAE,WAAW,cAAc,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE,CACnE;CAQA,OAAO;EAAE;EAAS,UAND,OAAO,SACtB,QAAQ,YAAY,CAAC,aAAa,IAAI,QAAQ,QAAQ,CAAC,CAAC,CACxD,QAAQ,YAAY,qBAAqB,SAAS,OAAO,SAAS,CAAC,CAAC,CACpE,IAAI,cAAc,CAAC,CACnB,KAAK,YAEkB;CAAE;AAC5B;;;ACjEA,MAAM,oBACL,aACA,YACA,eACA,WACA,SACA,aAC8C;CAC9C,IAAI,iBAAiB,KAAK,YAAY,WAAW,GAChD,OAAO,WAAW,KAAK,KAAK,WAAW;EAAE;EAAO,aAAa;CAAM,EAAE,CAAC;CAGvE,OAAO,IAAI,YAA0C,eAAe;EACnE,MAAM,gBAAgB,IAAI,aAAa;EACvC,MAAM,eAAe,IAAI,gBAAgB,IAAI;EAC7C,MAAM,qBAAqB;GAC1B,IAAI,aAAa,OAAO,aAAa,KAAK,KAAK;EAChD;EAEA,MAAM,gBAAgB,MAAM,aAAa,CAAC,CAAC,KAC1C,UAAU,IAAI,GACd,UAAU,KAAK,CAChB;EACA,MAAM,SAA8B,WACjC,cAAc,CAAC,eAAe,QAAQ,CAAC,CAAC,CAAC,KACzC,QAAQ,CAAC,cAAc,aAAa,gBAAgB,OAAO,GAC3D,KAAK,CAAC,CACP,IACC,MAAM,aAAa;EACtB,cAAc,IAAI,OAAO,UAAU,YAAY,CAAC;EAChD,cAAc,IAAI,MAAM,SAAS,CAAC,CAAC,UAAU,YAAY,CAAC;EAE1D,cAAc,IACb,cAAc,CAAC,WAAW,KAAK,UAAU,CAAC,CAAQ,CAAC,GAAG,YAAY,CAAC,CAAC,CAClE,KACA,KAAK,CAAC,WAAW,iBAChB,cACG;GAAE,OAAO,QAAQ,WAAW,WAAW;GAAG;EAAY,IACtD;GAAE,OAAO;GAAW;EAAY,CACpC,CACD,CAAC,CACA,UAAU,UAAU,CACvB;EAEA,aAAa;GACZ,cAAc,YAAY;GAC1B,aAAa,SAAS;EACvB;CACD,CAAC;AACF;;;;;;;;;;;;;;;;;AAkBA,MAAa,yBACZ,aACA,YACA,eACA,WACA,QACA,UACA,WACA,wBAC8C;CAC9C,OAAO,iBACN,aACA,YACA,eACA,YACC,WAAW,WAAW;EACtB,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;EACtE,MAAM,WAAW,IAAI,IAAI,UAAU,IAAI,MAAM,CAAC;EAK9C,MAAM,cAAyB,UAAU,KAAK,aAAa;GAC1D,MAAM,MAAM,OAAO,QAAQ;GAC3B,MAAM,aAAa,YAAY,IAAI,GAAG;GACtC,IAAI,CAAC,YAAY,OAAO;GACxB,OAAO,YAAY,UAAU,UAAU,UAAU,IAAI;EACtD,CAAC;EAGD,KAAK,MAAM,cAAc,QACxB,IAAI,CAAC,SAAS,IAAI,OAAO,UAAU,CAAC,GAAG;GACtC,MAAM,cAAc,sBACjB,oBAAoB,UAAU,IAC9B;GACH,YAAY,KAAK,WAAW;EAC7B;EAGD,OAAO;CACR,GACA,QACD;AACD;;;;;;;;;;;;;;;AAgBA,MAAa,gCACZ,gBACA,eACA,eACA,WACA,aACA,aAC0C;CAC1C,OAAO,iBACN,gBACA,eACA,eACA,YACC,cAAc,WAAW;EACzB,MAAM,0BAA0B,IAAI,IAAI,aAAa,IAAI,WAAW,CAAC;EACrE,MAAM,iBAAsB,CAAC,GAAG,YAAY;EAE5C,KAAK,MAAM,iBAAiB,QAC3B,IAAI,CAAC,wBAAwB,IAAI,YAAY,aAAa,CAAC,GAC1D,eAAe,KAAK,aAAa;EAInC,OAAO;CACR,GACA,QACD;AACD;;;ACnKA,MAAa,iBACZ,OACA,SAEA,KAAK,UAAU;CACd,MAAM,EAAE,aAAa,OAAO,UAAU,SAAS,QAAQ,CAAC;CAExD,IAAI,CAAC,SAAS,CAAC,SAAS;CAExB,MAAM,OAAO,0BAA0B,MAAM;CAE7C,IAAI,YAAY,QAAQ,MAAM,MAAM,KAAK;MACpC,QAAQ,MAAM,IAAI;AACxB,CAAC;;;ACPF,MAAa,gBACZ,QACA,YACI;CACJ,OAAO,IAAI,YAA2B,eAAe;EAIpD,MAAM,UAAU,OAAO,UAAU,KAAK,WACrC,SACC,OAAO,aACN,QAAQ,KACP,KAAK,OACJ,GAAG,QACD,MACA,sBAAsB,CAAC,KAAK,EAAE,aAAa,OAAO,QACpD,CACD,CACD,CACD,CACD,CACD;EAaA,MAAM,OAXU,QAAQ,SACrB,cAAc,OAAO,CAAC,CAAC,KACvB,KAAK,YAAY;GAChB,UAAU,OACR,SAAS,UAAU,MAAM,QAAQ,CAAC,CAClC,KAAK,YAAY;GACnB,UAAU,OAAO,SAAS,UAAU,MAAM,QAAQ;EACnD,EAAE,CACH,IACC,GAAkB;GAAE,UAAU,CAAC;GAAG,UAAU,CAAC;EAAE,CAAC,EAAA,CAE/B,UAAU,UAAU;EAExC,aAAa;GACZ,IAAI,YAAY;EACjB;CACD,CAAC,CAAC,CAAC,KAAK,YAAY;EAAE,UAAU;EAAM,YAAY;CAAE,CAAC,CAAC;AACvD;;;AClDA,MAAa,eACZ,KACA,cACA,UAA2B,kBAC3B,aAA8B,UAAU,UACpC;CACJ,MAAM,QAAQ,QAAuB,UAAU,UAAU,KAAK,YAAY,CAAC;CAC3E,MAAM,kBACL,OAAO,WAAW,eAAe,QAAQ,cAAc,KAAA;CACxD,MAAM,UAAU,IAAI,gBAAmB,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC;CACjE,IAAI,YAAY;CAChB,IAAI;CAEJ,MAAM,oBAAoB;EACzB,IAAI,mBAAmB,cAAc,GACpC,QAAQ,KAAK,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC;EACxC,OAAO,QAAQ,SAAS;CACzB;CAEA,MAAM,aAAa,IAAI,YAAe,eAAe;EACpD,IAAI,cAAc,KAAK,iBAAiB;GACvC,YAAY;GACZ,WAAW,QAAQ,YAAY,MAAM,aAAa;IACjD,QAAQ,KAAK,KAAK,QAAQ,CAAC;GAC5B,CAAC;EACF;EACA;EACA,MAAM,eAAe,QAAQ,UAAU,UAAU;EACjD,aAAa;GACZ,aAAa,YAAY;GACzB;GACA,IAAI,cAAc,GAAG,WAAW;EACjC;CACD,CAAC;CAED,MAAM,UAAU,QAAW;EAC1B,kBAAkB,KAAK,KAAK,OAAO;EACnC,QAAQ,KAAK,GAAG;CACjB;CAEA,OAAO;EACN;EACA,MAAM,QAAW,OAAO,GAAG;EAC3B,SAAS,cAA8B,OAAO,UAAU,YAAY,CAAC,CAAC;EACtE,WAAW,gBAAgB,YAAY,CAAC;EACxC,eAAe,QAAQ,SAAS;CACjC;AACD;AAEA,MAAM,aAAgB,KAAoB,iBAAuB;CAChE,IAAI;EACH,IAAI,KAAK,OAAO,KAAK,MAAM,GAAG;CAC/B,QAAQ,CAER;CACA,OAAO;AACR;AAEA,MAAM,qBACL,KACA,KACA,YACI;CACJ,MAAM,MAAM,KAAK,UAAU,GAAG;CAC9B,IAAI;EACH,QAAQ,QAAQ,KAAK,GAAG;CACzB,QAAQ,CAAC;AACV;;;ACZA,MAAM,mBAAuC,CAAC;AAI9C,MAAa,yBACZ,SACwB;CACxB,IAAI,MAAM,kBAAkB,KAAA,GAAW,OAAO;CAC9C,MAAM,EAAE,eAAe,GAAG,SAAS;CACnC,OAAO,KAAK,eAAe,KAAA,KAAa,MAAM,QAAQ,aAAa,IAChE;EAAE,GAAG;EAAM,YAAY;CAAc,IACrC;AACJ;AAEA,MAAM,gCACL,SACuC;CACvC,QAAQ,MAAR;EACC,KAAK,WACJ,OAAO;EACR,KAAK,WACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,SACC,OAAO;CACT;AACD;AAEA,MAAM,kCACL,SAC0C;CAC1C,QAAQ,MAAR;EACC,KAAK,GACJ,OAAO;EACR,KAAK,GACJ,OAAO;EACR,KAAK,GACJ,OAAO;EACR,KAAK,GACJ,OAAO;EACR,SACC;CACF;AACD;AAEA,MAAM,qBAAqB,aAAkD;CAC5E,QAAQ,UAAR;EACC,KAAK,YACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,UACJ,OAAO;CACT;AACD;AAEA,MAAM,uBACL,SACgC;CAChC,QAAQ,MAAR;EACC,KAAK,GACJ,OAAO;EACR,KAAK,GACJ,OAAO;EACR,KAAK,GACJ,OAAO;EACR,SACC;CACF;AACD;AAEA,MAAM,kBAAkB,UAA4C;CACnE,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO;CACxE,IAAI,mBAAmB,SAAS,oBAAoB,OAAO,OAAO;CAClE,OAAO,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO;AAC/D;AAEA,MAAM,kBAAkB,SAA6C;CACpE,MAAM,UAAU,KAAK,eAAe,KAClC,WAA+B;EAC/B,OAAO;EACP,OAAO;EACP,OAAO,cAAc,IAAI;EACzB,OAAO,SAAS,kBAAkB,IAAI;CACvC,CACD;CAEA,MAAM,WAAW,KAAK,gBAAgB,KACpC,YAAiC;EACjC,QAAQ;EACR,QAAQ;EACR,QAAQ,QAAQ;EAChB,QAAQ,WAAW;EACnB,6BAA6B,QAAQ,mBAAmB;EACxD,kBAAkB,QAAQ,QAAQ;CACnC,CACD;CAEA,OAAO;EACN,GAAG;EACH,GAAG,KAAK;EACR,GAAG,SAAS,SAAS,UAAU,KAAA;EAC/B,GAAG,UAAU,SAAS,WAAW,KAAA;CAClC;AACD;AAEA,MAAM,oBAAoB,SAA6C;CACtE,MAAM,gCAAgB,IAAI,IAAsB;CAKhD,MAAM,UAA0B,CAAC;CACjC,KAAK,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG;EACvD,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;EAC1B,MAAM,CAAC,IAAI,MAAM,aAAa,QAAQ;EACtC,IAAI,CAAC,gBAAgB,EAAE,GAAG;EAC1B,MAAM,kBAAkB,OAAO;EAC/B,MAAM,aAAa,SAAS,IAAI,kBAAkB;EAIlD,IAAI,qBAAqB,eAAe,kBAAkB;EAC1D,cAAc,IAAI,IAAI,IAAI;EAC1B,QAAQ,KAAK;GACZ;GACA,UAAU,kBAAkB,KAAA,IAAY,cAAc,EAAE,CAAC,CAAC;GAC1D,MAAM;GACN;GACA,aAAa,gBAAgB;EAC9B,CAAC;CACF;CAEA,MAAM,WAA4B,CAAC;CACnC,KAAK,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG;EACvD,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;EAC1B,MAAM,CACL,UACA,SACA,MACA,SACA,qBACA,gBACG;EACJ,IAAI,CAAC,gBAAgB,QAAQ,KAAK,OAAO,YAAY,YAAY,CAAC,SACjE;EAGD,MAAM,WACL,gBAAgB,OACb,oBAAoB,YAAY,IAChC,aAAA,kBACC,KAAA,IACA,cAAc,QAAQ,CAAC,CAAC;EAC7B,IAAI,CAAC,iBAAiB,QAAQ,GAAG;EACjC,SAAS,KAAK;GACb,IAAI,mBAAmB,UAAU,OAAO;GACxC;GACA;GACA,MAAM,QAAQ,KAAA;GACd,SAAS,WAAW,KAAA;GACpB,qBACC,aAAa,aACV,+BAA+B,mBAAmB,IAClD,KAAA;GACJ;GACA,YAAY,cAAc,IAAI,QAAQ,KAAK;EAC5C,CAAC;CACF;CAEA,OAAO;EACN,YAAY,KAAK;EACjB,eAAe;EACf,gBAAgB;CACjB;AACD;AAEA,MAAM,eAAe,KAAa,aAAiC;CAClE,IAAI;EACH,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,eAAe,MAAM,GAAG,OAAO,iBAAiB,MAAM;EAC1D,OAAO,sBAAsB,MAAwB;CACtD,QAAQ;EACP,OAAO;CACR;AACD;AAEA,MAAM,eAAe,SACpB,KAAK,UAAU,eAAe,IAAI,CAAC;;;;;AAMpC,MAAa,8BAA8B,mBAA4B;CACtE,MAAM,OAAO,cAAc,cAAc;CAEzC,OAAO;EACN,UAAU,QAAgB;GACzB,MAAM,MAAM,KAAK,QAAQ,GAAG;GAC5B,IAAI,CAAC,KAAK,OAAO;GACjB,MAAM,WAAW,YAAY,KAAK,gBAAgB;GAClD,IAAI,OAAO,aAAa,aACvB,IAAI;IACH,MAAM,SAAS,KAAK,MAAM,GAAG;IAC7B,IAAI,CAAC,eAAe,MAAM,GACzB,KAAK,QAAQ,KAAK,YAAY,QAAQ,CAAC;GAEzC,QAAQ,CAER;GAED,OAAO,KAAK,UAAU,QAAQ;EAC/B;EACA,UAAU,KAAa,UAAkB;GACxC,MAAM,WAAW,YAAY,OAAO,gBAAgB;GACpD,KAAK,QAAQ,KAAK,YAAY,QAAQ,CAAC;EACxC;EACA,YAAY,KAAK;EACjB,YAAY,KAAa,aAA6C;GACrE,MAAM,cAAc,KAAK,YAAY,MAAM,UAAU;IACpD,IAAI,CAAC,OAAO;KACX,SAAS,IAAI;KACb;IACD;IACA,MAAM,WAAW,YAAY,OAAO,gBAAgB;IACpD,SAAS,KAAK,UAAU,QAAQ,CAAC;GAClC,CAAC;GACD,aAAa;IACZ,cAAc;GACf;EACD;CACD;AACD;;;AC9QA,MAAM,mBAAuC,CAAC;;;;;;;AAQ9C,MAAM,uBAAuB,UAA0C;CACtE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,MAAM,IAAI;CACV,IAAI,CAAC,gBAAgB,EAAE,EAAE,GAAG,OAAO;CACnC,IAAI,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,gBAAgB,WAC1D,OAAO;CAGR,IAAI,EAAE,SAAS,iBACd,OAAO,EAAE,OAAA,mBAAmC,EAAE,aAAa,KAAA;CAC5D,OAAO,EAAE,SAAS,cAAc,iBAAiB,EAAE,QAAQ;AAC5D;;AAGA,MAAM,wBAAwB,UAA2C;CACxE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,MAAM,IAAI;CACV,OACC,OAAO,EAAE,OAAO,YAChB,CAAC,CAAC,EAAE,MACJ,iBAAiB,EAAE,QAAQ,KAC3B,OAAO,EAAE,YAAY,YACrB,CAAC,CAAC,EAAE,WACJ,gBAAgB,EAAE,QAAQ,KAC1B,OAAO,EAAE,eAAe;AAE1B;;;;;;;;AA2BA,MAAa,wBACZ,UAAuC,CAAC,MACpB;CACpB,MAAM,EAAE,YAAY,aAAa,wBAAwB;CACzD,MAAM,UACL,QAAQ,YACP,eAAe,KAAA,IACb,2BAA2B,UAAU,IACrC;CACJ,MAAM,QAAQ,YACb,YACA,kBACA,SACA,qBACD;CAEA,MAAM,kBAAkB,aAAuB;EAC9C,cAAc,QAAQ;EACtB,MAAM,QAAQ,UAAU;GACvB,GAAG;GACH,YAAY,MAAM,KAAK,cAAc,CAAC,EAAA,CAAG,OAAO,QAAQ,CAAC;EAC1D,EAAE;CACH;CAEA,MAAM,gBAAgB,aAAuB;EAC5C,MAAM,QAAQ,UAAU;GACvB,GAAG;GACH,YAAY,MAAM,KAAK,cAAc,CAAC,EAAA,CAAG,QAAQ,OAAO,OAAO,QAAQ,CAAC;EACzE,EAAE;CACH;CAEA,MAAM,uBAAuB;EAM5B,MAAM,OAAO,MAAM,IAAI;EACvB,MAAM,gBAAgB,MAAM,QAAQ,MAAM,aAAa,IACpD,KAAK,gBACL,CAAC;EACJ,MAAM,iBAAiB,MAAM,QAAQ,MAAM,cAAc,IACtD,KAAK,iBACL,CAAC;EACJ,OAAO;GACN,SAAS,cAAc,OAAO,mBAAmB;GACjD,UAAU,eAAe,OAAO,oBAAoB;EACrD;CACD;CAEA,MAAM,kBACL,SACA,aACI;EACJ,MAAM,QAAQ,UAAU;GACvB,GAAG;GACH,eAAe;GACf,gBAAgB;EACjB,EAAE;CACH;CAEA,OAAO;EACN,YAAY,MAAM;EAClB;EACA;EACA;EACA;EACA,SAAS,MAAM;CAChB;AACD;;;;;;AAOA,MAAM,uBAAuB,OAAO,IAAI,wBAAwB;;;;;;AAOhE,MAAa,wBAAwC;CACpD,MAAM,IAAI;CACV,IAAI,CAAC,EAAE,uBACN,EAAE,wBAAwB,qBAAqB;CAEhD,OAAO,EAAE;AACV;;;ACtJA,MAAa,eACZ,QACA,OACA,mBACI;CAEJ,MAAM,uBAAuB,MAAM,WAAW,KAC7C,KAAK,MAAM,EAAE,cAAc,CAAC,CAAC,GAC7B,KAAK,CAAC,GACN,YAAY;EAAE,YAAY;EAAG,UAAU;CAAK,CAAC,CAC9C;CAEA,OAAO,IAAI,YAAkD,eAAe;EAC3E,MAAM,MAAuB;GAAE;GAAQ;GAAO;EAAe;EAC7D,MAAM,cAAc,OAAO,UAAU,KAAK,WACzC,OAAO,YAAY,GAAG,CACvB;EAEA,MAAM,kBAAkB,sBAAsB;EAE9C,MAAM,oBAA0C,YAAkB;GACjE,GAAG;GACH,UAAU,YAA6B;IACtC,gBAAgB,OAAO,OAAO,EAAE;IAChC,OAAO,OAAO,QAAQ,OAAO;GAC9B;GACA,kBAAkB;IACjB,gBAAgB,OAAO,OAAO,EAAE;IAChC,OAAO,OAAO,WAAW;GAC1B;EACD;EAEA,MAAM,mBAAmB,YAAY,SAClC,cAAc,WAAW,CAAC,CAAC,KAAK,KAAK,YAAY,QAAQ,KAAK,CAAC,CAAC,IAChE,GAAiB,CAAC,CAAC;EAItB,MAAM,iBAAiB,OAAO,eAAe,WAAW,GAAG;EAW3D,MAAM,eATL,iBACG,cAAc,CAAC,kBAAkB,cAAc,CAAC,CAAC,CAAC,KAClD,KAAK,CAAC,iBAAiB,mBACtB,gBACG,CAAC,GAAG,iBAAiB,aAAa,IAClC,eACJ,CACD,IACC,iBAAA,CACiC,KACpC,KAAK,QAAQ,IAAI,KAAK,WAAW,CAAC,CACnC;EAEA,MAAM,WAAW,YAAY,KAC5B,KAAK,YACJ,QAAQ,KAAK,WACZ,iBAAiB,MAAM,IAAI,iBAAiB,MAAM,IAAI,MACvD,CACD,CACD;EAEA,MAAM,YAAY,OAAO,WAAuB;GAC/C,IAAI;IACH,MAAM,gBAAgB,QAAQ,OAAO,UAAU,OAAO,QAAQ,CAAC;GAChE,SAAS,KAAK;IACb,IAAI,WAAW,QAAQ;IACvB,IAAI,eAAe,gBAAgB;KAClC,IAAI,IAAI,SAAS,iBAAiB,MAAM,aAAa,OAAO,EAAE;KAC9D,IAAI,IAAI,SAAS,mBAAmB,IAAI,SAAS,WAChD,gBAAgB,OAAO,OAAO,EAAE;IAClC;IACA,IAAI,OAAO,OACV,QAAQ,MAAM,sCAAsC,OAAO,IAAI,GAAG;GACpE;EACD;EAEA,MAAM,aAAa,SAAS,UAAU,UAAU;EAChD,IAAI,WAAW,QAAQ,OAAO;EAE9B,MAAM,mBAAmB,cAAc,CAAC,aAAa,oBAAoB,CAAC,CAAC,CACzE,KACA,QACE,GAAG,eACH,OAAO,kBAAkB,SAAS,UAAU,SAAS,CACvD,GACA,UAAU,CAAC,SAAS,eACnB,QACE,OAAO,gBAAgB,CAAC,CACxB,QAAQ,WAAW,UAAU,SAAS,OAAO,EAAE,CAAC,CACnD,GACA,KAAK,WAAW;GACf,IAAI,OAAO,WAAW,aAAa,gBAAgB,OAAO,OAAO,EAAE;EACpE,CAAC,GACD,QACE,WACA,OAAO,WAAW,kBAClB,iBAAiB,OAAO,eAAe,MAAM,CAC/C,CACD,CAAC,CACA,UAAU,SAAS;EAErB,aAAa;GACZ,iBAAiB,YAAY;GAC7B,WAAW,YAAY;EACxB;CACD,CAAC,CAAC,CAAC,KAAK,YAAY;EAAE,UAAU;EAAM,YAAY;CAAE,CAAC,CAAC;AACvD;;;ACrEA,MAAa,iBAGZ,QACA,UAA+B,CAAC,MACG;CACnC,MAAM,EAAE,YAAY,OAAO,kBAAkB;CAC7C,MAAM,KAAK,cAAc,MAAM;CAC/B,MAAM,QACL,iBACA,qBAAqB;EAAE;EAAY,YAAY,GAAG;CAAW,CAAC;CAE/D,IAAI,GAAG,OAAO,QAAQ,MAAM,sBAAsB,EAAE;CAGpD,IAAI,GAAG,SAAS,OAAO,WAAW,eAAe,eAAe,KAAA,GAC/D,QAAQ,KACP,sHAED;CAID,MAAM,EAAE,SAAS,eAAe,UAAU,mBACzC,oBAAoB,OAAO,IAAI,EAAE,OAAO,KAAK,CAAC;CAE/C,IAAI,GAAG,SAAS,cAAc,SAAS,GACtC,QAAQ,MAAM,qCAAqC;EAClD,SAAS,cAAc;EACvB,UAAU,eAAe;CAC1B,CAAC;CAGF,OAAO,IAAI,YAA4B,eAAe;EACrD,IAAI;EACJ,IAAI,SAAS;EACb,MAAM,0BAAU,IAAI,IAAiB;EACrC,MAAM,8BAAc,IAAI,IAAiD;EACzE,MAAM,0BAAU,IAAI,QAGlB;EAEF,MAAM,WAAW,WAAwB;GACxC,QAAQ,OAAO,MAAM;GACrB,IAAI,OAAO,aACV,OAAO,OAAO,aAAa,OAAO,UAAU,SAAS,CAAC;QAClD,OAAO,QAAQ;EACrB;EAEA,MAAM,YAAY,QAAqB,UAA0B;GAChE,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,EAAE,OAAO,OAAO,QAAQ;GACjE,IAAI,CAAC,UAAU,OAAO,gBAAgB,OAAO,aAAa;IACzD,QAAQ,OAAO,MAAM;IACrB,OAAO,QAAQ;GAChB;EACD;EAEA,MAAM,aAAa,UAAoB,gBAAyB;GAC/D,KAAK,MAAM,UAAU,SACpB,IAAI,OAAO,aAAa,YAAY,OAAO,gBAAgB,aAC1D,QAAQ,MAAM;EACjB;EAEA,MAAM,aAAa,UAAoB,gBACtC,IAAI,SAAe,SAAS,WAAW;GACtC,MAAM,SAAS;IAAE;IAAU;IAAa;IAAS;GAAO;GACxD,QAAQ,IAAI,MAAM;GAClB,IAAI,QAAQ,SAAS,QAAQ,MAAM;GACnC,IAAI,UAAU,QAAQ,IAAI,MAAM,GAAG,QAAQ,MAAM;EAClD,CAAC;EAEF,MAAM,YAAY,UAAoB,WACrC,IAAI,SAA2C,SAAS,WAAW;GAClE,MAAM,UAAU,WAAuB;IACtC,YAAY,OAAO,KAAK;IACxB,QAAQ,oBAAoB,SAAS,OAAO;IAC5C,OAAO;GACR;GACA,MAAM,gBACL,aAAa,OAAO,aAAa,UAAU,SAAS,CAAC,CAAC;GACvD,MAAM,SAAS,UAAsC;IACpD,IAAI,CAAC,OAAO,OAAO,QAAQ;IAC3B,MAAM,OAAO,MAAM,QAAQ,MACzB,MAAM,EAAE,OAAO,YAAY,CAAC,EAAE,aAChC;IACA,IAAI,MAAM,aAAa,QAAQ,IAAI,CAAC;SAC/B,IAAI,CAAC,MAAM,aACf,aAAa,OAAO,mBAAmB,QAAQ,CAAC,CAAC;GACnD;GACA,IAAI,UAAU,QAAQ,SAAS,OAAO,QAAQ;GAC9C,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;GACzD,YAAY,IAAI,KAAK;GACrB,IAAI,QAAQ,MAAM,MAAM;EACzB,CAAC;EAEF,MAAM,eACL,iBACuC;GACvC,GAAG;GACH,SAAS,OAAO,YAAY;IAC3B,MAAM,OAAO,MAAM,SAAS,YAAY,IAAI,SAAS,MAAM;IAC3D,IAAI,QAAQ,MAAM,aAAa,YAAY,IAAI,SAAS;IACxD,MAAM,KAAK,QAAQ,OAAO;GAC3B;EACD;EAEA,MAAM,mBACL,WACsC;GACtC,MAAM,WAAW,QAAQ,IAAI,MAAM;GACnC,IAAI,UAAU,OAAO;GACrB,IAAI,OAAO,eAAe;IACzB,MAAM,WAAW,YAAY,MAAM;IACnC,QAAQ,IAAI,QAAQ,QAAQ;IAC5B,OAAO;GACR;GACA,IAAI,CAAC,iBAAiB,MAAM,GAAG,OAAO;GACtC,MAAM,UAAsB;IAC3B,GAAG;IACH,SAAS,OAAO,YAAY;KAC3B,IAAI,QAAQ,MAAM,aAAa,OAAO,IAAI,SAAS;KACnD,MAAM,OAAO,QAAQ,OAAO;KAC5B,UAAU,OAAO,IAAI,IAAI;KACzB,MAAM,UAAU,OAAO,IAAI,IAAI;IAChC;IACA,YAAY,YAAY;KACvB,IAAI,QAAQ,MAAM,aAAa,OAAO,IAAI,YAAY;KACtD,MAAM,OAAO,WAAW;KACxB,UAAU,OAAO,IAAI,KAAK;KAC1B,MAAM,UAAU,OAAO,IAAI,KAAK;IACjC;GACD;GACA,QAAQ,IAAI,QAAQ,OAAO;GAC3B,OAAO;EACR;EAEA,MAAM,iBAAiB,qBAAqB,CAAC,CAAC,KAC7C,YAAY;GAAE,YAAY;GAAG,UAAU;EAAK,CAAC,CAC9C;EACA,MAAM,eAAe,YAAY,IAAI,OAAO,cAAc;EAC1D,MAAM,iBAAiB,aAAa,IAAI,YAAY;EACpD,MAAM,gBAAgB,eAAe,KACpC,KAAK,EAAE,eAAe,SAAS,IAAI,MAAM,CAAC,CAC3C;EAEA,MAAM,iBAAiB,OACtB,GAAG,IAAI,GACP,eAAe,KAAK,eAAe,CAAC,GACpC,aAAa,KACZ,KAAK,CAAC,GACN,UAAU,KAAK,CAChB,CACD,CAAC,CAAC,KAAK,YAAY;GAAE,YAAY;GAAG,UAAU;EAAK,CAAC,CAAC;EAErD,MAAM,oBAAoB,cAAc;GACvC;GACA,eAAe,KAAK,UAAU,WAAW,CAAC;GAC1C;GACA,MAAM,WAAW,KAChB,KAAK,MAAM,EAAE,cAAc,CAAC,CAAC,GAC7B,KAAK,CAAC,CACP;EACD,CAAC,CAAC,CAAC,KACF,KAAK,CAAC,SAAS,EAAE,UAAU,YAAY,eAAe,gBACrD,cAAc,OAAO,WAAW;GAC/B,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,OAAO,OAAO,EAAE;GACrD,IAAI,CAAC,QAAQ,OAAO,CAAC;GACrB,OACC,OAAO,WAAW,gBAClB,iBAAiB,QAAQ,QAAQ;IAChC;IACA;IACA;IACA;GACD,CAAC;EAEH,CAAC,CACF,GACA,aAAa,GAAG,aAAa,GAC7B,qBAAqB,CACtB;EAGA,MAAM,mBAAmB,sBACxB,eACA,aAAa,KAAK,KAAK,YAAY,QAAQ,IAAI,MAAM,CAAC,CAAC,GACvD,GAAG,sBACH,GAAG,mBACF,MAAM,EAAE,IACT,oBACC,MAAM,WAAW;GACjB,MAAM,SAAS,iBAAiB,MAAM,MAAM,IACzC,eACA,KAAK;GACR,OAAO;IACN,GAAG;IACH;IACA,aAAa,WAAW;IACxB,MAAM,OAAO,QAAQ,cAAc,OAAO,EAAE,KAAK,KAAK;GACvD;EACD,IAEC,YAAY;GACZ,GAAG;GACH,MAAM,OAAO,QAAQ,cAAc,OAAO,EAAE,KAAK;EAClD,EACD;EAGA,MAAM,oBAAoB,6BACzB,gBACA,eACA,GAAG,sBACH,GAAG,mBACF,MAAM,EAAE,UACT,iBACD;EAKA,MAAM,iBAAiB,iBAAiB,KACvC,YAAY;GAAE,YAAY;GAAG,UAAU;EAAK,CAAC,CAC9C;EACA,MAAM,kBAAkB,kBAAkB,KACzC,YAAY;GAAE,YAAY;GAAG,UAAU;EAAK,CAAC,CAC9C;EAGA,MAAM,eAAe,cAAc;GAClC,SAAS;GACT,UAAU;GACV,eAAe;EAChB,CAAC,CAAC,CACA,KACA,KAAK,EAAE,SAAS,UAAU,oBAAoB;GAC7C,IAAI,GAAG,OACN,QAAQ,MAAM,+BAA+B;IAC5C,kBAAkB,QAAQ;IAC1B,mBAAmB,SAAS;IAC5B;IACA,kBAAkB,QAAQ,MAAM,QAAQ,MAAM,EAAE,WAAW,CAAC,CAC1D;IACF,cAAc,QAAQ,MAAM;GAC7B,CAAC;GAMF,OAAO;IACN,QAAQ;IACR,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,IAAI,eAAe;IACjE,UAAU,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,YAAY;IAC/C,aAAa,QAAQ,eAAe,SAAS;IAC7C;GACD;EACD,CAAC,GACD,aAAa,GAAG,aAAa,GAC7B,qBAAqB,WAAW,GAChC,KAAK,UAAU;GACd,SAAS;GACT,KAAK,MAAM,SAAS,aAAa,MAAM,KAAK;GAC5C,KAAK,MAAM,UAAU,SAAS,SAAS,QAAQ,KAAK;EACrD,CAAC,CACF,CAAC,CACA,UAAU,UAAU;EAGtB,MAAM,aAAa,cAAc;GAChC,SAAS;GACT,UAAU;EACX,CAAC,CAAC,CACA,KAEA,QACE,EAAE,SAAS,eACX,CAAC,QAAQ,eAAe,CAAC,SAAS,WACpC,GAEA,aAAa,GAAI,GAKjB,sBAAsB,MAAM,SAAS;GACpC,MAAM,iBAAiB,KAAK,QAAQ,MAAM,IAAI,kBAAkB;GAChE,MAAM,iBAAiB,KAAK,QAAQ,MAAM,IAAI,kBAAkB;GAChE,MAAM,kBAAkB,KAAK,SAAS,MAAM,IAAI,gBAAgB;GAChE,MAAM,kBAAkB,KAAK,SAAS,MAAM,IAAI,gBAAgB;GAChE,OACC,YAAY,gBAAgB,cAAc,KAC1C,YAAY,iBAAiB,eAAe;EAE9C,CAAC,CACF,CAAC,CACA,WAAW,EAAE,SAAS,eAAe;GACrC,MAAM,WAAW,kBAChB,QAAQ,OACR,SAAS,OACT,MAAM,eAAe,CACtB;GAEA,IAAI,GAAG,OACN,QAAQ,MAAM,0CAA0C;IACvD,SAAS,SAAS,QAAQ;IAC1B,UAAU,SAAS,SAAS;GAC7B,CAAC;GAGF,MAAM,eAAe,SAAS,SAAS,SAAS,QAAQ;GAGxD,MAAM,QAAgC,CAAC;GACvC,KAAK,MAAM,UAAU,QAAQ,OAC5B,IAAI,OAAO,MACV,MAAM,OAAO,MAAM,OAAO;GAG5B,eAAe,KAAK;EACrB,CAAC;EAEF,aAAa;GACZ,aAAa,YAAY;GACzB,WAAW,YAAY;GACvB,SAAS;GACT,KAAK,MAAM,UAAU,SAAS,QAAQ,MAAM;GAC5C,KAAK,MAAM,SAAS,aAAa,MAAM,KAAA,CAAS;EACjD;CACD,CAAC,CAAC,CAAC,KACF,cAAc,cAAc;EAAE,SAAS,GAAG;EAAO,YAAY;CAAK,CAAC,GACnE,YAAY;EAAE,YAAY;EAAG,UAAU;CAAK,CAAC,CAG9C;AACD;AAWA,MAAM,oBACL,MACA,WAEA,sBAAsB,IAAI,KAC1B,KAAK,WAAW,kBAChB,OAAO,WAAW;AAEnB,MAAM,0BAAU,IAAI,QAAwB;AAE5C,MAAM,UAA4B,SAA0C;CAC3E,MAAM,WAAW,QAAQ,IAAI,IAAI;CACjC,IAAI,UAAU,OAAO;CACrB,MAAM,OAAO;EAAE,GAAG;EAAM,eAAe;CAAe;CACtD,QAAQ,IAAI,MAAM,IAAI;CACtB,OAAO;AACR;AAEA,MAAM,cAA6B;CAAE,UAAU,CAAC;CAAG,UAAU,CAAC;AAAE;;;;;;AAOhE,MAAM,oBACL,QACA,QACA,SAIa;CACb,MAAM,SAAS,iBAAiB,QAAQ,MAAM,IAC3C,eACA,OAAO;CACV,IAAI,WAAW,cAAc,OAAO;CACpC,IAAI,WAAW,gBACd,OAAO,OAAO,UAAU,KAAA,KAAa,CAAC,KAAK,WAAW,SAAS,OAAO,EAAE;CACzE,OACC,KAAK,SAAS,SAAS,OAAO,EAAE,KAChC,CAAC,KAAK,eAAe,MAAM,MAAM,EAAE,aAAa,OAAO,EAAE,KACzD,KAAK,SAAS,MAAM,MAAM,EAAE,aAAa,OAAO,EAAE;AAEpD;;;;;;;AAQA,MAAM,qBACL,SACA,UACA,aAC4D;CAC5D,MAAM,aAAa,IAAI,IACtB,QAAQ,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE,CACjE;CACA,MAAM,YAAY,IAAI,IACrB,QAAQ,QAAQ,MAAM,EAAE,WAAW,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE,CACrD;CACA,MAAM,kBAAkB,IAAI,IAAI,SAAS,QAAQ,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CACtE,OAAO;EACN,SAAS,QAAQ,KACf,MACC,WAAW,IAAI,EAAE,EAAE,KAAK,gBAAgB,IAAI,EAAE,EAAE,KACjD,gBAAgB,CAAC,CACnB;EACA,UAAU,CACT,GAAG,SACD,QAAQ,MAAM,UAAU,IAAI,EAAE,QAAQ,CAAC,CAAC,CACxC,IAAI,gBAAgB,GACtB,GAAG,SAAS,SAAS,QAAQ,MAAM,WAAW,IAAI,EAAE,QAAQ,CAAC,CAC9D;CACD;AACD;AAEA,MAAM,eAAe,GAAa,MACjC,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,MAAM,EAAE,EAAE;;;;;;;;AAgBtD,MAAM,oBAAoB,YACzB,GAAG,QAAQ,QAAQ,GAAG,GAAG,mBAAmB,OAAO;AAEpD,MAAM,sBAAsB,YAAuC;CAClE,QAAQ,QAAQ,UAAhB;EACC,KAAK,YACJ,OAAO,GAAG,QAAQ,GAAG,GAAI,QAAkC,WAAW;EACvE,KAAK,YACJ,OAAO,GAAG,QAAQ,GAAG,GAAI,QAAkC,QAAQ;EACpE,KAAK,UACJ,OAAO,GAAG,QAAQ,GAAG,IAAK,QAAgC,UAAU,CAAC,EAAA,CAAG,KAAK,GAAG;EACjF,SACC,OAAO,QAAQ;CACjB;AACD;;AAGA,MAAM,mBAAmB,WACxB,sBAAsB,MAAM,IAAI,OAAO,UAAU,KAAK,GAAG,IAAI;;AAG9D,MAAM,oBAAoB,WACzB,GAAG,OAAO,GAAG,GAAG,OAAO,cAAc,IAAI,EAAE,GAAG,OAAO;;;;;;AAOtD,MAAM,sBAAsB,WAC3B,GAAG,iBAAiB,MAAM,EAAE,GAAG,OAAO;;;;;;;AAQvC,MAAM,eAAe,WACpB,GAAG,iBAAiB,MAAM,EAAE,GAAG,OAAO,OAAO,GAAG,OAAO,OAAO,QAAQ,GAAG,GAAG,OAAO,KAAK,GAAG,gBAAgB,MAAM;;;;;AAMlH,MAAM,eAAe,GAAmB,MACvC,EAAE,gBAAgB,EAAE,eACpB,EAAE,kBAAkB,EAAE,iBACtB,EAAE,QAAQ,WAAW,EAAE,QAAQ,UAC/B,EAAE,SAAS,WAAW,EAAE,SAAS,UACjC,EAAE,QAAQ,OAAO,GAAG,MAAM;CACzB,MAAM,QAAQ,EAAE,QAAQ;CACxB,OACC,CAAC,CAAC,SACF,EAAE,kBAAkB,MAAM,iBAC1B,YAAY,CAAC,MAAM,YAAY,KAAK;AAEtC,CAAC,KACD,EAAE,SAAS,OAAO,KAAK,MAAM;CAC5B,MAAM,QAAQ,EAAE,SAAS;CACzB,OACC,CAAC,CAAC,SACF,IAAI,kBAAkB,MAAM,iBAC5B,iBAAiB,GAAG,MAAM,iBAAiB,KAAK;AAElD,CAAC"}
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as getSafeLocalStorage } from "./storage-D3AwNgqc.mjs";
|
|
2
|
-
import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-
|
|
2
|
+
import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-DCaL9bIc.mjs";
|
|
3
3
|
import { n as clearCachedObservable, r as clearCachedObservablesByPrefix } from "./getCachedObservable-LUq9IfEx.mjs";
|
|
4
4
|
//#region src/utils/hydrateState.d.ts
|
|
5
5
|
/**
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as getSafeLocalStorage } from "./storage-D3AwNgqc.js";
|
|
2
|
-
import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-
|
|
2
|
+
import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-DCaL9bIc.js";
|
|
3
3
|
import { n as clearCachedObservable, r as clearCachedObservablesByPrefix } from "./getCachedObservable-LUq9IfEx.js";
|
|
4
4
|
//#region src/utils/hydrateState.d.ts
|
|
5
5
|
/**
|
package/dist/polkadot.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, g as PolkadotAccountType, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-
|
|
1
|
+
import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, g as PolkadotAccountType, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-DCaL9bIc.mjs";
|
|
2
2
|
import { InjectedPolkadotAccount, SignPayload } from "polkadot-api/pjs-signer";
|
|
3
3
|
//#region src/utils/isSs58Address.d.ts
|
|
4
4
|
/**
|
package/dist/polkadot.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, g as PolkadotAccountType, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-
|
|
1
|
+
import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, g as PolkadotAccountType, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-DCaL9bIc.js";
|
|
2
2
|
import { InjectedPolkadotAccount, SignPayload } from "polkadot-api/pjs-signer";
|
|
3
3
|
//#region src/utils/isSs58Address.d.ts
|
|
4
4
|
/**
|
package/dist/polkadot.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
const require_types = require("./types-BWHvNFlN.js");
|
|
25
25
|
const require_platformAccounts = require("./platformAccounts-BjIeRcFN.js");
|
|
26
26
|
const require_polkadotExtensions = require("./polkadotExtensions-y4J9UzYl.js");
|
|
27
|
-
const
|
|
27
|
+
const require_registryReads = require("./registryReads-BpHsWLd7.js");
|
|
28
28
|
const require_injectedWallets = require("./injectedWallets-Dy8YGKL-.js");
|
|
29
29
|
let _scure_base = require("@scure/base");
|
|
30
30
|
let rxjs = require("rxjs");
|
|
@@ -40,51 +40,34 @@ const isPolkadotInjected = (injected) => typeof injected?.accounts?.get === "fun
|
|
|
40
40
|
* resumes from the current list rather than the connect-time one.
|
|
41
41
|
*/
|
|
42
42
|
const latestAccounts = /* @__PURE__ */ new WeakMap();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
/**
|
|
44
|
+
* The connect each extension is still answering. An extension keeps its
|
|
45
|
+
* prompt open after kheopskit abandons the attempt, and a second `enable()`
|
|
46
|
+
* meanwhile fails (polkadot-js: "Pending authorisation request already
|
|
47
|
+
* exists") or resolves unauthorised (Talisman), so a new attempt joins this
|
|
48
|
+
* one instead.
|
|
49
|
+
*/
|
|
50
|
+
const pendingConnects = /* @__PURE__ */ new WeakMap();
|
|
51
|
+
const enableExtension = async (identifier, entry, appName) => {
|
|
46
52
|
const injected = await entry.enable(appName);
|
|
47
53
|
if (!isPolkadotInjected(injected)) throw new Error(`Unsupported extension: "${identifier}"`);
|
|
48
54
|
latestAccounts.set(injected, await injected.accounts.get());
|
|
49
55
|
return injected;
|
|
50
56
|
};
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
return new
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
let index = 0;
|
|
62
|
-
let timer;
|
|
63
|
-
const poll = () => {
|
|
64
|
-
subscriber.next(getInjectedWalletsIds());
|
|
65
|
-
if (index < intervals.length) {
|
|
66
|
-
const delay = intervals[index++];
|
|
67
|
-
timer = setTimeout(poll, delay);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
if (intervals.length > 0) timer = setTimeout(poll, intervals[index++] ?? 100);
|
|
71
|
-
let loadTimer;
|
|
72
|
-
const loadSub = require_pageLoad.pageLoaded$.pipe((0, rxjs.skip)(1)).subscribe(() => {
|
|
73
|
-
loadTimer = setTimeout(() => subscriber.next(getInjectedWalletsIds()), 100);
|
|
74
|
-
subscriber.next(getInjectedWalletsIds());
|
|
75
|
-
});
|
|
76
|
-
return () => {
|
|
77
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
78
|
-
clearTimeout(loadTimer);
|
|
79
|
-
loadSub.unsubscribe();
|
|
80
|
-
};
|
|
81
|
-
}).pipe((0, rxjs.distinctUntilChanged)(lodash_es.isEqual), (0, rxjs.shareReplay)({
|
|
82
|
-
refCount: true,
|
|
83
|
-
bufferSize: 1
|
|
84
|
-
}));
|
|
57
|
+
const connectExtension = (identifier, appName) => {
|
|
58
|
+
const entry = globalThis.injectedWeb3?.[identifier];
|
|
59
|
+
if (!entry) return Promise.reject(/* @__PURE__ */ new Error(`Unavailable extension: "${identifier}"`));
|
|
60
|
+
const pending = pendingConnects.get(entry);
|
|
61
|
+
if (pending) return pending;
|
|
62
|
+
const connecting = enableExtension(identifier, entry, appName);
|
|
63
|
+
pendingConnects.set(entry, connecting);
|
|
64
|
+
const settle = () => pendingConnects.delete(entry);
|
|
65
|
+
connecting.then(settle, settle);
|
|
66
|
+
return connecting;
|
|
85
67
|
};
|
|
86
|
-
const
|
|
87
|
-
|
|
68
|
+
const getInjectedWalletsIds = () => typeof window === "undefined" ? [] : (0, polkadot_api_pjs_signer.getInjectedExtensions)().map((name) => require_types.getWalletId("polkadot", name));
|
|
69
|
+
const getPolkadotWallets$ = (store, config, registryReads$ = require_registryReads.createRegistryReads$()) => require_injectedWallets.createInjectedWallets$(store, {
|
|
70
|
+
sources$: registryReads$.pipe((0, rxjs.map)(getInjectedWalletsIds), (0, rxjs.distinctUntilChanged)(lodash_es.isEqual)),
|
|
88
71
|
getWalletId: (walletId) => walletId,
|
|
89
72
|
connect: (walletId) => connectExtension(require_types.parseWalletId(walletId).identifier, config.appName || config.walletConnect?.metadata.name || window.location.hostname),
|
|
90
73
|
isUserRejection: require_types.isRefusalMessage,
|
|
@@ -280,7 +263,7 @@ const polkadot = (options = {}) => {
|
|
|
280
263
|
if (invalid.length > 0) console.warn(`[kheopskit] Unknown polkadot accountTypes: ${JSON.stringify(invalid)}. Valid values: "sr25519", "ed25519", "ecdsa", "ethereum".`);
|
|
281
264
|
return {
|
|
282
265
|
platform: "polkadot",
|
|
283
|
-
getWallets$: (ctx) => getPolkadotWallets$(ctx.store, ctx.config),
|
|
266
|
+
getWallets$: (ctx) => getPolkadotWallets$(ctx.store, ctx.config, ctx.registryReads$),
|
|
284
267
|
getAccounts$: (wallets$) => getPolkadotAccounts$(wallets$, accountTypes),
|
|
285
268
|
acceptsCachedAccount: (cached) => accountTypes.includes(cached.polkadotAccountType ?? "sr25519")
|
|
286
269
|
};
|