@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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @kheopskit/core
2
2
 
3
+ ## 6.0.0-rc.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#160](https://github.com/kheopskit/kheopskit/pull/160) [`4e55488`](https://github.com/kheopskit/kheopskit/commit/4e5548833b782669f00e33452f5ed4dff9ddcac0) Thanks [@0xKheops](https://github.com/0xKheops)! - Fixed: a remembered wallet forgotten before it injects is no longer reconnected when it does. A placeholder's `disconnect()` now forgets the wallet, or calls the live wallet's `disconnect()` once that one is discovered. `store.forgetWallet(walletId)` during the session cancels the automatic reconnect for good, even if the wallet is remembered again. `disconnect()` now forgets the wallet whatever its status, including while its automatic reconnect waits for the extension or after that reconnect failed, so the next load does not reconnect it. A wallet the user disconnects during hydration no longer holds `isHydrating` until `hydrationTimeout`.
8
+
3
9
  ## 6.0.0-rc.2
4
10
 
5
11
  ### Minor Changes
@@ -274,7 +274,7 @@ try {
274
274
 
275
275
  The list holds the injected wallets the user connected. Kheopskit adds a
276
276
  wallet on every successful connect, whatever `config.autoReconnect` says, and
277
- removes it when a connected wallet is disconnected. The WalletConnect
277
+ removes it on every `disconnect()`, whatever the wallet's status. The WalletConnect
278
278
  connector is never added; AppKit restores its own session. The `autoReconnect`
279
279
  config option keeps its name and meaning. It decides whether the remembered
280
280
  wallets reconnect on load.
@@ -492,8 +492,8 @@ stays silent. Any other failure sets `wallet.error`, keeps the wallet
492
492
  remembered and is retried on the next change to the wallet list, 3 attempts in
493
493
  total. A manual `connect()` or `disconnect()` on a remembered wallet ends its
494
494
  automatic reconnect for the session. A `disconnect()` while the automatic
495
- reconnect still waits for the extension aborts it without forgetting the
496
- wallet, so the next load reconnects it. Automatic reconnect also ends when the
495
+ reconnect still waits for the extension aborts it and forgets the wallet, so
496
+ the next load does not reconnect it. Automatic reconnect also ends when the
497
497
  wallet disappears mid-attempt; the wallet stays remembered for the next load.
498
498
  Nothing is written to `console.error` any more; `debug: true` logs the failure
499
499
  with `console.debug`.
@@ -763,8 +763,6 @@ now lists none holds hydration until `hydrationTimeout`.
763
763
  may never happen, so waiting
764
764
  for it would hold most failed reconnects until `hydrationTimeout`. A retry
765
765
  that does run shows on the live wallet's `status`, not as a placeholder.
766
- - A remembered wallet the user disconnects during or right after its reconnect
767
- holds hydration, and shows its cached accounts, until `hydrationTimeout`.
768
766
  - A prompt the extension opens for a revoked site holds hydration until the
769
767
  user answers or `hydrationTimeout` elapses. After a refusal the wallet is
770
768
  forgotten, so the next load opens no prompt.
package/README.md CHANGED
@@ -180,7 +180,9 @@ A placeholder wallet is never connected. Its `connect()` waits for kheopskit to
180
180
  discover the live wallet with the same id and connects that one. It rejects
181
181
  with `WALLET_PENDING` if hydration ends first, and with `ABORTED` if its
182
182
  `signal` fires or the last subscriber unsubscribes while it waits. Its
183
- `disconnect()` resolves at once. A cached wallet that kheopskit has already
183
+ `disconnect()` forgets the wallet and resolves at once, so kheopskit does not
184
+ reconnect it when it injects. Once the live wallet is discovered, it calls the
185
+ live wallet's `disconnect()` instead. A cached wallet that kheopskit has already
184
186
  discovered is no longer a placeholder. It carries its live `connect()` and
185
187
  `disconnect()` and shows `status: "connecting"` while its reconnect runs, and
186
188
  its `connect()` joins that reconnect. A Polkadot wallet's `extension` stays
@@ -197,7 +199,8 @@ its `connect()` joins that reconnect. A Polkadot wallet's `extension` stays
197
199
  3. Every discovered wallet that hydrated as `connecting` has settled. It has
198
200
  settled when connected once its account list has been read (an empty list
199
201
  counts) or connected with no cached accounts, disconnected with `error`
200
- set, or disconnected and not remembered when hydration began.
202
+ set, or disconnected and not remembered. A wallet remembered after
203
+ hydration began does not count.
201
204
 
202
205
  At `hydrationTimeout` (default 3000 ms) hydration ends whatever is pending, and
203
206
  a wallet whose reconnect is still pending stays `connecting`. The timeout wins
@@ -209,8 +212,6 @@ over a longer grace period, so an app that raises `hydrationGracePeriod` sets
209
212
  ends.
210
213
  - A failed reconnect ends that wallet's wait, even when the reconnect policy
211
214
  still permits a retry.
212
- - A remembered wallet the user disconnects during or right after its reconnect
213
- holds hydration, and shows its cached accounts, until `hydrationTimeout`.
214
215
  - A prompt the extension opens for a revoked site holds hydration until the
215
216
  user answers or `hydrationTimeout` elapses.
216
217
  - "Its account list has been read" relies on a signal that the built-in
@@ -241,8 +242,8 @@ Source: [`api/wallets.ts`](https://github.com/kheopskit/kheopskit/blob/main/pack
241
242
  [`api/injectedWallets.ts`](https://github.com/kheopskit/kheopskit/blob/main/packages/core/src/api/injectedWallets.ts).
242
243
 
243
244
  Kheopskit adds an injected wallet to the store's `remembered` list on every
244
- successful `connect()` and removes it when `disconnect()` starts on a
245
- connected wallet, whatever `autoReconnect` says, so an app can turn reconnect
245
+ successful `connect()` and removes it when `disconnect()` starts, whatever the
246
+ wallet's status and whatever `autoReconnect` says, so an app can turn reconnect
246
247
  on later. On the next load it reconnects the remembered injected wallets that
247
248
  `autoReconnect` accepts:
248
249
 
@@ -277,7 +278,13 @@ or removed, or any wallet's status changing), 3 attempts in total. If the list
277
278
  never changes again, no retry runs. A manual `connect()` or `disconnect()` on a
278
279
  remembered wallet ends its automatic reconnect for the session. A
279
280
  `disconnect()` while the automatic reconnect still waits for the extension
280
- aborts it without forgetting the wallet, so the next load reconnects it.
281
+ aborts it and forgets the wallet, so the next load does not reconnect it.
282
+ Forgetting a wallet with `store.forgetWallet(walletId)`, or calling
283
+ `disconnect()` on its placeholder before it injects, ends its automatic
284
+ reconnect for the rest of the session, even if the wallet is remembered again.
285
+ The next load reconnects it only if it is remembered by then.
286
+ `store.forgetWallet(walletId)` does not stop an attempt that already
287
+ waits for the extension. The wallet's `disconnect()` does.
281
288
  Automatic reconnect also ends when the wallet disappears mid-attempt, and the
282
289
  wallet stays remembered for the next load.
283
290
 
@@ -432,9 +439,8 @@ goes to `localStorage` as JSON:
432
439
  ```
433
440
 
434
441
  - `remembered` lists the injected wallets the user connected. It is written as
435
- soon as a connect succeeds and cleared as soon as `disconnect()` starts on a
436
- connected wallet. A `disconnect()` that aborts a pending connect leaves it
437
- unchanged.
442
+ soon as a connect succeeds and cleared as soon as `disconnect()` starts,
443
+ whatever the wallet's status.
438
444
  - `cachedWallets` and `cachedAccounts` are written by the hydration rule above:
439
445
  after hydration ends, 1 second after the state stops changing.
440
446
  - Wallet icons go to a separate `localStorage` key, `kheopskit-icons`, to keep
@@ -687,8 +693,9 @@ fail.
687
693
  that injects shortly after `load` is listed before `isDiscovering` turns
688
694
  `false`.
689
695
  Hydration waits for that end only while a cached wallet is missing.
690
- - `remembered` is read once at subscribe. A live read would make a connect in
691
- one tab connect every open tab, with no matching disconnect.
696
+ - A wallet remembered after subscribe is not reconnected. Reconnecting it
697
+ would make a connect in one tab connect every open tab, with no matching
698
+ disconnect. A wallet forgotten after subscribe is not reconnected either.
692
699
  - No `persist: false` option. The `autoReconnect` predicate covers "do not
693
700
  reconnect", and `storageKey` keeps two dapps apart.
694
701
 
@@ -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 { Account, CustomTransport, EIP1193Provider, WalletClient } from "viem";
3
3
  //#region src/utils/isEthereumAddress.d.ts
4
4
  /**
@@ -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 { Account, CustomTransport, EIP1193Provider, WalletClient } from "viem";
3
3
  //#region src/utils/isEthereumAddress.d.ts
4
4
  /**
package/dist/ethereum.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 viem = require("viem");
7
7
  let mipd = require("mipd");
package/dist/ethereum.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _ as getCachedObservable$, a as isEip1193UserRejection, h as clearCachedObservable, n as isWalletConnectWallet, t as isInjectedWallet, u as getWalletId } from "./types-Yor672md.mjs";
2
2
  import { d as isEthereumAddress, i as getSessionCaip10s, o as getWalletAccountId, r as getCaip10Addresses, t as createPlatformAccounts$ } 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, ReplaySubject, combineLatest, distinctUntilChanged, map, of, shareReplay } from "rxjs";
5
5
  import { createWalletClient, custom, getAddress } from "viem";
6
6
  import { createStore } from "mipd";
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-DCaL9bIc.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-C3I3w0jb.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-DCaL9bIc.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-C3I3w0jb.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
@@ -3,8 +3,8 @@ 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
5
  const require_registryReads = require("./registryReads-BpHsWLd7.js");
6
- let rxjs = require("rxjs");
7
6
  let lodash_es = require("lodash-es");
7
+ let rxjs = require("rxjs");
8
8
  //#region src/api/config.ts
9
9
  /**
10
10
  * Default storage key for persisting wallet connection state.
@@ -107,6 +107,10 @@ const createReconnectPolicy = ({ maxAttempts = 3 } = {}) => {
107
107
  };
108
108
  };
109
109
  const reconnectAccepts = (autoReconnect, wallet) => typeof autoReconnect === "function" ? autoReconnect(wallet) : autoReconnect;
110
+ const reconnectCandidates$ = (store) => {
111
+ const remembered$ = store.observable.pipe((0, rxjs.map)((s) => s.remembered ?? []));
112
+ return remembered$.pipe((0, rxjs.take)(1), (0, rxjs.switchMap)((initial) => remembered$.pipe((0, rxjs.scan)((remaining, current) => remaining.filter((id) => current.includes(id)), initial))), (0, rxjs.distinctUntilChanged)(lodash_es.isEqual));
113
+ };
110
114
  //#endregion
111
115
  //#region src/api/hydration.ts
112
116
  /**
@@ -558,10 +562,6 @@ const getDefaultStore = () => {
558
562
  //#endregion
559
563
  //#region src/api/wallets.ts
560
564
  const getWallets$ = (config, store, registryReads$) => {
561
- const rememberedWalletIds$ = store.observable.pipe((0, rxjs.map)((s) => s.remembered ?? []), (0, rxjs.take)(1), (0, rxjs.shareReplay)({
562
- bufferSize: 1,
563
- refCount: true
564
- }));
565
565
  return new rxjs.Observable((subscriber) => {
566
566
  const ctx = {
567
567
  config,
@@ -599,7 +599,7 @@ const getWallets$ = (config, store, registryReads$) => {
599
599
  };
600
600
  const subWallets = wallets$.subscribe(subscriber);
601
601
  if (subscriber.closed) return subWallets;
602
- const subAutoReconnect = (0, rxjs.combineLatest)([rawWallets$, rememberedWalletIds$]).pipe((0, rxjs.filter)(([, walletIds]) => config.autoReconnect !== false && walletIds.length > 0), (0, rxjs.mergeMap)(([wallets, walletIds]) => wallets.filter(require_types.isInjectedWallet).filter((wallet) => walletIds.includes(wallet.id))), (0, rxjs.tap)((wallet) => {
602
+ const subAutoReconnect = rawWallets$.pipe((0, rxjs.withLatestFrom)(reconnectCandidates$(store)), (0, rxjs.filter)(([, walletIds]) => config.autoReconnect !== false && walletIds.length > 0), (0, rxjs.mergeMap)(([wallets, walletIds]) => wallets.filter(require_types.isInjectedWallet).filter((wallet) => walletIds.includes(wallet.id))), (0, rxjs.tap)((wallet) => {
603
603
  if (wallet.status === "connected") reconnectPolicy.settle(wallet.id);
604
604
  }), (0, rxjs.filter)((wallet) => wallet.status === "disconnected" && reconnectAccepts(config.autoReconnect, wallet))).subscribe(reconnect);
605
605
  return () => {
@@ -683,6 +683,12 @@ const getKheopskit$ = (config, options = {}) => {
683
683
  const live = await whenLive(placeholder.id, options?.signal);
684
684
  if (closed) throw require_types.abortedError(placeholder.id, "connect");
685
685
  await live.connect(options);
686
+ },
687
+ disconnect: async () => {
688
+ if (closed) return;
689
+ const live = latest?.wallets.find((w) => w.id === placeholder.id && !w.isPlaceholder);
690
+ if (live) return live.disconnect();
691
+ store.forgetWallet(placeholder.id);
686
692
  }
687
693
  });
688
694
  const settleWithState = (wallet) => {
@@ -727,7 +733,7 @@ const getKheopskit$ = (config, options = {}) => {
727
733
  liveWallets$,
728
734
  accountFrames$.pipe((0, rxjs.startWith)(noAnswerYet)),
729
735
  isDiscovering$,
730
- store.observable.pipe((0, rxjs.map)((s) => s.remembered ?? []), (0, rxjs.take)(1))
736
+ reconnectCandidates$(store)
731
737
  ]).pipe((0, rxjs.map)(([wallets, { accounts, answered }, isDiscovering, remembered]) => cachedWallets.every((cached) => {
732
738
  const wallet = wallets.find((w) => w.id === cached.id);
733
739
  if (!wallet) return !isDiscovering;