@kheopskit/core 5.3.0 → 6.0.0-rc.0

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +426 -0
  2. package/MIGRATING_TO_V6.md +837 -0
  3. package/README.md +628 -12
  4. package/dist/ethereum.d.mts +12 -6
  5. package/dist/ethereum.d.ts +12 -6
  6. package/dist/ethereum.js +13 -10
  7. package/dist/ethereum.js.map +1 -1
  8. package/dist/ethereum.mjs +7 -4
  9. package/dist/ethereum.mjs.map +1 -1
  10. package/dist/{iconCache-pP2ES4pJ.mjs → iconCache-C-U3IEbP.mjs} +21 -40
  11. package/dist/iconCache-C-U3IEbP.mjs.map +1 -0
  12. package/dist/{iconCache-DUtkJlaX.js → iconCache-FR4iy6go.js} +21 -40
  13. package/dist/iconCache-FR4iy6go.js.map +1 -0
  14. package/dist/index.d.mts +17 -63
  15. package/dist/index.d.ts +17 -63
  16. package/dist/index.js +387 -373
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +384 -369
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/injectedWallets-48L-AL1I.mjs +173 -0
  21. package/dist/injectedWallets-48L-AL1I.mjs.map +1 -0
  22. package/dist/injectedWallets-Dy8YGKL-.js +178 -0
  23. package/dist/injectedWallets-Dy8YGKL-.js.map +1 -0
  24. package/dist/internal.d.mts +3 -27
  25. package/dist/internal.d.ts +3 -27
  26. package/dist/internal.js +2 -2
  27. package/dist/internal.mjs +2 -2
  28. package/dist/pageLoad-BZ7o8p5R.mjs +24 -0
  29. package/dist/pageLoad-BZ7o8p5R.mjs.map +1 -0
  30. package/dist/pageLoad-D1wLeuFG.js +28 -0
  31. package/dist/pageLoad-D1wLeuFG.js.map +1 -0
  32. package/dist/platformAccounts-BjIeRcFN.js +321 -0
  33. package/dist/platformAccounts-BjIeRcFN.js.map +1 -0
  34. package/dist/platformAccounts-yyRUrnel.mjs +256 -0
  35. package/dist/platformAccounts-yyRUrnel.mjs.map +1 -0
  36. package/dist/polkadot.d.mts +127 -11
  37. package/dist/polkadot.d.ts +127 -11
  38. package/dist/polkadot.js +170 -106
  39. package/dist/polkadot.js.map +1 -1
  40. package/dist/polkadot.mjs +163 -99
  41. package/dist/polkadot.mjs.map +1 -1
  42. package/dist/solana.d.mts +11 -5
  43. package/dist/solana.d.ts +11 -5
  44. package/dist/solana.js +18 -15
  45. package/dist/solana.js.map +1 -1
  46. package/dist/solana.mjs +7 -4
  47. package/dist/solana.mjs.map +1 -1
  48. package/dist/storage-D3AwNgqc.d.mts +27 -0
  49. package/dist/storage-D3AwNgqc.d.ts +27 -0
  50. package/dist/testing.d.mts +71 -0
  51. package/dist/testing.d.ts +71 -0
  52. package/dist/testing.js +136 -0
  53. package/dist/testing.js.map +1 -0
  54. package/dist/testing.mjs +131 -0
  55. package/dist/testing.mjs.map +1 -0
  56. package/dist/{types-DKU-SNio.js → types-BWHvNFlN.js} +149 -2
  57. package/dist/types-BWHvNFlN.js.map +1 -0
  58. package/dist/types-Dkyt9bf4.d.mts +683 -0
  59. package/dist/types-Dkyt9bf4.d.ts +683 -0
  60. package/dist/types-Yor672md.mjs +215 -0
  61. package/dist/types-Yor672md.mjs.map +1 -0
  62. package/dist/walletconnect.d.mts +41 -0
  63. package/dist/walletconnect.d.ts +41 -0
  64. package/dist/walletconnect.js +219 -0
  65. package/dist/walletconnect.js.map +1 -0
  66. package/dist/walletconnect.mjs +216 -0
  67. package/dist/walletconnect.mjs.map +1 -0
  68. package/package.json +30 -6
  69. package/dist/errors-BLFP1dQI.mjs +0 -181
  70. package/dist/errors-BLFP1dQI.mjs.map +0 -1
  71. package/dist/errors-DYWVPHrR.js +0 -222
  72. package/dist/errors-DYWVPHrR.js.map +0 -1
  73. package/dist/iconCache-DUtkJlaX.js.map +0 -1
  74. package/dist/iconCache-pP2ES4pJ.mjs.map +0 -1
  75. package/dist/injectedWallets-BqR-_aAy.js +0 -148
  76. package/dist/injectedWallets-BqR-_aAy.js.map +0 -1
  77. package/dist/injectedWallets-Uz4hPuoW.mjs +0 -119
  78. package/dist/injectedWallets-Uz4hPuoW.mjs.map +0 -1
  79. package/dist/types-AxUDtkR-.d.mts +0 -338
  80. package/dist/types-AxUDtkR-.d.ts +0 -338
  81. package/dist/types-DKU-SNio.js.map +0 -1
  82. package/dist/types-jnifAAA0.mjs +0 -104
  83. package/dist/types-jnifAAA0.mjs.map +0 -1
