@kheopskit/core 5.0.1 → 5.1.1

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 (73) hide show
  1. package/dist/errors-Caq2csKx.mjs +181 -0
  2. package/dist/errors-Caq2csKx.mjs.map +1 -0
  3. package/dist/errors-DPw6pc2H.js +222 -0
  4. package/dist/errors-DPw6pc2H.js.map +1 -0
  5. package/dist/ethereum.d.mts +39 -38
  6. package/dist/ethereum.d.ts +39 -38
  7. package/dist/ethereum.js +216 -343
  8. package/dist/ethereum.js.map +1 -1
  9. package/dist/ethereum.mjs +213 -344
  10. package/dist/ethereum.mjs.map +1 -1
  11. package/dist/{getCachedObservable-C4E8dfMp.d.ts → getCachedObservable-LUq9IfEx.d.mts} +5 -2
  12. package/dist/{getCachedObservable-C4E8dfMp.d.mts → getCachedObservable-LUq9IfEx.d.ts} +5 -2
  13. package/dist/iconCache-BSa42Sui.mjs +343 -0
  14. package/dist/iconCache-BSa42Sui.mjs.map +1 -0
  15. package/dist/iconCache-DS4zNiP1.js +396 -0
  16. package/dist/iconCache-DS4zNiP1.js.map +1 -0
  17. package/dist/index.d.mts +98 -36
  18. package/dist/index.d.ts +98 -36
  19. package/dist/index.js +897 -630
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +881 -631
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/injectedWallets-B1MCxAE9.js +148 -0
  24. package/dist/injectedWallets-B1MCxAE9.js.map +1 -0
  25. package/dist/injectedWallets-B3Vysfvr.mjs +119 -0
  26. package/dist/injectedWallets-B3Vysfvr.mjs.map +1 -0
  27. package/dist/internal.d.mts +18 -53
  28. package/dist/internal.d.ts +18 -53
  29. package/dist/internal.js +9 -32
  30. package/dist/internal.mjs +3 -32
  31. package/dist/polkadot.d.mts +37 -36
  32. package/dist/polkadot.d.ts +37 -36
  33. package/dist/polkadot.js +179 -294
  34. package/dist/polkadot.js.map +1 -1
  35. package/dist/polkadot.mjs +176 -295
  36. package/dist/polkadot.mjs.map +1 -1
  37. package/dist/polkadotExtensions-BoVKhNU_.mjs +23 -0
  38. package/dist/polkadotExtensions-BoVKhNU_.mjs.map +1 -0
  39. package/dist/polkadotExtensions-y4J9UzYl.js +28 -0
  40. package/dist/polkadotExtensions-y4J9UzYl.js.map +1 -0
  41. package/dist/solana.d.mts +50 -48
  42. package/dist/solana.d.ts +50 -48
  43. package/dist/solana.js +323 -449
  44. package/dist/solana.js.map +1 -1
  45. package/dist/solana.mjs +316 -449
  46. package/dist/solana.mjs.map +1 -1
  47. package/dist/types-Cb-vuEru.d.mts +330 -0
  48. package/dist/types-Cb-vuEru.d.ts +330 -0
  49. package/dist/types-DKU-SNio.js +169 -0
  50. package/dist/types-DKU-SNio.js.map +1 -0
  51. package/dist/types-jnifAAA0.mjs +104 -0
  52. package/dist/types-jnifAAA0.mjs.map +1 -0
  53. package/package.json +12 -12
  54. package/dist/chunk-4ENHC7G4.js +0 -210
  55. package/dist/chunk-4ENHC7G4.js.map +0 -1
  56. package/dist/chunk-6XAZANB5.mjs +0 -450
  57. package/dist/chunk-6XAZANB5.mjs.map +0 -1
  58. package/dist/chunk-7QSGAJ4A.mjs +0 -210
  59. package/dist/chunk-7QSGAJ4A.mjs.map +0 -1
  60. package/dist/chunk-B4L6GAYD.js +0 -179
  61. package/dist/chunk-B4L6GAYD.js.map +0 -1
  62. package/dist/chunk-BWUUHUDK.mjs +0 -24
  63. package/dist/chunk-BWUUHUDK.mjs.map +0 -1
  64. package/dist/chunk-D3EQMFZ2.js +0 -24
  65. package/dist/chunk-D3EQMFZ2.js.map +0 -1
  66. package/dist/chunk-XQWJM3KC.js +0 -450
  67. package/dist/chunk-XQWJM3KC.js.map +0 -1
  68. package/dist/chunk-YDLCHYHH.mjs +0 -179
  69. package/dist/chunk-YDLCHYHH.mjs.map +0 -1
  70. package/dist/internal.js.map +0 -1
  71. package/dist/internal.mjs.map +0 -1
  72. package/dist/types-C7V7DGlg.d.mts +0 -349
  73. package/dist/types-C7V7DGlg.d.ts +0 -349
