@kheopskit/core 6.0.0-rc.2 → 6.0.0-rc.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"injectedWallets-Dy8YGKL-.js","names":["abortedError","Observable","BehaviorSubject","toConnectError","combineLatest","tap","map","distinctUntilChanged","shareReplay"],"sources":["../src/api/injectedWallets.ts"],"sourcesContent":["import {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n\ttap,\n} from \"rxjs\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport { abortedError, type KheopskitError, toConnectError } from \"./errors\";\nimport type { KheopskitStore } from \"./store\";\nimport type { BaseWallet, ConnectOptions, WalletStatus } from \"./types\";\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n * Shared by every platform's injected-wallets stream.\n */\nconst walletsEqual = <\n\tW extends Pick<BaseWallet, \"id\" | \"status\" | \"error\" | \"name\">,\n>(\n\ta: W[],\n\tb: W[],\n): boolean => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(w, i) =>\n\t\t\tw.id === b[i]?.id &&\n\t\t\tw.status === b[i]?.status &&\n\t\t\tw.error === b[i]?.error &&\n\t\t\tw.name === b[i]?.name,\n\t);\n};\n\n/**\n * The platform-specific surface of an injected-wallets stream. Everything else\n * — the connect/disconnect state machine, the connected-ids bookkeeping, the\n * store persistence, change detection and sharing — is owned by\n * {@link createInjectedWallets$}.\n *\n * @typeParam TSource - a wallet as the platform's registry reports it\n * @typeParam TWallet - the platform's wallet type\n * @typeParam THandle - live connection handle retained while connected\n */\nexport type InjectedWalletsAdapter<\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n> = {\n\t/** Live registry of the platform's injected wallets (emits `[]` during SSR). */\n\tsources$: Observable<readonly TSource[]>;\n\t/** Stable wallet id for a registry entry. */\n\tgetWalletId: (source: TSource) => WalletId;\n\t/**\n\t * Platform connect call. The resolved value is retained as the wallet's\n\t * live handle until disconnect.\n\t */\n\tconnect: (source: TSource, walletId: WalletId) => Promise<THandle>;\n\t/** `true` maps the platform's rejection to `USER_REJECTED`; absent means never. */\n\tisUserRejection?: (error: unknown) => boolean;\n\treleaseAbandonedHandle?: (handle: THandle, walletId: WalletId) => void;\n\t/**\n\t * Optional platform disconnect call, awaited before local state clears so a\n\t * failed disconnect rejects without desyncing the connected list.\n\t */\n\tdisconnect?: (source: TSource, walletId: WalletId) => Promise<void>;\n\t/**\n\t * Runs after a disconnect fully applied — the place to drop cached account\n\t * observables so a later reconnect rebuilds them against a fresh handle.\n\t */\n\tonDisconnected?: (walletId: WalletId) => void;\n\t/** Build the platform wallet object for one registry entry. */\n\tbuildWallet: (args: {\n\t\tsource: TSource;\n\t\twalletId: WalletId;\n\t\t/** Live connection handle; `undefined` while disconnected. */\n\t\thandle: THandle | undefined;\n\t\tstatus: WalletStatus;\n\t\terror: KheopskitError | undefined;\n\t\tisConnected: boolean;\n\t\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t\tdisconnect: () => Promise<void>;\n\t}) => TWallet;\n};\n\ntype Connecting = {\n\tstatus: \"connecting\";\n\tpromise: Promise<void>;\n\tanchored: boolean;\n\twaiting: number;\n\tanswered: boolean;\n\tabort: () => void;\n};\n\ntype Connection<THandle> =\n\t| Connecting\n\t| { status: \"connected\"; handle: THandle; disconnecting?: Promise<void> }\n\t| { status: \"disconnected\"; error: KheopskitError };\n\nconst join = (\n\tconnecting: Connecting,\n\twalletId: WalletId,\n\tsignal: AbortSignal | undefined,\n): Promise<void> => {\n\tif (!signal) {\n\t\tconnecting.anchored = true;\n\t\treturn connecting.promise;\n\t}\n\tconnecting.waiting++;\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst leave = () => {\n\t\t\tif (connecting.answered) return;\n\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\tconnecting.waiting--;\n\t\t\tif (!connecting.anchored && connecting.waiting === 0) connecting.abort();\n\t\t};\n\t\tsignal.addEventListener(\"abort\", leave, { once: true });\n\t\tconnecting.promise\n\t\t\t.then(resolve, reject)\n\t\t\t.finally(() => signal.removeEventListener(\"abort\", leave));\n\t});\n};\n\n/**\n * The shared engine behind every platform's injected-wallets stream: tracks\n * each wallet's connection (pending attempt or live handle), shares one\n * in-flight connect per wallet, persists connected ids to the store for\n * auto-reconnect, and re-emits the wallet list whenever the registry or\n * connection state changes.\n */\nexport const createInjectedWallets$ = <\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n>(\n\tstore: KheopskitStore,\n\tadapter: InjectedWalletsAdapter<TSource, TWallet, THandle>,\n): Observable<TWallet[]> =>\n\tnew Observable<TWallet[]>((subscriber) => {\n\t\tconst connections$ = new BehaviorSubject<\n\t\t\tReadonlyMap<WalletId, Connection<THandle>>\n\t\t>(new Map());\n\t\tconst teardown = new AbortController();\n\t\tlet present = new Set<WalletId>();\n\n\t\tconst abortConnectsOfSourcesThatLeft = (sources: readonly TSource[]) => {\n\t\t\tpresent = new Set(sources.map((source) => adapter.getWalletId(source)));\n\t\t\tfor (const [walletId, connection] of connections$.value)\n\t\t\t\tif (connection.status === \"connecting\" && !present.has(walletId))\n\t\t\t\t\tconnection.abort();\n\t\t};\n\n\t\tconst setConnection = (\n\t\t\twalletId: WalletId,\n\t\t\tconnection: Connection<THandle> | undefined,\n\t\t) => {\n\t\t\tconst next = new Map(connections$.value);\n\t\t\tif (connection) next.set(walletId, connection);\n\t\t\telse next.delete(walletId);\n\t\t\tconnections$.next(next);\n\t\t};\n\n\t\tconst startConnect = (\n\t\t\tsource: TSource,\n\t\t\twalletId: WalletId,\n\t\t\tsignal: AbortSignal | undefined,\n\t\t): Promise<void> => {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst promise = new Promise<void>((resolve, reject) => {\n\t\t\t\tcontroller.signal.addEventListener(\n\t\t\t\t\t\"abort\",\n\t\t\t\t\t() => {\n\t\t\t\t\t\tsetConnection(walletId, undefined);\n\t\t\t\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true },\n\t\t\t\t);\n\t\t\t\tnew Promise<THandle>((res) =>\n\t\t\t\t\tres(adapter.connect(source, walletId)),\n\t\t\t\t).then(\n\t\t\t\t\t(handle) => {\n\t\t\t\t\t\tconnecting.answered = true;\n\t\t\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\t\t\tadapter.releaseAbandonedHandle?.(handle, walletId);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetConnection(walletId, { status: \"connected\", handle });\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\tstore.rememberWallet(walletId);\n\t\t\t\t\t},\n\t\t\t\t\t(error) => {\n\t\t\t\t\t\tconnecting.answered = true;\n\t\t\t\t\t\tif (controller.signal.aborted) return;\n\t\t\t\t\t\tconst connectError = toConnectError(\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\twalletId,\n\t\t\t\t\t\t\tadapter.isUserRejection ?? (() => false),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsetConnection(walletId, {\n\t\t\t\t\t\t\tstatus: \"disconnected\",\n\t\t\t\t\t\t\terror: connectError,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treject(connectError);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t\tconst connecting: Connecting = {\n\t\t\t\tstatus: \"connecting\",\n\t\t\t\tpromise,\n\t\t\t\tanchored: false,\n\t\t\t\twaiting: 0,\n\t\t\t\tanswered: false,\n\t\t\t\tabort: () => {\n\t\t\t\t\tif (connections$.value.get(walletId) === connecting)\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t},\n\t\t\t};\n\t\t\tsetConnection(walletId, connecting);\n\t\t\treturn join(connecting, walletId, signal);\n\t\t};\n\n\t\tconst untilSettled = (\n\t\t\tdisconnecting: Promise<void>,\n\t\t\twalletId: WalletId,\n\t\t\tsignal: AbortSignal | undefined,\n\t\t): Promise<void> =>\n\t\t\tnew Promise<void>((resolve, reject) => {\n\t\t\t\tconst signals = signal ? [teardown.signal, signal] : [teardown.signal];\n\t\t\t\tconst settle = () => {\n\t\t\t\t\tfor (const s of signals) s.removeEventListener(\"abort\", settle);\n\t\t\t\t\tif (signals.some((s) => s.aborted))\n\t\t\t\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\t\t\telse resolve();\n\t\t\t\t};\n\t\t\t\tif (signals.some((s) => s.aborted)) return settle();\n\t\t\t\tfor (const s of signals)\n\t\t\t\t\ts.addEventListener(\"abort\", settle, { once: true });\n\t\t\t\tdisconnecting.then(settle, settle);\n\t\t\t});\n\n\t\tconst connect = (\n\t\t\tsource: TSource,\n\t\t\twalletId: WalletId,\n\t\t\toptions?: ConnectOptions,\n\t\t): Promise<void> => {\n\t\t\tif (teardown.signal.aborted || !present.has(walletId))\n\t\t\t\treturn Promise.reject(abortedError(walletId, \"connect\"));\n\t\t\tconst current = connections$.value.get(walletId);\n\t\t\tif (current?.status === \"connected\") {\n\t\t\t\tif (!current.disconnecting) return Promise.resolve();\n\t\t\t\treturn untilSettled(\n\t\t\t\t\tcurrent.disconnecting,\n\t\t\t\t\twalletId,\n\t\t\t\t\toptions?.signal,\n\t\t\t\t).then(() => connect(source, walletId, options));\n\t\t\t}\n\t\t\tif (options?.signal?.aborted)\n\t\t\t\treturn Promise.reject(abortedError(walletId, \"connect\"));\n\t\t\tif (current?.status === \"connecting\")\n\t\t\t\treturn join(current, walletId, options?.signal);\n\t\t\treturn startConnect(source, walletId, options?.signal);\n\t\t};\n\n\t\tconst disconnect = (source: TSource, walletId: WalletId): Promise<void> => {\n\t\t\tconst current = connections$.value.get(walletId);\n\t\t\tif (!current || current.status === \"disconnected\")\n\t\t\t\treturn Promise.resolve();\n\t\t\tif (current.status === \"connecting\") {\n\t\t\t\tcurrent.abort();\n\t\t\t\treturn Promise.resolve();\n\t\t\t}\n\t\t\tif (current.disconnecting) return current.disconnecting;\n\n\t\t\tstore.forgetWallet(walletId);\n\t\t\tconst disconnecting = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait adapter.disconnect?.(source, walletId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!teardown.signal.aborted) {\n\t\t\t\t\t\tsetConnection(walletId, {\n\t\t\t\t\t\t\tstatus: \"connected\",\n\t\t\t\t\t\t\thandle: current.handle,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tstore.rememberWallet(walletId);\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (teardown.signal.aborted) return;\n\t\t\t\tsetConnection(walletId, undefined);\n\t\t\t\tadapter.onDisconnected?.(walletId);\n\t\t\t})();\n\t\t\tsetConnection(walletId, { ...current, disconnecting });\n\t\t\treturn disconnecting;\n\t\t};\n\n\t\tconst sub = combineLatest([adapter.sources$, connections$])\n\t\t\t.pipe(\n\t\t\t\ttap(([sources]) => abortConnectsOfSourcesThatLeft(sources)),\n\t\t\t\tmap(([sources, connections]) =>\n\t\t\t\t\tsources.map((source): TWallet => {\n\t\t\t\t\t\tconst walletId = adapter.getWalletId(source);\n\t\t\t\t\t\tconst connection = connections.get(walletId);\n\t\t\t\t\t\tconst connected =\n\t\t\t\t\t\t\tconnection?.status === \"connected\" ? connection : undefined;\n\t\t\t\t\t\treturn adapter.buildWallet({\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\twalletId,\n\t\t\t\t\t\t\thandle: connected?.handle,\n\t\t\t\t\t\t\tstatus: connection?.status ?? \"disconnected\",\n\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\tconnection?.status === \"disconnected\"\n\t\t\t\t\t\t\t\t\t? connection.error\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tisConnected: connected !== undefined,\n\t\t\t\t\t\t\tconnect: (options) => connect(source, walletId, options),\n\t\t\t\t\t\t\tdisconnect: () => disconnect(source, walletId),\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tdistinctUntilChanged(walletsEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tteardown.abort();\n\t\t\tfor (const connection of connections$.value.values())\n\t\t\t\tif (connection.status === \"connecting\") connection.abort();\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n"],"mappings":"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"}
1
+ {"version":3,"file":"injectedWallets-BQBgS-f0.js","names":["abortedError","Observable","BehaviorSubject","toConnectError","combineLatest","tap","map","distinctUntilChanged","shareReplay"],"sources":["../src/api/injectedWallets.ts"],"sourcesContent":["import {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n\ttap,\n} from \"rxjs\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport { abortedError, type KheopskitError, toConnectError } from \"./errors\";\nimport type { KheopskitStore } from \"./store\";\nimport type { BaseWallet, ConnectOptions, WalletStatus } from \"./types\";\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n * Shared by every platform's injected-wallets stream.\n */\nconst walletsEqual = <\n\tW extends Pick<BaseWallet, \"id\" | \"status\" | \"error\" | \"name\">,\n>(\n\ta: W[],\n\tb: W[],\n): boolean => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(w, i) =>\n\t\t\tw.id === b[i]?.id &&\n\t\t\tw.status === b[i]?.status &&\n\t\t\tw.error === b[i]?.error &&\n\t\t\tw.name === b[i]?.name,\n\t);\n};\n\n/**\n * The platform-specific surface of an injected-wallets stream. Everything else\n * — the connect/disconnect state machine, the connected-ids bookkeeping, the\n * store persistence, change detection and sharing — is owned by\n * {@link createInjectedWallets$}.\n *\n * @typeParam TSource - a wallet as the platform's registry reports it\n * @typeParam TWallet - the platform's wallet type\n * @typeParam THandle - live connection handle retained while connected\n */\nexport type InjectedWalletsAdapter<\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n> = {\n\t/** Live registry of the platform's injected wallets (emits `[]` during SSR). */\n\tsources$: Observable<readonly TSource[]>;\n\t/** Stable wallet id for a registry entry. */\n\tgetWalletId: (source: TSource) => WalletId;\n\t/**\n\t * Platform connect call. The resolved value is retained as the wallet's\n\t * live handle until disconnect.\n\t */\n\tconnect: (source: TSource, walletId: WalletId) => Promise<THandle>;\n\t/** `true` maps the platform's rejection to `USER_REJECTED`; absent means never. */\n\tisUserRejection?: (error: unknown) => boolean;\n\treleaseAbandonedHandle?: (handle: THandle, walletId: WalletId) => void;\n\t/**\n\t * Optional platform disconnect call, awaited before local state clears so a\n\t * failed disconnect rejects without desyncing the connected list.\n\t */\n\tdisconnect?: (source: TSource, walletId: WalletId) => Promise<void>;\n\t/**\n\t * Runs after a disconnect fully applied — the place to drop cached account\n\t * observables so a later reconnect rebuilds them against a fresh handle.\n\t */\n\tonDisconnected?: (walletId: WalletId) => void;\n\t/** Build the platform wallet object for one registry entry. */\n\tbuildWallet: (args: {\n\t\tsource: TSource;\n\t\twalletId: WalletId;\n\t\t/** Live connection handle; `undefined` while disconnected. */\n\t\thandle: THandle | undefined;\n\t\tstatus: WalletStatus;\n\t\terror: KheopskitError | undefined;\n\t\tisConnected: boolean;\n\t\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t\tdisconnect: () => Promise<void>;\n\t}) => TWallet;\n};\n\ntype Connecting = {\n\tstatus: \"connecting\";\n\tpromise: Promise<void>;\n\tanchored: boolean;\n\twaiting: number;\n\tanswered: boolean;\n\tabort: () => void;\n};\n\ntype Connection<THandle> =\n\t| Connecting\n\t| { status: \"connected\"; handle: THandle; disconnecting?: Promise<void> }\n\t| { status: \"disconnected\"; error: KheopskitError };\n\nconst join = (\n\tconnecting: Connecting,\n\twalletId: WalletId,\n\tsignal: AbortSignal | undefined,\n): Promise<void> => {\n\tif (!signal) {\n\t\tconnecting.anchored = true;\n\t\treturn connecting.promise;\n\t}\n\tconnecting.waiting++;\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst leave = () => {\n\t\t\tif (connecting.answered) return;\n\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\tconnecting.waiting--;\n\t\t\tif (!connecting.anchored && connecting.waiting === 0) connecting.abort();\n\t\t};\n\t\tsignal.addEventListener(\"abort\", leave, { once: true });\n\t\tconnecting.promise\n\t\t\t.then(resolve, reject)\n\t\t\t.finally(() => signal.removeEventListener(\"abort\", leave));\n\t});\n};\n\n/**\n * The shared engine behind every platform's injected-wallets stream: tracks\n * each wallet's connection (pending attempt or live handle), shares one\n * in-flight connect per wallet, persists connected ids to the store for\n * auto-reconnect, and re-emits the wallet list whenever the registry or\n * connection state changes.\n */\nexport const createInjectedWallets$ = <\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n>(\n\tstore: KheopskitStore,\n\tadapter: InjectedWalletsAdapter<TSource, TWallet, THandle>,\n): Observable<TWallet[]> =>\n\tnew Observable<TWallet[]>((subscriber) => {\n\t\tconst connections$ = new BehaviorSubject<\n\t\t\tReadonlyMap<WalletId, Connection<THandle>>\n\t\t>(new Map());\n\t\tconst teardown = new AbortController();\n\t\tlet present = new Set<WalletId>();\n\n\t\tconst abortConnectsOfSourcesThatLeft = (sources: readonly TSource[]) => {\n\t\t\tpresent = new Set(sources.map((source) => adapter.getWalletId(source)));\n\t\t\tfor (const [walletId, connection] of connections$.value)\n\t\t\t\tif (connection.status === \"connecting\" && !present.has(walletId))\n\t\t\t\t\tconnection.abort();\n\t\t};\n\n\t\tconst setConnection = (\n\t\t\twalletId: WalletId,\n\t\t\tconnection: Connection<THandle> | undefined,\n\t\t) => {\n\t\t\tconst next = new Map(connections$.value);\n\t\t\tif (connection) next.set(walletId, connection);\n\t\t\telse next.delete(walletId);\n\t\t\tconnections$.next(next);\n\t\t};\n\n\t\tconst startConnect = (\n\t\t\tsource: TSource,\n\t\t\twalletId: WalletId,\n\t\t\tsignal: AbortSignal | undefined,\n\t\t): Promise<void> => {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst promise = new Promise<void>((resolve, reject) => {\n\t\t\t\tcontroller.signal.addEventListener(\n\t\t\t\t\t\"abort\",\n\t\t\t\t\t() => {\n\t\t\t\t\t\tsetConnection(walletId, undefined);\n\t\t\t\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true },\n\t\t\t\t);\n\t\t\t\tnew Promise<THandle>((res) =>\n\t\t\t\t\tres(adapter.connect(source, walletId)),\n\t\t\t\t).then(\n\t\t\t\t\t(handle) => {\n\t\t\t\t\t\tconnecting.answered = true;\n\t\t\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\t\t\tadapter.releaseAbandonedHandle?.(handle, walletId);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetConnection(walletId, { status: \"connected\", handle });\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t\tstore.rememberWallet(walletId);\n\t\t\t\t\t},\n\t\t\t\t\t(error) => {\n\t\t\t\t\t\tconnecting.answered = true;\n\t\t\t\t\t\tif (controller.signal.aborted) return;\n\t\t\t\t\t\tconst connectError = toConnectError(\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\twalletId,\n\t\t\t\t\t\t\tadapter.isUserRejection ?? (() => false),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsetConnection(walletId, {\n\t\t\t\t\t\t\tstatus: \"disconnected\",\n\t\t\t\t\t\t\terror: connectError,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treject(connectError);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t\tconst connecting: Connecting = {\n\t\t\t\tstatus: \"connecting\",\n\t\t\t\tpromise,\n\t\t\t\tanchored: false,\n\t\t\t\twaiting: 0,\n\t\t\t\tanswered: false,\n\t\t\t\tabort: () => {\n\t\t\t\t\tif (connections$.value.get(walletId) === connecting)\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t},\n\t\t\t};\n\t\t\tsetConnection(walletId, connecting);\n\t\t\treturn join(connecting, walletId, signal);\n\t\t};\n\n\t\tconst untilSettled = (\n\t\t\tdisconnecting: Promise<void>,\n\t\t\twalletId: WalletId,\n\t\t\tsignal: AbortSignal | undefined,\n\t\t): Promise<void> =>\n\t\t\tnew Promise<void>((resolve, reject) => {\n\t\t\t\tconst signals = signal ? [teardown.signal, signal] : [teardown.signal];\n\t\t\t\tconst settle = () => {\n\t\t\t\t\tfor (const s of signals) s.removeEventListener(\"abort\", settle);\n\t\t\t\t\tif (signals.some((s) => s.aborted))\n\t\t\t\t\t\treject(abortedError(walletId, \"connect\"));\n\t\t\t\t\telse resolve();\n\t\t\t\t};\n\t\t\t\tif (signals.some((s) => s.aborted)) return settle();\n\t\t\t\tfor (const s of signals)\n\t\t\t\t\ts.addEventListener(\"abort\", settle, { once: true });\n\t\t\t\tdisconnecting.then(settle, settle);\n\t\t\t});\n\n\t\tconst connect = (\n\t\t\tsource: TSource,\n\t\t\twalletId: WalletId,\n\t\t\toptions?: ConnectOptions,\n\t\t): Promise<void> => {\n\t\t\tif (teardown.signal.aborted || !present.has(walletId))\n\t\t\t\treturn Promise.reject(abortedError(walletId, \"connect\"));\n\t\t\tconst current = connections$.value.get(walletId);\n\t\t\tif (current?.status === \"connected\") {\n\t\t\t\tif (!current.disconnecting) return Promise.resolve();\n\t\t\t\treturn untilSettled(\n\t\t\t\t\tcurrent.disconnecting,\n\t\t\t\t\twalletId,\n\t\t\t\t\toptions?.signal,\n\t\t\t\t).then(() => connect(source, walletId, options));\n\t\t\t}\n\t\t\tif (options?.signal?.aborted)\n\t\t\t\treturn Promise.reject(abortedError(walletId, \"connect\"));\n\t\t\tif (current?.status === \"connecting\")\n\t\t\t\treturn join(current, walletId, options?.signal);\n\t\t\treturn startConnect(source, walletId, options?.signal);\n\t\t};\n\n\t\tconst disconnect = (source: TSource, walletId: WalletId): Promise<void> => {\n\t\t\tconst current = connections$.value.get(walletId);\n\t\t\tstore.forgetWallet(walletId);\n\t\t\tif (!current || current.status === \"disconnected\")\n\t\t\t\treturn Promise.resolve();\n\t\t\tif (current.status === \"connecting\") {\n\t\t\t\tcurrent.abort();\n\t\t\t\treturn Promise.resolve();\n\t\t\t}\n\t\t\tif (current.disconnecting) return current.disconnecting;\n\n\t\t\tconst disconnecting = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait adapter.disconnect?.(source, walletId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!teardown.signal.aborted) {\n\t\t\t\t\t\tsetConnection(walletId, {\n\t\t\t\t\t\t\tstatus: \"connected\",\n\t\t\t\t\t\t\thandle: current.handle,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tstore.rememberWallet(walletId);\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (teardown.signal.aborted) return;\n\t\t\t\tsetConnection(walletId, undefined);\n\t\t\t\tadapter.onDisconnected?.(walletId);\n\t\t\t})();\n\t\t\tsetConnection(walletId, { ...current, disconnecting });\n\t\t\treturn disconnecting;\n\t\t};\n\n\t\tconst sub = combineLatest([adapter.sources$, connections$])\n\t\t\t.pipe(\n\t\t\t\ttap(([sources]) => abortConnectsOfSourcesThatLeft(sources)),\n\t\t\t\tmap(([sources, connections]) =>\n\t\t\t\t\tsources.map((source): TWallet => {\n\t\t\t\t\t\tconst walletId = adapter.getWalletId(source);\n\t\t\t\t\t\tconst connection = connections.get(walletId);\n\t\t\t\t\t\tconst connected =\n\t\t\t\t\t\t\tconnection?.status === \"connected\" ? connection : undefined;\n\t\t\t\t\t\treturn adapter.buildWallet({\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\twalletId,\n\t\t\t\t\t\t\thandle: connected?.handle,\n\t\t\t\t\t\t\tstatus: connection?.status ?? \"disconnected\",\n\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\tconnection?.status === \"disconnected\"\n\t\t\t\t\t\t\t\t\t? connection.error\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tisConnected: connected !== undefined,\n\t\t\t\t\t\t\tconnect: (options) => connect(source, walletId, options),\n\t\t\t\t\t\t\tdisconnect: () => disconnect(source, walletId),\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tdistinctUntilChanged(walletsEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tteardown.abort();\n\t\t\tfor (const connection of connections$.value.values())\n\t\t\t\tif (connection.status === \"connecting\") connection.abort();\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n"],"mappings":"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"}
@@ -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-DCaL9bIc.mjs";
2
+ import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-C3I3w0jb.mjs";
3
3
  import { n as clearCachedObservable, r as clearCachedObservablesByPrefix } from "./getCachedObservable-LUq9IfEx.mjs";
