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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/MIGRATING_TO_V6.md +56 -39
  3. package/README.md +48 -35
  4. package/dist/ethereum.d.mts +2 -1
  5. package/dist/ethereum.d.ts +2 -1
  6. package/dist/index.d.mts +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +21 -16
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +22 -17
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/internal.d.mts +1 -1
  13. package/dist/internal.d.ts +1 -1
  14. package/dist/polkadot.d.mts +1 -1
  15. package/dist/polkadot.d.ts +1 -1
  16. package/dist/polkadot.js +24 -41
  17. package/dist/polkadot.js.map +1 -1
  18. package/dist/polkadot.mjs +25 -42
  19. package/dist/polkadot.mjs.map +1 -1
  20. package/dist/registryReads-BpHsWLd7.js +38 -0
  21. package/dist/registryReads-BpHsWLd7.js.map +1 -0
  22. package/dist/{pageLoad-BZ7o8p5R.mjs → registryReads-BvtznSo3.mjs} +12 -3
  23. package/dist/registryReads-BvtznSo3.mjs.map +1 -0
  24. package/dist/solana.d.mts +2 -1
  25. package/dist/solana.d.ts +2 -1
  26. package/dist/solana.js +1 -0
  27. package/dist/solana.js.map +1 -1
  28. package/dist/solana.mjs +1 -0
  29. package/dist/solana.mjs.map +1 -1
  30. package/dist/testing.d.mts +1 -1
  31. package/dist/testing.d.ts +1 -1
  32. package/dist/types-BWHvNFlN.js.map +1 -1
  33. package/dist/{types-Dkyt9bf4.d.ts → types-DCaL9bIc.d.mts} +45 -29
  34. package/dist/{types-Dkyt9bf4.d.mts → types-DCaL9bIc.d.ts} +45 -29
  35. package/dist/types-Yor672md.mjs.map +1 -1
  36. package/dist/walletconnect.d.mts +1 -1
  37. package/dist/walletconnect.d.ts +1 -1
  38. package/package.json +1 -1
  39. package/dist/pageLoad-BZ7o8p5R.mjs.map +0 -1
  40. package/dist/pageLoad-D1wLeuFG.js +0 -28
  41. package/dist/pageLoad-D1wLeuFG.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @kheopskit/core
2
2
 