package/dist/index.js CHANGED
@@ -1,639 +1,906 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
- var _chunkB4L6GAYDjs = require('./chunk-B4L6GAYD.js');
12
- require('./chunk-D3EQMFZ2.js');
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
- var _chunkXQWJM3KCjs = require('./chunk-XQWJM3KC.js');
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
- var _chunk4ENHC7G4js = require('./chunk-4ENHC7G4.js');
34
-
35
- // src/api/appKit.ts
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- var _rxjs = require('rxjs');
47
- var loadAppKit = async () => {
48
- try {
49
- const { createAppKit } = await Promise.resolve().then(() => _interopRequireWildcard(require("@reown/appkit/core")));
50
- return createAppKit;
51
- } catch (cause) {
52
- console.error(
53
- "[kheopskit] WalletConnect is configured but @reown/appkit could not be loaded. Install it with `pnpm add @reown/appkit` (or remove config.walletConnect). WalletConnect wallets are disabled; injected wallets still work.",
54
- cause
55
- );
56
- return null;
57
- }
58
- };
59
- var WALLET_CONNECT_ICON = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+";
60
- var APPKIT_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.cachedAppKit");
61
- var APPKIT_PROJECT_ID_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.cachedAppKitProjectId");
62
- var getCachedAppKit = () => globalThis[APPKIT_SYMBOL];
63
- var getCachedAppKitProjectId = () => globalThis[APPKIT_PROJECT_ID_SYMBOL];
64
- var setCachedAppKit = (value, projectId) => {
65
- globalThis[APPKIT_SYMBOL] = value;
66
- globalThis[APPKIT_PROJECT_ID_SYMBOL] = projectId;
67
- };
68
- var resetAppKitCache = () => {
69
- setCachedAppKit(void 0);
70
- };
71
- var dropAccountsCache = (platform) => {
72
- _chunk4ENHC7G4js.clearCachedObservablesByPrefix.call(void 0,
73
- `accounts:${_chunk4ENHC7G4js.WALLET_CONNECT_WALLET_ID}:${platform}:`
74
- );
75
- };
76
- var getWalletConnectWallet$ = (config) => {
77
- if (!config.walletConnect) return _rxjs.of.call(void 0, null);
78
- if (typeof window === "undefined") return _rxjs.of.call(void 0, null);
79
- const walletConnect = config.walletConnect;
80
- const cachedProjectId = getCachedAppKitProjectId();
81
- if (cachedProjectId !== void 0 && cachedProjectId !== walletConnect.projectId) {
82
- console.warn(
83
- "[kheopskit] WalletConnect is already initialised with projectId %s; AppKit is a process-wide singleton, so the first configuration wins and projectId %s is ignored. Call resetAppKitCache() before re-initialising if the WalletConnect config must change.",
84
- cachedProjectId,
85
- walletConnect.projectId
86
- );
87
- }
88
- let cachedAppKit = getCachedAppKit();
89
- if (!cachedAppKit) {
90
- cachedAppKit = _rxjs.from.call(void 0, loadAppKit()).pipe(
91
- _rxjs.switchMap.call(void 0, (createAppKit) => {
92
- if (!createAppKit) return _rxjs.of.call(void 0, null);
93
- return new (0, _rxjs.Observable)((subscriber) => {
94
- const appKit = createAppKit({
95
- projectId: walletConnect.projectId,
96
- metadata: walletConnect.metadata,
97
- // Loosely typed in WalletConnectConfig to keep @reown/appkit's
98
- // types out of core; forwarded to AppKit verbatim.
99
- networks: walletConnect.networks,
100
- themeMode: walletConnect.themeMode,
101
- themeVariables: walletConnect.themeVariables,
102
- universalProviderConfigOverride: {
103
- methods: {
104
- polkadot: ["polkadot_signTransaction", "polkadot_signMessage"],
105
- solana: [
106
- "solana_signTransaction",
107
- "solana_signMessage",
108
- "solana_signAndSendTransaction"
109
- ]
110
- }
111
- },
112
- allWallets: "HIDE",
113
- debug: config.debug,
114
- allowUnsupportedChain: true
115
- });
116
- const appKitInstance = appKit;
117
- const status$ = new (0, _rxjs.BehaviorSubject)({
118
- isPolkadotConnected: false,
119
- isEthereumConnected: false,
120
- isSolanaConnected: false
121
- });
122
- const unsubProviders = appKit.subscribeProviders((providers) => {
123
- status$.next({
124
- isPolkadotConnected: !!providers.polkadot,
125
- isEthereumConnected: !!providers.eip155,
126
- isSolanaConnected: !!providers.solana
127
- });
128
- });
129
- const namespaceOf = {
130
- polkadot: "polkadot",
131
- ethereum: "eip155",
132
- solana: "solana"
133
- };
134
- const allPlatforms = [
135
- "polkadot",
136
- "ethereum",
137
- "solana"
138
- ];
139
- const enabledPlatforms = allPlatforms.filter(
140
- (p) => appKit.chainNamespaces.includes(namespaceOf[p])
141
- );
142
- let prevConnected = {
143
- polkadot: false,
144
- ethereum: false,
145
- solana: false
146
- };
147
- const sub = status$.pipe(
148
- _rxjs.map.call(void 0, (s) => ({
149
- polkadot: s.isPolkadotConnected,
150
- ethereum: s.isEthereumConnected,
151
- solana: s.isSolanaConnected
152
- })),
153
- _rxjs.distinctUntilChanged.call(void 0,
154
- (a, b) => a.polkadot === b.polkadot && a.ethereum === b.ethereum && a.solana === b.solana
155
- ),
156
- _rxjs.tap.call(void 0, (connected) => {
157
- for (const platform of allPlatforms)
158
- if (prevConnected[platform] && !connected[platform])
159
- dropAccountsCache(platform);
160
- prevConnected = connected;
161
- }),
162
- _rxjs.map.call(void 0, (connected) => {
163
- const platforms = enabledPlatforms.filter((p) => connected[p]);
164
- const isConnected = platforms.length > 0;
165
- const walletInfo = appKit.getWalletInfo();
166
- return {
167
- id: _chunk4ENHC7G4js.WALLET_CONNECT_WALLET_ID,
168
- type: "walletconnect",
169
- platforms,
170
- appKit: appKitInstance,
171
- name: _nullishCoalesce(_optionalChain([walletInfo, 'optionalAccess', _ => _.name]), () => ( "WalletConnect")),
172
- icon: _nullishCoalesce(_optionalChain([walletInfo, 'optionalAccess', _2 => _2.icon]), () => ( WALLET_CONNECT_ICON)),
173
- // One shared session: connecting opens the modal; the wallet
174
- // approves namespaces in that single pairing. Disconnect is
175
- // session-wide; re-pair to change the approved set.
176
- connect: async () => {
177
- if (!isConnected) await appKit.open();
178
- },
179
- disconnect: async () => {
180
- if (isConnected) await appKit.disconnect();
181
- },
182
- isConnected
183
- };
184
- })
185
- ).subscribe(subscriber);
186
- return () => {
187
- sub.unsubscribe();
188
- unsubProviders();
189
- };
190
- });
191
- }),
192
- // refCount:false keeps the AppKit instance alive for the process lifetime
193
- // once created: createAppKit runs at most once (Reown AppKit cannot be
194
- // instantiated twice). With refCount:true the producer would re-run
195
- // createAppKit whenever every subscriber drained and a new one
196
- // re-subscribed — e.g. a React unmount/remount or StrictMode's
197
- // mount→unmount→remount — throwing on the duplicate Lit web components and
198
- // WalletConnect modal singleton. The replayed connector value also keeps
199
- // the wallet list stable across such teardown/rebuild cycles.
200
- _rxjs.shareReplay.call(void 0, { refCount: false, bufferSize: 1 })
201
- );
202
- setCachedAppKit(cachedAppKit, walletConnect.projectId);
203
- }
204
- return cachedAppKit;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_types = require("./types-DKU-SNio.js");
3
+ const require_errors = require("./errors-DPw6pc2H.js");
4
+ const require_iconCache = require("./iconCache-DS4zNiP1.js");
5
+ let rxjs = require("rxjs");
6
+ let lodash_es = require("lodash-es");
7
+ //#region src/api/appKit.ts
8
+ /**
9
+ * Dynamically import @reown/appkit/core to avoid loading browser-only code
10
+ * during SSR or in edge runtimes like Cloudflare Workers.
11
+ * The AppKit library uses Lit for web components which requires document.
12
+ */
13
+ const loadAppKit = async () => {
14
+ try {
15
+ const { createAppKit } = await import("@reown/appkit/core");
16
+ return createAppKit;
17
+ } catch (cause) {
18
+ console.error("[kheopskit] WalletConnect is configured but @reown/appkit could not be loaded. Install it with `pnpm add @reown/appkit` (or remove config.walletConnect). WalletConnect wallets are disabled; injected wallets still work.", cause);
19
+ return null;
20
+ }
205
21
  };
206
-
207
- // src/api/kheopskit.ts
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
- // src/utils/createHydrationBuffer.ts
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
- var createBufferCore = (cachedItems, liveItems$, gracePeriodMs, mergeFn, isConverged) => {
233
- if (gracePeriodMs <= 0 || cachedItems.length === 0) {
234
- return liveItems$.pipe(_rxjs.map.call(void 0, (items) => ({ items, isHydrating: false })));
235
- }
236
- return new (0, _rxjs.Observable)((subscriber) => {
237
- const subscriptions = new (0, _rxjs.Subscription)();
238
- const isHydrating$ = new (0, _rxjs.BehaviorSubject)(true);
239
- const liveWithInitial$ = liveItems$.pipe(_rxjs.startWith.call(void 0, []));
240
- if (isConverged) {
241
- const timerFired$ = _rxjs.timer.call(void 0, gracePeriodMs).pipe(
242
- _rxjs.map.call(void 0, () => true),
243
- _rxjs.startWith.call(void 0, false),
244
- _rxjs.shareReplay.call(void 0, { bufferSize: 1, refCount: true })
245
- );
246
- subscriptions.add(
247
- _rxjs.combineLatest.call(void 0, [liveWithInitial$, timerFired$]).pipe(
248
- _rxjs.filter.call(void 0, ([, timerFired]) => timerFired),
249
- _rxjs.filter.call(void 0, ([liveItems]) => isConverged(liveItems, cachedItems)),
250
- _rxjs.take.call(void 0, 1)
251
- ).subscribe(() => {
252
- isHydrating$.next(false);
253
- })
254
- );
255
- subscriptions.add(
256
- _rxjs.timer.call(void 0, gracePeriodMs * 6).subscribe(() => {
257
- if (isHydrating$.value) {
258
- isHydrating$.next(false);
259
- }
260
- })
261
- );
262
- } else {
263
- subscriptions.add(
264
- _rxjs.timer.call(void 0, gracePeriodMs).subscribe(() => {
265
- isHydrating$.next(false);
266
- })
267
- );
268
- }
269
- subscriptions.add(
270
- _rxjs.combineLatest.call(void 0, [liveWithInitial$, isHydrating$]).pipe(
271
- _rxjs.map.call(void 0, ([liveItems, isHydrating]) => {
272
- if (!isHydrating) {
273
- return { items: liveItems, isHydrating: false };
274
- }
275
- return {
276
- items: mergeFn(liveItems, cachedItems),
277
- isHydrating: true
278
- };
279
- })
280
- ).subscribe(subscriber)
281
- );
282
- return () => {
283
- subscriptions.unsubscribe();
284
- isHydrating$.complete();
285
- };
286
- });
287
- };
288
- var createHydrationBuffer = (cachedItems, liveItems$, gracePeriodMs, getKey, isConverged, mergeItem, transformCachedOnly) => {
289
- return createBufferCore(
290
- cachedItems,
291
- liveItems$,
292
- gracePeriodMs,
293
- (liveItems, cached) => {
294
- const cachedByKey = new Map(cached.map((item) => [getKey(item), item]));
295
- const liveKeys = new Set(liveItems.map(getKey));
296
- const mergedItems = liveItems.map((liveItem) => {
297
- const key = getKey(liveItem);
298
- const cachedItem = cachedByKey.get(key);
299
- if (!cachedItem) return liveItem;
300
- return mergeItem ? mergeItem(liveItem, cachedItem) : cachedItem;
301
- });
302
- for (const cachedItem of cached) {
303
- if (!liveKeys.has(getKey(cachedItem))) {
304
- const transformed = transformCachedOnly ? transformCachedOnly(cachedItem) : cachedItem;
305
- mergedItems.push(transformed);
306
- }
307
- }
308
- return mergedItems;
309
- },
310
- isConverged
311
- );
312
- };
313
- var createAccountHydrationBuffer = (cachedAccounts, liveAccounts$, gracePeriodMs, getWalletId2, isConverged) => {
314
- return createBufferCore(
315
- cachedAccounts,
316
- liveAccounts$,
317
- gracePeriodMs,
318
- (liveAccounts, cached) => {
319
- const walletsWithLiveAccounts = new Set(liveAccounts.map(getWalletId2));
320
- const mergedAccounts = [...liveAccounts];
321
- for (const cachedAccount of cached) {
322
- if (!walletsWithLiveAccounts.has(getWalletId2(cachedAccount))) {
323
- mergedAccounts.push(cachedAccount);
324
- }
325
- }
326
- return mergedAccounts;
327
- },
328
- isConverged
329
- );
22
+ const WALLET_CONNECT_ICON = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+";
23
+ const APPKIT_SYMBOL = Symbol.for("kheopskit.cachedAppKit");
24
+ const APPKIT_PROJECT_ID_SYMBOL = Symbol.for("kheopskit.cachedAppKitProjectId");
25
+ const getCachedAppKit = () => globalThis[APPKIT_SYMBOL];
26
+ const getCachedAppKitProjectId = () => globalThis[APPKIT_PROJECT_ID_SYMBOL];
27
+ const setCachedAppKit = (value, projectId) => {
28
+ globalThis[APPKIT_SYMBOL] = value;
29
+ globalThis[APPKIT_PROJECT_ID_SYMBOL] = projectId;
330
30
  };
331
-
332
- // src/utils/logObservable.ts
333
-
334
- var logObservable = (label, opts) => _rxjs.tap.call(void 0, (value) => {
335
- const { printValue = false, enabled = true } = opts || {};
336
- if (!label || !enabled) return;
337
- const text = `[kheopskit] observable ${label} emit`;
338
- if (printValue) console.debug(text, value);
339
- else console.debug(text);
31
+ /**
32
+ * Clears the cached AppKit observable.
33
+ * Use when configuration changes or for testing purposes.
34
+ * Note: This does NOT destroy the appKit instance created by Reown.
35
+ */
36
+ const resetAppKitCache = () => {
37
+ setCachedAppKit(void 0);
38
+ };
39
+ /**
40
+ * Drops a WalletConnect namespace's cached account observables. Called when a
41
+ * namespace transitions to disconnected — including external disconnects (from
42
+ * the wallet app), which flip status via `subscribeProviders` without ever
43
+ * calling `disconnect()` — so a later reconnect rebuilds the account observables
44
+ * against the fresh session instead of a stale closure.
45
+ *
46
+ * Keys are `accounts:<walletId>:...`; the trailing colon scopes the prefix to
47
+ * this wallet and avoids matching a sibling whose id is a string prefix.
48
+ */
49
+ const dropAccountsCache = (platform) => {
50
+ require_types.clearCachedObservablesByPrefix(`accounts:${require_types.WALLET_CONNECT_WALLET_ID}:${platform}:`);
51
+ };
52
+ /**
53
+ * The single, platform-less WalletConnect connector for the given config — or
54
+ * `null` when WalletConnect isn't configured, on the server, or when
55
+ * `@reown/appkit` isn't installed.
56
+ *
57
+ * @remarks
58
+ * The AppKit instance is a process-wide singleton (Reown AppKit itself cannot
59
+ * be instantiated twice). The **first** call with a `walletConnect` config wins;
60
+ * later calls with a *different* `walletConnect` config reuse that first
61
+ * instance. Call {@link resetAppKitCache} before re-initialising if the
62
+ * WalletConnect config must change.
63
+ *
64
+ * One WalletConnect session is shared across every namespace, and a namespace
65
+ * can only be established during the initial pairing — it can't be added to a
66
+ * live session afterwards. So this exposes ONE connector (not one per platform):
67
+ * `connect()` opens the modal; the wallet approves whichever namespaces it
68
+ * supports in that single pairing, and `platforms` reflects what the live
69
+ * session carries. Per-namespace accounts are derived by each platform plugin.
70
+ */
71
+ const getWalletConnectWallet$ = (config) => {
72
+ if (!config.walletConnect) return (0, rxjs.of)(null);
73
+ if (typeof window === "undefined") return (0, rxjs.of)(null);
74
+ const walletConnect = config.walletConnect;
75
+ const cachedProjectId = getCachedAppKitProjectId();
76
+ if (cachedProjectId !== void 0 && cachedProjectId !== walletConnect.projectId) console.warn("[kheopskit] WalletConnect is already initialised with projectId %s; AppKit is a process-wide singleton, so the first configuration wins and projectId %s is ignored. Call resetAppKitCache() before re-initialising if the WalletConnect config must change.", cachedProjectId, walletConnect.projectId);
77
+ let cachedAppKit = getCachedAppKit();
78
+ if (!cachedAppKit) {
79
+ cachedAppKit = (0, rxjs.from)(loadAppKit()).pipe((0, rxjs.switchMap)((createAppKit) => {
80
+ if (!createAppKit) return (0, rxjs.of)(null);
81
+ return new rxjs.Observable((subscriber) => {
82
+ const appKit = createAppKit({
83
+ projectId: walletConnect.projectId,
84
+ metadata: walletConnect.metadata,
85
+ networks: walletConnect.networks,
86
+ themeMode: walletConnect.themeMode,
87
+ themeVariables: walletConnect.themeVariables,
88
+ universalProviderConfigOverride: { methods: {
89
+ polkadot: ["polkadot_signTransaction", "polkadot_signMessage"],
90
+ solana: [
91
+ "solana_signTransaction",
92
+ "solana_signMessage",
93
+ "solana_signAndSendTransaction"
94
+ ]
95
+ } },
96
+ allWallets: "HIDE",
97
+ debug: config.debug,
98
+ allowUnsupportedChain: true
99
+ });
100
+ const appKitInstance = appKit;
101
+ const status$ = new rxjs.BehaviorSubject({
102
+ isPolkadotConnected: false,
103
+ isEthereumConnected: false,
104
+ isSolanaConnected: false
105
+ });
106
+ const unsubProviders = appKit.subscribeProviders((providers) => {
107
+ status$.next({
108
+ isPolkadotConnected: !!providers.polkadot,
109
+ isEthereumConnected: !!providers.eip155,
110
+ isSolanaConnected: !!providers.solana
111
+ });
112
+ });
113
+ const namespaceOf = {
114
+ polkadot: "polkadot",
115
+ ethereum: "eip155",
116
+ solana: "solana"
117
+ };
118
+ const allPlatforms = [
119
+ "polkadot",
120
+ "ethereum",
121
+ "solana"
122
+ ];
123
+ const enabledPlatforms = allPlatforms.filter((p) => appKit.chainNamespaces.includes(namespaceOf[p]));
124
+ let prevConnected = {
125
+ polkadot: false,
126
+ ethereum: false,
127
+ solana: false
128
+ };
129
+ const sub = status$.pipe((0, rxjs.map)((s) => ({
130
+ polkadot: s.isPolkadotConnected,
131
+ ethereum: s.isEthereumConnected,
132
+ solana: s.isSolanaConnected
133
+ })), (0, rxjs.distinctUntilChanged)((a, b) => a.polkadot === b.polkadot && a.ethereum === b.ethereum && a.solana === b.solana), (0, rxjs.tap)((connected) => {
134
+ for (const platform of allPlatforms) if (prevConnected[platform] && !connected[platform]) dropAccountsCache(platform);
135
+ prevConnected = connected;
136
+ }), (0, rxjs.map)((connected) => {
137
+ const platforms = enabledPlatforms.filter((p) => connected[p]);
138
+ const isConnected = platforms.length > 0;
139
+ const walletInfo = appKit.getWalletInfo();
140
+ return {
141
+ id: require_types.WALLET_CONNECT_WALLET_ID,
142
+ type: "walletconnect",
143
+ platforms,
144
+ appKit: appKitInstance,
145
+ name: walletInfo?.name ?? "WalletConnect",
146
+ icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
147
+ connect: async () => {
148
+ if (!isConnected) await appKit.open();
149
+ },
150
+ disconnect: async () => {
151
+ if (isConnected) await appKit.disconnect();
152
+ },
153
+ isConnected
154
+ };
155
+ })).subscribe(subscriber);
156
+ return () => {
157
+ sub.unsubscribe();
158
+ unsubProviders();
159
+ };
160
+ });
161
+ }), (0, rxjs.shareReplay)({
162
+ refCount: false,
163
+ bufferSize: 1
164
+ }));
165
+ setCachedAppKit(cachedAppKit, walletConnect.projectId);
166
+ }
167
+ return cachedAppKit;
168
+ };
169
+ //#endregion
170
+ //#region src/api/config.ts
171
+ /**
172
+ * Default storage key for persisting wallet connection state.
173
+ * Can be overridden via config.storageKey to avoid conflicts
174
+ * when running multiple dapps on the same domain.
175
+ */
176
+ const DEFAULT_STORAGE_KEY = "kheopskit";
177
+ const DEFAULTS = {
178
+ autoReconnect: true,
179
+ debug: false,
180
+ storageKey: DEFAULT_STORAGE_KEY,
181
+ hydrationGracePeriod: 500
182
+ };
183
+ const resolveConfig = (config) => {
184
+ const platforms = config?.platforms ?? [];
185
+ const invalidPlatforms = platforms.filter((p) => typeof p !== "object" || p === null || typeof p.getWallets$ !== "function");
186
+ if (invalidPlatforms.length > 0) throw new Error(`[kheopskit] config.platforms must contain plugin instances created by the per-platform factories (e.g. platforms: [polkadot(), ethereum(), solana()] imported from "@kheopskit/core/<platform>"). Invalid entries: ${JSON.stringify(invalidPlatforms)}. String platform names like "polkadot" were removed in v4 — see MIGRATING_TO_V4.md.`);
187
+ if (platforms.length === 0) console.warn("[kheopskit] No platforms configured; wallets and accounts will be empty. Pass e.g. platforms: [polkadot()] from \"@kheopskit/core/polkadot\".");
188
+ return Object.assign({}, DEFAULTS, config, { platforms });
189
+ };
190
+ //#endregion
191
+ //#region src/utils/sortAccounts.ts
192
+ const PLATFORM_ORDER$1 = {
193
+ polkadot: 0,
194
+ ethereum: 1,
195
+ solana: 2
196
+ };
197
+ const byWalletName = (a1, a2) => {
198
+ if (a1.walletName.toLowerCase() === "talisman") return -1;
199
+ if (a2.walletName.toLowerCase() === "talisman") return 1;
200
+ return a1.walletName.localeCompare(a2.walletName);
201
+ };
202
+ const sortAccounts = (a1, a2) => {
203
+ if (a1.platform !== a2.platform) return PLATFORM_ORDER$1[a1.platform] - PLATFORM_ORDER$1[a2.platform];
204
+ if (a1.walletName !== a2.walletName) return byWalletName(a1, a2);
205
+ if (a1.platform === "polkadot" && a2.platform === "polkadot") return a1.name !== a2.name ? (a1.name ?? "").localeCompare(a2.name ?? "") : a1.address.localeCompare(a2.address);
206
+ return a1.id.localeCompare(a2.id);
207
+ };
208
+ //#endregion
209
+ //#region src/utils/sortWallets.ts
210
+ const PLATFORM_ORDER = {
211
+ polkadot: 0,
212
+ ethereum: 1,
213
+ solana: 2
214
+ };
215
+ const orderOf = (wallet) => require_types.isWalletConnectWallet(wallet) ? 3 : PLATFORM_ORDER[wallet.platform];
216
+ const sortWallets = (w1, w2) => {
217
+ const o1 = orderOf(w1);
218
+ const o2 = orderOf(w2);
219
+ if (o1 !== o2) return o1 - o2;
220
+ if (w1.name.toLowerCase() === "talisman") return -1;
221
+ if (w2.name.toLowerCase() === "talisman") return 1;
222
+ return w1.name.localeCompare(w2.name);
223
+ };
224
+ //#endregion
225
+ //#region src/api/platform.ts
226
+ /**
227
+ * Whether a cached account should survive SSR hydration, per its platform
228
+ * plugin's `acceptsCachedAccount` hook. Plugins without the hook (and platforms
229
+ * with no enabled plugin) accept all — matching the pre-plugin behavior where
230
+ * only Polkadot accounts were filtered (by key type).
231
+ */
232
+ const acceptsCachedAccount = (cached, platforms) => {
233
+ return platforms.find((p) => p.platform === cached.platform)?.acceptsCachedAccount?.(cached) ?? true;
234
+ };
235
+ //#endregion
236
+ //#region src/api/hydration.ts
237
+ /**
238
+ * Builds the cached-state snapshot every consumer must agree on: read the
239
+ * store's cached state, hydrate wallets/accounts into placeholders, filter
240
+ * accounts through each platform plugin's `acceptsCachedAccount` hook, and sort
241
+ * with the same comparators the live pipeline uses.
242
+ *
243
+ * This is the single implementation behind the observable's initial seed and
244
+ * both React snapshot sources (`serverValue`/`initialValue`). They must produce
245
+ * the same shape in the same order or the UI flickers/reorders on reload — by
246
+ * sharing this helper, that agreement holds by construction.
247
+ */
248
+ const getHydratedSnapshot = (store, platforms, options = {}) => {
249
+ const cached = store.getCachedState();
250
+ return {
251
+ wallets: cached.wallets.map((cachedWallet) => {
252
+ const wallet = require_iconCache.hydrateWallet(cachedWallet);
253
+ if (!options.icons || wallet.icon) return wallet;
254
+ const icon = require_iconCache.getCachedIcon(wallet.id);
255
+ return icon ? {
256
+ ...wallet,
257
+ icon
258
+ } : wallet;
259
+ }).sort(sortWallets),
260
+ accounts: cached.accounts.filter((account) => acceptsCachedAccount(account, platforms)).map(require_iconCache.hydrateAccount).sort(sortAccounts)
261
+ };
262
+ };
263
+ //#endregion
264
+ //#region src/utils/createHydrationBuffer.ts
265
+ /**
266
+ * Core hydration buffer logic shared between wallets and accounts.
267
+ *
268
+ * During the grace period:
269
+ * - Emits cached items immediately (before any live emissions)
270
+ * - As live items arrive, merges them using the provided merge function
271
+ *
272
+ * After the grace period (and convergence, if provided):
273
+ * - Only live items are returned
274
+ * - isHydrating becomes false
275
+ *
276
+ * If an `isConverged` function is provided, hydration ends only when BOTH
277
+ * the grace period has elapsed AND the live items have converged with cached
278
+ * items (e.g., all previously-connected wallets have reconnected).
279
+ * A max timeout (6x grace period) prevents infinite hydration.
280
+ *
281
+ * @param cachedItems - Initial cached items from storage
282
+ * @param liveItems$ - Observable of live items as they become available
283
+ * @param gracePeriodMs - Time in ms to wait before syncing to live state
284
+ * @param mergeFn - Function to merge live and cached items during hydration
285
+ * @param isConverged - Optional function to check if live items have caught up to cached items
286
+ */
287
+ const createBufferCore = (cachedItems, liveItems$, gracePeriodMs, mergeFn, isConverged) => {
288
+ if (gracePeriodMs <= 0 || cachedItems.length === 0) return liveItems$.pipe((0, rxjs.map)((items) => ({
289
+ items,
290
+ isHydrating: false
291
+ })));
292
+ return new rxjs.Observable((subscriber) => {
293
+ const subscriptions = new rxjs.Subscription();
294
+ const isHydrating$ = new rxjs.BehaviorSubject(true);
295
+ const liveWithInitial$ = liveItems$.pipe((0, rxjs.startWith)([]));
296
+ if (isConverged) {
297
+ const timerFired$ = (0, rxjs.timer)(gracePeriodMs).pipe((0, rxjs.map)(() => true), (0, rxjs.startWith)(false), (0, rxjs.shareReplay)({
298
+ bufferSize: 1,
299
+ refCount: true
300
+ }));
301
+ subscriptions.add((0, rxjs.combineLatest)([liveWithInitial$, timerFired$]).pipe((0, rxjs.filter)(([, timerFired]) => timerFired), (0, rxjs.filter)(([liveItems]) => isConverged(liveItems, cachedItems)), (0, rxjs.take)(1)).subscribe(() => {
302
+ isHydrating$.next(false);
303
+ }));
304
+ subscriptions.add((0, rxjs.timer)(gracePeriodMs * 6).subscribe(() => {
305
+ if (isHydrating$.value) isHydrating$.next(false);
306
+ }));
307
+ } else subscriptions.add((0, rxjs.timer)(gracePeriodMs).subscribe(() => {
308
+ isHydrating$.next(false);
309
+ }));
310
+ subscriptions.add((0, rxjs.combineLatest)([liveWithInitial$, isHydrating$]).pipe((0, rxjs.map)(([liveItems, isHydrating]) => {
311
+ if (!isHydrating) return {
312
+ items: liveItems,
313
+ isHydrating: false
314
+ };
315
+ return {
316
+ items: mergeFn(liveItems, cachedItems),
317
+ isHydrating: true
318
+ };
319
+ })).subscribe(subscriber));
320
+ return () => {
321
+ subscriptions.unsubscribe();
322
+ isHydrating$.complete();
323
+ };
324
+ });
325
+ };
326
+ /**
327
+ * Creates a hydration buffer that merges cached items with live items.
328
+ *
329
+ * During hydration, cached items take precedence over live items with the same key.
330
+ * This preserves the cached connected state (e.g., isConnected: true) while
331
+ * auto-reconnect is still in progress. New live items not in the cache are added.
332
+ *
333
+ * @param cachedItems - Initial cached items from storage
334
+ * @param liveItems$ - Observable of live items as they become available
335
+ * @param gracePeriodMs - Time in ms to wait before syncing to live state
336
+ * @param getKey - Function to extract a unique key from an item
337
+ * @param isConverged - Optional function to check if live items have caught up to cached items
338
+ * @param mergeItem - Optional function to merge a live item with its cached counterpart
339
+ * @param transformCachedOnly - Optional function to transform cached items not yet in the live stream
340
+ */
341
+ const createHydrationBuffer = (cachedItems, liveItems$, gracePeriodMs, getKey, isConverged, mergeItem, transformCachedOnly) => {
342
+ return createBufferCore(cachedItems, liveItems$, gracePeriodMs, (liveItems, cached) => {
343
+ const cachedByKey = new Map(cached.map((item) => [getKey(item), item]));
344
+ const liveKeys = new Set(liveItems.map(getKey));
345
+ const mergedItems = liveItems.map((liveItem) => {
346
+ const key = getKey(liveItem);
347
+ const cachedItem = cachedByKey.get(key);
348
+ if (!cachedItem) return liveItem;
349
+ return mergeItem ? mergeItem(liveItem, cachedItem) : cachedItem;
350
+ });
351
+ for (const cachedItem of cached) if (!liveKeys.has(getKey(cachedItem))) {
352
+ const transformed = transformCachedOnly ? transformCachedOnly(cachedItem) : cachedItem;
353
+ mergedItems.push(transformed);
354
+ }
355
+ return mergedItems;
356
+ }, isConverged);
357
+ };
358
+ /**
359
+ * Creates a hydration buffer specifically for accounts, which need special handling.
360
+ *
361
+ * Accounts are grouped by wallet - when a wallet provides its account list,
362
+ * we replace all cached accounts for that wallet with the live ones.
363
+ * Cached accounts for wallets that haven't provided accounts yet are preserved.
364
+ *
365
+ * @param cachedAccounts - Initial cached accounts from storage
366
+ * @param liveAccounts$ - Observable of live accounts as they become available
367
+ * @param gracePeriodMs - Time in ms to wait before syncing to live state
368
+ * @param getWalletId - Function to extract the wallet ID from an account
369
+ * @param isConverged - Optional function to check if live accounts have caught up to cached accounts
370
+ */
371
+ const createAccountHydrationBuffer = (cachedAccounts, liveAccounts$, gracePeriodMs, getWalletId, isConverged) => {
372
+ return createBufferCore(cachedAccounts, liveAccounts$, gracePeriodMs, (liveAccounts, cached) => {
373
+ const walletsWithLiveAccounts = new Set(liveAccounts.map(getWalletId));
374
+ const mergedAccounts = [...liveAccounts];
375
+ for (const cachedAccount of cached) if (!walletsWithLiveAccounts.has(getWalletId(cachedAccount))) mergedAccounts.push(cachedAccount);
376
+ return mergedAccounts;
377
+ }, isConverged);
378
+ };
379
+ //#endregion
380
+ //#region src/utils/logObservable.ts
381
+ const logObservable = (label, opts) => (0, rxjs.tap)((value) => {
382
+ const { printValue = false, enabled = true } = opts || {};
383
+ if (!label || !enabled) return;
384
+ const text = `[kheopskit] observable ${label} emit`;
385
+ if (printValue) console.debug(text, value);
386
+ else console.debug(text);
340
387
  });
341
-
342
- // src/api/accounts.ts
343
-
344
- var getAccounts$ = (config, wallets) => {
345
- return new (0, _rxjs.Observable)((subscriber) => {
346
- const sources = config.platforms.map(
347
- (plugin) => plugin.getAccounts$(
348
- wallets.pipe(
349
- _rxjs.map.call(void 0,
350
- (ws) => ws.filter(
351
- (w) => _chunk4ENHC7G4js.isWalletConnectWallet.call(void 0, w) || w.platform === plugin.platform
352
- )
353
- )
354
- )
355
- )
356
- );
357
- const accounts$ = sources.length ? _rxjs.combineLatest.call(void 0, sources).pipe(
358
- _rxjs.map.call(void 0, (accounts) => accounts.flat().sort(_chunkB4L6GAYDjs.sortAccounts))
359
- ) : _rxjs.of.call(void 0, []);
360
- const sub = accounts$.subscribe(subscriber);
361
- return () => {
362
- sub.unsubscribe();
363
- };
364
- }).pipe(_rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 }));
388
+ //#endregion
389
+ //#region src/api/accounts.ts
390
+ const getAccounts$ = (config, wallets) => {
391
+ return new rxjs.Observable((subscriber) => {
392
+ const sources = config.platforms.map((plugin) => plugin.getAccounts$(wallets.pipe((0, rxjs.map)((ws) => ws.filter((w) => require_types.isWalletConnectWallet(w) || w.platform === plugin.platform)))));
393
+ const sub = (sources.length ? (0, rxjs.combineLatest)(sources).pipe((0, rxjs.map)((accounts) => accounts.flat().sort(sortAccounts))) : (0, rxjs.of)([])).subscribe(subscriber);
394
+ return () => {
395
+ sub.unsubscribe();
396
+ };
397
+ }).pipe((0, rxjs.shareReplay)({
398
+ refCount: true,
399
+ bufferSize: 1
400
+ }));
365
401
  };
366
-
367
- // src/api/wallets.ts
368
-
369
-
370
-
371
-
372
-
373
-
374
-
375
-
376
-
377
-
378
- var getWallets$ = (config, store2 = _chunkXQWJM3KCjs.store) => {
379
- const autoReconnectWalletIds$ = store2.observable.pipe(
380
- _rxjs.map.call(void 0, (s) => _nullishCoalesce(s.autoReconnect, () => ( []))),
381
- _rxjs.take.call(void 0, 1),
382
- _rxjs.shareReplay.call(void 0, { bufferSize: 1, refCount: true })
383
- );
384
- return new (0, _rxjs.Observable)((subscriber) => {
385
- const ctx = { config, store: store2 };
386
- const observables = config.platforms.map(
387
- (plugin) => plugin.getWallets$(ctx)
388
- );
389
- const platformWallets$ = observables.length ? _rxjs.combineLatest.call(void 0, observables).pipe(_rxjs.map.call(void 0, (wallets) => wallets.flat())) : _rxjs.of.call(void 0, []);
390
- const wallets$ = _rxjs.combineLatest.call(void 0, [
391
- platformWallets$,
392
- getWalletConnectWallet$(config)
393
- ]).pipe(
394
- _rxjs.map.call(void 0, ([platformWallets, walletConnect]) => {
395
- const all = walletConnect ? [...platformWallets, walletConnect] : platformWallets;
396
- return all.sort(_chunkB4L6GAYDjs.sortWallets);
397
- })
398
- // Note: No startWith([]) here - the hydration buffer handles initial state
399
- );
400
- const reconnectingWallets = /* @__PURE__ */ new Set();
401
- const reconnectedWallets = /* @__PURE__ */ new Set();
402
- const MAX_RECONNECT_ATTEMPTS = 3;
403
- const failedAttempts = /* @__PURE__ */ new Map();
404
- const subAutoReconnect = _rxjs.combineLatest.call(void 0, [wallets$, autoReconnectWalletIds$]).pipe(
405
- _rxjs.filter.call(void 0, ([, walletIds]) => config.autoReconnect && !!_optionalChain([walletIds, 'optionalAccess', _3 => _3.length])),
406
- _rxjs.mergeMap.call(void 0,
407
- ([wallets, walletIds]) => wallets.filter((wallet) => _optionalChain([walletIds, 'optionalAccess', _4 => _4.includes, 'call', _5 => _5(wallet.id)]))
408
- )
409
- ).subscribe(async (wallet) => {
410
- if (wallet.isConnected || reconnectingWallets.has(wallet.id) || reconnectedWallets.has(wallet.id) || (_nullishCoalesce(failedAttempts.get(wallet.id), () => ( 0))) >= MAX_RECONNECT_ATTEMPTS) {
411
- return;
412
- }
413
- reconnectingWallets.add(wallet.id);
414
- try {
415
- await wallet.connect();
416
- reconnectedWallets.add(wallet.id);
417
- failedAttempts.delete(wallet.id);
418
- } catch (err) {
419
- failedAttempts.set(
420
- wallet.id,
421
- (_nullishCoalesce(failedAttempts.get(wallet.id), () => ( 0))) + 1
422
- );
423
- console.error("Failed to reconnect wallet %s", wallet.id, { err });
424
- } finally {
425
- reconnectingWallets.delete(wallet.id);
426
- }
427
- });
428
- const subWallets = wallets$.subscribe(subscriber);
429
- return () => {
430
- subAutoReconnect.unsubscribe();
431
- subWallets.unsubscribe();
432
- };
433
- }).pipe(_rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 }));
402
+ //#endregion
403
+ //#region src/utils/createStore.ts
404
+ const createStore = (key, defaultValue, storage = require_iconCache.safeLocalStorage) => {
405
+ const subject = new rxjs.BehaviorSubject(getStoredData(key, defaultValue, storage));
406
+ let unsubscribeStorage;
407
+ if (typeof window !== "undefined" && storage.subscribe) unsubscribeStorage = storage.subscribe(key, (newValue) => {
408
+ subject.next(parseData(newValue, defaultValue));
409
+ });
410
+ const update = (val) => {
411
+ setStoredData(key, val, storage);
412
+ subject.next(val);
413
+ };
414
+ return {
415
+ observable: subject.asObservable(),
416
+ set: (val) => update(val),
417
+ mutate: (transform) => update(transform(subject.getValue())),
418
+ get: () => structuredClone(subject.getValue()),
419
+ /**
420
+ * Cleanup subscriptions. Call this when the store is no longer needed.
421
+ */
422
+ destroy: () => {
423
+ unsubscribeStorage?.();
424
+ subject.complete();
425
+ }
426
+ };
434
427
  };
435
-
436
- // src/api/kheopskit.ts
437
- var getKheopskit$ = (config, options = {}) => {
438
- const { ssrCookies, store: existingStore } = options;
439
- const kc = _chunkXQWJM3KCjs.resolveConfig.call(void 0, config);
440
- const store2 = _nullishCoalesce(existingStore, () => ( _chunkXQWJM3KCjs.createKheopskitStore.call(void 0, { ssrCookies, storageKey: kc.storageKey })));
441
- if (kc.debug) console.debug("[kheopskit] config", kc);
442
- if (kc.debug && typeof window === "undefined" && ssrCookies === void 0) {
443
- console.warn(
444
- "[kheopskit] Running on server without `ssrCookies`. Wallet state will not be hydrated. Pass cookies for SSR support."
445
- );
446
- }
447
- const cachedState = store2.getCachedState();
448
- const cachedWallets = cachedState.wallets.map((w) => {
449
- const wallet = _chunkB4L6GAYDjs.hydrateWallet.call(void 0, w);
450
- if (!wallet.icon) {
451
- const cachedIcon = _chunkB4L6GAYDjs.getCachedIcon.call(void 0, wallet.id);
452
- if (cachedIcon) {
453
- return { ...wallet, icon: cachedIcon };
454
- }
455
- }
456
- return wallet;
457
- });
458
- const cachedAccounts = cachedState.accounts.filter((cached) => _chunkB4L6GAYDjs.acceptsCachedAccount.call(void 0, cached, kc.platforms)).map(_chunkB4L6GAYDjs.hydrateAccount);
459
- if (kc.debug && cachedWallets.length > 0) {
460
- console.debug("[kheopskit] hydrating from cache:", {
461
- wallets: cachedWallets.length,
462
- accounts: cachedAccounts.length
463
- });
464
- }
465
- return new (0, _rxjs.Observable)((subscriber) => {
466
- const liveWallets$ = getWallets$(kc, store2);
467
- const liveAccounts$ = getAccounts$(kc, liveWallets$);
468
- const bufferedWallets$ = createHydrationBuffer(
469
- cachedWallets,
470
- liveWallets$,
471
- kc.hydrationGracePeriod,
472
- (w) => w.id,
473
- // Hydration converges when all cached-connected wallets are connected in live
474
- (liveWallets, cached) => {
475
- const cachedConnectedIds = new Set(
476
- cached.filter((w) => w.isConnected).map((w) => w.id)
477
- );
478
- if (cachedConnectedIds.size === 0) return true;
479
- return [...cachedConnectedIds].every(
480
- (id) => liveWallets.some((w) => w.id === id && w.isConnected)
481
- );
482
- },
483
- // Merge: prefer cached isConnected state but get icon from cache or live
484
- (live, cached) => ({
485
- ...cached,
486
- // Priority: cached icon > localStorage cache > live icon
487
- icon: cached.icon || _chunkB4L6GAYDjs.getCachedIcon.call(void 0, cached.id) || live.icon,
488
- // Use live wallet's connect/disconnect functions
489
- connect: live.connect,
490
- disconnect: live.disconnect
491
- }),
492
- // Transform cached-only items: add icon from localStorage cache
493
- (cached) => ({
494
- ...cached,
495
- icon: cached.icon || _chunkB4L6GAYDjs.getCachedIcon.call(void 0, cached.id) || ""
496
- })
497
- );
498
- const bufferedAccounts$ = createAccountHydrationBuffer(
499
- cachedAccounts,
500
- liveAccounts$,
501
- kc.hydrationGracePeriod,
502
- (a) => a.walletId,
503
- // Hydration converges when all wallets with cached accounts have provided live accounts
504
- (liveAccounts, cached) => {
505
- const cachedWalletIds = new Set(cached.map((a) => a.walletId));
506
- if (cachedWalletIds.size === 0) return true;
507
- const liveWalletIds = new Set(liveAccounts.map((a) => a.walletId));
508
- return [...cachedWalletIds].every((id) => liveWalletIds.has(id));
509
- }
510
- );
511
- const sharedWallets$ = bufferedWallets$.pipe(
512
- _rxjs.shareReplay.call(void 0, { bufferSize: 1, refCount: true })
513
- );
514
- const sharedAccounts$ = bufferedAccounts$.pipe(
515
- _rxjs.shareReplay.call(void 0, { bufferSize: 1, refCount: true })
516
- );
517
- const subscription = _rxjs.combineLatest.call(void 0, {
518
- wallets: sharedWallets$,
519
- accounts: sharedAccounts$
520
- }).pipe(
521
- _rxjs.map.call(void 0, ({ wallets, accounts }) => {
522
- if (kc.debug) {
523
- console.debug("[kheopskit] hydration state", {
524
- walletsHydrating: wallets.isHydrating,
525
- accountsHydrating: accounts.isHydrating,
526
- walletsConnected: wallets.items.filter((w) => w.isConnected).length,
527
- walletsTotal: wallets.items.length
528
- });
529
- }
530
- return {
531
- config: kc,
532
- wallets: [...wallets.items].sort(_chunkB4L6GAYDjs.sortWallets),
533
- accounts: [...accounts.items].sort(_chunkB4L6GAYDjs.sortAccounts),
534
- isHydrating: wallets.isHydrating || accounts.isHydrating
535
- };
536
- })
537
- ).subscribe(subscriber);
538
- const persistSub = _rxjs.combineLatest.call(void 0, {
539
- wallets: sharedWallets$,
540
- accounts: sharedAccounts$
541
- }).pipe(
542
- // Wait for hydration to complete
543
- _rxjs.filter.call(void 0,
544
- ({ wallets, accounts }) => !wallets.isHydrating && !accounts.isHydrating
545
- ),
546
- // Debounce to avoid excessive writes
547
- _rxjs.debounceTime.call(void 0, 1e3),
548
- // Only persist if the serialized snapshot would actually change.
549
- // Compare the persisted fields (not just ids): an Ethereum chain switch
550
- // keeps the same account id but changes the cached chainId, so an
551
- // id-only comparator would skip persisting it.
552
- _rxjs.distinctUntilChanged.call(void 0, (prev, curr) => {
553
- const prevWalletKeys = prev.wallets.items.map(walletPersistKey);
554
- const currWalletKeys = curr.wallets.items.map(walletPersistKey);
555
- const prevAccountKeys = prev.accounts.items.map(accountChangeKey);
556
- const currAccountKeys = curr.accounts.items.map(accountChangeKey);
557
- return arraysEqual(prevWalletKeys, currWalletKeys) && arraysEqual(prevAccountKeys, currAccountKeys);
558
- })
559
- ).subscribe(({ wallets, accounts }) => {
560
- const connectedWalletIds = new Set(
561
- wallets.items.filter((w) => w.isConnected).map((w) => w.id)
562
- );
563
- const relevantAccounts = accounts.items.filter(
564
- (a) => connectedWalletIds.has(a.walletId)
565
- );
566
- if (kc.debug) {
567
- console.debug("[kheopskit] persisting state snapshot:", {
568
- wallets: wallets.items.length,
569
- accounts: relevantAccounts.length
570
- });
571
- }
572
- store2.setCachedState(
573
- wallets.items.map(_chunkB4L6GAYDjs.serializeWallet),
574
- relevantAccounts.map(_chunkB4L6GAYDjs.serializeAccount)
575
- );
576
- const icons = {};
577
- for (const wallet of wallets.items) {
578
- if (wallet.icon) {
579
- icons[wallet.id] = wallet.icon;
580
- }
581
- }
582
- _chunkB4L6GAYDjs.setCachedIcons.call(void 0, icons);
583
- });
584
- return () => {
585
- subscription.unsubscribe();
586
- persistSub.unsubscribe();
587
- };
588
- }).pipe(
589
- _rxjs.distinctUntilChanged.call(void 0, statesEqual),
590
- _rxjs.throttleTime.call(void 0, 16, void 0, { leading: true, trailing: true }),
591
- // ~1 frame at 60fps
592
- logObservable("kheopskit$", { enabled: kc.debug, printValue: true }),
593
- _rxjs.shareReplay.call(void 0, { bufferSize: 1, refCount: true })
594
- // The runtime objects are the concrete per-plugin wallet/account types;
595
- // recover the precise KheopskitState<P> the caller's plugins imply.
596
- );
597
- };
598
- var arraysEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
599
- var accountChangeKey = (account) => {
600
- switch (account.platform) {
601
- case "ethereum":
602
- return `${account.id}|${_nullishCoalesce(account.chainId, () => ( ""))}`;
603
- case "polkadot":
604
- return `${account.id}|${_nullishCoalesce(account.type, () => ( ""))}`;
605
- case "solana":
606
- return `${account.id}|${(_nullishCoalesce(account.chains, () => ( []))).join(",")}`;
607
- default:
608
- return account.id;
609
- }
610
- };
611
- var walletPlatforms = (wallet) => _chunk4ENHC7G4js.isWalletConnectWallet.call(void 0, wallet) ? wallet.platforms.join(",") : "";
612
- var walletPersistKey = (wallet) => `${wallet.id}|${wallet.isConnected ? 1 : 0}|${wallet.name}`;
613
- var walletUiKey = (wallet) => `${walletPersistKey(wallet)}|${wallet.icon}|${walletPlatforms(wallet)}`;
614
- var statesEqual = (a, b) => a.isHydrating === b.isHydrating && a.wallets.length === b.wallets.length && a.accounts.length === b.accounts.length && a.wallets.every((w, i) => {
615
- const other = b.wallets[i];
616
- return !!other && walletUiKey(w) === walletUiKey(other);
428
+ const parseData = (str, defaultValue) => {
429
+ try {
430
+ if (str) return JSON.parse(str);
431
+ } catch {}
432
+ return defaultValue;
433
+ };
434
+ const getStoredData = (key, defaultValue, storage) => {
435
+ const str = storage.getItem(key);
436
+ return parseData(str, defaultValue);
437
+ };
438
+ const setStoredData = (key, val, storage) => {
439
+ const str = JSON.stringify(val);
440
+ storage.setItem(key, str);
441
+ };
442
+ //#endregion
443
+ //#region src/api/compactStore.ts
444
+ const EMPTY_STORE_DATA = {};
445
+ const toCompactPolkadotAccountType = (type) => {
446
+ switch (type) {
447
+ case "sr25519": return 0;
448
+ case "ed25519": return 1;
449
+ case "ecdsa": return 2;
450
+ case "ethereum": return 3;
451
+ default: return null;
452
+ }
453
+ };
454
+ const fromCompactPolkadotAccountType = (type) => {
455
+ switch (type) {
456
+ case 0: return "sr25519";
457
+ case 1: return "ed25519";
458
+ case 2: return "ecdsa";
459
+ case 3: return "ethereum";
460
+ default: return;
461
+ }
462
+ };
463
+ const toCompactPlatform = (platform) => {
464
+ switch (platform) {
465
+ case "polkadot": return 0;
466
+ case "ethereum": return 1;
467
+ case "solana": return 2;
468
+ }
469
+ };
470
+ const fromCompactPlatform = (code) => {
471
+ switch (code) {
472
+ case 0: return "polkadot";
473
+ case 1: return "ethereum";
474
+ case 2: return "solana";
475
+ default: return;
476
+ }
477
+ };
478
+ const isCompactStore = (value) => {
479
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
480
+ if ("cachedWallets" in value || "cachedAccounts" in value) return false;
481
+ return "v" in value || "w" in value || "a" in value || "r" in value;
482
+ };
483
+ const toCompactStore = (data) => {
484
+ const wallets = data.cachedWallets?.map((wallet) => [
485
+ wallet.id,
486
+ wallet.name,
487
+ wallet.isConnected ? 1 : 0,
488
+ wallet.type === "walletconnect" ? 1 : 0
489
+ ]);
490
+ const accounts = data.cachedAccounts?.map((account) => [
491
+ account.walletId,
492
+ account.address,
493
+ account.name ?? null,
494
+ account.chainId ?? null,
495
+ toCompactPolkadotAccountType(account.polkadotAccountType),
496
+ toCompactPlatform(account.platform)
497
+ ]);
498
+ return {
499
+ v: 1,
500
+ r: data.autoReconnect,
501
+ w: wallets?.length ? wallets : void 0,
502
+ a: accounts?.length ? accounts : void 0
503
+ };
504
+ };
505
+ const fromCompactStore = (data) => {
506
+ const walletNameMap = /* @__PURE__ */ new Map();
507
+ const wallets = [];
508
+ for (const item of Array.isArray(data.w) ? data.w : []) {
509
+ if (!Array.isArray(item)) continue;
510
+ const [id, name, isConnected, type] = item;
511
+ if (!require_types.isValidWalletId(id)) continue;
512
+ const isWalletConnect = id === require_types.WALLET_CONNECT_WALLET_ID;
513
+ const walletType = type === 1 ? "walletconnect" : "injected";
514
+ if (isWalletConnect !== (walletType === "walletconnect")) continue;
515
+ walletNameMap.set(id, name);
516
+ wallets.push({
517
+ id,
518
+ platform: isWalletConnect ? void 0 : require_types.parseWalletId(id).platform,
519
+ type: walletType,
520
+ name,
521
+ isConnected: isConnected === 1
522
+ });
523
+ }
524
+ const accounts = [];
525
+ for (const item of Array.isArray(data.a) ? data.a : []) {
526
+ if (!Array.isArray(item)) continue;
527
+ const [walletId, address, name, chainId, polkadotAccountType, platformCode] = item;
528
+ if (!require_types.isValidWalletId(walletId) || typeof address !== "string" || !address) continue;
529
+ const platform = platformCode != null ? fromCompactPlatform(platformCode) : walletId === "walletconnect" ? void 0 : require_types.parseWalletId(walletId).platform;
530
+ if (!require_types.isWalletPlatform(platform)) continue;
531
+ accounts.push({
532
+ id: require_errors.getWalletAccountId(walletId, address),
533
+ platform,
534
+ address,
535
+ name: name ?? void 0,
536
+ chainId: chainId ?? void 0,
537
+ polkadotAccountType: platform === "polkadot" ? fromCompactPolkadotAccountType(polkadotAccountType) : void 0,
538
+ walletId,
539
+ walletName: walletNameMap.get(walletId) ?? walletId
540
+ });
541
+ }
542
+ return {
543
+ autoReconnect: data.r,
544
+ cachedWallets: wallets,
545
+ cachedAccounts: accounts
546
+ };
547
+ };
548
+ const decodeStore = (raw, fallback) => {
549
+ try {
550
+ const parsed = JSON.parse(raw);
551
+ if (isCompactStore(parsed)) return fromCompactStore(parsed);
552
+ return parsed;
553
+ } catch {
554
+ return fallback;
555
+ }
556
+ };
557
+ const encodeStore = (data) => JSON.stringify(toCompactStore(data));
558
+ /**
559
+ * Cookie storage that transparently encodes/decodes {@link CompactStoreV1},
560
+ * migrating legacy verbose-JSON cookies to the compact format on first read.
561
+ */
562
+ const createCompactCookieStorage = (initialCookies) => {
563
+ const base = require_iconCache.cookieStorage(initialCookies);
564
+ return {
565
+ getItem: (key) => {
566
+ const raw = base.getItem(key);
567
+ if (!raw) return null;
568
+ const expanded = decodeStore(raw, EMPTY_STORE_DATA);
569
+ if (typeof document !== "undefined") try {
570
+ const parsed = JSON.parse(raw);
571
+ if (!isCompactStore(parsed)) base.setItem(key, encodeStore(expanded));
572
+ } catch {}
573
+ return JSON.stringify(expanded);
574
+ },
575
+ setItem: (key, value) => {
576
+ const expanded = decodeStore(value, EMPTY_STORE_DATA);
577
+ base.setItem(key, encodeStore(expanded));
578
+ },
579
+ removeItem: base.removeItem,
580
+ subscribe: (key, callback) => {
581
+ const unsubscribe = base.subscribe?.(key, (value) => {
582
+ if (!value) {
583
+ callback(null);
584
+ return;
585
+ }
586
+ const expanded = decodeStore(value, EMPTY_STORE_DATA);
587
+ callback(JSON.stringify(expanded));
588
+ });
589
+ return () => {
590
+ unsubscribe?.();
591
+ };
592
+ }
593
+ };
594
+ };
595
+ //#endregion
596
+ //#region src/api/store.ts
597
+ const DEFAULT_SETTINGS = {};
598
+ /**
599
+ * Validates a cached wallet read from persisted storage. Cached state may have
600
+ * been written by an older (or corrupted) version with a different shape, so we
601
+ * drop anything that wouldn't survive hydration/sort rather than letting it
602
+ * throw at render time. Only the fields downstream code relies on are checked.
603
+ */
604
+ const isValidCachedWallet = (value) => {
605
+ if (!value || typeof value !== "object") return false;
606
+ const w = value;
607
+ if (!require_types.isValidWalletId(w.id)) return false;
608
+ if (typeof w.name !== "string" || typeof w.isConnected !== "boolean") return false;
609
+ if (w.type === "walletconnect") return w.id === "walletconnect" && w.platform === void 0;
610
+ return w.type === "injected" && require_types.isWalletPlatform(w.platform);
611
+ };
612
+ /** Validates a cached account read from persisted storage. See {@link isValidCachedWallet}. */
613
+ const isValidCachedAccount = (value) => {
614
+ if (!value || typeof value !== "object") return false;
615
+ const a = value;
616
+ return typeof a.id === "string" && !!a.id && require_types.isWalletPlatform(a.platform) && typeof a.address === "string" && !!a.address && require_types.isValidWalletId(a.walletId) && typeof a.walletName === "string";
617
+ };
618
+ /**
619
+ * Creates a kheopskit store with the appropriate storage backend.
620
+ * Uses cookieStorage when ssrCookies is provided (for SSR hydration),
621
+ * otherwise falls back to safeLocalStorage.
622
+ *
623
+ * @param options - Configuration options for the store
624
+ */
625
+ const createKheopskitStore = (options = {}) => {
626
+ const { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;
627
+ const storage = ssrCookies !== void 0 ? createCompactCookieStorage(ssrCookies) : require_iconCache.safeLocalStorage;
628
+ const store = createStore(storageKey, DEFAULT_SETTINGS, storage);
629
+ const addEnabledWalletId = (walletId) => {
630
+ require_types.parseWalletId(walletId);
631
+ store.mutate((prev) => ({
632
+ ...prev,
633
+ autoReconnect: (0, lodash_es.uniq)((prev.autoReconnect ?? []).concat(walletId))
634
+ }));
635
+ };
636
+ const removeEnabledWalletId = (walletId) => {
637
+ store.mutate((prev) => ({
638
+ ...prev,
639
+ autoReconnect: (0, lodash_es.uniq)((prev.autoReconnect ?? []).filter((id) => id !== walletId))
640
+ }));
641
+ };
642
+ const getCachedState = () => {
643
+ const data = store.get();
644
+ const cachedWallets = Array.isArray(data?.cachedWallets) ? data.cachedWallets : [];
645
+ const cachedAccounts = Array.isArray(data?.cachedAccounts) ? data.cachedAccounts : [];
646
+ return {
647
+ wallets: cachedWallets.filter(isValidCachedWallet),
648
+ accounts: cachedAccounts.filter(isValidCachedAccount)
649
+ };
650
+ };
651
+ const setCachedState = (wallets, accounts) => {
652
+ store.mutate((prev) => ({
653
+ ...prev,
654
+ cachedWallets: wallets,
655
+ cachedAccounts: accounts
656
+ }));
657
+ };
658
+ return {
659
+ observable: store.observable,
660
+ addEnabledWalletId,
661
+ removeEnabledWalletId,
662
+ getCachedState,
663
+ setCachedState
664
+ };
665
+ };
666
+ /**
667
+ * Cached default store instance, anchored on globalThis so it stays a single
668
+ * instance even if this module is duplicated across bundle chunks (e.g. CJS
669
+ * subpath entries). Lazily initialized on first access to be SSR-safe.
670
+ */
671
+ const DEFAULT_STORE_SYMBOL = Symbol.for("kheopskit.defaultStore");
672
+ /**
673
+ * Gets the default store, creating it on first access.
674
+ * Uses localStorage on client, noop on server.
675
+ * Lazily initialized to avoid SSR issues with module-level code.
676
+ */
677
+ const getDefaultStore = () => {
678
+ const g = globalThis;
679
+ if (!g[DEFAULT_STORE_SYMBOL]) g[DEFAULT_STORE_SYMBOL] = createKheopskitStore();
680
+ return g[DEFAULT_STORE_SYMBOL];
681
+ };
682
+ //#endregion
683
+ //#region src/api/reconnectPolicy.ts
684
+ const createReconnectPolicy = ({ maxAttempts = 3 } = {}) => {
685
+ const reconnecting = /* @__PURE__ */ new Set();
686
+ const reconnected = /* @__PURE__ */ new Set();
687
+ const failedAttempts = /* @__PURE__ */ new Map();
688
+ const shouldAttempt = (walletId) => !reconnecting.has(walletId) && !reconnected.has(walletId) && (failedAttempts.get(walletId) ?? 0) < maxAttempts;
689
+ /**
690
+ * Runs `connect` under the policy. Resolves `false` without connecting when
691
+ * an attempt is already in flight, the wallet already reconnected, or it
692
+ * exhausted its attempts; resolves `true` on success. A rejection from
693
+ * `connect` is recorded as a failed attempt and rethrown for the caller to
694
+ * report.
695
+ */
696
+ const attempt = async (walletId, connect) => {
697
+ if (!shouldAttempt(walletId)) return false;
698
+ reconnecting.add(walletId);
699
+ try {
700
+ await connect();
701
+ reconnected.add(walletId);
702
+ failedAttempts.delete(walletId);
703
+ return true;
704
+ } catch (err) {
705
+ failedAttempts.set(walletId, (failedAttempts.get(walletId) ?? 0) + 1);
706
+ throw err;
707
+ } finally {
708
+ reconnecting.delete(walletId);
709
+ }
710
+ };
711
+ return {
712
+ shouldAttempt,
713
+ attempt
714
+ };
715
+ };
716
+ //#endregion
717
+ //#region src/api/wallets.ts
718
+ const getWallets$ = (config, store) => {
719
+ const autoReconnectWalletIds$ = store.observable.pipe((0, rxjs.map)((s) => s.autoReconnect ?? []), (0, rxjs.take)(1), (0, rxjs.shareReplay)({
720
+ bufferSize: 1,
721
+ refCount: true
722
+ }));
723
+ return new rxjs.Observable((subscriber) => {
724
+ const ctx = {
725
+ config,
726
+ store
727
+ };
728
+ const observables = config.platforms.map((plugin) => plugin.getWallets$(ctx));
729
+ const wallets$ = (0, rxjs.combineLatest)([observables.length ? (0, rxjs.combineLatest)(observables).pipe((0, rxjs.map)((wallets) => wallets.flat())) : (0, rxjs.of)([]), getWalletConnectWallet$(config)]).pipe((0, rxjs.map)(([platformWallets, walletConnect]) => {
730
+ return (walletConnect ? [...platformWallets, walletConnect] : platformWallets).sort(sortWallets);
731
+ }));
732
+ const reconnectPolicy = createReconnectPolicy();
733
+ const subAutoReconnect = (0, rxjs.combineLatest)([wallets$, autoReconnectWalletIds$]).pipe((0, rxjs.filter)(([, walletIds]) => config.autoReconnect && !!walletIds?.length), (0, rxjs.mergeMap)(([wallets, walletIds]) => wallets.filter((wallet) => walletIds?.includes(wallet.id)))).subscribe(async (wallet) => {
734
+ if (wallet.isConnected) return;
735
+ try {
736
+ await reconnectPolicy.attempt(wallet.id, () => wallet.connect());
737
+ } catch (err) {
738
+ console.error("Failed to reconnect wallet %s", wallet.id, { err });
739
+ }
740
+ });
741
+ const subWallets = wallets$.subscribe(subscriber);
742
+ return () => {
743
+ subAutoReconnect.unsubscribe();
744
+ subWallets.unsubscribe();
745
+ };
746
+ }).pipe((0, rxjs.shareReplay)({
747
+ refCount: true,
748
+ bufferSize: 1
749
+ }));
750
+ };
751
+ //#endregion
752
+ //#region src/api/kheopskit.ts
753
+ const getKheopskit$ = (config, options = {}) => {
754
+ const { ssrCookies, store: existingStore } = options;
755
+ const kc = resolveConfig(config);
756
+ const store = existingStore ?? createKheopskitStore({
757
+ ssrCookies,
758
+ storageKey: kc.storageKey
759
+ });
760
+ if (kc.debug) console.debug("[kheopskit] config", kc);
761
+ if (kc.debug && typeof window === "undefined" && ssrCookies === void 0) console.warn("[kheopskit] Running on server without `ssrCookies`. Wallet state will not be hydrated. Pass cookies for SSR support.");
762
+ const { wallets: cachedWallets, accounts: cachedAccounts } = getHydratedSnapshot(store, kc.platforms, { icons: true });
763
+ if (kc.debug && cachedWallets.length > 0) console.debug("[kheopskit] hydrating from cache:", {
764
+ wallets: cachedWallets.length,
765
+ accounts: cachedAccounts.length
766
+ });
767
+ return new rxjs.Observable((subscriber) => {
768
+ const liveWallets$ = getWallets$(kc, store);
769
+ const liveAccounts$ = getAccounts$(kc, liveWallets$);
770
+ const bufferedWallets$ = createHydrationBuffer(cachedWallets, liveWallets$, kc.hydrationGracePeriod, (w) => w.id, (liveWallets, cached) => {
771
+ const cachedConnectedIds = new Set(cached.filter((w) => w.isConnected).map((w) => w.id));
772
+ if (cachedConnectedIds.size === 0) return true;
773
+ return [...cachedConnectedIds].every((id) => liveWallets.some((w) => w.id === id && w.isConnected));
774
+ }, (live, cached) => ({
775
+ ...cached,
776
+ icon: cached.icon || require_iconCache.getCachedIcon(cached.id) || live.icon,
777
+ connect: live.connect,
778
+ disconnect: live.disconnect
779
+ }), (cached) => ({
780
+ ...cached,
781
+ icon: cached.icon || require_iconCache.getCachedIcon(cached.id) || ""
782
+ }));
783
+ const bufferedAccounts$ = createAccountHydrationBuffer(cachedAccounts, liveAccounts$, kc.hydrationGracePeriod, (a) => a.walletId, (liveAccounts, cached) => {
784
+ const cachedWalletIds = new Set(cached.map((a) => a.walletId));
785
+ if (cachedWalletIds.size === 0) return true;
786
+ const liveWalletIds = new Set(liveAccounts.map((a) => a.walletId));
787
+ return [...cachedWalletIds].every((id) => liveWalletIds.has(id));
788
+ });
789
+ const sharedWallets$ = bufferedWallets$.pipe((0, rxjs.shareReplay)({
790
+ bufferSize: 1,
791
+ refCount: true
792
+ }));
793
+ const sharedAccounts$ = bufferedAccounts$.pipe((0, rxjs.shareReplay)({
794
+ bufferSize: 1,
795
+ refCount: true
796
+ }));
797
+ const subscription = (0, rxjs.combineLatest)({
798
+ wallets: sharedWallets$,
799
+ accounts: sharedAccounts$
800
+ }).pipe((0, rxjs.map)(({ wallets, accounts }) => {
801
+ if (kc.debug) console.debug("[kheopskit] hydration state", {
802
+ walletsHydrating: wallets.isHydrating,
803
+ accountsHydrating: accounts.isHydrating,
804
+ walletsConnected: wallets.items.filter((w) => w.isConnected).length,
805
+ walletsTotal: wallets.items.length
806
+ });
807
+ return {
808
+ config: kc,
809
+ wallets: [...wallets.items].sort(sortWallets),
810
+ accounts: [...accounts.items].sort(sortAccounts),
811
+ isHydrating: wallets.isHydrating || accounts.isHydrating
812
+ };
813
+ })).subscribe(subscriber);
814
+ const persistSub = (0, rxjs.combineLatest)({
815
+ wallets: sharedWallets$,
816
+ accounts: sharedAccounts$
817
+ }).pipe((0, rxjs.filter)(({ wallets, accounts }) => !wallets.isHydrating && !accounts.isHydrating), (0, rxjs.debounceTime)(1e3), (0, rxjs.distinctUntilChanged)((prev, curr) => {
818
+ const prevWalletKeys = prev.wallets.items.map(walletPersistKey);
819
+ const currWalletKeys = curr.wallets.items.map(walletPersistKey);
820
+ const prevAccountKeys = prev.accounts.items.map(accountChangeKey);
821
+ const currAccountKeys = curr.accounts.items.map(accountChangeKey);
822
+ return arraysEqual(prevWalletKeys, currWalletKeys) && arraysEqual(prevAccountKeys, currAccountKeys);
823
+ })).subscribe(({ wallets, accounts }) => {
824
+ const connectedWalletIds = new Set(wallets.items.filter((w) => w.isConnected).map((w) => w.id));
825
+ const relevantAccounts = accounts.items.filter((a) => connectedWalletIds.has(a.walletId));
826
+ if (kc.debug) console.debug("[kheopskit] persisting state snapshot:", {
827
+ wallets: wallets.items.length,
828
+ accounts: relevantAccounts.length
829
+ });
830
+ store.setCachedState(wallets.items.map(require_iconCache.serializeWallet), relevantAccounts.map(require_iconCache.serializeAccount));
831
+ const icons = {};
832
+ for (const wallet of wallets.items) if (wallet.icon) icons[wallet.id] = wallet.icon;
833
+ require_iconCache.setCachedIcons(icons);
834
+ });
835
+ return () => {
836
+ subscription.unsubscribe();
837
+ persistSub.unsubscribe();
838
+ };
839
+ }).pipe((0, rxjs.distinctUntilChanged)(statesEqual), (0, rxjs.throttleTime)(16, void 0, {
840
+ leading: true,
841
+ trailing: true
842
+ }), logObservable("kheopskit$", {
843
+ enabled: kc.debug,
844
+ printValue: true
845
+ }), (0, rxjs.shareReplay)({
846
+ bufferSize: 1,
847
+ refCount: true
848
+ }));
849
+ };
850
+ const arraysEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
851
+ /**
852
+ * A signature of an account covering its id plus the platform-specific fields
853
+ * that can change without the id changing (Ethereum chainId, Polkadot key type,
854
+ * Solana clusters). Used to detect both UI-relevant changes and changes worth
855
+ * re-persisting, so the two comparators can't drift apart.
856
+ */
857
+ const accountChangeKey = (account) => {
858
+ switch (account.platform) {
859
+ case "ethereum": return `${account.id}|${account.chainId ?? ""}`;
860
+ case "polkadot": return `${account.id}|${account.type ?? ""}`;
861
+ case "solana": return `${account.id}|${(account.chains ?? []).join(",")}`;
862
+ default: return account.id;
863
+ }
864
+ };
865
+ /** Platforms a wallet's live session carries (only the WalletConnect connector). */
866
+ const walletPlatforms = (wallet) => require_types.isWalletConnectWallet(wallet) ? wallet.platforms.join(",") : "";
867
+ /** Fields persisted to the cache for a wallet (icon is stored separately). */
868
+ const walletPersistKey = (wallet) => `${wallet.id}|${wallet.isConnected ? 1 : 0}|${wallet.name}`;
869
+ /**
870
+ * UI-significant signature of a wallet: the persisted fields plus icon and the
871
+ * WalletConnect connector's `platforms` array, which drive what the UI shows but
872
+ * aren't part of the id (icon and platforms can arrive asynchronously after
873
+ * connect without isConnected flipping).
874
+ */
875
+ const walletUiKey = (wallet) => `${walletPersistKey(wallet)}|${wallet.icon}|${walletPlatforms(wallet)}`;
876
+ /**
877
+ * Equality check for KheopskitState to prevent unnecessary emissions. Compares
878
+ * the UI-significant signature of every wallet and account, in order.
879
+ */
880
+ const statesEqual = (a, b) => a.isHydrating === b.isHydrating && a.wallets.length === b.wallets.length && a.accounts.length === b.accounts.length && a.wallets.every((w, i) => {
881
+ const other = b.wallets[i];
882
+ return !!other && walletUiKey(w) === walletUiKey(other);
617
883
  }) && a.accounts.every((acc, i) => {
618
- const other = b.accounts[i];
619
- return !!other && accountChangeKey(acc) === accountChangeKey(other);
884
+ const other = b.accounts[i];
885
+ return !!other && accountChangeKey(acc) === accountChangeKey(other);
620
886
  });
887
+ //#endregion
888
+ exports.DEFAULT_STORAGE_KEY = DEFAULT_STORAGE_KEY;
889
+ exports.KheopskitError = require_errors.KheopskitError;
890
+ exports.clearAllCachedObservables = require_types.clearAllCachedObservables;
891
+ exports.createKheopskitStore = createKheopskitStore;
892
+ exports.getDefaultStore = getDefaultStore;
893
+ exports.getHydratedSnapshot = getHydratedSnapshot;
894
+ exports.getKheopskit$ = getKheopskit$;
895
+ exports.getWalletAccountId = require_errors.getWalletAccountId;
896
+ exports.getWalletId = require_types.getWalletId;
897
+ exports.isInjectedWallet = require_types.isInjectedWallet;
898
+ exports.isValidAddress = require_errors.isValidAddress;
899
+ exports.isValidWalletId = require_types.isValidWalletId;
900
+ exports.isWalletConnectWallet = require_types.isWalletConnectWallet;
901
+ exports.parseWalletAccountId = require_errors.parseWalletAccountId;
902
+ exports.parseWalletId = require_types.parseWalletId;
903
+ exports.resetAppKitCache = resetAppKitCache;
904
+ exports.resolveConfig = resolveConfig;
621
905
 
622
-
623
-
624
-
625
-
626
-
627
-
628
-
629
-
630
-
631
-
632
-
633
-
634
-
635
-
636
-
637
-
638
- exports.DEFAULT_STORAGE_KEY = _chunkXQWJM3KCjs.DEFAULT_STORAGE_KEY; exports.KheopskitError = _chunkXQWJM3KCjs.KheopskitError; exports.clearAllCachedObservables = _chunk4ENHC7G4js.clearAllCachedObservables; exports.createKheopskitStore = _chunkXQWJM3KCjs.createKheopskitStore; exports.getDefaultStore = _chunkXQWJM3KCjs.getDefaultStore; exports.getKheopskit$ = getKheopskit$; exports.getWalletAccountId = _chunkXQWJM3KCjs.getWalletAccountId; exports.getWalletId = _chunk4ENHC7G4js.getWalletId; exports.isInjectedWallet = _chunk4ENHC7G4js.isInjectedWallet; exports.isValidAddress = _chunkXQWJM3KCjs.isValidAddress; exports.isValidWalletId = _chunk4ENHC7G4js.isValidWalletId; exports.isWalletConnectWallet = _chunk4ENHC7G4js.isWalletConnectWallet; exports.parseWalletAccountId = _chunkXQWJM3KCjs.parseWalletAccountId; exports.parseWalletId = _chunk4ENHC7G4js.parseWalletId; exports.resetAppKitCache = resetAppKitCache; exports.resolveConfig = _chunkXQWJM3KCjs.resolveConfig;
639
906
  //# sourceMappingURL=index.js.map