4
4
  //#region src/utils/hydrateState.d.ts
5
5
  /**
@@ -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-DCaL9bIc.js";
2
+ import { a as CachedAccount, b as WalletConnectWallet, i as BaseWalletAccount, o as CachedWallet, r as BaseWallet } from "./types-C3I3w0jb.js";
3
3
  import { n as clearCachedObservable, r as clearCachedObservablesByPrefix } from "./getCachedObservable-LUq9IfEx.js";
4
4
  //#region src/utils/hydrateState.d.ts
5
5
  /**
@@ -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-DCaL9bIc.mjs";
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-C3I3w0jb.mjs";
2
2
  import { InjectedPolkadotAccount, SignPayload } from "polkadot-api/pjs-signer";
3
3
  //#region src/utils/isSs58Address.d.ts
4
4
  /**
@@ -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-DCaL9bIc.js";
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-C3I3w0jb.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
@@ -25,10 +25,10 @@ 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
27
  const require_registryReads = require("./registryReads-BpHsWLd7.js");
28
- const require_injectedWallets = require("./injectedWallets-Dy8YGKL-.js");
28
+ const require_injectedWallets = require("./injectedWallets-BQBgS-f0.js");
29
29
  let _scure_base = require("@scure/base");
30
- let rxjs = require("rxjs");
31
30
  let lodash_es = require("lodash-es");
31
+ let rxjs = require("rxjs");
32
32
  let polkadot_api_pjs_signer = require("polkadot-api/pjs-signer");
33
33
  polkadot_api_pjs_signer = __toESM(polkadot_api_pjs_signer);
34
34
  //#region src/api/polkadot/wallets.ts
package/dist/polkadot.mjs CHANGED
@@ -2,10 +2,10 @@ import { f as parseWalletId, n as isWalletConnectWallet, o as isRefusalMessage,
2
2
  import { a as getWalletConnectSessionAccounts$, i as getSessionCaip10s, l as isSs58Address, o as getWalletAccountId, r as getCaip10Addresses, t as createPlatformAccounts$ } from "./platformAccounts-yyRUrnel.mjs";
3
3
  import { t as POLKADOT_EXTENSIONS } from "./polkadotExtensions-BoVKhNU_.mjs";
4
4
  import { t as createRegistryReads$ } from "./registryReads-BvtznSo3.mjs";
5
- import { t as createInjectedWallets$ } from "./injectedWallets-48L-AL1I.mjs";
5
+ import { t as createInjectedWallets$ } from "./injectedWallets-5GL1Jder.mjs";
6
6
  import { hex } from "@scure/base";
7
- import { Observable, distinctUntilChanged, map, of } from "rxjs";
8
7
  import { isEqual } from "lodash-es";
8
+ import { Observable, distinctUntilChanged, map, of } from "rxjs";
9
9
  import * as pjs from "polkadot-api/pjs-signer";
10
10
  import { getInjectedExtensions } from "polkadot-api/pjs-signer";
11
11
  //#region src/api/polkadot/wallets.ts
package/dist/solana.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-DCaL9bIc.mjs";
1
+ import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-C3I3w0jb.mjs";
2
2
  import { MessageModifyingSigner, TransactionModifyingSigner, TransactionSendingSigner } from "@solana/kit";
3
3
  import { Wallet } from "@wallet-standard/base";
4
4
  //#region src/utils/isSolanaAddress.d.ts
package/dist/solana.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-DCaL9bIc.js";
1
+ import { E as isWalletConnectWallet, N as WalletAccountId, T as isInjectedWallet, b as WalletConnectWallet, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, p as Placeholder, r as BaseWallet } from "./types-C3I3w0jb.js";
2
2
  import { MessageModifyingSigner, TransactionModifyingSigner, TransactionSendingSigner } from "@solana/kit";
3
3
  import { Wallet } from "@wallet-standard/base";
4
4
  //#region src/utils/isSolanaAddress.d.ts
package/dist/solana.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_types = require("./types-BWHvNFlN.js");
3
3
  const require_platformAccounts = require("./platformAccounts-BjIeRcFN.js");
4
- const require_injectedWallets = require("./injectedWallets-Dy8YGKL-.js");
4
+ const require_injectedWallets = require("./injectedWallets-BQBgS-f0.js");
5
5
  let rxjs = require("rxjs");
6
6
  let _solana_kit = require("@solana/kit");
7
7
  let _wallet_standard_app = require("@wallet-standard/app");
package/dist/solana.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _ as getCachedObservable$, a as isEip1193UserRejection, g as clearCachedObservablesByPrefix, n as isWalletConnectWallet, o as isRefusalMessage, r as KheopskitError, t as isInjectedWallet, u as getWalletId } from "./types-Yor672md.mjs";
2
2
  import { a as getWalletConnectSessionAccounts$, i as getSessionCaip10s, o as getWalletAccountId, r as getCaip10Addresses, t as createPlatformAccounts$, u as isSolanaAddress } from "./platformAccounts-yyRUrnel.mjs";
3
- import { t as createInjectedWallets$ } from "./injectedWallets-48L-AL1I.mjs";
3
+ import { t as createInjectedWallets$ } from "./injectedWallets-5GL1Jder.mjs";
4
4
  import { Observable, of, shareReplay } from "rxjs";
5
5
  import { address, getBase58Decoder, getBase58Encoder, getBase64Decoder, getBase64Encoder, getTransactionDecoder, getTransactionEncoder } from "@solana/kit";
6
6
  import { getWallets } from "@wallet-standard/app";
@@ -1,5 +1,5 @@
1
1
  import { t as SyncableStorage } from "./storage-D3AwNgqc.mjs";
2
- import { S as WalletPlatform, a as CachedAccount, g as PolkadotAccountType, o as CachedWallet } from "./types-DCaL9bIc.mjs";
2
+ import { S as WalletPlatform, a as CachedAccount, g as PolkadotAccountType, o as CachedWallet } from "./types-C3I3w0jb.mjs";
3
3
  //#region src/testing/cachedState.d.ts
4
4
  type InjectedWalletId = `${WalletPlatform}:${string}`;
5
5
  type CachedInjectedWallet = CachedWallet & {
package/dist/testing.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as SyncableStorage } from "./storage-D3AwNgqc.js";
2
- import { S as WalletPlatform, a as CachedAccount, g as PolkadotAccountType, o as CachedWallet } from "./types-DCaL9bIc.js";
2
+ import { S as WalletPlatform, a as CachedAccount, g as PolkadotAccountType, o as CachedWallet } from "./types-C3I3w0jb.js";
3
3
  //#region src/testing/cachedState.d.ts
4
4
  type InjectedWalletId = `${WalletPlatform}:${string}`;
5
5
  type CachedInjectedWallet = CachedWallet & {
@@ -1 +1 @@
1
- {"version":3,"file":"types-BWHvNFlN.js","names":[],"sources":["../src/utils/getCachedObservable.ts","../src/utils/isWalletPlatform.ts","../src/utils/WalletId.ts","../src/api/errors.ts","../src/api/types.ts"],"sourcesContent":["import type { Observable } from \"rxjs\";\n\n// Anchored on globalThis so the cache stays a single instance even if the\n// module is duplicated across bundle chunks (e.g. CJS subpath entries).\nconst CACHE_SYMBOL = Symbol.for(\"kheopskit.observableCache\");\n\nconst getCache = (): Map<string, Observable<unknown>> => {\n\tconst g = globalThis as unknown as Record<\n\t\tsymbol,\n\t\tMap<string, Observable<unknown>> | undefined\n\t>;\n\tlet cache = g[CACHE_SYMBOL];\n\tif (!cache) {\n\t\tcache = new Map();\n\t\tg[CACHE_SYMBOL] = cache;\n\t}\n\treturn cache;\n};\n\nexport const getCachedObservable$ = <T, Obs = Observable<T>>(\n\tkey: string,\n\tcreate: () => Obs,\n): Obs => {\n\tconst cache = getCache();\n\tif (!cache.has(key)) cache.set(key, create() as Observable<unknown>);\n\n\treturn cache.get(key) as Obs;\n};\n\n/**\n * Clears an observable from the cache.\n * Use when a wallet disconnects or configuration changes.\n */\nexport const clearCachedObservable = (key: string): void => {\n\tgetCache().delete(key);\n};\n\n/**\n * Clears all cached observables whose key starts with `prefix`.\n *\n * Used to drop a wallet's account observables when it disconnects, so a later\n * reconnect rebuilds them against the current wallet handle instead of a stale\n * closure — and to keep the cache from growing unbounded across connect cycles.\n */\nexport const clearCachedObservablesByPrefix = (prefix: string): void => {\n\tconst cache = getCache();\n\tfor (const key of cache.keys()) {\n\t\tif (key.startsWith(prefix)) cache.delete(key);\n\t}\n};\n\n/**\n * Clears all cached observables.\n * Use when resetting the entire kheopskit state.\n */\nexport const clearAllCachedObservables = (): void => {\n\tgetCache().clear();\n};\n","import type { WalletPlatform } from \"../api/types\";\n\nexport const isWalletPlatform = (\n\tplatform: unknown,\n): platform is WalletPlatform =>\n\ttypeof platform === \"string\" &&\n\t[\"polkadot\", \"ethereum\", \"solana\"].includes(platform as WalletPlatform);\n","import type { WalletPlatform } from \"../api/types\";\nimport { isWalletPlatform } from \"./isWalletPlatform\";\n\nexport type WalletId = string;\n\n/**\n * Stable id of the single WalletConnect connector. It is platform-less: one WC\n * session spans whichever namespaces the wallet approves, so it isn't tied to a\n * platform (unlike injected wallet ids, which are `<platform>:<identifier>`).\n */\nexport const WALLET_CONNECT_WALLET_ID: WalletId = \"walletconnect\";\n\nexport const getWalletId = (\n\tplatform: WalletPlatform,\n\tidentifier: string,\n): WalletId => {\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid name\");\n\treturn `${platform}:${identifier}`;\n};\n\nexport const parseWalletId = (walletId: string) => {\n\tif (!walletId) throw new Error(\"Invalid walletId\");\n\tconst [platform, identifier] = walletId.split(\":\");\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid address\");\n\treturn { platform, identifier };\n};\n\n/**\n * Non-throwing variant of {@link parseWalletId}. Use when validating untrusted\n * input (e.g. cached state persisted by an older version) before parsing.\n */\nexport const isValidWalletId = (walletId: unknown): walletId is WalletId => {\n\tif (typeof walletId !== \"string\" || !walletId) return false;\n\tif (walletId === WALLET_CONNECT_WALLET_ID) return true;\n\tconst [platform, identifier] = walletId.split(\":\");\n\treturn isWalletPlatform(platform) && !!identifier;\n};\n","import type { WalletId } from \"../utils/WalletId\";\n\n/**\n * Stable error codes thrown by kheopskit. Catch a {@link KheopskitError} and\n * branch on `error.code` instead of matching message strings.\n */\nexport type KheopskitErrorCode =\n\t/**\n\t * This `connect()` or `disconnect()` call was abandoned. For `connect()`:\n\t * its `signal` fired before the platform answered, `disconnect()` was\n\t * called while it pended, its wallet disappeared, or the last `kheopskit$`\n\t * subscriber unsubscribed.\n\t * For either call on an injected wallet: the wallet object came from a\n\t * subscription that had already ended, in which case the call rejects\n\t * without asking the platform and without changing the remembered list. A\n\t * placeholder's `connect()` rejects the same way, its `disconnect()`\n\t * resolves, and the WalletConnect connector still calls AppKit.\n\t */\n\t| \"ABORTED\"\n\t/** The user refused the wallet's connect prompt. `cause` holds the platform error. */\n\t| \"USER_REJECTED\"\n\t/** The wallet's connect call failed for another reason. `cause` holds the platform error. */\n\t| \"CONNECT_FAILED\"\n\t/**\n\t * `connect()` was called on a placeholder wallet restored from the cache:\n\t * on `kheopskit$`, hydration ended without kheopskit discovering that\n\t * wallet; on `getHydratedSnapshot` and the React provider's initial\n\t * snapshot, always.\n\t */\n\t| \"WALLET_PENDING\"\n\t/** The wallet does not advertise a capability kheopskit needs to proceed. */\n\t| \"FEATURE_NOT_SUPPORTED\"\n\t/** No active WalletConnect session for the requested operation. */\n\t| \"NO_SESSION\"\n\t/** No provider available for the requested namespace. */\n\t| \"NO_PROVIDER\"\n\t/** The installed polkadot-api version exposes neither `getTxCreatorFromPjs` (v3) nor `getPolkadotSignerFromPjs` (v2). */\n\t| \"UNSUPPORTED_VERSION\"\n\t/** The requested chain cannot be used for this operation (e.g. a Solana cluster with no CAIP-2 id over WalletConnect). */\n\t| \"UNSUPPORTED_CHAIN\"\n\t/** `getKheopskit$` received a config value it cannot use. The message names the fix. */\n\t| \"INVALID_CONFIG\";\n\n/**\n * Error thrown by kheopskit wallet/account operations. Carries a stable\n * {@link KheopskitErrorCode} and, when relevant, the offending wallet id.\n *\n * @example\n * ```ts\n * try {\n * await wallet.connect();\n * } catch (error) {\n * if (error instanceof KheopskitError && error.code === \"USER_REJECTED\") {\n * // the user closed or refused the wallet prompt\n * } else throw error;\n * }\n * ```\n */\nexport class KheopskitError extends Error {\n\treadonly code: KheopskitErrorCode;\n\t/** The wallet id this error relates to, when applicable. */\n\treadonly walletId?: WalletId;\n\n\tconstructor(\n\t\tcode: KheopskitErrorCode,\n\t\tmessage: string,\n\t\toptions?: { walletId?: WalletId; cause?: unknown },\n\t) {\n\t\tsuper(`[kheopskit] ${message}`, { cause: options?.cause });\n\t\tthis.name = \"KheopskitError\";\n\t\tthis.code = code;\n\t\tthis.walletId = options?.walletId;\n\t}\n}\n\nexport const abortedError = (\n\twalletId: WalletId,\n\toperation: \"connect\" | \"disconnect\",\n): KheopskitError =>\n\tnew KheopskitError(\n\t\t\"ABORTED\",\n\t\t`${operation} of wallet ${walletId} was aborted`,\n\t\t{ walletId },\n\t);\n\nexport const walletPendingError = (walletId: WalletId): KheopskitError =>\n\tnew KheopskitError(\n\t\t\"WALLET_PENDING\",\n\t\t`wallet ${walletId} was not discovered before hydration ended`,\n\t\t{ walletId },\n\t);\n\nexport const toConnectError = (\n\terror: unknown,\n\twalletId: WalletId,\n\tisUserRejection: (error: unknown) => boolean,\n): KheopskitError => {\n\tif (error instanceof KheopskitError) return error;\n\treturn isUserRejection(error)\n\t\t? new KheopskitError(\n\t\t\t\t\"USER_REJECTED\",\n\t\t\t\t`the user rejected the connect request of wallet ${walletId}`,\n\t\t\t\t{ walletId, cause: error },\n\t\t\t)\n\t\t: new KheopskitError(\n\t\t\t\t\"CONNECT_FAILED\",\n\t\t\t\t`wallet ${walletId} failed to connect`,\n\t\t\t\t{ walletId, cause: error },\n\t\t\t);\n};\n\nconst EIP1193_USER_REJECTED_REQUEST = 4001;\n\nexport const isEip1193UserRejection = (error: unknown): boolean =>\n\ttypeof error === \"object\" &&\n\terror !== null &&\n\t(error as { code?: unknown }).code === EIP1193_USER_REJECTED_REQUEST;\n\ntype RefusalMessage = {\n\tpattern: RegExp;\n\twallet: string;\n\tevidence: \"live\" | \"inferred\";\n};\n\n/**\n * How Polkadot extensions and Wallet Standard wallets reject a refused connect\n * prompt. They send a plain `Error`, so the message is the only signal.\n * `evidence` records whether the row was observed live or inferred from the\n * wallet's source or documentation.\n */\nconst REFUSAL_MESSAGES: readonly RefusalMessage[] = [\n\t{\n\t\tpattern: /^Site .+ has not been authorised for Talisman yet$/,\n\t\twallet: \"Talisman 3.11.0, Reject button or prompt window closed\",\n\t\tevidence: \"live\",\n\t},\n\t{\n\t\tpattern: /^Connection request was (rejected|cancelled) by the user\\.$/,\n\t\twallet: \"polkadot-js extension (extension-base 0.64 State.ts)\",\n\t\tevidence: \"inferred\",\n\t},\n\t{\n\t\tpattern: /^(Rejected|Cancelled)$/,\n\t\twallet: \"SubWallet (Extension.ts)\",\n\t\tevidence: \"inferred\",\n\t},\n\t{\n\t\tpattern: /^User rejected the request\\.$/,\n\t\twallet: \"Phantom (Wallet Standard)\",\n\t\tevidence: \"inferred\",\n\t},\n];\n\nexport const isRefusalMessage = (error: unknown): boolean => {\n\tconst message = (error as { message?: unknown } | null | undefined)?.message;\n\treturn (\n\t\ttypeof message === \"string\" &&\n\t\tREFUSAL_MESSAGES.some((row) => row.pattern.test(message))\n\t);\n};\n","import type { Observable } from \"rxjs\";\nimport type { WalletAccountId } from \"../utils\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport type { KheopskitError } from \"./errors\";\n\nexport type WalletPlatform = \"polkadot\" | \"ethereum\" | \"solana\";\n\n/**\n * Minimal structural view of a WalletConnect `UniversalProvider`, the subset\n * kheopskit reads. Declared locally so core never depends on\n * `@walletconnect/universal-provider`. The concrete instance comes from\n * `@reown/appkit` at runtime.\n */\nexport type WalletConnectProvider = {\n\tsession?: {\n\t\ttopic: string;\n\t\tnamespaces: Record<string, { accounts?: string[] }>;\n\t};\n\tclient: {\n\t\trequest<T = unknown>(args: {\n\t\t\ttopic: string;\n\t\t\tchainId: string;\n\t\t\trequest: { method: string; params: unknown };\n\t\t}): Promise<T>;\n\t};\n\trequest(args: { method: string; params?: unknown }): Promise<unknown>;\n\ton(event: string, listener: (...args: unknown[]) => void): void;\n\toff(event: string, listener: (...args: unknown[]) => void): void;\n};\n\n/**\n * Minimal structural view of the Reown AppKit instance, the subset kheopskit's\n * account factories use. Exposed as the `appKit` escape hatch on AppKit wallets;\n * cast it to `@reown/appkit`'s `AppKit` type for the full API. Declared locally\n * so core never depends on `@reown/appkit`'s types (it's an optional peer).\n */\nexport type AppKitInstance = {\n\tgetProvider<T = WalletConnectProvider>(namespace: string): T | undefined;\n\tgetAccount(\n\t\tnamespace: string,\n\t): { allAccounts: { address: string }[] } | undefined;\n\tgetCaipNetworks(namespace: string): { caipNetworkId?: string }[];\n};\n\nexport type WalletType = \"injected\" | \"walletconnect\";\n\n/**\n * Where a wallet stands with the dapp. `connecting` covers a `connect()` call\n * in flight and an auto-reconnect in flight alike.\n */\nexport type WalletStatus = \"disconnected\" | \"connecting\" | \"connected\";\n\nexport type PolkadotAccountType = \"sr25519\" | \"ed25519\" | \"ecdsa\" | \"ethereum\";\n\n/** Options accepted by {@link BaseWallet.connect}. */\nexport type ConnectOptions = {\n\t/**\n\t * Ends this caller's wait for the platform's answer: its promise rejects\n\t * with a `KheopskitError` of code `ABORTED`. An abort after the platform\n\t * has granted the connect changes nothing, and a Polkadot extension counts\n\t * as granted only once its account list has been read. Other callers\n\t * sharing the attempt keep waiting. The extension's own prompt may stay\n\t * open: nothing can withdraw it from the page. A Polkadot `connect()`\n\t * started while that prompt is open waits for it instead of asking again,\n\t * and connects with the handle it answers. Once no caller waits any more\n\t * and no later `connect()` joined that prompt, kheopskit drops a handle\n\t * the platform hands back afterwards without revoking the platform's\n\t * grant, and the wallet is neither connected nor remembered. Kheopskit\n\t * sets no timeout of its own, because an extension prompt\n\t * pends only while the user has not answered it; pass\n\t * `AbortSignal.timeout(ms)` to cap the wait.\n\t */\n\tsignal?: AbortSignal;\n};\n\n/**\n * SDK-free fields common to every wallet, regardless of platform. Platform\n * packages (`@kheopskit/core/<platform>`) extend this with SDK-typed fields\n * (the injected provider/extension/standard-wallet handle).\n */\nexport type BaseWallet = {\n\t/** `<platform>:<identifier>`, e.g. `polkadot:talisman`. Stable across reloads. */\n\tid: WalletId;\n\t/** The platform whose registry listed the wallet. */\n\tplatform: WalletPlatform;\n\t/**\n\t * `\"injected\"`, for a browser extension or Wallet Standard wallet. The\n\t * WalletConnect connector is the separate {@link WalletConnectWallet}.\n\t */\n\ttype: WalletType;\n\t/** Display name, e.g. `Talisman`. */\n\tname: string;\n\t/** Icon URL or data URI. `\"\"` when the wallet exposes none. */\n\ticon: string;\n\t/**\n\t * `true` for a wallet restored from the cache that kheopskit has not\n\t * discovered yet: its SDK handle and `sourceId` are absent and it is never\n\t * connected. On `kheopskit$` its `connect()` waits for the live wallet and\n\t * connects that one, rejecting with `WALLET_PENDING` if hydration ends first\n\t * and `ABORTED` if its `signal` fires or the subscription ends. On\n\t * `getHydratedSnapshot` it rejects with `WALLET_PENDING`. Its `disconnect()`\n\t * resolves at once. Set on every wallet of `kheopskit$` and of the hydrated\n\t * snapshot; plugins leave it unset.\n\t */\n\tisPlaceholder?: boolean;\n\t/**\n\t * `connecting` while a `connect()` call or an auto-reconnect waits for the\n\t * platform, `connected` once the platform granted it, `disconnected`\n\t * otherwise. On a reload, a remembered wallet kheopskit will reconnect is\n\t * `connecting` from the first frame when the cache recorded it connected,\n\t * which the cache does 1 s after the state settles.\n\t */\n\tstatus: WalletStatus;\n\t/**\n\t * The last `connect()` or auto-reconnect that the platform refused or\n\t * failed (`USER_REJECTED` or `CONNECT_FAILED`, or `FEATURE_NOT_SUPPORTED`\n\t * for a Wallet Standard wallet without `standard:connect`). Cleared when\n\t * the next attempt starts. An aborted attempt sets nothing.\n\t */\n\terror?: KheopskitError;\n\t/** `status === \"connected\"`. */\n\tisConnected: boolean;\n\t/**\n\t * Connects the wallet.\n\t *\n\t * - **Shared in flight.** Concurrent calls on one wallet share a single\n\t * platform attempt and the platform is asked once. Each call gets its own\n\t * promise: aborting a caller's `signal` rejects only that caller with code\n\t * `ABORTED`. The attempt itself is abandoned only when every caller that\n\t * passed a signal has aborted and no caller without one joined, when\n\t * `disconnect()` is called, or when the last `kheopskit$` subscriber\n\t * unsubscribes; those reject every remaining caller with `ABORTED`.\n\t * - **Idempotent.** On a connected wallet it resolves at once without\n\t * touching the platform, unless a `disconnect()` still waits for the\n\t * platform. It then waits for that disconnect to settle and connects\n\t * again if the wallet ended up disconnected.\n\t * - **Abortable.** See {@link ConnectOptions.signal}. There is no default\n\t * timeout.\n\t * - **Settles with the state.** It resolves only after `kheopskit$` has\n\t * emitted a state in which this wallet has `isConnected: true`, so the\n\t * consumer-visible state already reflects the connect. On platforms that\n\t * list accounts asynchronously (Ethereum `eth_accounts`), the accounts may\n\t * arrive in a later emission. No emission shows a disconnected wallet\n\t * still listing live accounts, or a connected wallet listing the accounts\n\t * of a previous connection. During hydration a wallet's cached\n\t * placeholder accounts stay listed whatever its status. Another wallet's\n\t * pending `eth_accounts` request never delays them. A `disconnect()` that\n\t * completes while it waits for that state rejects it with `ABORTED`. If\n\t * the platform's disconnect is still pending or refuses, it resolves once\n\t * the state shows the wallet connected (today only Solana has a platform\n\t * disconnect). A `connect()`\n\t * whose wallet disappears before the platform grants it (an extension\n\t * removed, a Wallet Standard wallet unregistered) rejects `ABORTED`;\n\t * granted first, it resolves and the wallet stays remembered. Once the last `kheopskit$`\n\t * subscriber has unsubscribed, a call on a wallet object from that\n\t * subscription rejects with `ABORTED` without asking the platform,\n\t * placeholders included.\n\t * - **Typed rejections.** A platform rejection is wrapped in a\n\t * `KheopskitError` carrying the original error as `cause` and the\n\t * `walletId`: `USER_REJECTED` when the user refused the prompt,\n\t * `CONNECT_FAILED` otherwise. A Wallet Standard wallet without\n\t * `standard:connect` rejects with `FEATURE_NOT_SUPPORTED`.\n\t */\n\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t/**\n\t * Disconnects the wallet.\n\t *\n\t * On a disconnected wallet it resolves at once. While a `connect()` waits\n\t * for the platform to grant it, it aborts that connect (its promise rejects\n\t * with `ABORTED`) and never waits for the extension prompt. Otherwise it\n\t * first waits for the platform's disconnect and rejects if that fails, so\n\t * callers can surface or retry. It then resolves once `kheopskit$` has\n\t * emitted a state in which this wallet has `isConnected: false`, or once a\n\t * later `connect()`, the wallet leaving the list or the end of the\n\t * subscription makes that emission impossible. Once the last `kheopskit$`\n\t * subscriber has unsubscribed, a call on a wallet object from that\n\t * subscription rejects with `ABORTED` without asking the platform and\n\t * without changing the remembered list, except on a placeholder, whose\n\t * `disconnect()` resolves. A `disconnect()` started before that point\n\t * settles once the platform has answered: the wallet was\n\t * forgotten when it was called, and nothing else is written once the\n\t * subscription has ended.\n\t */\n\tdisconnect: () => Promise<void>;\n};\n\n/**\n * SDK-free fields common to every account, regardless of platform. Platform\n * packages extend this with their SDK-typed signer/client.\n */\nexport type BaseWalletAccount = {\n\t/** `<walletId>::<address>`, e.g. `polkadot:talisman::5Grw…`. */\n\tid: WalletAccountId;\n\t/**\n\t * `true` for an account restored from the cache that the live wallet has\n\t * not listed yet: its signing surface is absent. Set on every account of\n\t * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.\n\t */\n\tisPlaceholder?: boolean;\n\t/** The platform of the wallet that lists the account. */\n\tplatform: WalletPlatform;\n\t/** Base58 (Solana), SS58 (Polkadot) or 0x-hex (Ethereum) address. */\n\taddress: string;\n\t/**\n\t * Friendly account name, when the wallet exposes one: the extension's\n\t * account name on Polkadot, the Wallet Standard `label` on Solana. Always\n\t * `undefined` on Ethereum.\n\t */\n\tname?: string;\n\t/** `name` of the wallet that lists the account. */\n\twalletName: string;\n\t/** `id` of the wallet that lists the account. */\n\twalletId: WalletId;\n};\n\ntype LiveWalletConnectWallet = {\n\t/** See {@link BaseWallet.isPlaceholder}. */\n\tisPlaceholder?: false;\n\t/** `\"walletconnect\"`, the one connector shared by every platform. */\n\tid: WalletId;\n\t/** Narrow with {@link isWalletConnectWallet}. */\n\ttype: \"walletconnect\";\n\t/**\n\t * Platforms (namespaces) the live session currently carries. Empty until\n\t * connected; populated with whatever the wallet approved (e.g. just\n\t * `[\"ethereum\"]`, or `[\"polkadot\", \"ethereum\"]`).\n\t */\n\tplatforms: WalletPlatform[];\n\t/**\n\t * Raw Reown AppKit instance, exposed as an escape hatch for advanced use\n\t * (custom modal control, reading providers directly). Most consumers should\n\t * use `connect`/`disconnect` and the derived accounts instead.\n\t */\n\tappKit: AppKitInstance;\n\t/** The name AppKit reports for the paired wallet, `\"WalletConnect\"` when it reports none. */\n\tname: string;\n\t/** The icon AppKit reports for the paired wallet, the WalletConnect logo when it reports none. */\n\ticon: string;\n\t/**\n\t * `connecting` while `connect()` opens the modal, `connected` while a\n\t * session is live, `disconnected` otherwise. On a reload with a cached\n\t * session it is `connecting` until AppKit restores the session or hydration\n\t * ends.\n\t */\n\tstatus: WalletStatus;\n\t/** The last `connect()` whose modal failed to open. Cleared by the next call. */\n\terror?: KheopskitError;\n\t/** `status === \"connected\"`. */\n\tisConnected: boolean;\n\t/**\n\t * Opens the WalletConnect modal and resolves once it is open; `isConnected`\n\t * follows when the user approves a session. Unlike injected wallets, this\n\t * promise does not wait for the state to show the connector connected, and\n\t * `signal` is accepted for signature compatibility only.\n\t */\n\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t/** Ends the live session when there is one; resolves at once otherwise. */\n\tdisconnect: () => Promise<void>;\n};\n\n/**\n * The single WalletConnect connector, shared across every platform.\n *\n * Unlike injected wallets, it is **not tied to a platform**: one WalletConnect\n * session spans whichever namespaces the remote wallet approves in a single\n * pairing (a namespace can't be added to a live session afterwards). So there is\n * exactly one of these in `wallets`, discriminated by `type: \"walletconnect\"`.\n * Its accounts appear in `accounts`, each carrying its own `platform`.\n *\n * A placeholder (see {@link BaseWallet.isPlaceholder}) has no `appKit`.\n */\nexport type WalletConnectWallet =\n\t| LiveWalletConnectWallet\n\t| PlaceholderWallet<LiveWalletConnectWallet, \"appKit\">;\n\n/**\n * The cached stand-in for a live item `T`: `isPlaceholder: true`, and the\n * fields `K`, which only the live item carries, absent. Platform account and\n * wallet types are `T | Placeholder<T, K>`, so narrow on `isPlaceholder`\n * before reading a field of `K`.\n */\nexport type Placeholder<T, K extends keyof T> = Omit<T, K | \"isPlaceholder\"> & {\n\t/** Restored from the cache and not yet replaced by the live item. */\n\tisPlaceholder: true;\n} & { [P in K]?: undefined };\n\n/** A {@link Placeholder} wallet, which is never connected. */\nexport type PlaceholderWallet<\n\tT extends { isConnected: boolean },\n\tK extends keyof T,\n> = Omit<Placeholder<T, K>, \"isConnected\"> & { isConnected: false };\n\n/** Narrows a wallet to the platform-less {@link WalletConnectWallet}. */\nexport const isWalletConnectWallet = (\n\twallet: BaseWallet | WalletConnectWallet,\n): wallet is WalletConnectWallet => wallet.type === \"walletconnect\";\n\n/**\n * Narrows a wallet to an injected (browser-extension / Wallet Standard) wallet,\n * the complement of {@link isWalletConnectWallet}. `state.wallets` is\n * `(InjectedWallet | WalletConnectWallet)[]`, so use this to recover the\n * injected-only fields when iterating: `platform`, `sourceId`, and the SDK\n * handle (`provider` on Ethereum, `extension` on Polkadot, `wallet` on Solana).\n *\n * @example\n * ```ts\n * for (const wallet of wallets.filter(isInjectedWallet)) {\n * console.log(wallet.platform, wallet.sourceId); // typed, no WC widening\n * }\n * ```\n */\nexport const isInjectedWallet = <W extends BaseWallet | WalletConnectWallet>(\n\twallet: W,\n): wallet is Exclude<W, WalletConnectWallet> => wallet.type === \"injected\";\n\n/**\n * Dapp metadata shown in the WalletConnect modal. Mirrors WalletConnect's\n * `Metadata`, declared locally so core doesn't depend on\n * `@walletconnect/universal-provider`.\n */\nexport type WalletConnectMetadata = {\n\tname: string;\n\tdescription: string;\n\turl: string;\n\ticons: string[];\n};\n\n/**\n * The WalletConnect connector for `config.walletConnect`. Create it with\n * `walletConnect()` from `@kheopskit/core/walletconnect`; that entry is the only\n * one that loads Reown AppKit.\n */\nexport type WalletConnectPlugin = {\n\treadonly type: \"walletconnect\";\n\treadonly metadata: WalletConnectMetadata;\n\tgetWallet$(ctx: PlatformContext): Observable<WalletConnectWallet | null>;\n};\n\n/**\n * Context passed to a platform plugin's `getWallets$`. Carries the shared store\n * and the resolved core config (for WalletConnect / debug).\n */\nexport type PlatformContext = {\n\tstore: KheopskitStore;\n\tconfig: KheopskitConfig;\n\t/**\n\t * Moments to re-read a registry that has no announce event. Emits at\n\t * subscribe and on a tail restarted at window `load`, and completes after\n\t * the last read. {@link KheopskitState.isDiscovering} turns `false` on the\n\t * first wallet list after that, which waits for a WalletConnect connector\n\t * still loading.\n\t */\n\tregistryReads$?: Observable<void>;\n};\n\n/**\n * A platform plugin. Created by the per-platform factories exported from\n * `@kheopskit/core/polkadot`, `/ethereum`, `/solana`. Core iterates plugins\n * generically and never imports a platform SDK itself.\n *\n * @typeParam TPlatform - the platform discriminant\n * @typeParam TWallet - the platform's wallet type (extends {@link BaseWallet})\n * @typeParam TAccount - the platform's account type (extends {@link BaseWalletAccount})\n */\nexport type KheopskitPlatform<\n\tTPlatform extends WalletPlatform = WalletPlatform,\n\tTWallet extends BaseWallet = BaseWallet,\n\tTAccount extends BaseWalletAccount = BaseWalletAccount,\n> = {\n\treadonly platform: TPlatform;\n\t// Declared as methods (not arrow properties) so parameters are checked\n\t// bivariantly — this lets a specific `KheopskitPlatform<\"polkadot\", …>` be\n\t// assigned to the base `KheopskitPlatform` despite the contravariant\n\t// `wallets$` parameter.\n\tgetWallets$(ctx: PlatformContext): Observable<TWallet[]>;\n\t// Receives this platform's (injected) wallets plus the shared, platform-less\n\t// WalletConnect connector — the plugin derives its injected accounts and, if\n\t// the WC session carries its namespace, its WalletConnect accounts.\n\tgetAccounts$(\n\t\twallets$: Observable<(TWallet | WalletConnectWallet)[]>,\n\t): Observable<TAccount[]>;\n\t/**\n\t * Optional hydration filter. Cached accounts for which this returns false are\n\t * dropped during SSR hydration (Polkadot uses it to honour `accountTypes`).\n\t */\n\tacceptsCachedAccount?(cached: CachedAccount): boolean;\n};\n\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n/** The account type produced by a plugin (inferred from its `getAccounts$`). */\nexport type AccountOf<T> = T extends {\n\tgetAccounts$: (wallets$: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\n/** The wallet type produced by a plugin (inferred from its `getWallets$`). */\nexport type WalletOf<T> = T extends {\n\tgetWallets$: (ctx: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\nexport type KheopskitConfig<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\t/**\n\t * Which remembered injected wallets kheopskit reconnects after a reload.\n\t *\n\t * A wallet is remembered on every successful `connect()` and forgotten on\n\t * `disconnect()`, whatever this option says; the list is the store's\n\t * `remembered`. `true` reconnects every remembered injected wallet, `false`\n\t * none, and a function is asked for each cached connected injected wallet\n\t * on the first frame, then for each remembered one with its live object\n\t * before the attempt. The function must be synchronous and pure. It runs on\n\t * the server and on the client for the same input and both must agree, or\n\t * the markup diverges. It receives the {@link BaseWallet} fields only, so\n\t * key on `id`.\n\t *\n\t * The WalletConnect row is not governed by this option: AppKit restores its\n\t * own session on load, and the row hydrates `connecting` while it does.\n\t *\n\t * A reconnect opens no connect prompt while the site stays authorised in\n\t * the extension. When the authorisation was revoked the extension prompts\n\t * once; a refusal forgets the wallet, so the next load stays silent. A manual\n\t * `connect()` or `disconnect()` on a remembered wallet ends its automatic\n\t * reconnect for the session. A `disconnect()` while the automatic reconnect\n\t * still waits for the extension aborts it without forgetting the wallet, so\n\t * the next load reconnects it.\n\t * Automatic reconnect also ends when the wallet disappears mid-attempt; the\n\t * wallet stays remembered for the next load.\n\t *\n\t * A cached connected wallet this accepts shows `status: \"connecting\"` from\n\t * the first frame until its attempt settles. A wallet this rejects shows\n\t * `disconnected` from the first frame, without its cached accounts, so\n\t * nothing flashes from connected to disconnected.\n\t *\n\t * @default true\n\t */\n\tautoReconnect: boolean | ((wallet: BaseWallet) => boolean);\n\t/**\n\t * Platform plugins to enable, e.g. `[polkadot(), solana({ chain })]`.\n\t * Import factories from `@kheopskit/core/<platform>`.\n\t */\n\tplatforms: P;\n\t/** Create with `walletConnect()` from `@kheopskit/core/walletconnect`. */\n\twalletConnect?: WalletConnectPlugin;\n\t/**\n\t * Dapp name sent to Polkadot injected extensions on connect. Some\n\t * extensions (e.g. polkadot.js) warn about a suspicious origin when it's\n\t * empty.\n\t *\n\t * @default walletConnect.metadata.name, then window.location.hostname\n\t */\n\tappName?: string;\n\t/**\n\t * Logs the resolved config, every state emission and the hydration and\n\t * persistence steps with `console.debug`.\n\t *\n\t * @default false\n\t */\n\tdebug: boolean;\n\t/**\n\t * Custom storage key for persisting wallet connection state.\n\t * Useful when running multiple kheopskit instances on the same domain\n\t * to prevent state conflicts between different dapps.\n\t *\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey: string;\n\t/**\n\t * Minimum time in milliseconds the cached placeholders are shown after a\n\t * reload, so the wallet list does not flash while extensions inject and\n\t * remembered wallets reconnect. Hydration goes on past it until the rule\n\t * documented on {@link KheopskitConfig.hydrationTimeout} ends it, and that\n\t * timeout wins over a longer grace period. The old cap of six times this\n\t * value is gone, so an app that raises it sets `hydrationTimeout` as well.\n\t *\n\t * `0` disables placeholders: `isHydrating` is `false` from the first\n\t * emission.\n\t *\n\t * @default 500\n\t */\n\thydrationGracePeriod: number;\n\t/**\n\t * Upper bound in milliseconds on {@link KheopskitState.isHydrating}.\n\t *\n\t * `isHydrating` turns `false` once `hydrationGracePeriod` has elapsed and\n\t * every cached wallet has settled. A cached wallet missing from the\n\t * discovered wallets settles when discovery ends\n\t * ({@link KheopskitState.isDiscovering} is `false`). A discovered one\n\t * settles at once unless it hydrated as `connecting`. Then it settles when\n\t * connected once its account list has been read (an empty list counts) or\n\t * connected with no cached accounts, disconnected with `error` set, or\n\t * disconnected and not remembered when hydration began. At\n\t * `hydrationTimeout` hydration ends whatever is pending, and a wallet whose\n\t * reconnect is still pending stays `connecting`.\n\t *\n\t * - When every cached wallet is discovered and settled, hydration ends at\n\t * the grace period, without waiting for `load`. A cached wallet that has\n\t * not appeared holds hydration until discovery ends (1100 ms after `load`\n\t * or after subscribe, whichever is later, or later while a WalletConnect\n\t * connector loads), or until `hydrationTimeout`.\n\t * - A wallet that reconnects without sharing any account with the site\n\t * settles as soon as it answers; its cached accounts leave the list when\n\t * hydration ends.\n\t * - A failed reconnect ends that wallet's wait, even when the reconnect\n\t * policy still permits a retry. A retry runs only when the wallet list next\n\t * changes (a wallet discovered or removed, or any wallet's status, error\n\t * or name changing), which may never happen, so waiting for it would\n\t * hold most failed reconnects until `hydrationTimeout`. A retry that\n\t * does run shows on the live wallet's `status`, not as a placeholder.\n\t * - A remembered wallet the user disconnects during or right after its\n\t * reconnect holds hydration, and shows its cached accounts, until\n\t * `hydrationTimeout`.\n\t * - A prompt the extension opens for a revoked site holds hydration until\n\t * the user answers or `hydrationTimeout` elapses.\n\t *\n\t * @default 3000\n\t */\n\thydrationTimeout: number;\n};\n\n/**\n * The current kheopskit state.\n *\n * @remarks\n * While {@link KheopskitState.isHydrating} is `true`, `wallets` and `accounts`\n * may contain placeholders restored from the cache, flagged\n * `isPlaceholder: true`. Each platform type is a union on that flag: a\n * placeholder lacks the SDK handles (`account.txCreator` or `polkadotSigner`\n * on Polkadot, `account.client` on Ethereum, `account.signer` / `getSigner` on\n * Solana, `wallet.extension` / `provider` / `wallet` and `sourceId`). Reading\n * one without narrowing yields a possibly-`undefined` value, so the compiler\n * rejects using it as present until you narrow:\n *\n * ```ts\n * if (account.isPlaceholder) return;\n * account.txCreator; // TxCreator\n * ```\n *\n * A placeholder wallet's `connect()` waits for the live wallet and connects\n * it, rejecting with `WALLET_PENDING` if hydration ends first. No item is a\n * placeholder once `isHydrating` is `false`.\n *\n * The plain, serializable platform data that is persisted in the cache IS\n * restored on the placeholders (Ethereum `chainId`, Polkadot key `type`), so it\n * renders immediately on reload without flashing. Solana `chains` is not\n * cached: a placeholder account's is empty.\n */\nexport type KheopskitState<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\t/**\n\t * Every discovered wallet, connected or not, then the WalletConnect\n\t * connector once AppKit has loaded, when `config.walletConnect` is set.\n\t * While `isHydrating` is `true`, also the cached placeholders. Sorted by\n\t * platform (Polkadot, Ethereum, Solana, WalletConnect), then Talisman\n\t * first, then by name.\n\t */\n\twallets: (WalletOf<P[number]> | WalletConnectWallet)[];\n\t/**\n\t * The accounts of every connected wallet. While `isHydrating` is `true`,\n\t * also the cached placeholders of every wallet that has no live account\n\t * yet. Grouped by platform, then by wallet (Talisman first, then by wallet\n\t * name); inside a wallet, in the order the wallet lists them.\n\t */\n\taccounts: AccountOf<P[number]>[];\n\t/** The resolved config, with every default filled in. */\n\tconfig: KheopskitConfig<P>;\n\t/**\n\t * Whether the state is still being hydrated from cache.\n\t *\n\t * During hydration, cached wallets/accounts may be displayed before the\n\t * actual wallet extensions have injected. See the type-level remarks: those\n\t * are flagged `isPlaceholder: true` and carry no SDK handle.\n\t */\n\tisHydrating: boolean;\n\t/**\n\t * Whether wallet discovery may still be incomplete.\n\t *\n\t * `true` until the Polkadot registry (`window.injectedWeb3`) read window\n\t * ends, 1100 ms after `load` or after subscribe, whichever is later. With\n\t * `config.walletConnect`, it also waits for the connector to load. The\n\t * emission that turns it `false` lists every Polkadot extension injected\n\t * before the last read. A wallet that injects later is not listed until\n\t * the next subscription. Always `true` on the server.\n\t *\n\t * Ethereum (EIP-6963) and Solana (Wallet Standard) registries are\n\t * event-driven and need no re-read.\n\t */\n\tisDiscovering: boolean;\n};\n\n/** Shape of the persisted store data (localStorage, or cookies in compact form). */\nexport type KheopskitStoreData = {\n\t/** Wallets the user connected and has not disconnected */\n\tremembered?: WalletId[];\n\t/** Cached wallet state for SSR hydration to prevent UI flash */\n\tcachedWallets?: CachedWallet[];\n\t/** Cached account state for SSR hydration to prevent UI flash */\n\tcachedAccounts?: CachedAccount[];\n};\n\n/**\n * The persisted settings store shared between core and framework bindings.\n * Declared structurally here (implemented by `createKheopskitStore`) so modules\n * can depend on the interface without importing the implementation.\n */\nexport type KheopskitStore = {\n\tobservable: Observable<KheopskitStoreData>;\n\trememberWallet: (walletId: WalletId) => void;\n\tforgetWallet: (walletId: WalletId) => void;\n\tgetCachedState: () => { wallets: CachedWallet[]; accounts: CachedAccount[] };\n\tsetCachedState: (wallets: CachedWallet[], accounts: CachedAccount[]) => void;\n\t/** Stops cross-tab storage sync and completes `observable`. */\n\tdestroy: () => void;\n};\n\n/**\n * Serializable wallet data for SSR hydration cache.\n * Contains only the data needed to render wallet UI without flash.\n * Note: icon is NOT stored to save cookie space - it's looked up at hydration time.\n */\nexport type CachedWallet = {\n\tid: WalletId;\n\t/** Absent for the platform-less WalletConnect connector. */\n\tplatform?: WalletPlatform;\n\ttype: WalletType;\n\tname: string;\n\tisConnected: boolean;\n};\n\n/**\n * Serializable account data for SSR hydration cache.\n * Contains only the data needed to render account UI without flash.\n */\nexport type CachedAccount = {\n\tid: string;\n\tplatform: WalletPlatform;\n\taddress: string;\n\tname?: string;\n\t/** Cached chain ID for Ethereum accounts. */\n\tchainId?: number;\n\t/** Cached key type for Polkadot accounts. */\n\tpolkadotAccountType?: PolkadotAccountType;\n\twalletId: WalletId;\n\twalletName: string;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"types-BWHvNFlN.js","names":[],"sources":["../src/utils/getCachedObservable.ts","../src/utils/isWalletPlatform.ts","../src/utils/WalletId.ts","../src/api/errors.ts","../src/api/types.ts"],"sourcesContent":["import type { Observable } from \"rxjs\";\n\n// Anchored on globalThis so the cache stays a single instance even if the\n// module is duplicated across bundle chunks (e.g. CJS subpath entries).\nconst CACHE_SYMBOL = Symbol.for(\"kheopskit.observableCache\");\n\nconst getCache = (): Map<string, Observable<unknown>> => {\n\tconst g = globalThis as unknown as Record<\n\t\tsymbol,\n\t\tMap<string, Observable<unknown>> | undefined\n\t>;\n\tlet cache = g[CACHE_SYMBOL];\n\tif (!cache) {\n\t\tcache = new Map();\n\t\tg[CACHE_SYMBOL] = cache;\n\t}\n\treturn cache;\n};\n\nexport const getCachedObservable$ = <T, Obs = Observable<T>>(\n\tkey: string,\n\tcreate: () => Obs,\n): Obs => {\n\tconst cache = getCache();\n\tif (!cache.has(key)) cache.set(key, create() as Observable<unknown>);\n\n\treturn cache.get(key) as Obs;\n};\n\n/**\n * Clears an observable from the cache.\n * Use when a wallet disconnects or configuration changes.\n */\nexport const clearCachedObservable = (key: string): void => {\n\tgetCache().delete(key);\n};\n\n/**\n * Clears all cached observables whose key starts with `prefix`.\n *\n * Used to drop a wallet's account observables when it disconnects, so a later\n * reconnect rebuilds them against the current wallet handle instead of a stale\n * closure — and to keep the cache from growing unbounded across connect cycles.\n */\nexport const clearCachedObservablesByPrefix = (prefix: string): void => {\n\tconst cache = getCache();\n\tfor (const key of cache.keys()) {\n\t\tif (key.startsWith(prefix)) cache.delete(key);\n\t}\n};\n\n/**\n * Clears all cached observables.\n * Use when resetting the entire kheopskit state.\n */\nexport const clearAllCachedObservables = (): void => {\n\tgetCache().clear();\n};\n","import type { WalletPlatform } from \"../api/types\";\n\nexport const isWalletPlatform = (\n\tplatform: unknown,\n): platform is WalletPlatform =>\n\ttypeof platform === \"string\" &&\n\t[\"polkadot\", \"ethereum\", \"solana\"].includes(platform as WalletPlatform);\n","import type { WalletPlatform } from \"../api/types\";\nimport { isWalletPlatform } from \"./isWalletPlatform\";\n\nexport type WalletId = string;\n\n/**\n * Stable id of the single WalletConnect connector. It is platform-less: one WC\n * session spans whichever namespaces the wallet approves, so it isn't tied to a\n * platform (unlike injected wallet ids, which are `<platform>:<identifier>`).\n */\nexport const WALLET_CONNECT_WALLET_ID: WalletId = \"walletconnect\";\n\nexport const getWalletId = (\n\tplatform: WalletPlatform,\n\tidentifier: string,\n): WalletId => {\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid name\");\n\treturn `${platform}:${identifier}`;\n};\n\nexport const parseWalletId = (walletId: string) => {\n\tif (!walletId) throw new Error(\"Invalid walletId\");\n\tconst [platform, identifier] = walletId.split(\":\");\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid address\");\n\treturn { platform, identifier };\n};\n\n/**\n * Non-throwing variant of {@link parseWalletId}. Use when validating untrusted\n * input (e.g. cached state persisted by an older version) before parsing.\n */\nexport const isValidWalletId = (walletId: unknown): walletId is WalletId => {\n\tif (typeof walletId !== \"string\" || !walletId) return false;\n\tif (walletId === WALLET_CONNECT_WALLET_ID) return true;\n\tconst [platform, identifier] = walletId.split(\":\");\n\treturn isWalletPlatform(platform) && !!identifier;\n};\n","import type { WalletId } from \"../utils/WalletId\";\n\n/**\n * Stable error codes thrown by kheopskit. Catch a {@link KheopskitError} and\n * branch on `error.code` instead of matching message strings.\n */\nexport type KheopskitErrorCode =\n\t/**\n\t * This `connect()` or `disconnect()` call was abandoned. For `connect()`:\n\t * its `signal` fired before the platform answered, `disconnect()` was\n\t * called while it pended, its wallet disappeared, or the last `kheopskit$`\n\t * subscriber unsubscribed.\n\t * For either call on an injected wallet: the wallet object came from a\n\t * subscription that had already ended, in which case the call rejects\n\t * without asking the platform and without changing the remembered list. A\n\t * placeholder's `connect()` rejects the same way, its `disconnect()`\n\t * resolves, and the WalletConnect connector still calls AppKit.\n\t */\n\t| \"ABORTED\"\n\t/** The user refused the wallet's connect prompt. `cause` holds the platform error. */\n\t| \"USER_REJECTED\"\n\t/** The wallet's connect call failed for another reason. `cause` holds the platform error. */\n\t| \"CONNECT_FAILED\"\n\t/**\n\t * `connect()` was called on a placeholder wallet restored from the cache:\n\t * on `kheopskit$`, hydration ended without kheopskit discovering that\n\t * wallet; on `getHydratedSnapshot` and the React provider's initial\n\t * snapshot, always.\n\t */\n\t| \"WALLET_PENDING\"\n\t/** The wallet does not advertise a capability kheopskit needs to proceed. */\n\t| \"FEATURE_NOT_SUPPORTED\"\n\t/** No active WalletConnect session for the requested operation. */\n\t| \"NO_SESSION\"\n\t/** No provider available for the requested namespace. */\n\t| \"NO_PROVIDER\"\n\t/** The installed polkadot-api version exposes neither `getTxCreatorFromPjs` (v3) nor `getPolkadotSignerFromPjs` (v2). */\n\t| \"UNSUPPORTED_VERSION\"\n\t/** The requested chain cannot be used for this operation (e.g. a Solana cluster with no CAIP-2 id over WalletConnect). */\n\t| \"UNSUPPORTED_CHAIN\"\n\t/** `getKheopskit$` received a config value it cannot use. The message names the fix. */\n\t| \"INVALID_CONFIG\";\n\n/**\n * Error thrown by kheopskit wallet/account operations. Carries a stable\n * {@link KheopskitErrorCode} and, when relevant, the offending wallet id.\n *\n * @example\n * ```ts\n * try {\n * await wallet.connect();\n * } catch (error) {\n * if (error instanceof KheopskitError && error.code === \"USER_REJECTED\") {\n * // the user closed or refused the wallet prompt\n * } else throw error;\n * }\n * ```\n */\nexport class KheopskitError extends Error {\n\treadonly code: KheopskitErrorCode;\n\t/** The wallet id this error relates to, when applicable. */\n\treadonly walletId?: WalletId;\n\n\tconstructor(\n\t\tcode: KheopskitErrorCode,\n\t\tmessage: string,\n\t\toptions?: { walletId?: WalletId; cause?: unknown },\n\t) {\n\t\tsuper(`[kheopskit] ${message}`, { cause: options?.cause });\n\t\tthis.name = \"KheopskitError\";\n\t\tthis.code = code;\n\t\tthis.walletId = options?.walletId;\n\t}\n}\n\nexport const abortedError = (\n\twalletId: WalletId,\n\toperation: \"connect\" | \"disconnect\",\n): KheopskitError =>\n\tnew KheopskitError(\n\t\t\"ABORTED\",\n\t\t`${operation} of wallet ${walletId} was aborted`,\n\t\t{ walletId },\n\t);\n\nexport const walletPendingError = (walletId: WalletId): KheopskitError =>\n\tnew KheopskitError(\n\t\t\"WALLET_PENDING\",\n\t\t`wallet ${walletId} was not discovered before hydration ended`,\n\t\t{ walletId },\n\t);\n\nexport const toConnectError = (\n\terror: unknown,\n\twalletId: WalletId,\n\tisUserRejection: (error: unknown) => boolean,\n): KheopskitError => {\n\tif (error instanceof KheopskitError) return error;\n\treturn isUserRejection(error)\n\t\t? new KheopskitError(\n\t\t\t\t\"USER_REJECTED\",\n\t\t\t\t`the user rejected the connect request of wallet ${walletId}`,\n\t\t\t\t{ walletId, cause: error },\n\t\t\t)\n\t\t: new KheopskitError(\n\t\t\t\t\"CONNECT_FAILED\",\n\t\t\t\t`wallet ${walletId} failed to connect`,\n\t\t\t\t{ walletId, cause: error },\n\t\t\t);\n};\n\nconst EIP1193_USER_REJECTED_REQUEST = 4001;\n\nexport const isEip1193UserRejection = (error: unknown): boolean =>\n\ttypeof error === \"object\" &&\n\terror !== null &&\n\t(error as { code?: unknown }).code === EIP1193_USER_REJECTED_REQUEST;\n\ntype RefusalMessage = {\n\tpattern: RegExp;\n\twallet: string;\n\tevidence: \"live\" | \"inferred\";\n};\n\n/**\n * How Polkadot extensions and Wallet Standard wallets reject a refused connect\n * prompt. They send a plain `Error`, so the message is the only signal.\n * `evidence` records whether the row was observed live or inferred from the\n * wallet's source or documentation.\n */\nconst REFUSAL_MESSAGES: readonly RefusalMessage[] = [\n\t{\n\t\tpattern: /^Site .+ has not been authorised for Talisman yet$/,\n\t\twallet: \"Talisman 3.11.0, Reject button or prompt window closed\",\n\t\tevidence: \"live\",\n\t},\n\t{\n\t\tpattern: /^Connection request was (rejected|cancelled) by the user\\.$/,\n\t\twallet: \"polkadot-js extension (extension-base 0.64 State.ts)\",\n\t\tevidence: \"inferred\",\n\t},\n\t{\n\t\tpattern: /^(Rejected|Cancelled)$/,\n\t\twallet: \"SubWallet (Extension.ts)\",\n\t\tevidence: \"inferred\",\n\t},\n\t{\n\t\tpattern: /^User rejected the request\\.$/,\n\t\twallet: \"Phantom (Wallet Standard)\",\n\t\tevidence: \"inferred\",\n\t},\n];\n\nexport const isRefusalMessage = (error: unknown): boolean => {\n\tconst message = (error as { message?: unknown } | null | undefined)?.message;\n\treturn (\n\t\ttypeof message === \"string\" &&\n\t\tREFUSAL_MESSAGES.some((row) => row.pattern.test(message))\n\t);\n};\n","import type { Observable } from \"rxjs\";\nimport type { WalletAccountId } from \"../utils\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport type { KheopskitError } from \"./errors\";\n\nexport type WalletPlatform = \"polkadot\" | \"ethereum\" | \"solana\";\n\n/**\n * Minimal structural view of a WalletConnect `UniversalProvider`, the subset\n * kheopskit reads. Declared locally so core never depends on\n * `@walletconnect/universal-provider`. The concrete instance comes from\n * `@reown/appkit` at runtime.\n */\nexport type WalletConnectProvider = {\n\tsession?: {\n\t\ttopic: string;\n\t\tnamespaces: Record<string, { accounts?: string[] }>;\n\t};\n\tclient: {\n\t\trequest<T = unknown>(args: {\n\t\t\ttopic: string;\n\t\t\tchainId: string;\n\t\t\trequest: { method: string; params: unknown };\n\t\t}): Promise<T>;\n\t};\n\trequest(args: { method: string; params?: unknown }): Promise<unknown>;\n\ton(event: string, listener: (...args: unknown[]) => void): void;\n\toff(event: string, listener: (...args: unknown[]) => void): void;\n};\n\n/**\n * Minimal structural view of the Reown AppKit instance, the subset kheopskit's\n * account factories use. Exposed as the `appKit` escape hatch on AppKit wallets;\n * cast it to `@reown/appkit`'s `AppKit` type for the full API. Declared locally\n * so core never depends on `@reown/appkit`'s types (it's an optional peer).\n */\nexport type AppKitInstance = {\n\tgetProvider<T = WalletConnectProvider>(namespace: string): T | undefined;\n\tgetAccount(\n\t\tnamespace: string,\n\t): { allAccounts: { address: string }[] } | undefined;\n\tgetCaipNetworks(namespace: string): { caipNetworkId?: string }[];\n};\n\nexport type WalletType = \"injected\" | \"walletconnect\";\n\n/**\n * Where a wallet stands with the dapp. `connecting` covers a `connect()` call\n * in flight and an auto-reconnect in flight alike.\n */\nexport type WalletStatus = \"disconnected\" | \"connecting\" | \"connected\";\n\nexport type PolkadotAccountType = \"sr25519\" | \"ed25519\" | \"ecdsa\" | \"ethereum\";\n\n/** Options accepted by {@link BaseWallet.connect}. */\nexport type ConnectOptions = {\n\t/**\n\t * Ends this caller's wait for the platform's answer: its promise rejects\n\t * with a `KheopskitError` of code `ABORTED`. An abort after the platform\n\t * has granted the connect changes nothing, and a Polkadot extension counts\n\t * as granted only once its account list has been read. Other callers\n\t * sharing the attempt keep waiting. The extension's own prompt may stay\n\t * open: nothing can withdraw it from the page. A Polkadot `connect()`\n\t * started while that prompt is open waits for it instead of asking again,\n\t * and connects with the handle it answers. Once no caller waits any more\n\t * and no later `connect()` joined that prompt, kheopskit drops a handle\n\t * the platform hands back afterwards without revoking the platform's\n\t * grant, and the wallet is neither connected nor remembered. Kheopskit\n\t * sets no timeout of its own, because an extension prompt\n\t * pends only while the user has not answered it; pass\n\t * `AbortSignal.timeout(ms)` to cap the wait.\n\t */\n\tsignal?: AbortSignal;\n};\n\n/**\n * SDK-free fields common to every wallet, regardless of platform. Platform\n * packages (`@kheopskit/core/<platform>`) extend this with SDK-typed fields\n * (the injected provider/extension/standard-wallet handle).\n */\nexport type BaseWallet = {\n\t/** `<platform>:<identifier>`, e.g. `polkadot:talisman`. Stable across reloads. */\n\tid: WalletId;\n\t/** The platform whose registry listed the wallet. */\n\tplatform: WalletPlatform;\n\t/**\n\t * `\"injected\"`, for a browser extension or Wallet Standard wallet. The\n\t * WalletConnect connector is the separate {@link WalletConnectWallet}.\n\t */\n\ttype: WalletType;\n\t/** Display name, e.g. `Talisman`. */\n\tname: string;\n\t/** Icon URL or data URI. `\"\"` when the wallet exposes none. */\n\ticon: string;\n\t/**\n\t * `true` for a wallet restored from the cache that kheopskit has not\n\t * discovered yet: its SDK handle and `sourceId` are absent and it is never\n\t * connected. On `kheopskit$` its `connect()` waits for the live wallet and\n\t * connects that one, rejecting with `WALLET_PENDING` if hydration ends first\n\t * and `ABORTED` if its `signal` fires or the subscription ends. On\n\t * `getHydratedSnapshot` it rejects with `WALLET_PENDING`. Its `disconnect()`\n\t * resolves at once, and on `kheopskit$` forgets the wallet first so it is\n\t * not reconnected when it injects, or calls the live wallet's\n\t * `disconnect()` once that one is discovered. Set on every wallet of\n\t * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.\n\t */\n\tisPlaceholder?: boolean;\n\t/**\n\t * `connecting` while a `connect()` call or an auto-reconnect waits for the\n\t * platform, `connected` once the platform granted it, `disconnected`\n\t * otherwise. On a reload, a remembered wallet kheopskit will reconnect is\n\t * `connecting` from the first frame when the cache recorded it connected,\n\t * which the cache does 1 s after the state settles.\n\t */\n\tstatus: WalletStatus;\n\t/**\n\t * The last `connect()` or auto-reconnect that the platform refused or\n\t * failed (`USER_REJECTED` or `CONNECT_FAILED`, or `FEATURE_NOT_SUPPORTED`\n\t * for a Wallet Standard wallet without `standard:connect`). Cleared when\n\t * the next attempt starts. An aborted attempt sets nothing.\n\t */\n\terror?: KheopskitError;\n\t/** `status === \"connected\"`. */\n\tisConnected: boolean;\n\t/**\n\t * Connects the wallet.\n\t *\n\t * - **Shared in flight.** Concurrent calls on one wallet share a single\n\t * platform attempt and the platform is asked once. Each call gets its own\n\t * promise: aborting a caller's `signal` rejects only that caller with code\n\t * `ABORTED`. The attempt itself is abandoned only when every caller that\n\t * passed a signal has aborted and no caller without one joined, when\n\t * `disconnect()` is called, or when the last `kheopskit$` subscriber\n\t * unsubscribes; those reject every remaining caller with `ABORTED`.\n\t * - **Idempotent.** On a connected wallet it resolves at once without\n\t * touching the platform, unless a `disconnect()` still waits for the\n\t * platform. It then waits for that disconnect to settle and connects\n\t * again if the wallet ended up disconnected.\n\t * - **Abortable.** See {@link ConnectOptions.signal}. There is no default\n\t * timeout.\n\t * - **Settles with the state.** It resolves only after `kheopskit$` has\n\t * emitted a state in which this wallet has `isConnected: true`, so the\n\t * consumer-visible state already reflects the connect. On platforms that\n\t * list accounts asynchronously (Ethereum `eth_accounts`), the accounts may\n\t * arrive in a later emission. No emission shows a disconnected wallet\n\t * still listing live accounts, or a connected wallet listing the accounts\n\t * of a previous connection. During hydration a wallet's cached\n\t * placeholder accounts stay listed whatever its status. Another wallet's\n\t * pending `eth_accounts` request never delays them. A `disconnect()` that\n\t * completes while it waits for that state rejects it with `ABORTED`. If\n\t * the platform's disconnect is still pending or refuses, it resolves once\n\t * the state shows the wallet connected (today only Solana has a platform\n\t * disconnect). A `connect()`\n\t * whose wallet disappears before the platform grants it (an extension\n\t * removed, a Wallet Standard wallet unregistered) rejects `ABORTED`;\n\t * granted first, it resolves and the wallet stays remembered. Once the last `kheopskit$`\n\t * subscriber has unsubscribed, a call on a wallet object from that\n\t * subscription rejects with `ABORTED` without asking the platform,\n\t * placeholders included.\n\t * - **Typed rejections.** A platform rejection is wrapped in a\n\t * `KheopskitError` carrying the original error as `cause` and the\n\t * `walletId`: `USER_REJECTED` when the user refused the prompt,\n\t * `CONNECT_FAILED` otherwise. A Wallet Standard wallet without\n\t * `standard:connect` rejects with `FEATURE_NOT_SUPPORTED`.\n\t */\n\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t/**\n\t * Disconnects the wallet.\n\t *\n\t * It forgets the wallet at once, whatever its status, so the next load does\n\t * not reconnect it. On a disconnected wallet it then resolves. While a `connect()` waits\n\t * for the platform to grant it, it aborts that connect (its promise rejects\n\t * with `ABORTED`) and never waits for the extension prompt. Otherwise it\n\t * first waits for the platform's disconnect and rejects if that fails, so\n\t * callers can surface or retry. It then resolves once `kheopskit$` has\n\t * emitted a state in which this wallet has `isConnected: false`, or once a\n\t * later `connect()`, the wallet leaving the list or the end of the\n\t * subscription makes that emission impossible. Once the last `kheopskit$`\n\t * subscriber has unsubscribed, a call on a wallet object from that\n\t * subscription rejects with `ABORTED` without asking the platform and\n\t * without changing the remembered list, except on a placeholder, whose\n\t * `disconnect()` resolves. A `disconnect()` started before that point\n\t * settles once the platform has answered: the wallet was\n\t * forgotten when it was called, and nothing else is written once the\n\t * subscription has ended.\n\t */\n\tdisconnect: () => Promise<void>;\n};\n\n/**\n * SDK-free fields common to every account, regardless of platform. Platform\n * packages extend this with their SDK-typed signer/client.\n */\nexport type BaseWalletAccount = {\n\t/** `<walletId>::<address>`, e.g. `polkadot:talisman::5Grw…`. */\n\tid: WalletAccountId;\n\t/**\n\t * `true` for an account restored from the cache that the live wallet has\n\t * not listed yet: its signing surface is absent. Set on every account of\n\t * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.\n\t */\n\tisPlaceholder?: boolean;\n\t/** The platform of the wallet that lists the account. */\n\tplatform: WalletPlatform;\n\t/** Base58 (Solana), SS58 (Polkadot) or 0x-hex (Ethereum) address. */\n\taddress: string;\n\t/**\n\t * Friendly account name, when the wallet exposes one: the extension's\n\t * account name on Polkadot, the Wallet Standard `label` on Solana. Always\n\t * `undefined` on Ethereum.\n\t */\n\tname?: string;\n\t/** `name` of the wallet that lists the account. */\n\twalletName: string;\n\t/** `id` of the wallet that lists the account. */\n\twalletId: WalletId;\n};\n\ntype LiveWalletConnectWallet = {\n\t/** See {@link BaseWallet.isPlaceholder}. */\n\tisPlaceholder?: false;\n\t/** `\"walletconnect\"`, the one connector shared by every platform. */\n\tid: WalletId;\n\t/** Narrow with {@link isWalletConnectWallet}. */\n\ttype: \"walletconnect\";\n\t/**\n\t * Platforms (namespaces) the live session currently carries. Empty until\n\t * connected; populated with whatever the wallet approved (e.g. just\n\t * `[\"ethereum\"]`, or `[\"polkadot\", \"ethereum\"]`).\n\t */\n\tplatforms: WalletPlatform[];\n\t/**\n\t * Raw Reown AppKit instance, exposed as an escape hatch for advanced use\n\t * (custom modal control, reading providers directly). Most consumers should\n\t * use `connect`/`disconnect` and the derived accounts instead.\n\t */\n\tappKit: AppKitInstance;\n\t/** The name AppKit reports for the paired wallet, `\"WalletConnect\"` when it reports none. */\n\tname: string;\n\t/** The icon AppKit reports for the paired wallet, the WalletConnect logo when it reports none. */\n\ticon: string;\n\t/**\n\t * `connecting` while `connect()` opens the modal, `connected` while a\n\t * session is live, `disconnected` otherwise. On a reload with a cached\n\t * session it is `connecting` until AppKit restores the session or hydration\n\t * ends.\n\t */\n\tstatus: WalletStatus;\n\t/** The last `connect()` whose modal failed to open. Cleared by the next call. */\n\terror?: KheopskitError;\n\t/** `status === \"connected\"`. */\n\tisConnected: boolean;\n\t/**\n\t * Opens the WalletConnect modal and resolves once it is open; `isConnected`\n\t * follows when the user approves a session. Unlike injected wallets, this\n\t * promise does not wait for the state to show the connector connected, and\n\t * `signal` is accepted for signature compatibility only.\n\t */\n\tconnect: (options?: ConnectOptions) => Promise<void>;\n\t/** Ends the live session when there is one; resolves at once otherwise. */\n\tdisconnect: () => Promise<void>;\n};\n\n/**\n * The single WalletConnect connector, shared across every platform.\n *\n * Unlike injected wallets, it is **not tied to a platform**: one WalletConnect\n * session spans whichever namespaces the remote wallet approves in a single\n * pairing (a namespace can't be added to a live session afterwards). So there is\n * exactly one of these in `wallets`, discriminated by `type: \"walletconnect\"`.\n * Its accounts appear in `accounts`, each carrying its own `platform`.\n *\n * A placeholder (see {@link BaseWallet.isPlaceholder}) has no `appKit`.\n */\nexport type WalletConnectWallet =\n\t| LiveWalletConnectWallet\n\t| PlaceholderWallet<LiveWalletConnectWallet, \"appKit\">;\n\n/**\n * The cached stand-in for a live item `T`: `isPlaceholder: true`, and the\n * fields `K`, which only the live item carries, absent. Platform account and\n * wallet types are `T | Placeholder<T, K>`, so narrow on `isPlaceholder`\n * before reading a field of `K`.\n */\nexport type Placeholder<T, K extends keyof T> = Omit<T, K | \"isPlaceholder\"> & {\n\t/** Restored from the cache and not yet replaced by the live item. */\n\tisPlaceholder: true;\n} & { [P in K]?: undefined };\n\n/** A {@link Placeholder} wallet, which is never connected. */\nexport type PlaceholderWallet<\n\tT extends { isConnected: boolean },\n\tK extends keyof T,\n> = Omit<Placeholder<T, K>, \"isConnected\"> & { isConnected: false };\n\n/** Narrows a wallet to the platform-less {@link WalletConnectWallet}. */\nexport const isWalletConnectWallet = (\n\twallet: BaseWallet | WalletConnectWallet,\n): wallet is WalletConnectWallet => wallet.type === \"walletconnect\";\n\n/**\n * Narrows a wallet to an injected (browser-extension / Wallet Standard) wallet,\n * the complement of {@link isWalletConnectWallet}. `state.wallets` is\n * `(InjectedWallet | WalletConnectWallet)[]`, so use this to recover the\n * injected-only fields when iterating: `platform`, `sourceId`, and the SDK\n * handle (`provider` on Ethereum, `extension` on Polkadot, `wallet` on Solana).\n *\n * @example\n * ```ts\n * for (const wallet of wallets.filter(isInjectedWallet)) {\n * console.log(wallet.platform, wallet.sourceId); // typed, no WC widening\n * }\n * ```\n */\nexport const isInjectedWallet = <W extends BaseWallet | WalletConnectWallet>(\n\twallet: W,\n): wallet is Exclude<W, WalletConnectWallet> => wallet.type === \"injected\";\n\n/**\n * Dapp metadata shown in the WalletConnect modal. Mirrors WalletConnect's\n * `Metadata`, declared locally so core doesn't depend on\n * `@walletconnect/universal-provider`.\n */\nexport type WalletConnectMetadata = {\n\tname: string;\n\tdescription: string;\n\turl: string;\n\ticons: string[];\n};\n\n/**\n * The WalletConnect connector for `config.walletConnect`. Create it with\n * `walletConnect()` from `@kheopskit/core/walletconnect`; that entry is the only\n * one that loads Reown AppKit.\n */\nexport type WalletConnectPlugin = {\n\treadonly type: \"walletconnect\";\n\treadonly metadata: WalletConnectMetadata;\n\tgetWallet$(ctx: PlatformContext): Observable<WalletConnectWallet | null>;\n};\n\n/**\n * Context passed to a platform plugin's `getWallets$`. Carries the shared store\n * and the resolved core config (for WalletConnect / debug).\n */\nexport type PlatformContext = {\n\tstore: KheopskitStore;\n\tconfig: KheopskitConfig;\n\t/**\n\t * Moments to re-read a registry that has no announce event. Emits at\n\t * subscribe and on a tail restarted at window `load`, and completes after\n\t * the last read. {@link KheopskitState.isDiscovering} turns `false` on the\n\t * first wallet list after that, which waits for a WalletConnect connector\n\t * still loading.\n\t */\n\tregistryReads$?: Observable<void>;\n};\n\n/**\n * A platform plugin. Created by the per-platform factories exported from\n * `@kheopskit/core/polkadot`, `/ethereum`, `/solana`. Core iterates plugins\n * generically and never imports a platform SDK itself.\n *\n * @typeParam TPlatform - the platform discriminant\n * @typeParam TWallet - the platform's wallet type (extends {@link BaseWallet})\n * @typeParam TAccount - the platform's account type (extends {@link BaseWalletAccount})\n */\nexport type KheopskitPlatform<\n\tTPlatform extends WalletPlatform = WalletPlatform,\n\tTWallet extends BaseWallet = BaseWallet,\n\tTAccount extends BaseWalletAccount = BaseWalletAccount,\n> = {\n\treadonly platform: TPlatform;\n\t// Declared as methods (not arrow properties) so parameters are checked\n\t// bivariantly — this lets a specific `KheopskitPlatform<\"polkadot\", …>` be\n\t// assigned to the base `KheopskitPlatform` despite the contravariant\n\t// `wallets$` parameter.\n\tgetWallets$(ctx: PlatformContext): Observable<TWallet[]>;\n\t// Receives this platform's (injected) wallets plus the shared, platform-less\n\t// WalletConnect connector — the plugin derives its injected accounts and, if\n\t// the WC session carries its namespace, its WalletConnect accounts.\n\tgetAccounts$(\n\t\twallets$: Observable<(TWallet | WalletConnectWallet)[]>,\n\t): Observable<TAccount[]>;\n\t/**\n\t * Optional hydration filter. Cached accounts for which this returns false are\n\t * dropped during SSR hydration (Polkadot uses it to honour `accountTypes`).\n\t */\n\tacceptsCachedAccount?(cached: CachedAccount): boolean;\n};\n\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n/** The account type produced by a plugin (inferred from its `getAccounts$`). */\nexport type AccountOf<T> = T extends {\n\tgetAccounts$: (wallets$: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\n/** The wallet type produced by a plugin (inferred from its `getWallets$`). */\nexport type WalletOf<T> = T extends {\n\tgetWallets$: (ctx: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\nexport type KheopskitConfig<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\t/**\n\t * Which remembered injected wallets kheopskit reconnects after a reload.\n\t *\n\t * A wallet is remembered on every successful `connect()` and forgotten on\n\t * `disconnect()`, whatever this option says; the list is the store's\n\t * `remembered`. `true` reconnects every remembered injected wallet, `false`\n\t * none, and a function is asked for each cached connected injected wallet\n\t * on the first frame, then for each remembered one with its live object\n\t * before the attempt. The function must be synchronous and pure. It runs on\n\t * the server and on the client for the same input and both must agree, or\n\t * the markup diverges. It receives the {@link BaseWallet} fields only, so\n\t * key on `id`.\n\t *\n\t * The WalletConnect row is not governed by this option: AppKit restores its\n\t * own session on load, and the row hydrates `connecting` while it does.\n\t *\n\t * A reconnect opens no connect prompt while the site stays authorised in\n\t * the extension. When the authorisation was revoked the extension prompts\n\t * once; a refusal forgets the wallet, so the next load stays silent. A manual\n\t * `connect()` or `disconnect()` on a remembered wallet ends its automatic\n\t * reconnect for the session. A `disconnect()` forgets the wallet whatever\n\t * its status, so one made while the automatic reconnect still waits for the\n\t * extension aborts it, and the next load does not reconnect it.\n\t * Automatic reconnect also ends when the wallet disappears mid-attempt; the\n\t * wallet stays remembered for the next load.\n\t *\n\t * A cached connected wallet this accepts shows `status: \"connecting\"` from\n\t * the first frame until its attempt settles. A wallet this rejects shows\n\t * `disconnected` from the first frame, without its cached accounts, so\n\t * nothing flashes from connected to disconnected.\n\t *\n\t * @default true\n\t */\n\tautoReconnect: boolean | ((wallet: BaseWallet) => boolean);\n\t/**\n\t * Platform plugins to enable, e.g. `[polkadot(), solana({ chain })]`.\n\t * Import factories from `@kheopskit/core/<platform>`.\n\t */\n\tplatforms: P;\n\t/** Create with `walletConnect()` from `@kheopskit/core/walletconnect`. */\n\twalletConnect?: WalletConnectPlugin;\n\t/**\n\t * Dapp name sent to Polkadot injected extensions on connect. Some\n\t * extensions (e.g. polkadot.js) warn about a suspicious origin when it's\n\t * empty.\n\t *\n\t * @default walletConnect.metadata.name, then window.location.hostname\n\t */\n\tappName?: string;\n\t/**\n\t * Logs the resolved config, every state emission and the hydration and\n\t * persistence steps with `console.debug`.\n\t *\n\t * @default false\n\t */\n\tdebug: boolean;\n\t/**\n\t * Custom storage key for persisting wallet connection state.\n\t * Useful when running multiple kheopskit instances on the same domain\n\t * to prevent state conflicts between different dapps.\n\t *\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey: string;\n\t/**\n\t * Minimum time in milliseconds the cached placeholders are shown after a\n\t * reload, so the wallet list does not flash while extensions inject and\n\t * remembered wallets reconnect. Hydration goes on past it until the rule\n\t * documented on {@link KheopskitConfig.hydrationTimeout} ends it, and that\n\t * timeout wins over a longer grace period. The old cap of six times this\n\t * value is gone, so an app that raises it sets `hydrationTimeout` as well.\n\t *\n\t * `0` disables placeholders: `isHydrating` is `false` from the first\n\t * emission.\n\t *\n\t * @default 500\n\t */\n\thydrationGracePeriod: number;\n\t/**\n\t * Upper bound in milliseconds on {@link KheopskitState.isHydrating}.\n\t *\n\t * `isHydrating` turns `false` once `hydrationGracePeriod` has elapsed and\n\t * every cached wallet has settled. A cached wallet missing from the\n\t * discovered wallets settles when discovery ends\n\t * ({@link KheopskitState.isDiscovering} is `false`). A discovered one\n\t * settles at once unless it hydrated as `connecting`. Then it settles when\n\t * connected once its account list has been read (an empty list counts) or\n\t * connected with no cached accounts, disconnected with `error` set, or\n\t * disconnected and not remembered (a wallet remembered after hydration\n\t * began does not count). At\n\t * `hydrationTimeout` hydration ends whatever is pending, and a wallet whose\n\t * reconnect is still pending stays `connecting`.\n\t *\n\t * - When every cached wallet is discovered and settled, hydration ends at\n\t * the grace period, without waiting for `load`. A cached wallet that has\n\t * not appeared holds hydration until discovery ends (1100 ms after `load`\n\t * or after subscribe, whichever is later, or later while a WalletConnect\n\t * connector loads), or until `hydrationTimeout`.\n\t * - A wallet that reconnects without sharing any account with the site\n\t * settles as soon as it answers; its cached accounts leave the list when\n\t * hydration ends.\n\t * - A failed reconnect ends that wallet's wait, even when the reconnect\n\t * policy still permits a retry. A retry runs only when the wallet list next\n\t * changes (a wallet discovered or removed, or any wallet's status, error\n\t * or name changing), which may never happen, so waiting for it would\n\t * hold most failed reconnects until `hydrationTimeout`. A retry that\n\t * does run shows on the live wallet's `status`, not as a placeholder.\n\t * - A prompt the extension opens for a revoked site holds hydration until\n\t * the user answers or `hydrationTimeout` elapses.\n\t *\n\t * @default 3000\n\t */\n\thydrationTimeout: number;\n};\n\n/**\n * The current kheopskit state.\n *\n * @remarks\n * While {@link KheopskitState.isHydrating} is `true`, `wallets` and `accounts`\n * may contain placeholders restored from the cache, flagged\n * `isPlaceholder: true`. Each platform type is a union on that flag: a\n * placeholder lacks the SDK handles (`account.txCreator` or `polkadotSigner`\n * on Polkadot, `account.client` on Ethereum, `account.signer` / `getSigner` on\n * Solana, `wallet.extension` / `provider` / `wallet` and `sourceId`). Reading\n * one without narrowing yields a possibly-`undefined` value, so the compiler\n * rejects using it as present until you narrow:\n *\n * ```ts\n * if (account.isPlaceholder) return;\n * account.txCreator; // TxCreator\n * ```\n *\n * A placeholder wallet's `connect()` waits for the live wallet and connects\n * it, rejecting with `WALLET_PENDING` if hydration ends first. No item is a\n * placeholder once `isHydrating` is `false`.\n *\n * The plain, serializable platform data that is persisted in the cache IS\n * restored on the placeholders (Ethereum `chainId`, Polkadot key `type`), so it\n * renders immediately on reload without flashing. Solana `chains` is not\n * cached: a placeholder account's is empty.\n */\nexport type KheopskitState<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\t/**\n\t * Every discovered wallet, connected or not, then the WalletConnect\n\t * connector once AppKit has loaded, when `config.walletConnect` is set.\n\t * While `isHydrating` is `true`, also the cached placeholders. Sorted by\n\t * platform (Polkadot, Ethereum, Solana, WalletConnect), then Talisman\n\t * first, then by name.\n\t */\n\twallets: (WalletOf<P[number]> | WalletConnectWallet)[];\n\t/**\n\t * The accounts of every connected wallet. While `isHydrating` is `true`,\n\t * also the cached placeholders of every wallet that has no live account\n\t * yet. Grouped by platform, then by wallet (Talisman first, then by wallet\n\t * name); inside a wallet, in the order the wallet lists them.\n\t */\n\taccounts: AccountOf<P[number]>[];\n\t/** The resolved config, with every default filled in. */\n\tconfig: KheopskitConfig<P>;\n\t/**\n\t * Whether the state is still being hydrated from cache.\n\t *\n\t * During hydration, cached wallets/accounts may be displayed before the\n\t * actual wallet extensions have injected. See the type-level remarks: those\n\t * are flagged `isPlaceholder: true` and carry no SDK handle.\n\t */\n\tisHydrating: boolean;\n\t/**\n\t * Whether wallet discovery may still be incomplete.\n\t *\n\t * `true` until the Polkadot registry (`window.injectedWeb3`) read window\n\t * ends, 1100 ms after `load` or after subscribe, whichever is later. With\n\t * `config.walletConnect`, it also waits for the connector to load. The\n\t * emission that turns it `false` lists every Polkadot extension injected\n\t * before the last read. A wallet that injects later is not listed until\n\t * the next subscription. Always `true` on the server.\n\t *\n\t * Ethereum (EIP-6963) and Solana (Wallet Standard) registries are\n\t * event-driven and need no re-read.\n\t */\n\tisDiscovering: boolean;\n};\n\n/** Shape of the persisted store data (localStorage, or cookies in compact form). */\nexport type KheopskitStoreData = {\n\t/** Wallets the user connected and has not disconnected */\n\tremembered?: WalletId[];\n\t/** Cached wallet state for SSR hydration to prevent UI flash */\n\tcachedWallets?: CachedWallet[];\n\t/** Cached account state for SSR hydration to prevent UI flash */\n\tcachedAccounts?: CachedAccount[];\n};\n\n/**\n * The persisted settings store shared between core and framework bindings.\n * Declared structurally here (implemented by `createKheopskitStore`) so modules\n * can depend on the interface without importing the implementation.\n */\nexport type KheopskitStore = {\n\tobservable: Observable<KheopskitStoreData>;\n\trememberWallet: (walletId: WalletId) => void;\n\tforgetWallet: (walletId: WalletId) => void;\n\tgetCachedState: () => { wallets: CachedWallet[]; accounts: CachedAccount[] };\n\tsetCachedState: (wallets: CachedWallet[], accounts: CachedAccount[]) => void;\n\t/** Stops cross-tab storage sync and completes `observable`. */\n\tdestroy: () => void;\n};\n\n/**\n * Serializable wallet data for SSR hydration cache.\n * Contains only the data needed to render wallet UI without flash.\n * Note: icon is NOT stored to save cookie space - it's looked up at hydration time.\n */\nexport type CachedWallet = {\n\tid: WalletId;\n\t/** Absent for the platform-less WalletConnect connector. */\n\tplatform?: WalletPlatform;\n\ttype: WalletType;\n\tname: string;\n\tisConnected: boolean;\n};\n\n/**\n * Serializable account data for SSR hydration cache.\n * Contains only the data needed to render account UI without flash.\n */\nexport type CachedAccount = {\n\tid: string;\n\tplatform: WalletPlatform;\n\taddress: string;\n\tname?: string;\n\t/** Cached chain ID for Ethereum accounts. */\n\tchainId?: number;\n\t/** Cached key type for Polkadot accounts. */\n\tpolkadotAccountType?: PolkadotAccountType;\n\twalletId: WalletId;\n\twalletName: string;\n};\n"],"mappings":"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"}
@@ -188,8 +188,10 @@ type BaseWallet = {
188
188
  * connects that one, rejecting with `WALLET_PENDING` if hydration ends first
189
189
  * and `ABORTED` if its `signal` fires or the subscription ends. On
190
190
  * `getHydratedSnapshot` it rejects with `WALLET_PENDING`. Its `disconnect()`
191
- * resolves at once. Set on every wallet of `kheopskit$` and of the hydrated
192
- * snapshot; plugins leave it unset.
191
+ * resolves at once, and on `kheopskit$` forgets the wallet first so it is
192
+ * not reconnected when it injects, or calls the live wallet's
193
+ * `disconnect()` once that one is discovered. Set on every wallet of
194
+ * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.
193
195
  */
194
196
  isPlaceholder?: boolean;
195
197
  /**
@@ -254,7 +256,8 @@ type BaseWallet = {
254
256
  /**
255
257
  * Disconnects the wallet.
256
258
  *
257
- * On a disconnected wallet it resolves at once. While a `connect()` waits
259
+ * It forgets the wallet at once, whatever its status, so the next load does
260
+ * not reconnect it. On a disconnected wallet it then resolves. While a `connect()` waits
258
261
  * for the platform to grant it, it aborts that connect (its promise rejects
259
262
  * with `ABORTED`) and never waits for the extension prompt. Otherwise it
260
263
  * first waits for the platform's disconnect and rejects if that fails, so
@@ -475,9 +478,9 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
475
478
  * the extension. When the authorisation was revoked the extension prompts
476
479
  * once; a refusal forgets the wallet, so the next load stays silent. A manual
477
480
  * `connect()` or `disconnect()` on a remembered wallet ends its automatic
478
- * reconnect for the session. A `disconnect()` while the automatic reconnect
479
- * still waits for the extension aborts it without forgetting the wallet, so
480
- * the next load reconnects it.
481
+ * reconnect for the session. A `disconnect()` forgets the wallet whatever
482
+ * its status, so one made while the automatic reconnect still waits for the
483
+ * extension aborts it, and the next load does not reconnect it.
481
484
  * Automatic reconnect also ends when the wallet disappears mid-attempt; the
482
485
  * wallet stays remembered for the next load.
483
486
  *
@@ -543,7 +546,8 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
543
546
  * settles at once unless it hydrated as `connecting`. Then it settles when
544
547
  * connected once its account list has been read (an empty list counts) or
545
548
  * connected with no cached accounts, disconnected with `error` set, or
546
- * disconnected and not remembered when hydration began. At
549
+ * disconnected and not remembered (a wallet remembered after hydration
550
+ * began does not count). At
547
551
  * `hydrationTimeout` hydration ends whatever is pending, and a wallet whose
548
552
  * reconnect is still pending stays `connecting`.
549
553
  *
@@ -561,9 +565,6 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
561
565
  * or name changing), which may never happen, so waiting for it would
562
566
  * hold most failed reconnects until `hydrationTimeout`. A retry that
563
567
  * does run shows on the live wallet's `status`, not as a placeholder.
564
- * - A remembered wallet the user disconnects during or right after its
565
- * reconnect holds hydration, and shows its cached accounts, until
566
- * `hydrationTimeout`.
567
568
  * - A prompt the extension opens for a revoked site holds hydration until
568
569
  * the user answers or `hydrationTimeout` elapses.
569
570
  *
@@ -696,4 +697,4 @@ type CachedAccount = {
696
697
  };
697
698
  //#endregion
698
699
  export { getWalletId as A, WalletStatus as C, KheopskitError as D, isWalletConnectWallet as E, parseWalletAccountId as F, parseWalletId as M, WalletAccountId as N, KheopskitErrorCode as O, getWalletAccountId as P, WalletPlatform as S, isInjectedWallet as T, WalletConnectMetadata as _, CachedAccount as a, WalletConnectWallet as b, KheopskitConfig as c, KheopskitStore as d, KheopskitStoreData as f, PolkadotAccountType as g, PlatformContext as h, BaseWalletAccount as i, isValidWalletId as j, WalletId as k, KheopskitPlatform as l, PlaceholderWallet as m, AppKitInstance as n, CachedWallet as o, Placeholder as p, BaseWallet as r, ConnectOptions as s, AccountOf as t, KheopskitState as u, WalletConnectPlugin as v, WalletType as w, WalletOf as x, WalletConnectProvider as y };
699
- //# sourceMappingURL=types-DCaL9bIc.d.ts.map
700
+ //# sourceMappingURL=types-C3I3w0jb.d.mts.map
@@ -188,8 +188,10 @@ type BaseWallet = {
188
188
  * connects that one, rejecting with `WALLET_PENDING` if hydration ends first
189
189
  * and `ABORTED` if its `signal` fires or the subscription ends. On
190
190
  * `getHydratedSnapshot` it rejects with `WALLET_PENDING`. Its `disconnect()`
191
- * resolves at once. Set on every wallet of `kheopskit$` and of the hydrated
192
- * snapshot; plugins leave it unset.
191
+ * resolves at once, and on `kheopskit$` forgets the wallet first so it is
192
+ * not reconnected when it injects, or calls the live wallet's
193
+ * `disconnect()` once that one is discovered. Set on every wallet of
194
+ * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.
193
195
  */
194
196
  isPlaceholder?: boolean;
195
197
  /**
@@ -254,7 +256,8 @@ type BaseWallet = {
254
256
  /**
255
257
  * Disconnects the wallet.
256
258
  *
257
- * On a disconnected wallet it resolves at once. While a `connect()` waits
259
+ * It forgets the wallet at once, whatever its status, so the next load does
260
+ * not reconnect it. On a disconnected wallet it then resolves. While a `connect()` waits
258
261
  * for the platform to grant it, it aborts that connect (its promise rejects
259
262
  * with `ABORTED`) and never waits for the extension prompt. Otherwise it
260
263
  * first waits for the platform's disconnect and rejects if that fails, so
@@ -475,9 +478,9 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
475
478
  * the extension. When the authorisation was revoked the extension prompts
476
479
  * once; a refusal forgets the wallet, so the next load stays silent. A manual
477
480
  * `connect()` or `disconnect()` on a remembered wallet ends its automatic
478
- * reconnect for the session. A `disconnect()` while the automatic reconnect
479
- * still waits for the extension aborts it without forgetting the wallet, so
480
- * the next load reconnects it.
481
+ * reconnect for the session. A `disconnect()` forgets the wallet whatever
482
+ * its status, so one made while the automatic reconnect still waits for the
483
+ * extension aborts it, and the next load does not reconnect it.
481
484
  * Automatic reconnect also ends when the wallet disappears mid-attempt; the
482
485
  * wallet stays remembered for the next load.
483
486
  *
@@ -543,7 +546,8 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
543
546
  * settles at once unless it hydrated as `connecting`. Then it settles when
544
547
  * connected once its account list has been read (an empty list counts) or
545
548
  * connected with no cached accounts, disconnected with `error` set, or
546
- * disconnected and not remembered when hydration began. At
549
+ * disconnected and not remembered (a wallet remembered after hydration
550
+ * began does not count). At
547
551
  * `hydrationTimeout` hydration ends whatever is pending, and a wallet whose
548
552
  * reconnect is still pending stays `connecting`.
549
553
  *
@@ -561,9 +565,6 @@ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly Kheopskit
561
565
  * or name changing), which may never happen, so waiting for it would
562
566
  * hold most failed reconnects until `hydrationTimeout`. A retry that
563
567
  * does run shows on the live wallet's `status`, not as a placeholder.
564
- * - A remembered wallet the user disconnects during or right after its
565
- * reconnect holds hydration, and shows its cached accounts, until
566
- * `hydrationTimeout`.
567
568
  * - A prompt the extension opens for a revoked site holds hydration until
568
569
  * the user answers or `hydrationTimeout` elapses.
569
570
  *
@@ -696,4 +697,4 @@ type CachedAccount = {
696
697
  };
697
698
  //#endregion
698
699
  export { getWalletId as A, WalletStatus as C, KheopskitError as D, isWalletConnectWallet as E, parseWalletAccountId as F, parseWalletId as M, WalletAccountId as N, KheopskitErrorCode as O, getWalletAccountId as P, WalletPlatform as S, isInjectedWallet as T, WalletConnectMetadata as _, CachedAccount as a, WalletConnectWallet as b, KheopskitConfig as c, KheopskitStore as d, KheopskitStoreData as f, PolkadotAccountType as g, PlatformContext as h, BaseWalletAccount as i, isValidWalletId as j, WalletId as k, KheopskitPlatform as l, PlaceholderWallet as m, AppKitInstance as n, CachedWallet as o, Placeholder as p, BaseWallet as r, ConnectOptions as s, AccountOf as t, KheopskitState as u, WalletConnectPlugin as v, WalletType as w, WalletOf as x, WalletConnectProvider as y };
699
- //# sourceMappingURL=types-DCaL9bIc.d.mts.map
700
+ //# sourceMappingURL=types-C3I3w0jb.d.ts.map