@@ -0,0 +1,683 @@
1
+ import { Observable } from "rxjs";
2
+ //#region src/utils/WalletAccountId.d.ts
3
+ type WalletAccountId = string;
4
+ declare const getWalletAccountId: (walletId: string, address: string) => WalletAccountId;
5
+ declare const parseWalletAccountId: (accountId: string) => {
6
+ walletId: string;
7
+ address: string;
8
+ };
9
+ //#endregion
10
+ //#region src/utils/WalletId.d.ts
11
+ type WalletId = string;
12
+ declare const getWalletId: (platform: WalletPlatform, identifier: string) => WalletId;
13
+ declare const parseWalletId: (walletId: string) => {
14
+ platform: WalletPlatform;
15
+ identifier: string;
16
+ };
17
+ /**
18
+ * Non-throwing variant of {@link parseWalletId}. Use when validating untrusted
19
+ * input (e.g. cached state persisted by an older version) before parsing.
20
+ */
21
+ declare const isValidWalletId: (walletId: unknown) => walletId is WalletId;
22
+ //#endregion
23
+ //#region src/api/errors.d.ts
24
+ /**
25
+ * Stable error codes thrown by kheopskit. Catch a {@link KheopskitError} and
26
+ * branch on `error.code` instead of matching message strings.
27
+ */
28
+ type KheopskitErrorCode =
29
+ /**
30
+ * This `connect()` or `disconnect()` call was abandoned. For `connect()`:
31
+ * its `signal` fired before the platform answered, `disconnect()` was
32
+ * called while it pended, its wallet disappeared, or the last `kheopskit$`
33
+ * subscriber unsubscribed.
34
+ * For either call on an injected wallet: the wallet object came from a
35
+ * subscription that had already ended, in which case the call rejects
36
+ * without asking the platform and without changing the remembered list. A
37
+ * placeholder's `connect()` rejects the same way, its `disconnect()`
38
+ * resolves, and the WalletConnect connector still calls AppKit.
39
+ */
40
+ "ABORTED" |
41
+ /** The user refused the wallet's connect prompt. `cause` holds the platform error. */
42
+ "USER_REJECTED" |
43
+ /** The wallet's connect call failed for another reason. `cause` holds the platform error. */
44
+ "CONNECT_FAILED" |
45
+ /**
46
+ * `connect()` was called on a placeholder wallet restored from the cache:
47
+ * on `kheopskit$`, hydration ended without kheopskit discovering that
48
+ * wallet; on `getHydratedSnapshot` and the React provider's initial
49
+ * snapshot, always.
50
+ */
51
+ "WALLET_PENDING" |
52
+ /** The wallet does not advertise a capability kheopskit needs to proceed. */
53
+ "FEATURE_NOT_SUPPORTED" |
54
+ /** No active WalletConnect session for the requested operation. */
55
+ "NO_SESSION" |
56
+ /** No provider available for the requested namespace. */
57
+ "NO_PROVIDER" |
58
+ /** The installed polkadot-api version exposes neither `getTxCreatorFromPjs` (v3) nor `getPolkadotSignerFromPjs` (v2). */
59
+ "UNSUPPORTED_VERSION" |
60
+ /** The requested chain cannot be used for this operation (e.g. a Solana cluster with no CAIP-2 id over WalletConnect). */
61
+ "UNSUPPORTED_CHAIN" |
62
+ /** `getKheopskit$` received a config value it cannot use. The message names the fix. */
63
+ "INVALID_CONFIG";
64
+ /**
65
+ * Error thrown by kheopskit wallet/account operations. Carries a stable
66
+ * {@link KheopskitErrorCode} and, when relevant, the offending wallet id.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * try {
71
+ * await wallet.connect();
72
+ * } catch (error) {
73
+ * if (error instanceof KheopskitError && error.code === "USER_REJECTED") {
74
+ * // the user closed or refused the wallet prompt
75
+ * } else throw error;
76
+ * }
77
+ * ```
78
+ */
79
+ declare class KheopskitError extends Error {
80
+ readonly code: KheopskitErrorCode;
81
+ /** The wallet id this error relates to, when applicable. */
82
+ readonly walletId?: WalletId;
83
+ constructor(code: KheopskitErrorCode, message: string, options?: {
84
+ walletId?: WalletId;
85
+ cause?: unknown;
86
+ });
87
+ }
88
+ //#endregion
89
+ //#region src/api/types.d.ts
90
+ type WalletPlatform = "polkadot" | "ethereum" | "solana";
91
+ /**
92
+ * Minimal structural view of a WalletConnect `UniversalProvider`, the subset
93
+ * kheopskit reads. Declared locally so core never depends on
94
+ * `@walletconnect/universal-provider`. The concrete instance comes from
95
+ * `@reown/appkit` at runtime.
96
+ */
97
+ type WalletConnectProvider = {
98
+ session?: {
99
+ topic: string;
100
+ namespaces: Record<string, {
101
+ accounts?: string[];
102
+ }>;
103
+ };
104
+ client: {
105
+ request<T = unknown>(args: {
106
+ topic: string;
107
+ chainId: string;
108
+ request: {
109
+ method: string;
110
+ params: unknown;
111
+ };
112
+ }): Promise<T>;
113
+ };
114
+ request(args: {
115
+ method: string;
116
+ params?: unknown;
117
+ }): Promise<unknown>;
118
+ on(event: string, listener: (...args: unknown[]) => void): void;
119
+ off(event: string, listener: (...args: unknown[]) => void): void;
120
+ };
121
+ /**
122
+ * Minimal structural view of the Reown AppKit instance, the subset kheopskit's
123
+ * account factories use. Exposed as the `appKit` escape hatch on AppKit wallets;
124
+ * cast it to `@reown/appkit`'s `AppKit` type for the full API. Declared locally
125
+ * so core never depends on `@reown/appkit`'s types (it's an optional peer).
126
+ */
127
+ type AppKitInstance = {
128
+ getProvider<T = WalletConnectProvider>(namespace: string): T | undefined;
129
+ getAccount(namespace: string): {
130
+ allAccounts: {
131
+ address: string;
132
+ }[];
133
+ } | undefined;
134
+ getCaipNetworks(namespace: string): {
135
+ caipNetworkId?: string;
136
+ }[];
137
+ };
138
+ type WalletType = "injected" | "walletconnect";
139
+ /**
140
+ * Where a wallet stands with the dapp. `connecting` covers a `connect()` call
141
+ * in flight and an auto-reconnect in flight alike.
142
+ */
143
+ type WalletStatus = "disconnected" | "connecting" | "connected";
144
+ type PolkadotAccountType = "sr25519" | "ed25519" | "ecdsa" | "ethereum";
145
+ /** Options accepted by {@link BaseWallet.connect}. */
146
+ type ConnectOptions = {
147
+ /**
148
+ * Ends this caller's wait for the platform's answer: its promise rejects
149
+ * with a `KheopskitError` of code `ABORTED`. An abort after the platform
150
+ * has granted the connect changes nothing, and a Polkadot extension counts
151
+ * as granted only once its account list has been read. Other callers
152
+ * sharing the attempt keep waiting. Once no caller waits any more,
153
+ * kheopskit drops a handle the platform hands back afterwards without
154
+ * revoking the platform's grant, and the wallet is neither connected nor
155
+ * remembered. The
156
+ * extension's own prompt may stay open: nothing can withdraw it from the
157
+ * page. Kheopskit sets no timeout of its own, because an extension prompt
158
+ * pends only while the user has not answered it; pass
159
+ * `AbortSignal.timeout(ms)` to cap the wait.
160
+ */
161
+ signal?: AbortSignal;
162
+ };
163
+ /**
164
+ * SDK-free fields common to every wallet, regardless of platform. Platform
165
+ * packages (`@kheopskit/core/<platform>`) extend this with SDK-typed fields
166
+ * (the injected provider/extension/standard-wallet handle).
167
+ */
168
+ type BaseWallet = {
169
+ /** `<platform>:<identifier>`, e.g. `polkadot:talisman`. Stable across reloads. */
170
+ id: WalletId;
171
+ /** The platform whose registry listed the wallet. */
172
+ platform: WalletPlatform;
173
+ /**
174
+ * `"injected"`, for a browser extension or Wallet Standard wallet. The
175
+ * WalletConnect connector is the separate {@link WalletConnectWallet}.
176
+ */
177
+ type: WalletType;
178
+ /** Display name, e.g. `Talisman`. */
179
+ name: string;
180
+ /** Icon URL or data URI. `""` when the wallet exposes none. */
181
+ icon: string;
182
+ /**
183
+ * `true` for a wallet restored from the cache that kheopskit has not
184
+ * discovered yet: its SDK handle and `sourceId` are absent and it is never
185
+ * connected. On `kheopskit$` its `connect()` waits for the live wallet and
186
+ * connects that one, rejecting with `WALLET_PENDING` if hydration ends first
187
+ * and `ABORTED` if its `signal` fires or the subscription ends. On
188
+ * `getHydratedSnapshot` it rejects with `WALLET_PENDING`. Its `disconnect()`
189
+ * resolves at once. Set on every wallet of `kheopskit$` and of the hydrated
190
+ * snapshot; plugins leave it unset.
191
+ */
192
+ isPlaceholder?: boolean;
193
+ /**
194
+ * `connecting` while a `connect()` call or an auto-reconnect waits for the
195
+ * platform, `connected` once the platform granted it, `disconnected`
196
+ * otherwise. On a reload, a remembered wallet kheopskit will reconnect is
197
+ * `connecting` from the first frame when the cache recorded it connected,
198
+ * which the cache does 1 s after the state settles.
199
+ */
200
+ status: WalletStatus;
201
+ /**
202
+ * The last `connect()` or auto-reconnect that the platform refused or
203
+ * failed (`USER_REJECTED` or `CONNECT_FAILED`, or `FEATURE_NOT_SUPPORTED`
204
+ * for a Wallet Standard wallet without `standard:connect`). Cleared when
205
+ * the next attempt starts. An aborted attempt sets nothing.
206
+ */
207
+ error?: KheopskitError;
208
+ /** `status === "connected"`. */
209
+ isConnected: boolean;
210
+ /**
211
+ * Connects the wallet.
212
+ *
213
+ * - **Shared in flight.** Concurrent calls on one wallet share a single
214
+ * platform attempt and the platform is asked once. Each call gets its own
215
+ * promise: aborting a caller's `signal` rejects only that caller with code
216
+ * `ABORTED`. The attempt itself is abandoned only when every caller that
217
+ * passed a signal has aborted and no caller without one joined, when
218
+ * `disconnect()` is called, or when the last `kheopskit$` subscriber
219
+ * unsubscribes; those reject every remaining caller with `ABORTED`.
220
+ * - **Idempotent.** On a connected wallet it resolves at once without
221
+ * touching the platform, unless a `disconnect()` still waits for the
222
+ * platform. It then waits for that disconnect to settle and connects
223
+ * again if the wallet ended up disconnected.
224
+ * - **Abortable.** See {@link ConnectOptions.signal}. There is no default
225
+ * timeout.
226
+ * - **Settles with the state.** It resolves only after `kheopskit$` has
227
+ * emitted a state in which this wallet has `isConnected: true`, so the
228
+ * consumer-visible state already reflects the connect. On platforms that
229
+ * list accounts asynchronously (Ethereum `eth_accounts`), the accounts may
230
+ * arrive in a later emission. No emission shows a disconnected wallet
231
+ * still listing live accounts, or a connected wallet listing the accounts
232
+ * of a previous connection. During hydration a wallet's cached
233
+ * placeholder accounts stay listed whatever its status. Another wallet's
234
+ * pending `eth_accounts` request never delays them. A `disconnect()` that
235
+ * completes while it waits for that state rejects it with `ABORTED`. If
236
+ * the platform's disconnect is still pending or refuses, it resolves once
237
+ * the state shows the wallet connected (today only Solana has a platform
238
+ * disconnect). A `connect()`
239
+ * whose wallet disappears before the platform grants it (an extension
240
+ * removed, a Wallet Standard wallet unregistered) rejects `ABORTED`;
241
+ * granted first, it resolves and the wallet stays remembered. Once the last `kheopskit$`
242
+ * subscriber has unsubscribed, a call on a wallet object from that
243
+ * subscription rejects with `ABORTED` without asking the platform,
244
+ * placeholders included.
245
+ * - **Typed rejections.** A platform rejection is wrapped in a
246
+ * `KheopskitError` carrying the original error as `cause` and the
247
+ * `walletId`: `USER_REJECTED` when the user refused the prompt,
248
+ * `CONNECT_FAILED` otherwise. A Wallet Standard wallet without
249
+ * `standard:connect` rejects with `FEATURE_NOT_SUPPORTED`.
250
+ */
251
+ connect: (options?: ConnectOptions) => Promise<void>;
252
+ /**
253
+ * Disconnects the wallet.
254
+ *
255
+ * On a disconnected wallet it resolves at once. While a `connect()` waits
256
+ * for the platform to grant it, it aborts that connect (its promise rejects
257
+ * with `ABORTED`) and never waits for the extension prompt. Otherwise it
258
+ * first waits for the platform's disconnect and rejects if that fails, so
259
+ * callers can surface or retry. It then resolves once `kheopskit$` has
260
+ * emitted a state in which this wallet has `isConnected: false`, or once a
261
+ * later `connect()`, the wallet leaving the list or the end of the
262
+ * subscription makes that emission impossible. Once the last `kheopskit$`
263
+ * subscriber has unsubscribed, a call on a wallet object from that
264
+ * subscription rejects with `ABORTED` without asking the platform and
265
+ * without changing the remembered list, except on a placeholder, whose
266
+ * `disconnect()` resolves. A `disconnect()` started before that point
267
+ * settles once the platform has answered: the wallet was
268
+ * forgotten when it was called, and nothing else is written once the
269
+ * subscription has ended.
270
+ */
271
+ disconnect: () => Promise<void>;
272
+ };
273
+ /**
274
+ * SDK-free fields common to every account, regardless of platform. Platform
275
+ * packages extend this with their SDK-typed signer/client.
276
+ */
277
+ type BaseWalletAccount = {
278
+ /** `<walletId>::<address>`, e.g. `polkadot:talisman::5Grw…`. */
279
+ id: WalletAccountId;
280
+ /**
281
+ * `true` for an account restored from the cache that the live wallet has
282
+ * not listed yet: its signing surface is absent. Set on every account of
283
+ * `kheopskit$` and of the hydrated snapshot; plugins leave it unset.
284
+ */
285
+ isPlaceholder?: boolean;
286
+ /** The platform of the wallet that lists the account. */
287
+ platform: WalletPlatform;
288
+ /** Base58 (Solana), SS58 (Polkadot) or 0x-hex (Ethereum) address. */
289
+ address: string;
290
+ /** Friendly account name, when the wallet exposes one (e.g. Polkadot). */
291
+ name?: string;
292
+ /** `name` of the wallet that lists the account. */
293
+ walletName: string;
294
+ /** `id` of the wallet that lists the account. */
295
+ walletId: WalletId;
296
+ };
297
+ type LiveWalletConnectWallet = {
298
+ /** See {@link BaseWallet.isPlaceholder}. */
299
+ isPlaceholder?: false;
300
+ /** `"walletconnect"`, the one connector shared by every platform. */
301
+ id: WalletId;
302
+ /** Narrow with {@link isWalletConnectWallet}. */
303
+ type: "walletconnect";
304
+ /**
305
+ * Platforms (namespaces) the live session currently carries. Empty until
306
+ * connected; populated with whatever the wallet approved (e.g. just
307
+ * `["ethereum"]`, or `["polkadot", "ethereum"]`).
308
+ */
309
+ platforms: WalletPlatform[];
310
+ /**
311
+ * Raw Reown AppKit instance, exposed as an escape hatch for advanced use
312
+ * (custom modal control, reading providers directly). Most consumers should
313
+ * use `connect`/`disconnect` and the derived accounts instead.
314
+ */
315
+ appKit: AppKitInstance;
316
+ /** The name AppKit reports for the paired wallet, `"WalletConnect"` when it reports none. */
317
+ name: string;
318
+ /** The icon AppKit reports for the paired wallet, the WalletConnect logo when it reports none. */
319
+ icon: string;
320
+ /**
321
+ * `connecting` while `connect()` opens the modal, `connected` while a
322
+ * session is live, `disconnected` otherwise. On a reload with a cached
323
+ * session it is `connecting` until AppKit restores the session or hydration
324
+ * ends.
325
+ */
326
+ status: WalletStatus;
327
+ /** The last `connect()` whose modal failed to open. Cleared by the next call. */
328
+ error?: KheopskitError;
329
+ /** `status === "connected"`. */
330
+ isConnected: boolean;
331
+ /**
332
+ * Opens the WalletConnect modal and resolves once it is open; `isConnected`
333
+ * follows when the user approves a session. Unlike injected wallets, this
334
+ * promise does not wait for the state to show the connector connected, and
335
+ * `signal` is accepted for signature compatibility only.
336
+ */
337
+ connect: (options?: ConnectOptions) => Promise<void>;
338
+ /** Ends the live session when there is one; resolves at once otherwise. */
339
+ disconnect: () => Promise<void>;
340
+ };
341
+ /**
342
+ * The single WalletConnect connector, shared across every platform.
343
+ *
344
+ * Unlike injected wallets, it is **not tied to a platform**: one WalletConnect
345
+ * session spans whichever namespaces the remote wallet approves in a single
346
+ * pairing (a namespace can't be added to a live session afterwards). So there is
347
+ * exactly one of these in `wallets`, discriminated by `type: "walletconnect"`.
348
+ * Its accounts appear in `accounts`, each carrying its own `platform`.
349
+ *
350
+ * A placeholder (see {@link BaseWallet.isPlaceholder}) has no `appKit`.
351
+ */
352
+ type WalletConnectWallet = LiveWalletConnectWallet | PlaceholderWallet<LiveWalletConnectWallet, "appKit">;
353
+ /**
354
+ * The cached stand-in for a live item `T`: `isPlaceholder: true`, and the
355
+ * fields `K`, which only the live item carries, absent. Platform account and
356
+ * wallet types are `T | Placeholder<T, K>`, so narrow on `isPlaceholder`
357
+ * before reading a field of `K`.
358
+ */
359
+ type Placeholder<T, K extends keyof T> = Omit<T, K | "isPlaceholder"> & {
360
+ /** Restored from the cache and not yet replaced by the live item. */
361
+ isPlaceholder: true;
362
+ } & { [P in K]?: undefined; };
363
+ /** A {@link Placeholder} wallet, which is never connected. */
364
+ type PlaceholderWallet<T extends {
365
+ isConnected: boolean;
366
+ }, K extends keyof T> = Omit<Placeholder<T, K>, "isConnected"> & {
367
+ isConnected: false;
368
+ };
369
+ /** Narrows a wallet to the platform-less {@link WalletConnectWallet}. */
370
+ declare const isWalletConnectWallet: (wallet: BaseWallet | WalletConnectWallet) => wallet is WalletConnectWallet;
371
+ /**
372
+ * Narrows a wallet to an injected (browser-extension / Wallet Standard) wallet,
373
+ * the complement of {@link isWalletConnectWallet}. `state.wallets` is
374
+ * `(InjectedWallet | WalletConnectWallet)[]`, so use this to recover the
375
+ * injected-only fields when iterating: `platform`, `sourceId`, and the SDK
376
+ * handle (`provider` on Ethereum, `extension` on Polkadot, `wallet` on Solana).
377
+ *
378
+ * @example
379
+ * ```ts
380
+ * for (const wallet of wallets.filter(isInjectedWallet)) {
381
+ * console.log(wallet.platform, wallet.sourceId); // typed, no WC widening
382
+ * }
383
+ * ```
384
+ */
385
+ declare const isInjectedWallet: <W extends BaseWallet | WalletConnectWallet>(wallet: W) => wallet is Exclude<W, WalletConnectWallet>;
386
+ /**
387
+ * Dapp metadata shown in the WalletConnect modal. Mirrors WalletConnect's
388
+ * `Metadata`, declared locally so core doesn't depend on
389
+ * `@walletconnect/universal-provider`.
390
+ */
391
+ type WalletConnectMetadata = {
392
+ name: string;
393
+ description: string;
394
+ url: string;
395
+ icons: string[];
396
+ };
397
+ /**
398
+ * The WalletConnect connector for `config.walletConnect`. Create it with
399
+ * `walletConnect()` from `@kheopskit/core/walletconnect`; that entry is the only
400
+ * one that loads Reown AppKit.
401
+ */
402
+ type WalletConnectPlugin = {
403
+ readonly type: "walletconnect";
404
+ readonly metadata: WalletConnectMetadata;
405
+ getWallet$(ctx: PlatformContext): Observable<WalletConnectWallet | null>;
406
+ };
407
+ /**
408
+ * Context passed to a platform plugin's `getWallets$`. Carries the shared store
409
+ * and the resolved core config (for WalletConnect / debug).
410
+ */
411
+ type PlatformContext = {
412
+ store: KheopskitStore;
413
+ config: KheopskitConfig;
414
+ };
415
+ /**
416
+ * A platform plugin. Created by the per-platform factories exported from
417
+ * `@kheopskit/core/polkadot`, `/ethereum`, `/solana`. Core iterates plugins
418
+ * generically and never imports a platform SDK itself.
419
+ *
420
+ * @typeParam TPlatform - the platform discriminant
421
+ * @typeParam TWallet - the platform's wallet type (extends {@link BaseWallet})
422
+ * @typeParam TAccount - the platform's account type (extends {@link BaseWalletAccount})
423
+ */
424
+ type KheopskitPlatform<TPlatform extends WalletPlatform = WalletPlatform, TWallet extends BaseWallet = BaseWallet, TAccount extends BaseWalletAccount = BaseWalletAccount> = {
425
+ readonly platform: TPlatform;
426
+ getWallets$(ctx: PlatformContext): Observable<TWallet[]>;
427
+ getAccounts$(wallets$: Observable<(TWallet | WalletConnectWallet)[]>): Observable<TAccount[]>;
428
+ /**
429
+ * Optional hydration filter. Cached accounts for which this returns false are
430
+ * dropped during SSR hydration (Polkadot uses it to honour `accountTypes`).
431
+ */
432
+ acceptsCachedAccount?(cached: CachedAccount): boolean;
433
+ };
434
+ type ElementOf<T> = T extends readonly (infer E)[] ? E : never;
435
+ /** The account type produced by a plugin (inferred from its `getAccounts$`). */
436
+ type AccountOf<T> = T extends {
437
+ getAccounts$: (wallets$: never) => Observable<infer R>;
438
+ } ? ElementOf<R> : never;
439
+ /** The wallet type produced by a plugin (inferred from its `getWallets$`). */
440
+ type WalletOf<T> = T extends {
441
+ getWallets$: (ctx: never) => Observable<infer R>;
442
+ } ? ElementOf<R> : never;
443
+ type KheopskitConfig<P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[]> = {
444
+ /**
445
+ * Which remembered injected wallets kheopskit reconnects after a reload.
446
+ *
447
+ * A wallet is remembered on every successful `connect()` and forgotten on
448
+ * `disconnect()`, whatever this option says; the list is the store's
449
+ * `remembered`. `true` reconnects every remembered injected wallet, `false`
450
+ * none, and a function is asked for each cached connected injected wallet
451
+ * on the first frame, then for each remembered one with its live object
452
+ * before the attempt. The function must be synchronous and pure. It runs on
453
+ * the server and on the client for the same input and both must agree, or
454
+ * the markup diverges. It receives the {@link BaseWallet} fields only, so
455
+ * key on `id`.
456
+ *
457
+ * The WalletConnect row is not governed by this option: AppKit restores its
458
+ * own session on load, and the row hydrates `connecting` while it does.
459
+ *
460
+ * A reconnect opens no connect prompt while the site stays authorised in
461
+ * the extension. When the authorisation was revoked the extension prompts
462
+ * once; a refusal forgets the wallet, so the next load stays silent. A manual
463
+ * `connect()` or `disconnect()` on a remembered wallet ends its automatic
464
+ * reconnect for the session. A `disconnect()` while the automatic reconnect
465
+ * still waits for the extension aborts it without forgetting the wallet, so
466
+ * the next load reconnects it.
467
+ * Automatic reconnect also ends when the wallet disappears mid-attempt; the
468
+ * wallet stays remembered for the next load.
469
+ *
470
+ * A cached connected wallet this accepts shows `status: "connecting"` from
471
+ * the first frame until its attempt settles. A wallet this rejects shows
472
+ * `disconnected` from the first frame, without its cached accounts, so
473
+ * nothing flashes from connected to disconnected.
474
+ *
475
+ * @default true
476
+ */
477
+ autoReconnect: boolean | ((wallet: BaseWallet) => boolean);
478
+ /**
479
+ * Platform plugins to enable, e.g. `[polkadot(), solana({ chain })]`.
480
+ * Import factories from `@kheopskit/core/<platform>`.
481
+ */
482
+ platforms: P;
483
+ /** Create with `walletConnect()` from `@kheopskit/core/walletconnect`. */
484
+ walletConnect?: WalletConnectPlugin;
485
+ /**
486
+ * Dapp name sent to Polkadot injected extensions on connect. Some
487
+ * extensions (e.g. polkadot.js) warn about a suspicious origin when it's
488
+ * empty.
489
+ *
490
+ * @default walletConnect.metadata.name, then window.location.hostname
491
+ */
492
+ appName?: string;
493
+ /**
494
+ * Logs the resolved config, every state emission and the hydration and
495
+ * persistence steps with `console.debug`.
496
+ *
497
+ * @default false
498
+ */
499
+ debug: boolean;
500
+ /**
501
+ * Custom storage key for persisting wallet connection state.
502
+ * Useful when running multiple kheopskit instances on the same domain
503
+ * to prevent state conflicts between different dapps.
504
+ *
505
+ * @default "kheopskit"
506
+ */
507
+ storageKey: string;
508
+ /**
509
+ * Minimum time in milliseconds the cached placeholders are shown after a
510
+ * reload, so the wallet list does not flash while extensions inject and
511
+ * remembered wallets reconnect. Hydration goes on past it until the rule
512
+ * documented on {@link KheopskitConfig.hydrationTimeout} ends it, and that
513
+ * timeout wins over a longer grace period. The old cap of six times this
514
+ * value is gone, so an app that raises it sets `hydrationTimeout` as well.
515
+ *
516
+ * `0` disables placeholders: `isHydrating` is `false` from the first
517
+ * emission.
518
+ *
519
+ * @default 500
520
+ */
521
+ hydrationGracePeriod: number;
522
+ /**
523
+ * Upper bound in milliseconds on {@link KheopskitState.isHydrating}.
524
+ *
525
+ * `isHydrating` turns `false` once `hydrationGracePeriod` has elapsed,
526
+ * discovery has ended ({@link KheopskitState.isDiscovering} is `false`),
527
+ * and every wallet that hydrated as `connecting` has settled. A wallet has
528
+ * settled when it is absent from the discovered wallets, connected once its
529
+ * account list has been read (an empty list counts) or connected with no
530
+ * cached accounts, disconnected with `error` set, or disconnected and not
531
+ * remembered when hydration began. At `hydrationTimeout` hydration ends
532
+ * whatever is pending, and a wallet whose reconnect is still pending stays
533
+ * `connecting`.
534
+ *
535
+ * - Discovery ends only after the page fires `load`, so a page with a cache
536
+ * hydrates until `load` or `hydrationTimeout`, whichever comes first,
537
+ * even when no wallet reconnects.
538
+ * - A wallet that reconnects without sharing any account with the site
539
+ * settles as soon as it answers; its cached accounts leave the list when
540
+ * hydration ends.
541
+ * - A failed reconnect ends that wallet's wait, even when the reconnect
542
+ * policy still permits a retry. A retry runs only when the wallet list next
543
+ * changes (a wallet discovered or removed, or any wallet's status, error
544
+ * or name changing), which may never happen, so waiting for it would
545
+ * hold most failed reconnects until `hydrationTimeout`. A retry that
546
+ * does run shows on the live wallet's `status`, not as a placeholder.
547
+ * - A remembered wallet the user disconnects during or right after its
548
+ * reconnect holds hydration, and shows its cached accounts, until
549
+ * `hydrationTimeout`.
550
+ * - A prompt the extension opens for a revoked site holds hydration until
551
+ * the user answers or `hydrationTimeout` elapses.
552
+ *
553
+ * @default 3000
554
+ */
555
+ hydrationTimeout: number;
556
+ };
557
+ /**
558
+ * The current kheopskit state.
559
+ *
560
+ * @remarks
561
+ * While {@link KheopskitState.isHydrating} is `true`, `wallets` and `accounts`
562
+ * may contain placeholders restored from the cache, flagged
563
+ * `isPlaceholder: true`. Each platform type is a union on that flag: a
564
+ * placeholder lacks the SDK handles (`account.txCreator` or `polkadotSigner`
565
+ * on Polkadot, `account.client` on Ethereum, `account.signer` / `getSigner` on
566
+ * Solana, `wallet.extension` / `provider` / `wallet` and `sourceId`). Reading
567
+ * one without narrowing yields a possibly-`undefined` value, so the compiler
568
+ * rejects using it as present until you narrow:
569
+ *
570
+ * ```ts
571
+ * if (account.isPlaceholder) return;
572
+ * account.txCreator; // TxCreator
573
+ * ```
574
+ *
575
+ * A placeholder wallet's `connect()` waits for the live wallet and connects
576
+ * it, rejecting with `WALLET_PENDING` if hydration ends first. No item is a
577
+ * placeholder once `isHydrating` is `false`.
578
+ *
579
+ * The plain, serializable platform data that is persisted in the cache IS
580
+ * restored on the placeholders (Ethereum `chainId`, Polkadot key `type`), so it
581
+ * renders immediately on reload without flashing. Solana `chains` is not
582
+ * cached: a placeholder account's is empty.
583
+ */
584
+ type KheopskitState<P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[]> = {
585
+ /**
586
+ * Every discovered wallet, connected or not, then the WalletConnect
587
+ * connector once AppKit has loaded, when `config.walletConnect` is set.
588
+ * While `isHydrating` is `true`, also the cached placeholders. Sorted by
589
+ * platform (Polkadot, Ethereum, Solana, WalletConnect), then Talisman
590
+ * first, then by name.
591
+ */
592
+ wallets: (WalletOf<P[number]> | WalletConnectWallet)[];
593
+ /**
594
+ * The accounts of every connected wallet. While `isHydrating` is `true`,
595
+ * also the cached placeholders of every wallet that has no live account
596
+ * yet. Grouped by platform, then by wallet (Talisman first, then by wallet
597
+ * name); inside a wallet, in the order the wallet lists them.
598
+ */
599
+ accounts: AccountOf<P[number]>[];
600
+ /** The resolved config, with every default filled in. */
601
+ config: KheopskitConfig<P>;
602
+ /**
603
+ * Whether the state is still being hydrated from cache.
604
+ *
605
+ * During hydration, cached wallets/accounts may be displayed before the
606
+ * actual wallet extensions have injected. See the type-level remarks: those
607
+ * are flagged `isPlaceholder: true` and carry no SDK handle.
608
+ */
609
+ isHydrating: boolean;
610
+ /**
611
+ * Whether wallet discovery may still be incomplete.
612
+ *
613
+ * `true` when the subscription started before `document.readyState` was
614
+ * `"complete"`. It turns `false` in the first emission after `window` fired
615
+ * `load` and the Polkadot registry (`window.injectedWeb3`) was read again,
616
+ * so that emission already lists every extension injected by `load`. When the
617
+ * subscription starts after `load`, it is `false` from the first emission.
618
+ * Always `true` on the server.
619
+ *
620
+ * This rests on wallets injecting `injectedWeb3` before `load`. It says
621
+ * nothing about wallets that inject after `load`. Ethereum (EIP-6963) and
622
+ * Solana (Wallet Standard) registries are event-driven and need no re-read.
623
+ */
624
+ isDiscovering: boolean;
625
+ };
626
+ /** Shape of the persisted store data (localStorage, or cookies in compact form). */
627
+ type KheopskitStoreData = {
628
+ /** Wallets the user connected and has not disconnected */
629
+ remembered?: WalletId[];
630
+ /** Cached wallet state for SSR hydration to prevent UI flash */
631
+ cachedWallets?: CachedWallet[];
632
+ /** Cached account state for SSR hydration to prevent UI flash */
633
+ cachedAccounts?: CachedAccount[];
634
+ };
635
+ /**
636
+ * The persisted settings store shared between core and framework bindings.
637
+ * Declared structurally here (implemented by `createKheopskitStore`) so modules
638
+ * can depend on the interface without importing the implementation.
639
+ */
640
+ type KheopskitStore = {
641
+ observable: Observable<KheopskitStoreData>;
642
+ rememberWallet: (walletId: WalletId) => void;
643
+ forgetWallet: (walletId: WalletId) => void;
644
+ getCachedState: () => {
645
+ wallets: CachedWallet[];
646
+ accounts: CachedAccount[];
647
+ };
648
+ setCachedState: (wallets: CachedWallet[], accounts: CachedAccount[]) => void;
649
+ /** Stops cross-tab storage sync and completes `observable`. */
650
+ destroy: () => void;
651
+ };
652
+ /**
653
+ * Serializable wallet data for SSR hydration cache.
654
+ * Contains only the data needed to render wallet UI without flash.
655
+ * Note: icon is NOT stored to save cookie space - it's looked up at hydration time.
656
+ */
657
+ type CachedWallet = {
658
+ id: WalletId;
659
+ /** Absent for the platform-less WalletConnect connector. */
660
+ platform?: WalletPlatform;
661
+ type: WalletType;
662
+ name: string;
663
+ isConnected: boolean;
664
+ };
665
+ /**
666
+ * Serializable account data for SSR hydration cache.
667
+ * Contains only the data needed to render account UI without flash.
668
+ */
669
+ type CachedAccount = {
670
+ id: string;
671
+ platform: WalletPlatform;
672
+ address: string;
673
+ name?: string;
674
+ /** Cached chain ID for Ethereum accounts. */
675
+ chainId?: number;
676
+ /** Cached key type for Polkadot accounts. */
677
+ polkadotAccountType?: PolkadotAccountType;
678
+ walletId: WalletId;
679
+ walletName: string;
680
+ };
681
+ //#endregion
682
+ 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 };
683
+ //# sourceMappingURL=types-Dkyt9bf4.d.ts.map