3
+ ## 6.0.0-rc.2
4
+
5
+ ### Minor Changes
6
+
7
+ - [#155](https://github.com/kheopskit/kheopskit/pull/155) [`d3a05e1`](https://github.com/kheopskit/kheopskit/commit/d3a05e14f6eebebf182f3d2ddfee4057321fbab0) Thanks [@0xKheops](https://github.com/0xKheops)! - Added: `account.name` is readable on every account type. Solana accounts take it from the Wallet Standard `label`, and Ethereum accounts leave it `undefined`.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#157](https://github.com/kheopskit/kheopskit/pull/157) [`2eb5c08`](https://github.com/kheopskit/kheopskit/commit/2eb5c086c201763e84065e05785012d0a845d05d) Thanks [@0xKheops](https://github.com/0xKheops)! - Fixed: Polkadot discovery now reads `window.injectedWeb3` at `load` and 100, 300, 600 and 1100 ms after it, as it already did after subscribe. `isDiscovering` is `true` until the last read, 1100 ms after `load` or after subscribe, whichever is later, so no read is pending once it turns `false`, and that emission lists every extension injected before that read. With `config.walletConnect`, it also waits for the connector to load. A subscription that starts after `load` no longer reads `false` from its first emission. On the server, the registry is read once and no timer is set.
12
+
13
+ Hydration waits for discovery only while a cached wallet has not been discovered. When every cached wallet is discovered and settled, `isHydrating` ends at the grace period without waiting for `load`.
14
+
15
+ ## 6.0.0-rc.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [#152](https://github.com/kheopskit/kheopskit/pull/152) [`af84029`](https://github.com/kheopskit/kheopskit/commit/af84029112400600db23a901bb8e8fea10366f2b) Thanks [@0xKheops](https://github.com/0xKheops)! - Fixed: a Polkadot `connect()` started while the extension prompt of an abandoned attempt (aborted `signal` or `disconnect()`) is still open now waits for that prompt instead of calling `enable()` again, and connects when the user approves it. Before, Talisman rejected the new attempt with `USER_REJECTED` ("has not been authorised") and polkadot-js with `CONNECT_FAILED` ("Pending authorisation request already exists"), and approving the first prompt connected nothing.
20
+
3
21
  ## 6.0.0-rc.0
4
22
 
5
23
  ### Major Changes
@@ -48,8 +48,8 @@ This guide grows with each v6 change. Each section covers one area.
48
48
  | Test kit | none; apps fake `injectedWeb3` themselves | `@kheopskit/core/testing` | [6](#6-test-kit) |
49
49
  | Placeholder SDK handles | typed as present, `undefined` at runtime while hydrating | absent from the placeholder type; narrow on `isPlaceholder` | [7](#7-placeholders-carry-isplaceholder) |
50
50
  | `connect()` on a placeholder | throws `PendingWalletError` | waits for the live wallet, or rejects `WALLET_PENDING` | [7](#7-placeholders-carry-isplaceholder) |
51
- | Hydration end | `isHydrating` stays `true` until every cached connected wallet reconnected, capped at six times the grace period | `isHydrating` ends once the grace period has elapsed, discovery has ended and every wallet that hydrated as `connecting` has settled, or at `hydrationTimeout` (default 3000 ms) | [8](#8-discovery-hydration-end-and-persistence) |
52
- | Discovery at page load | the Polkadot registry was read at 0, 100, 300, 600 and 1100 ms after subscribe only | read again at `load` and 100 ms later; `state.isDiscovering` says whether that read has landed | [8](#8-discovery-hydration-end-and-persistence) |
51
+ | Hydration end | `isHydrating` stays `true` until every cached connected wallet reconnected, capped at six times the grace period | `isHydrating` ends once the grace period has elapsed and every cached wallet has settled, or at `hydrationTimeout` (default 3000 ms); a cached wallet not yet discovered settles when discovery ends | [8](#8-discovery-hydration-end-and-persistence) |
52
+ | Discovery at page load | the Polkadot registry was read at 0, 100, 300, 600 and 1100 ms after subscribe only | read at subscribe and at `load`, then 100, 300, 600 and 1100 ms after each; `state.isDiscovering` is `true` until the last read, 1100 ms after `load` or after subscribe, whichever is later, and while a WalletConnect connector loads | [8](#8-discovery-hydration-end-and-persistence) |
53
53
  | Cache during a slow reconnect | a reconnect slower than the persistence debounce wrote `isConnected: false` and no accounts | a wallet still `connecting` keeps its previous cached entry and accounts | [8](#8-discovery-hydration-end-and-persistence) |
54
54
  | React instance and hooks | `createKheopskit` returns a provider and `useWallets`/`useAccounts`; reaching one wallet means reading the whole state; unmounting the provider leaves the pipeline running | `createKheopskit` also returns `kheopskit$` and `store`; `useWallet`, `useAccount` and `useConnect` read one item; unmounting the provider stops the pipeline | [9](#9-kheopskitreact-one-shared-instance-and-wallet-hooks) |
55
55
 
@@ -59,10 +59,13 @@ This guide grows with each v6 change. Each section covers one area.
59
59
 
60
60
  Each section ends with the app code it makes redundant. In short:
61
61
 
62
- - A page-load gate that waits a fixed delay before concluding that a wallet is
63
- missing. Wait for `isDiscovering` to turn `false` (section 8).
62
+ - A gate that delays subscribing until `load`, and a fixed grace after it
63
+ before concluding that a wallet is missing. Both are redundant, because the
64
+ read window now runs until 1100 ms after `load` or after subscribe,
65
+ whichever is later. Wait for `isDiscovering` to turn `false` (section 8).
64
66
  - Connect dedup wrappers, such as a `requestOnce` or `connectOnce` map keyed by
65
- wallet id (section 1).
67
+ wallet id (section 1). An app that calls `connect()` in reaction to state
68
+ must then skip a wallet whose `error.code` is `USER_REJECTED`.
66
69
  - `auditTime(20)` or `debounceTime(20)` placed after `kheopskit$` to skip the
67
70
  stale intermediate state (section 1).
68
71
  - Refusal detection by `error.name === "Error"` or by message text. Branch on
@@ -152,7 +155,9 @@ try {
152
155
  no caller without one joined, on `disconnect()`, or when the last `kheopskit$`
153
156
  subscriber unsubscribes; those reject every remaining caller `ABORTED`.
154
157
  - **Resolution follows the state.** `connect()` resolves once `kheopskit$` has
155
- emitted a state in which the wallet has `isConnected: true`. `disconnect()`
158
+ emitted a state in which the wallet has `isConnected: true`. An injected
159
+ wallet's refused or failed `connect()` rejects after `kheopskit$` has
160
+ emitted the wallet `disconnected` with that `error`. `disconnect()`
156
161
  first waits for the platform's disconnect, when the platform has one, then
157
162
  resolves once a state shows `isConnected: false`, or once a later
158
163
  `connect()`, the wallet leaving the list or the end of the subscription
@@ -172,10 +177,13 @@ try {
172
177
  - **No default timeout.** A Polkadot extension prompt pends until the user
173
178
  answers it. Pass `AbortSignal.timeout(ms)` to cap your wait for the platform's
174
179
  answer. The wait for the state after a grant is not capped. Aborting ends
175
- your wait; it cannot close the extension's own prompt. Once no caller waits
176
- any more, kheopskit drops a handle the extension returns afterwards without
177
- revoking the extension's grant, and the wallet is neither connected nor
178
- remembered.
180
+ your wait; it cannot close the extension's own prompt. A `connect()` started
181
+ while that prompt is open, after an abort or a `disconnect()`, waits for the
182
+ same prompt instead of asking the extension again, and connects with the
183
+ handle it returns. Once no caller waits any more and no later `connect()`
184
+ joined that prompt, kheopskit drops a handle the extension returns
185
+ afterwards without revoking the extension's grant, and the wallet is
186
+ neither connected nor remembered.
179
187
  - **A wallet that disappears.** A `connect()` whose wallet leaves the list (an
180
188
  extension removed, a Wallet Standard wallet unregistered) before the platform
181
189
  grants it rejects `ABORTED`. Granted first, it resolves and the wallet stays
@@ -235,7 +243,12 @@ try {
235
243
  ### What to delete in your app
236
244
 
237
245
  - Dedup wrappers around `connect()`, such as a `requestOnce` or `connectOnce`
238
- map keyed by wallet id.
246
+ map keyed by wallet id. Kheopskit shares only concurrent calls. A refused
247
+ attempt has ended when its `USER_REJECTED` state is emitted, so a
248
+ `connect()` made in reaction to that state asks the extension again. An app
249
+ that connects from state skips a wallet whose `error.code` is
250
+ `USER_REJECTED`. The map used to hide this, because its entry outlived the
251
+ emission.
239
252
  - `auditTime(20)` or `debounceTime(20)` placed after `kheopskit$` to skip the
240
253
  stale intermediate state.
241
254
  - Treating `WALLET_ALREADY_CONNECTED` as success and swallowing
@@ -673,19 +686,19 @@ has no live stream behind it, `connect()` rejects `WALLET_PENDING`.
673
686
 
674
687
  ### New state field: `isDiscovering`
675
688
 
676
- `KheopskitState.isDiscovering` is new and required. It is `true` until the page
677
- has fired `load` and kheopskit has read `window.injectedWeb3` again, so the
678
- emission that turns it `false` already lists every Polkadot extension injected
679
- by then. It is `false` from the first emission when you subscribe after
680
- `load`, and always `true` on the server.
689
+ `KheopskitState.isDiscovering` is new and required. It is `true` until the
690
+ last read of `window.injectedWeb3`, 1100 ms after `load` or after subscribe,
691
+ whichever is later, so the emission that turns it `false` already lists every
692
+ Polkadot extension injected before that read. With `config.walletConnect`, it
693
+ also waits for the connector to load. It is always `true` on the server.
681
694
 
682
- Kheopskit now reads the Polkadot registry at `load` and 100 ms after `load`, on
683
- top of the reads at subscribe and 100, 300, 600 and 1100 ms after it. An
684
- extension that injects after the 1100 ms read but before `load` is listed
685
- without a reload. Nothing reads the registry after the last of these reads. A
686
- wallet that injects after `load` is listed only when a read still runs after
687
- it, the one 100 ms after `load` or a subscribe read still pending, so its
688
- discovery is not guaranteed.
695
+ Kheopskit reads the Polkadot registry at subscribe and 100, 300, 600 and
696
+ 1100 ms after it, as in 5.x. At `load` it starts the same schedule again, and
697
+ drops the subscribe reads still pending. An extension that injects after the
698
+ 1100 ms read but before `load`, or up to 1100 ms after `load`, is listed
699
+ without a reload. A wallet that injects after the last read is not listed
700
+ until the next subscription. On the server kheopskit reads once and sets no
701
+ timer.
689
702
 
690
703
  A state literal or test mock typed as `KheopskitState` must add the field:
691
704
 
@@ -699,8 +712,10 @@ A state literal or test mock typed as `KheopskitState` must add the field:
699
712
  };
700
713
  ```
701
714
 
702
- Hydration now also waits for discovery. With a cache, `isHydrating` stays
703
- `true` until `load` or `hydrationTimeout`, whichever comes first. A
715
+ Hydration waits for discovery only while a cached wallet has not been
716
+ discovered. When every cached wallet injects early, `isHydrating` ends at the
717
+ grace period without waiting for `load`. A cached wallet that has not appeared
718
+ holds it until discovery ends or `hydrationTimeout`, whichever comes first. A
704
719
  `hydrationGracePeriod` of `0` still turns hydration off in `kheopskit$`. Under
705
720
  `KheopskitProvider`, the first render still shows the cached placeholders with
706
721
  `isHydrating: true` until the first emission.
@@ -721,14 +736,15 @@ grace period.
721
736
 
722
737
  ### New end rule
723
738
 
724
- `isHydrating` turns `false` once `hydrationGracePeriod` has elapsed, discovery
725
- has ended (`isDiscovering` is `false`), and every wallet that hydrated as
726
- `connecting` has settled. A wallet has settled when it is absent from the
727
- discovered wallets, connected once its account list has been read (an empty
728
- list counts) or connected with no cached accounts, disconnected with `error`
729
- set, or disconnected and not remembered when hydration began. At
730
- `hydrationTimeout` hydration ends whatever is pending, and a wallet whose
731
- reconnect is still pending stays `connecting`.
739
+ `isHydrating` turns `false` once `hydrationGracePeriod` has elapsed and every
740
+ cached wallet has settled. A cached wallet missing from the discovered wallets
741
+ settles when discovery ends (`isDiscovering` is `false`). A discovered one
742
+ settles at once unless it hydrated as `connecting`. Then it settles when
743
+ connected once its account list has been read (an empty list counts) or
744
+ connected with no cached accounts, disconnected with `error` set, or
745
+ disconnected and not remembered when hydration began. At `hydrationTimeout`
746
+ hydration ends whatever is pending, and a wallet whose reconnect is still
747
+ pending stays `connecting`.
732
748
 
733
749
  "Its account list has been read" relies on a signal the built-in plugins send.
734
750
  A custom `KheopskitPlatform` plugin, or a wrapper that pipes a built-in
@@ -736,9 +752,8 @@ plugin's `getAccounts$`, does not send it. Such a wallet settles on its first
736
752
  listed account, as in 5.x, and a reconnected wallet with cached accounts that
737
753
  now lists none holds hydration until `hydrationTimeout`.
738
754
 
739
- - Discovery ends only after the page fires `load`, so a page with a cache
740
- hydrates until `load` or `hydrationTimeout`, whichever comes first, even
741
- when no wallet reconnects.
755
+ - When every cached wallet is discovered and settled, hydration ends at the
756
+ grace period, without waiting for `load`.
742
757
  - A wallet that reconnects without sharing any account with the site settles
743
758
  as soon as it answers; its cached accounts leave the list when hydration
744
759
  ends.
@@ -754,9 +769,11 @@ now lists none holds hydration until `hydrationTimeout`.
754
769
  user answers or `hydrationTimeout` elapses. After a refusal the wallet is
755
770
  forgotten, so the next load opens no prompt.
756
771
 
757
- In practice, with the extension removed or with `autoReconnect: false`,
758
- hydration no longer runs to 3 s. It ends once the grace period has elapsed and
759
- the page has loaded, or at `hydrationTimeout` if that comes first.
772
+ In practice, hydration no longer runs to 3 s. With `autoReconnect: false` and
773
+ the extension installed, it ends at the grace period. With the extension
774
+ removed, it ends when discovery ends, 1100 ms after `load` or after subscribe,
775
+ whichever is later (or once a WalletConnect connector has loaded, if later),
776
+ or at `hydrationTimeout` if that comes first.
760
777
 
761
778
  ### Persistence guarantee
762
779
 
package/README.md CHANGED
@@ -110,6 +110,7 @@ implements them.
110
110
  ### Discovery
111
111
 
112
112
  Source: [`api/polkadot/wallets.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/api/polkadot/wallets.ts),
113
+ [`utils/registryReads.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/utils/registryReads.ts),
113
114
  [`utils/pageLoad.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/utils/pageLoad.ts),
114
115
  [`api/kheopskit.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/api/kheopskit.ts).
115
116
 
@@ -117,16 +118,15 @@ Polkadot extensions register themselves on `window.injectedWeb3` and send no
117
118
  event, so kheopskit reads that registry on a fixed schedule:
118
119
 
119
120
  - At subscribe, then 100, 300, 600 and 1100 ms after subscribe.
120
- - When `window` fires `load`, and again 100 ms after `load`. A subscription
121
- that starts after `load` skips these two reads.
121
+ - When `window` fires `load`, then 100, 300, 600 and 1100 ms after `load`. The
122
+ subscribe reads still pending at `load` are dropped. A subscription that
123
+ starts after `load` has only the subscribe reads.
122
124
 
123
- Nothing reads the registry after the last of these reads. A wallet that
124
- injects after `load` is listed only when a read still runs after it, the one
125
- 100 ms after `load` or a subscribe read still pending, so its discovery is not
126
- guaranteed. Wallets inject `injectedWeb3` while the page loads, so a wallet
127
- that injects after the last read is not listed until the next subscription,
128
- usually the next page load. Kheopskit has no
129
- `refreshWallets()` and does not read again on focus or on connect.
125
+ The read window ends 1100 ms after `load` or after subscribe, whichever is
126
+ later. Nothing reads the registry after that, so a wallet that injects later
127
+ is not listed until the next subscription, usually the next page load.
128
+ Kheopskit has no `refreshWallets()` and does not read again on focus or on
129
+ connect. On the server it reads once and sets no timer.
130
130
 
131
131
  Ethereum (EIP-6963, through `mipd`) and Solana (Wallet Standard) wallets
132
132
  announce themselves with events, so those lists update whenever a wallet
@@ -134,19 +134,19 @@ announces or unregisters.
134
134
 
135
135
  `state.isDiscovering` tells you whether the list may still grow:
136
136
 
137
- - `true` when the subscription started before `document.readyState` was
138
- `"complete"`.
139
- - It turns `false` in the first emission after `load` in which the registry was
140
- read again. That emission already lists every extension injected by `load`.
141
- Wait for it before you conclude that a wallet is missing.
142
- - `false` from the first emission when you subscribe after `load`.
137
+ - `true` until the read window ends, 1100 ms after `load` or after subscribe,
138
+ whichever is later, and while a WalletConnect connector loads.
139
+ - It turns `false` in the emission of the last read, or once the
140
+ WalletConnect connector has loaded if that comes later. That emission lists
141
+ every Polkadot extension injected before the last read. Wait for it before
142
+ you conclude that a wallet is missing.
143
143
  - Always `true` on the server.
144
144
 
145
- It says nothing about wallets that inject after `load`. In the end-to-end test
146
- `e2e/tests/discovery-at-load.spec.ts`, an extension injected 1500 ms after the
147
- first read and before `load` showed in the wallet list 16.2 ms after `load` on
148
- vite-react, and 15.8 to 18.3 ms across the three example apps (the test's
149
- limit is 300 ms).
145
+ In the end-to-end test `e2e/tests/discovery-at-load.spec.ts`, an extension
146
+ injected 1500 ms after the first read and before `load` showed in the wallet
147
+ list 23.9 ms after `load` on vite-react, and 13.1 to 23.9 ms across the three
148
+ example apps (the test's limit is 300 ms). The "Looking for wallets…" status
149
+ went away 1114 to 1124 ms after `load`.
150
150
 
151
151
  ### Hydration
152
152
 
@@ -190,13 +190,14 @@ its `connect()` joins that reconnect. A Polkadot wallet's `extension` stays
190
190
  `isHydrating` turns `false` once all three hold:
191
191
 
192
192
  1. `hydrationGracePeriod` has elapsed (default 500 ms).
193
- 2. Discovery has ended (`isDiscovering` is `false`), so a page with a cache
194
- hydrates until `load` or `hydrationTimeout`, whichever comes first.
195
- 3. Every wallet that hydrated as `connecting` has settled. A wallet has
196
- settled when it is absent from the discovered wallets, connected once its
197
- account list has been read (an empty list counts) or connected with no
198
- cached accounts, disconnected with `error` set, or disconnected and not
199
- remembered when hydration began.
193
+ 2. Every cached wallet has been discovered, or discovery has ended
194
+ (`isDiscovering` is `false`). When every cached wallet injects early,
195
+ hydration does not wait for `load`. A cached wallet that has not appeared
196
+ holds it until discovery ends.
197
+ 3. Every discovered wallet that hydrated as `connecting` has settled. It has
198
+ settled when connected once its account list has been read (an empty list
199
+ counts) or connected with no cached accounts, disconnected with `error`
200
+ set, or disconnected and not remembered when hydration began.
200
201
 
201
202
  At `hydrationTimeout` (default 3000 ms) hydration ends whatever is pending, and
202
203
  a wallet whose reconnect is still pending stays `connecting`. The timeout wins
@@ -314,7 +315,8 @@ code:
314
315
  last `kheopskit$` subscriber unsubscribes. An abort after the platform
315
316
  granted the connect changes nothing, and a Polkadot extension counts as
316
317
  granted only once its account list has been read. Aborting cannot close the
317
- extension's own prompt.
318
+ extension's own prompt, so a Polkadot `connect()` started while it is open
319
+ waits for that prompt instead of asking again.
318
320
  - **No default timeout.** An extension prompt pends only while the user has
319
321
  not answered it, so kheopskit sets no timeout. Pass `AbortSignal.timeout(ms)`
320
322
  to cap the wait.
@@ -400,6 +402,13 @@ the order the extension lists them in. `state.wallets` follows the same
400
402
  platform order, then the WalletConnect connector, with Talisman first, then by
401
403
  name.
402
404
 
405
+ Every account has an optional `name`. On Polkadot it is the account name the
406
+ extension lists. On Solana it is the Wallet Standard `label`, when the wallet
407
+ provides one. On Ethereum it is always `undefined`, because EIP-1193 and
408
+ EIP-6963 expose no account name. A wallet can report an empty name, so
409
+ `account.name || account.address` gives a display label on every platform. A
410
+ cached placeholder keeps the `name` of the account it stands for.
411
+
403
412
  ### Persistence
404
413
 
405
414
  Source: [`api/store.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/api/store.ts),
@@ -665,15 +674,19 @@ fail.
665
674
 
666
675
  ### Design choices
667
676
 
668
- - Kheopskit does not look for wallets that inject after `load`, and has no
669
- `refreshWallets()`. Wallets inject at page load, and a rescan would add
670
- timers and states for a case no supported wallet produces.
677
+ - Kheopskit stops reading the Polkadot registry when the read window ends, and
678
+ has no `refreshWallets()`. Wallets inject at page load, and a permanent
679
+ watcher would add timers and states for a case no supported wallet produces.
671
680
  - No `walletsReady` promise. It would be a second surface for the one fact
672
681
  `isDiscovering` carries.
673
- - No longer fixed poll. Any duration is still a guess about how long a page
674
- takes to boot, and wallets inject before `load`.
675
- - Discovery does not end at the last scheduled read (1100 ms). On a warm load
676
- that is slower than `load`, for no gain.
682
+ - The read window restarts at `load` instead of running a longer poll from
683
+ subscribe. Its coverage after `load` then no longer depends on when the app
684
+ subscribes.
685
+ - Discovery ends with the last read, 1100 ms after `load` (or once a
686
+ WalletConnect connector has loaded, if later), not at `load`, so a wallet
687
+ that injects shortly after `load` is listed before `isDiscovering` turns
688
+ `false`.
689
+ Hydration waits for that end only while a cached wallet is missing.
677
690
  - `remembered` is read once at subscribe. A live read would make a connect in
678
691
  one tab connect every open tab, with no matching disconnect.
679
692
  - No `persist: false` option. The `autoReconnect` predicate covers "do not
@@ -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-Dkyt9bf4.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-DCaL9bIc.mjs";
2
2
  import { Account, CustomTransport, EIP1193Provider, WalletClient } from "viem";
3
3
  //#region src/utils/isEthereumAddress.d.ts
4
4
  /**
@@ -47,6 +47,7 @@ type LiveEthereumAccount = {
47
47
  address: `0x${string}`;
48
48
  /** Current chain ID the wallet is connected to. `undefined` while loading or after provider disconnect. */
49
49
  chainId: number | undefined;
50
+ name?: string;
50
51
  walletName: string;
51
52
  walletId: WalletId;
52
53
  };
@@ -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-Dkyt9bf4.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-DCaL9bIc.js";
2
2
  import { Account, CustomTransport, EIP1193Provider, WalletClient } from "viem";
3
3
  //#region src/utils/isEthereumAddress.d.ts
4
4
  /**
@@ -47,6 +47,7 @@ type LiveEthereumAccount = {
47
47
  address: `0x${string}`;
48
48
  /** Current chain ID the wallet is connected to. `undefined` while loading or after provider disconnect. */
49
49
  chainId: number | undefined;
50
+ name?: string;
50
51
  walletName: string;
51
52
  walletId: WalletId;
52
53
  };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as SyncableStorage } from "./storage-D3AwNgqc.mjs";
2
- import { A as getWalletId, C as WalletStatus, D as KheopskitError, E as isWalletConnectWallet, F as parseWalletAccountId, M as parseWalletId, N as WalletAccountId, O as KheopskitErrorCode, P as getWalletAccountId, S as WalletPlatform, T as isInjectedWallet, _ as WalletConnectMetadata, a as CachedAccount, b as WalletConnectWallet, c as KheopskitConfig, d as KheopskitStore, f as KheopskitStoreData, g as PolkadotAccountType, h as PlatformContext, i as BaseWalletAccount, j as isValidWalletId, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, n as AppKitInstance, o as CachedWallet, p as Placeholder, r as BaseWallet, s as ConnectOptions, t as AccountOf, u as KheopskitState, v as WalletConnectPlugin, w as WalletType, x as WalletOf, y as WalletConnectProvider } from "./types-Dkyt9bf4.mjs";
2
+ import { A as getWalletId, C as WalletStatus, D as KheopskitError, E as isWalletConnectWallet, F as parseWalletAccountId, M as parseWalletId, N as WalletAccountId, O as KheopskitErrorCode, P as getWalletAccountId, S as WalletPlatform, T as isInjectedWallet, _ as WalletConnectMetadata, a as CachedAccount, b as WalletConnectWallet, c as KheopskitConfig, d as KheopskitStore, f as KheopskitStoreData, g as PolkadotAccountType, h as PlatformContext, i as BaseWalletAccount, j as isValidWalletId, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, n as AppKitInstance, o as CachedWallet, p as Placeholder, r as BaseWallet, s as ConnectOptions, t as AccountOf, u as KheopskitState, v as WalletConnectPlugin, w as WalletType, x as WalletOf, y as WalletConnectProvider } from "./types-DCaL9bIc.mjs";
3
3
  import { t as clearAllCachedObservables } from "./getCachedObservable-LUq9IfEx.mjs";
4
4
  import { Observable } from "rxjs";
5
5
  //#region src/utils/isValidAddress.d.ts
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as SyncableStorage } from "./storage-D3AwNgqc.js";
2
- import { A as getWalletId, C as WalletStatus, D as KheopskitError, E as isWalletConnectWallet, F as parseWalletAccountId, M as parseWalletId, N as WalletAccountId, O as KheopskitErrorCode, P as getWalletAccountId, S as WalletPlatform, T as isInjectedWallet, _ as WalletConnectMetadata, a as CachedAccount, b as WalletConnectWallet, c as KheopskitConfig, d as KheopskitStore, f as KheopskitStoreData, g as PolkadotAccountType, h as PlatformContext, i as BaseWalletAccount, j as isValidWalletId, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, n as AppKitInstance, o as CachedWallet, p as Placeholder, r as BaseWallet, s as ConnectOptions, t as AccountOf, u as KheopskitState, v as WalletConnectPlugin, w as WalletType, x as WalletOf, y as WalletConnectProvider } from "./types-Dkyt9bf4.js";
2
+ import { A as getWalletId, C as WalletStatus, D as KheopskitError, E as isWalletConnectWallet, F as parseWalletAccountId, M as parseWalletId, N as WalletAccountId, O as KheopskitErrorCode, P as getWalletAccountId, S as WalletPlatform, T as isInjectedWallet, _ as WalletConnectMetadata, a as CachedAccount, b as WalletConnectWallet, c as KheopskitConfig, d as KheopskitStore, f as KheopskitStoreData, g as PolkadotAccountType, h as PlatformContext, i as BaseWalletAccount, j as isValidWalletId, k as WalletId, l as KheopskitPlatform, m as PlaceholderWallet, n as AppKitInstance, o as CachedWallet, p as Placeholder, r as BaseWallet, s as ConnectOptions, t as AccountOf, u as KheopskitState, v as WalletConnectPlugin, w as WalletType, x as WalletOf, y as WalletConnectProvider } from "./types-DCaL9bIc.js";
3
3
  import { t as clearAllCachedObservables } from "./getCachedObservable-LUq9IfEx.js";
4
4
  import { Observable } from "rxjs";
5
5
  //#region src/utils/isValidAddress.d.ts
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ 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
4
  const require_iconCache = require("./iconCache-FR4iy6go.js");
5
- const require_pageLoad = require("./pageLoad-D1wLeuFG.js");
5
+ const require_registryReads = require("./registryReads-BpHsWLd7.js");
6
6
  let rxjs = require("rxjs");
7
7
  let lodash_es = require("lodash-es");
8
8
  //#region src/api/config.ts
@@ -557,7 +557,7 @@ const getDefaultStore = () => {
557
557
  };
558
558
  //#endregion
559
559
  //#region src/api/wallets.ts
560
- const getWallets$ = (config, store) => {
560
+ const getWallets$ = (config, store, registryReads$) => {
561
561
  const rememberedWalletIds$ = store.observable.pipe((0, rxjs.map)((s) => s.remembered ?? []), (0, rxjs.take)(1), (0, rxjs.shareReplay)({
562
562
  bufferSize: 1,
563
563
  refCount: true
@@ -565,7 +565,8 @@ const getWallets$ = (config, store) => {
565
565
  return new rxjs.Observable((subscriber) => {
566
566
  const ctx = {
567
567
  config,
568
- store
568
+ store,
569
+ registryReads$
569
570
  };
570
571
  const observables = config.platforms.map((plugin) => plugin.getWallets$(ctx));
571
572
  const reconnectPolicy = createReconnectPolicy();
@@ -711,26 +712,32 @@ const getKheopskit$ = (config, options = {}) => {
711
712
  wrapped.set(wallet, settled);
712
713
  return settled;
713
714
  };
714
- const liveWallets$ = getWallets$(kc, store);
715
+ const registryReads$ = require_registryReads.createRegistryReads$().pipe((0, rxjs.shareReplay)({
716
+ bufferSize: 1,
717
+ refCount: true
718
+ }));
719
+ const liveWallets$ = getWallets$(kc, store, registryReads$);
715
720
  const accountFrames$ = getAccounts$(kc, liveWallets$);
716
721
  const liveAccounts$ = accountFrames$.pipe((0, rxjs.map)(({ accounts }) => accounts.map(asLive)));
717
- const isDiscovering$ = require_pageLoad.pageLoaded$.pipe((0, rxjs.switchMap)((loaded) => loaded ? liveWallets$.pipe((0, rxjs.take)(1), (0, rxjs.map)(() => false)) : (0, rxjs.of)(true)), (0, rxjs.shareReplay)({
722
+ const isDiscovering$ = (0, rxjs.concat)((0, rxjs.of)(true), registryReads$.pipe((0, rxjs.ignoreElements)()), liveWallets$.pipe((0, rxjs.take)(1), (0, rxjs.map)(() => false))).pipe((0, rxjs.shareReplay)({
718
723
  bufferSize: 1,
719
724
  refCount: true
720
725
  }));
721
- const reconnecting = cachedWallets.filter((w) => w.status === "connecting");
722
726
  const hydrationSettled$ = (0, rxjs.combineLatest)([
723
727
  liveWallets$,
724
728
  accountFrames$.pipe((0, rxjs.startWith)(noAnswerYet)),
725
729
  isDiscovering$,
726
730
  store.observable.pipe((0, rxjs.map)((s) => s.remembered ?? []), (0, rxjs.take)(1))
727
- ]).pipe((0, rxjs.map)(([wallets, { accounts, answered }, isDiscovering, remembered]) => !isDiscovering && reconnecting.every((cached) => reconnectSettled(cached, {
728
- wallets,
729
- accounts,
730
- answered,
731
- cachedAccounts,
732
- remembered
733
- }))), (0, rxjs.debounceTime)(0, rxjs.asapScheduler), (0, rxjs.distinctUntilChanged)());
731
+ ]).pipe((0, rxjs.map)(([wallets, { accounts, answered }, isDiscovering, remembered]) => cachedWallets.every((cached) => {
732
+ const wallet = wallets.find((w) => w.id === cached.id);
733
+ if (!wallet) return !isDiscovering;
734
+ return cached.status !== "connecting" || reconnectSettled(cached, wallet, {
735
+ accounts,
736
+ answered,
737
+ cachedAccounts,
738
+ remembered
739
+ });
740
+ })), (0, rxjs.debounceTime)(0, rxjs.asapScheduler), (0, rxjs.distinctUntilChanged)());
734
741
  const bufferedWallets$ = createHydrationBuffer(cachedWallets, liveWallets$.pipe((0, rxjs.map)((wallets) => wallets.map(asLive))), kc.hydrationGracePeriod, kc.hydrationTimeout, (w) => w.id, hydrationSettled$, (live, cached) => {
735
742
  const status = sessionRestoring(live, cached) ? "connecting" : live.status;
736
743
  return {
@@ -832,9 +839,7 @@ const noAnswerYet = {
832
839
  * waiting for its reconnect: getWallets$ emits the wallet list before its
833
840
  * connect() flips the status to connecting.
834
841
  */
835
- const reconnectSettled = (cached, live) => {
836
- const wallet = live.wallets.find((w) => w.id === cached.id);
837
- if (!wallet) return true;
842
+ const reconnectSettled = (cached, wallet, live) => {
838
843
  const status = sessionRestoring(wallet, cached) ? "connecting" : wallet.status;
839
844
  if (status === "connecting") return false;
840
845
  if (status === "disconnected") return wallet.error !== void 0 || !live.remembered.includes(cached.id);