@kheopskit/core 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/{chunk-7QSGAJ4A.mjs → chunk-3Y5N4N3Q.mjs} +119 -62
  2. package/dist/chunk-3Y5N4N3Q.mjs.map +1 -0
  3. package/dist/chunk-DF7EKK4G.mjs +106 -0
  4. package/dist/chunk-DF7EKK4G.mjs.map +1 -0
  5. package/dist/chunk-EH73P476.js +106 -0
  6. package/dist/chunk-EH73P476.js.map +1 -0
  7. package/dist/chunk-JVSCMJY5.mjs +147 -0
  8. package/dist/chunk-JVSCMJY5.mjs.map +1 -0
  9. package/dist/chunk-P7BPHHVV.js +76 -0
  10. package/dist/chunk-P7BPHHVV.js.map +1 -0
  11. package/dist/{chunk-4ENHC7G4.js → chunk-SO64R7Z6.js} +114 -57
  12. package/dist/chunk-SO64R7Z6.js.map +1 -0
  13. package/dist/chunk-WOPCW2OX.mjs +76 -0
  14. package/dist/chunk-WOPCW2OX.mjs.map +1 -0
  15. package/dist/chunk-XOGQMEV2.js +147 -0
  16. package/dist/chunk-XOGQMEV2.js.map +1 -0
  17. package/dist/ethereum.d.mts +2 -2
  18. package/dist/ethereum.d.ts +2 -2
  19. package/dist/ethereum.js +56 -116
  20. package/dist/ethereum.js.map +1 -1
  21. package/dist/ethereum.mjs +56 -116
  22. package/dist/ethereum.mjs.map +1 -1
  23. package/dist/index.d.mts +59 -3
  24. package/dist/index.d.ts +59 -3
  25. package/dist/index.js +442 -61
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +429 -48
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/internal.d.mts +2 -39
  30. package/dist/internal.d.ts +2 -39
  31. package/dist/internal.js +3 -15
  32. package/dist/internal.js.map +1 -1
  33. package/dist/internal.mjs +6 -18
  34. package/dist/polkadot.d.mts +2 -2
  35. package/dist/polkadot.d.ts +2 -2
  36. package/dist/polkadot.js +75 -148
  37. package/dist/polkadot.js.map +1 -1
  38. package/dist/polkadot.mjs +76 -149
  39. package/dist/polkadot.mjs.map +1 -1
  40. package/dist/solana.d.mts +2 -2
  41. package/dist/solana.d.ts +2 -2
  42. package/dist/solana.js +90 -158
  43. package/dist/solana.js.map +1 -1
  44. package/dist/solana.mjs +86 -154
  45. package/dist/solana.mjs.map +1 -1
  46. package/dist/{types-C7V7DGlg.d.ts → types-0iDBydsK.d.mts} +24 -46
  47. package/dist/{types-C7V7DGlg.d.mts → types-0iDBydsK.d.ts} +24 -46
  48. package/package.json +1 -1
  49. package/dist/chunk-4ENHC7G4.js.map +0 -1
  50. package/dist/chunk-6XAZANB5.mjs +0 -450
  51. package/dist/chunk-6XAZANB5.mjs.map +0 -1
  52. package/dist/chunk-7QSGAJ4A.mjs.map +0 -1
  53. package/dist/chunk-B4L6GAYD.js +0 -179
  54. package/dist/chunk-B4L6GAYD.js.map +0 -1
  55. package/dist/chunk-XQWJM3KC.js +0 -450
  56. package/dist/chunk-XQWJM3KC.js.map +0 -1
  57. package/dist/chunk-YDLCHYHH.mjs +0 -179
  58. package/dist/chunk-YDLCHYHH.mjs.map +0 -1
@@ -0,0 +1,147 @@
1
+ import {
2
+ KheopskitError
3
+ } from "./chunk-DF7EKK4G.mjs";
4
+ import {
5
+ getCachedObservable$,
6
+ isWalletConnectWallet
7
+ } from "./chunk-WOPCW2OX.mjs";
8
+
9
+ // src/api/platformAccounts.ts
10
+ import {
11
+ combineLatest,
12
+ distinctUntilChanged,
13
+ map,
14
+ Observable,
15
+ of,
16
+ shareReplay,
17
+ switchMap
18
+ } from "rxjs";
19
+ var createPlatformAccounts$ = ({
20
+ wallets$,
21
+ getInjectedAccounts$,
22
+ getWalletConnectAccounts$,
23
+ mapAccounts,
24
+ accountChangeKey = (account) => account.id
25
+ }) => {
26
+ const accountsListEqual = (a, b) => a.length === b.length && a.every((account, i) => {
27
+ const other = b[i];
28
+ return !!other && accountChangeKey(account) === accountChangeKey(other);
29
+ });
30
+ return new Observable((subscriber) => {
31
+ const sub = wallets$.pipe(
32
+ map((wallets) => wallets.filter((w) => w.isConnected)),
33
+ switchMap(
34
+ (wallets) => wallets.length ? combineLatest([
35
+ ...wallets.filter((w) => !isWalletConnectWallet(w)).map(getInjectedAccounts$),
36
+ ...wallets.filter(isWalletConnectWallet).map(getWalletConnectAccounts$)
37
+ ]) : of([])
38
+ ),
39
+ map((accounts) => {
40
+ const flat = accounts.flat();
41
+ return mapAccounts ? mapAccounts(flat) : flat;
42
+ }),
43
+ distinctUntilChanged(accountsListEqual)
44
+ ).subscribe(subscriber);
45
+ return () => {
46
+ sub.unsubscribe();
47
+ };
48
+ }).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
49
+ };
50
+ var getSessionCaip10s = (session, namespace) => Object.values(session.namespaces).flatMap((ns) => ns.accounts ?? []).filter((account) => account.startsWith(`${namespace}:`));
51
+ var getCaip10Addresses = (caip10s) => [
52
+ ...new Set(
53
+ caip10s.map((account) => account.split(":")[2]).filter((address) => !!address)
54
+ )
55
+ ];
56
+ var getWalletConnectSessionAccounts$ = (options) => {
57
+ const { wallet, platform, namespace, cacheKey, buildAccounts } = options;
58
+ const provider = wallet.appKit.getProvider(namespace);
59
+ if (!wallet.platforms.includes(platform) || !provider?.session) return of([]);
60
+ return getCachedObservable$(
61
+ cacheKey,
62
+ () => new Observable((subscriber) => {
63
+ subscriber.next(buildAccounts(provider));
64
+ const reemit = () => subscriber.next(buildAccounts(provider));
65
+ provider.on("session_update", reemit);
66
+ provider.on("accountsChanged", reemit);
67
+ return () => {
68
+ provider.off("session_update", reemit);
69
+ provider.off("accountsChanged", reemit);
70
+ };
71
+ }).pipe(shareReplay({ refCount: true, bufferSize: 1 }))
72
+ );
73
+ };
74
+
75
+ // src/api/injectedWallets.ts
76
+ import {
77
+ BehaviorSubject,
78
+ combineLatest as combineLatest2,
79
+ distinctUntilChanged as distinctUntilChanged2,
80
+ map as map2,
81
+ Observable as Observable2,
82
+ shareReplay as shareReplay2
83
+ } from "rxjs";
84
+ var walletsEqual = (a, b) => {
85
+ if (a.length !== b.length) return false;
86
+ return a.every(
87
+ (w, i) => w.id === b[i]?.id && w.isConnected === b[i]?.isConnected && w.name === b[i]?.name
88
+ );
89
+ };
90
+ var createInjectedWallets$ = (store, adapter) => new Observable2((subscriber) => {
91
+ const handles$ = new BehaviorSubject(/* @__PURE__ */ new Map());
92
+ const connect = async (source, walletId) => {
93
+ if (handles$.value.has(walletId))
94
+ throw new KheopskitError(
95
+ "WALLET_ALREADY_CONNECTED",
96
+ `wallet ${walletId} is already connected`,
97
+ { walletId }
98
+ );
99
+ const handle = await adapter.connect(source, walletId);
100
+ const next = new Map(handles$.value);
101
+ next.set(walletId, handle);
102
+ handles$.next(next);
103
+ store.addEnabledWalletId(walletId);
104
+ };
105
+ const disconnect = async (source, walletId) => {
106
+ if (!handles$.value.has(walletId))
107
+ throw new KheopskitError(
108
+ "WALLET_NOT_CONNECTED",
109
+ `wallet ${walletId} is not connected`,
110
+ { walletId }
111
+ );
112
+ await adapter.disconnect?.(source, walletId);
113
+ const next = new Map(handles$.value);
114
+ next.delete(walletId);
115
+ handles$.next(next);
116
+ store.removeEnabledWalletId(walletId);
117
+ adapter.onDisconnected?.(walletId);
118
+ };
119
+ const sub = combineLatest2([adapter.sources$, handles$]).pipe(
120
+ map2(
121
+ ([sources, handles]) => sources.map((source) => {
122
+ const walletId = adapter.getWalletId(source);
123
+ return adapter.buildWallet({
124
+ source,
125
+ walletId,
126
+ handle: handles.get(walletId),
127
+ isConnected: handles.has(walletId),
128
+ connect: () => connect(source, walletId),
129
+ disconnect: () => disconnect(source, walletId)
130
+ });
131
+ })
132
+ ),
133
+ distinctUntilChanged2(walletsEqual)
134
+ ).subscribe(subscriber);
135
+ return () => {
136
+ sub.unsubscribe();
137
+ };
138
+ }).pipe(shareReplay2({ refCount: true, bufferSize: 1 }));
139
+
140
+ export {
141
+ createPlatformAccounts$,
142
+ getSessionCaip10s,
143
+ getCaip10Addresses,
144
+ getWalletConnectSessionAccounts$,
145
+ createInjectedWallets$
146
+ };
147
+ //# sourceMappingURL=chunk-JVSCMJY5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/platformAccounts.ts","../src/api/injectedWallets.ts"],"sourcesContent":["import {\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tof,\n\tshareReplay,\n\tswitchMap,\n} from \"rxjs\";\nimport { getCachedObservable$ } from \"../utils/getCachedObservable\";\nimport type {\n\tBaseWallet,\n\tBaseWalletAccount,\n\tWalletConnectProvider,\n\tWalletConnectWallet,\n\tWalletPlatform,\n} from \"./types\";\nimport { isWalletConnectWallet } from \"./types\";\n\n/**\n * The platform-specific surface of an accounts stream. The shared pipeline —\n * filter connected wallets, fan out per-wallet account streams, flatten,\n * change-detect, share — is owned by {@link createPlatformAccounts$}.\n */\nexport type PlatformAccountsOptions<\n\tTWallet extends BaseWallet,\n\tTAccount extends BaseWalletAccount,\n> = {\n\t/** This platform's wallets plus the shared WalletConnect connector. */\n\twallets$: Observable<(TWallet | WalletConnectWallet)[]>;\n\t/** Account stream for one connected injected wallet. */\n\tgetInjectedAccounts$: (wallet: TWallet) => Observable<TAccount[]>;\n\t/** Account stream for the WalletConnect connector. */\n\tgetWalletConnectAccounts$: (\n\t\twallet: WalletConnectWallet,\n\t) => Observable<TAccount[]>;\n\t/** Optional post-flatten transform (e.g. Polkadot's `accountTypes` filter). */\n\tmapAccounts?: (accounts: TAccount[]) => TAccount[];\n\t/**\n\t * Signature of the account fields that should trigger a re-emission.\n\t * Defaults to the account id; platforms add mutable fields (Ethereum\n\t * `chainId`, Solana `chains`).\n\t */\n\taccountChangeKey?: (account: TAccount) => string;\n};\n\n/** Shared engine behind every platform's `getAccounts$`. */\nexport const createPlatformAccounts$ = <\n\tTWallet extends BaseWallet,\n\tTAccount extends BaseWalletAccount,\n>({\n\twallets$,\n\tgetInjectedAccounts$,\n\tgetWalletConnectAccounts$,\n\tmapAccounts,\n\taccountChangeKey = (account) => account.id,\n}: PlatformAccountsOptions<TWallet, TAccount>): Observable<TAccount[]> => {\n\tconst accountsListEqual = (a: TAccount[], b: TAccount[]) =>\n\t\ta.length === b.length &&\n\t\ta.every((account, i) => {\n\t\t\tconst other = b[i];\n\t\t\treturn !!other && accountChangeKey(account) === accountChangeKey(other);\n\t\t});\n\n\treturn new Observable<TAccount[]>((subscriber) => {\n\t\tconst sub = wallets$\n\t\t\t.pipe(\n\t\t\t\tmap((wallets) => wallets.filter((w) => w.isConnected)),\n\t\t\t\tswitchMap((wallets) =>\n\t\t\t\t\twallets.length\n\t\t\t\t\t\t? combineLatest([\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter((w): w is TWallet => !isWalletConnectWallet(w))\n\t\t\t\t\t\t\t\t\t.map(getInjectedAccounts$),\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter(isWalletConnectWallet)\n\t\t\t\t\t\t\t\t\t.map(getWalletConnectAccounts$),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t: of([]),\n\t\t\t\t),\n\t\t\t\tmap((accounts) => {\n\t\t\t\t\tconst flat = accounts.flat();\n\t\t\t\t\treturn mapAccounts ? mapAccounts(flat) : flat;\n\t\t\t\t}),\n\t\t\t\tdistinctUntilChanged(accountsListEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n};\n\n/**\n * CAIP-10 account strings (\"<namespace>:<chainRef>:<address>\") the live\n * WalletConnect session carries for a namespace.\n */\nexport const getSessionCaip10s = (\n\tsession: NonNullable<WalletConnectProvider[\"session\"]>,\n\tnamespace: string,\n): string[] =>\n\tObject.values(session.namespaces)\n\t\t.flatMap((ns) => ns.accounts ?? [])\n\t\t.filter((account) => account.startsWith(`${namespace}:`));\n\n/**\n * Unique addresses from CAIP-10 account strings (one entry per chain, so the\n * same address repeats — dedupe).\n */\nexport const getCaip10Addresses = (caip10s: string[]): string[] => [\n\t...new Set(\n\t\tcaip10s\n\t\t\t.map((account) => account.split(\":\")[2])\n\t\t\t.filter((address): address is string => !!address),\n\t),\n];\n\n/**\n * Shared shape of the Polkadot/Solana WalletConnect account streams: no-op\n * unless the session carries the platform's namespace, then a cached\n * observable that rebuilds the account list from the session on\n * `session_update` / `accountsChanged`.\n *\n * AppKit's `getAccount(namespace).allAccounts` is always empty for namespaces\n * without a native AppKit adapter — the WalletConnect session is the source of\n * truth, hence the session-driven rebuild.\n */\nexport const getWalletConnectSessionAccounts$ = <\n\tTAccount extends BaseWalletAccount,\n>(options: {\n\twallet: WalletConnectWallet;\n\tplatform: WalletPlatform;\n\t/** WalletConnect namespace, e.g. \"polkadot\" | \"solana\" | \"eip155\". */\n\tnamespace: string;\n\t/** Cache key for {@link getCachedObservable$} — must be reconnect-safe. */\n\tcacheKey: string;\n\t/** Build the account list from the live session. */\n\tbuildAccounts: (provider: WalletConnectProvider) => TAccount[];\n}): Observable<TAccount[]> => {\n\tconst { wallet, platform, namespace, cacheKey, buildAccounts } = options;\n\tconst provider = wallet.appKit.getProvider(namespace);\n\n\tif (!wallet.platforms.includes(platform) || !provider?.session) return of([]);\n\n\treturn getCachedObservable$(cacheKey, () =>\n\t\tnew Observable<TAccount[]>((subscriber) => {\n\t\t\tsubscriber.next(buildAccounts(provider));\n\n\t\t\t// Re-derive when the WalletConnect session's accounts change, mirroring\n\t\t\t// the injected paths' change subscriptions.\n\t\t\tconst reemit = () => subscriber.next(buildAccounts(provider));\n\t\t\tprovider.on(\"session_update\", reemit);\n\t\t\tprovider.on(\"accountsChanged\", reemit);\n\n\t\t\treturn () => {\n\t\t\t\tprovider.off(\"session_update\", reemit);\n\t\t\t\tprovider.off(\"accountsChanged\", reemit);\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n","import {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n} from \"rxjs\";\nimport type { WalletId } from \"../utils/WalletId\";\nimport { KheopskitError } from \"./errors\";\nimport type { KheopskitStore } from \"./store\";\nimport type { BaseWallet } from \"./types\";\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n * Shared by every platform's injected-wallets stream.\n */\nconst walletsEqual = <\n\tW extends Pick<BaseWallet, \"id\" | \"isConnected\" | \"name\">,\n>(\n\ta: W[],\n\tb: W[],\n): boolean => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(w, i) =>\n\t\t\tw.id === b[i]?.id &&\n\t\t\tw.isConnected === b[i]?.isConnected &&\n\t\t\tw.name === b[i]?.name,\n\t);\n};\n\n/**\n * The platform-specific surface of an injected-wallets stream. Everything else\n * — the connect/disconnect state machine, the connected-ids bookkeeping, the\n * store persistence, change detection and sharing — is owned by\n * {@link createInjectedWallets$}.\n *\n * @typeParam TSource - a wallet as the platform's registry reports it\n * @typeParam TWallet - the platform's wallet type\n * @typeParam THandle - live connection handle retained while connected\n * (Polkadot keeps the `InjectedExtension`; platforms with no handle use void)\n */\nexport type InjectedWalletsAdapter<\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n> = {\n\t/** Live registry of the platform's injected wallets (emits `[]` during SSR). */\n\tsources$: Observable<readonly TSource[]>;\n\t/** Stable wallet id for a registry entry. */\n\tgetWalletId: (source: TSource) => WalletId;\n\t/**\n\t * Platform connect call (e.g. `connectInjectedExtension`,\n\t * `eth_requestAccounts`, `standard:connect`). The resolved value is retained\n\t * as the wallet's live handle until disconnect.\n\t */\n\tconnect: (source: TSource, walletId: WalletId) => Promise<THandle>;\n\t/**\n\t * Optional platform disconnect call, awaited before local state clears so a\n\t * failed disconnect rejects without desyncing the connected list.\n\t */\n\tdisconnect?: (source: TSource, walletId: WalletId) => Promise<void>;\n\t/**\n\t * Runs after a disconnect fully applied — the place to drop cached account\n\t * observables so a later reconnect rebuilds them against a fresh handle.\n\t */\n\tonDisconnected?: (walletId: WalletId) => void;\n\t/** Build the platform wallet object for one registry entry. */\n\tbuildWallet: (args: {\n\t\tsource: TSource;\n\t\twalletId: WalletId;\n\t\t/** Live connection handle; `undefined` while disconnected. */\n\t\thandle: THandle | undefined;\n\t\tisConnected: boolean;\n\t\tconnect: () => Promise<void>;\n\t\tdisconnect: () => Promise<void>;\n\t}) => TWallet;\n};\n\n/**\n * The shared engine behind every platform's injected-wallets stream: tracks\n * connected wallets (and their live handles), guards double\n * connect/disconnect, persists connected ids to the store for auto-reconnect,\n * and re-emits the wallet list whenever the registry or connection state\n * changes.\n */\nexport const createInjectedWallets$ = <\n\tTSource,\n\tTWallet extends BaseWallet,\n\tTHandle = void,\n>(\n\tstore: KheopskitStore,\n\tadapter: InjectedWalletsAdapter<TSource, TWallet, THandle>,\n): Observable<TWallet[]> =>\n\tnew Observable<TWallet[]>((subscriber) => {\n\t\tconst handles$ = new BehaviorSubject<Map<WalletId, THandle>>(new Map());\n\n\t\tconst connect = async (source: TSource, walletId: WalletId) => {\n\t\t\tif (handles$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_ALREADY_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is already connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\n\t\t\tconst handle = await adapter.connect(source, walletId);\n\n\t\t\tconst next = new Map(handles$.value);\n\t\t\tnext.set(walletId, handle);\n\t\t\thandles$.next(next);\n\n\t\t\tstore.addEnabledWalletId(walletId);\n\t\t};\n\n\t\tconst disconnect = async (source: TSource, walletId: WalletId) => {\n\t\t\tif (!handles$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_NOT_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is not connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\n\t\t\tawait adapter.disconnect?.(source, walletId);\n\n\t\t\tconst next = new Map(handles$.value);\n\t\t\tnext.delete(walletId);\n\t\t\thandles$.next(next);\n\n\t\t\tstore.removeEnabledWalletId(walletId);\n\n\t\t\tadapter.onDisconnected?.(walletId);\n\t\t};\n\n\t\tconst sub = combineLatest([adapter.sources$, handles$])\n\t\t\t.pipe(\n\t\t\t\tmap(([sources, handles]) =>\n\t\t\t\t\tsources.map((source): TWallet => {\n\t\t\t\t\t\tconst walletId = adapter.getWalletId(source);\n\t\t\t\t\t\treturn adapter.buildWallet({\n\t\t\t\t\t\t\tsource,\n\t\t\t\t\t\t\twalletId,\n\t\t\t\t\t\t\thandle: handles.get(walletId),\n\t\t\t\t\t\t\tisConnected: handles.has(walletId),\n\t\t\t\t\t\t\tconnect: () => connect(source, walletId),\n\t\t\t\t\t\t\tdisconnect: () => disconnect(source, walletId),\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tdistinctUntilChanged(walletsEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n"],"mappings":"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","names":["combineLatest","distinctUntilChanged","map","Observable","shareReplay","Observable","combineLatest","map","distinctUntilChanged","shareReplay"]}
@@ -0,0 +1,76 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/utils/isWalletPlatform.ts
6
+ var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum", "solana"].includes(platform);
7
+
8
+ // src/utils/WalletId.ts
9
+ var WALLET_CONNECT_WALLET_ID = "walletconnect";
10
+ var getWalletId = (platform, identifier) => {
11
+ if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
12
+ if (!identifier) throw new Error("Invalid name");
13
+ return `${platform}:${identifier}`;
14
+ };
15
+ var parseWalletId = (walletId) => {
16
+ if (!walletId) throw new Error("Invalid walletId");
17
+ const [platform, identifier] = walletId.split(":");
18
+ if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
19
+ if (!identifier) throw new Error("Invalid address");
20
+ return { platform, identifier };
21
+ };
22
+ var isValidWalletId = (walletId) => {
23
+ if (typeof walletId !== "string" || !walletId) return false;
24
+ if (walletId === WALLET_CONNECT_WALLET_ID) return true;
25
+ const [platform, identifier] = walletId.split(":");
26
+ return isWalletPlatform(platform) && !!identifier;
27
+ };
28
+
29
+ // src/utils/getCachedObservable.ts
30
+ var CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.observableCache");
31
+ var getCache = () => {
32
+ const g = globalThis;
33
+ let cache = g[CACHE_SYMBOL];
34
+ if (!cache) {
35
+ cache = /* @__PURE__ */ new Map();
36
+ g[CACHE_SYMBOL] = cache;
37
+ }
38
+ return cache;
39
+ };
40
+ var getCachedObservable$ = (key, create) => {
41
+ const cache = getCache();
42
+ if (!cache.has(key)) cache.set(key, create());
43
+ return cache.get(key);
44
+ };
45
+ var clearCachedObservable = (key) => {
46
+ getCache().delete(key);
47
+ };
48
+ var clearCachedObservablesByPrefix = (prefix) => {
49
+ const cache = getCache();
50
+ for (const key of cache.keys()) {
51
+ if (key.startsWith(prefix)) cache.delete(key);
52
+ }
53
+ };
54
+ var clearAllCachedObservables = () => {
55
+ getCache().clear();
56
+ };
57
+
58
+ // src/api/types.ts
59
+ var isWalletConnectWallet = (wallet) => wallet.type === "walletconnect";
60
+ var isInjectedWallet = (wallet) => wallet.type === "injected";
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+ exports.__publicField = __publicField; exports.isWalletPlatform = isWalletPlatform; exports.WALLET_CONNECT_WALLET_ID = WALLET_CONNECT_WALLET_ID; exports.getWalletId = getWalletId; exports.parseWalletId = parseWalletId; exports.isValidWalletId = isValidWalletId; exports.getCachedObservable$ = getCachedObservable$; exports.clearCachedObservable = clearCachedObservable; exports.clearCachedObservablesByPrefix = clearCachedObservablesByPrefix; exports.clearAllCachedObservables = clearAllCachedObservables; exports.isWalletConnectWallet = isWalletConnectWallet; exports.isInjectedWallet = isInjectedWallet;
76
+ //# sourceMappingURL=chunk-P7BPHHVV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-P7BPHHVV.js","../src/utils/isWalletPlatform.ts","../src/utils/WalletId.ts","../src/utils/getCachedObservable.ts","../src/api/types.ts"],"names":[],"mappings":"AAAA,6EAAI,UAAU,EAAE,MAAM,CAAC,cAAc;AACrC,IAAI,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK;AAC/J,IAAI,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,IAAI,IAAI,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC;AAC9G;AACA;ACFO,IAAM,iBAAA,EAAmB,CAC/B,QAAA,EAAA,GAEA,OAAO,SAAA,IAAa,SAAA,GACpB,CAAC,UAAA,EAAY,UAAA,EAAY,QAAQ,CAAA,CAAE,QAAA,CAAS,QAA0B,CAAA;ADAvE;AACA;AEGO,IAAM,yBAAA,EAAqC,eAAA;AAE3C,IAAM,YAAA,EAAc,CAC1B,QAAA,EACA,UAAA,EAAA,GACc;AACd,EAAA,GAAA,CAAI,CAAC,gBAAA,CAAiB,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,kBAAkB,CAAA;AACnE,EAAA,GAAA,CAAI,CAAC,UAAA,EAAY,MAAM,IAAI,KAAA,CAAM,cAAc,CAAA;AAC/C,EAAA,OAAO,CAAA,EAAA;AACR;AAEa;AACP,EAAA;AACE,EAAA;AACF,EAAA;AACA,EAAA;AACE,EAAA;AACR;AAMa;AACR,EAAA;AACA,EAAA;AACG,EAAA;AACA,EAAA;AACR;AFXU;AACA;AGxBJ;AAEA;AACC,EAAA;AAIF,EAAA;AACC,EAAA;AACJ,IAAA;AACE,IAAA;AACH,EAAA;AACO,EAAA;AACR;AAEa;AAIN,EAAA;AACD,EAAA;AAEE,EAAA;AACR;AAMa;AACZ,EAAA;AACD;AASa;AACN,EAAA;AACN,EAAA;AACK,IAAA;AACL,EAAA;AACD;AAMa;AACZ,EAAA;AACD;AHDU;AACA;AIyDG;AAkBA;AJxEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-P7BPHHVV.js","sourcesContent":[null,"import type { WalletPlatform } from \"../api/types\";\n\nexport const isWalletPlatform = (\n\tplatform: unknown,\n): platform is WalletPlatform =>\n\ttypeof platform === \"string\" &&\n\t[\"polkadot\", \"ethereum\", \"solana\"].includes(platform as WalletPlatform);\n","import type { WalletPlatform } from \"../api/types\";\nimport { isWalletPlatform } from \"./isWalletPlatform\";\n\nexport type WalletId = string;\n\n/**\n * Stable id of the single WalletConnect connector. It is platform-less: one WC\n * session spans whichever namespaces the wallet approves, so it isn't tied to a\n * platform (unlike injected wallet ids, which are `<platform>:<identifier>`).\n */\nexport const WALLET_CONNECT_WALLET_ID: WalletId = \"walletconnect\";\n\nexport const getWalletId = (\n\tplatform: WalletPlatform,\n\tidentifier: string,\n): WalletId => {\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid name\");\n\treturn `${platform}:${identifier}`;\n};\n\nexport const parseWalletId = (walletId: string) => {\n\tif (!walletId) throw new Error(\"Invalid walletId\");\n\tconst [platform, identifier] = walletId.split(\":\");\n\tif (!isWalletPlatform(platform)) throw new Error(\"Invalid platform\");\n\tif (!identifier) throw new Error(\"Invalid address\");\n\treturn { platform, identifier };\n};\n\n/**\n * Non-throwing variant of {@link parseWalletId}. Use when validating untrusted\n * input (e.g. cached state persisted by an older version) before parsing.\n */\nexport const isValidWalletId = (walletId: unknown): walletId is WalletId => {\n\tif (typeof walletId !== \"string\" || !walletId) return false;\n\tif (walletId === WALLET_CONNECT_WALLET_ID) return true;\n\tconst [platform, identifier] = walletId.split(\":\");\n\treturn isWalletPlatform(platform) && !!identifier;\n};\n","import type { Observable } from \"rxjs\";\n\n// Anchored on globalThis so the cache stays a single instance even if the\n// module is duplicated across bundle chunks (e.g. CJS subpath entries).\nconst CACHE_SYMBOL = Symbol.for(\"kheopskit.observableCache\");\n\nconst getCache = (): Map<string, Observable<unknown>> => {\n\tconst g = globalThis as unknown as Record<\n\t\tsymbol,\n\t\tMap<string, Observable<unknown>> | undefined\n\t>;\n\tlet cache = g[CACHE_SYMBOL];\n\tif (!cache) {\n\t\tcache = new Map();\n\t\tg[CACHE_SYMBOL] = cache;\n\t}\n\treturn cache;\n};\n\nexport const getCachedObservable$ = <T, Obs = Observable<T>>(\n\tkey: string,\n\tcreate: () => Obs,\n): Obs => {\n\tconst cache = getCache();\n\tif (!cache.has(key)) cache.set(key, create() as Observable<unknown>);\n\n\treturn cache.get(key) as Obs;\n};\n\n/**\n * Clears an observable from the cache.\n * Use when a wallet disconnects or configuration changes.\n */\nexport const clearCachedObservable = (key: string): void => {\n\tgetCache().delete(key);\n};\n\n/**\n * Clears all cached observables whose key starts with `prefix`.\n *\n * Used to drop a wallet's account observables when it disconnects, so a later\n * reconnect rebuilds them against the current wallet handle instead of a stale\n * closure — and to keep the cache from growing unbounded across connect cycles.\n */\nexport const clearCachedObservablesByPrefix = (prefix: string): void => {\n\tconst cache = getCache();\n\tfor (const key of cache.keys()) {\n\t\tif (key.startsWith(prefix)) cache.delete(key);\n\t}\n};\n\n/**\n * Clears all cached observables.\n * Use when resetting the entire kheopskit state.\n */\nexport const clearAllCachedObservables = (): void => {\n\tgetCache().clear();\n};\n","import type { Observable } from \"rxjs\";\nimport type { WalletAccountId } from \"../utils\";\nimport type { WalletId } from \"../utils/WalletId\";\n\nexport type WalletPlatform = \"polkadot\" | \"ethereum\" | \"solana\";\n\n/**\n * Minimal structural view of a WalletConnect `UniversalProvider` — the subset\n * kheopskit reads. Declared locally so core never depends on\n * `@walletconnect/universal-provider`. The concrete instance comes from\n * `@reown/appkit` at runtime.\n */\nexport type WalletConnectProvider = {\n\tsession?: {\n\t\ttopic: string;\n\t\tnamespaces: Record<string, { accounts?: string[] }>;\n\t};\n\tclient: {\n\t\trequest<T = unknown>(args: {\n\t\t\ttopic: string;\n\t\t\tchainId: string;\n\t\t\trequest: { method: string; params: unknown };\n\t\t}): Promise<T>;\n\t};\n\trequest(args: { method: string; params?: unknown }): Promise<unknown>;\n\ton(event: string, listener: (...args: unknown[]) => void): void;\n\toff(event: string, listener: (...args: unknown[]) => void): void;\n};\n\n/**\n * Minimal structural view of the Reown AppKit instance — the subset kheopskit's\n * account factories use. Exposed as the `appKit` escape hatch on AppKit wallets;\n * cast it to `@reown/appkit`'s `AppKit` type for the full API. Declared locally\n * so core never depends on `@reown/appkit`'s types (it's an optional peer).\n */\nexport type AppKitInstance = {\n\tgetProvider<T = WalletConnectProvider>(namespace: string): T | undefined;\n\tgetAccount(\n\t\tnamespace: string,\n\t): { allAccounts: { address: string }[] } | undefined;\n\tgetCaipNetworks(namespace: string): { caipNetworkId?: string }[];\n};\n\nexport type WalletType = \"injected\" | \"walletconnect\";\n\nexport type PolkadotAccountType = \"sr25519\" | \"ed25519\" | \"ecdsa\" | \"ethereum\";\n\n/**\n * SDK-free fields common to every wallet, regardless of platform. Platform\n * packages (`@kheopskit/core/<platform>`) extend this with SDK-typed fields\n * (the injected provider/extension/standard-wallet handle).\n */\nexport type BaseWallet = {\n\tid: WalletId;\n\tplatform: WalletPlatform;\n\ttype: WalletType;\n\tname: string;\n\ticon: string;\n\tisConnected: boolean;\n\tconnect: () => Promise<void>;\n\t/**\n\t * Disconnect the wallet. Resolves once the underlying provider/extension\n\t * disconnect completes; rejects if it fails so callers can surface or retry.\n\t */\n\tdisconnect: () => Promise<void>;\n};\n\n/**\n * SDK-free fields common to every account, regardless of platform. Platform\n * packages extend this with their SDK-typed signer/client.\n */\nexport type BaseWalletAccount = {\n\tid: WalletAccountId;\n\tplatform: WalletPlatform;\n\t/** Base58 (Solana), SS58 (Polkadot) or 0x-hex (Ethereum) address. */\n\taddress: string;\n\t/** Friendly account name, when the wallet exposes one (e.g. Polkadot). */\n\tname?: string;\n\twalletName: string;\n\twalletId: WalletId;\n};\n\n/**\n * The single WalletConnect connector, shared across every platform.\n *\n * Unlike injected wallets, it is **not tied to a platform**: one WalletConnect\n * session spans whichever namespaces the remote wallet approves in a single\n * pairing (a namespace can't be added to a live session afterwards). So there is\n * exactly one of these in `wallets`, discriminated by `type: \"walletconnect\"`.\n * Its accounts appear in `accounts`, each carrying its own `platform`.\n */\nexport type WalletConnectWallet = {\n\tid: WalletId;\n\ttype: \"walletconnect\";\n\t/**\n\t * Platforms (namespaces) the live session currently carries. Empty until\n\t * connected; populated with whatever the wallet approved (e.g. just\n\t * `[\"ethereum\"]`, or `[\"polkadot\", \"ethereum\"]`).\n\t */\n\tplatforms: WalletPlatform[];\n\t/**\n\t * Raw Reown AppKit instance, exposed as an escape hatch for advanced use\n\t * (custom modal control, reading providers directly). Most consumers should\n\t * use `connect`/`disconnect` and the derived accounts instead.\n\t */\n\tappKit: AppKitInstance;\n\tname: string;\n\ticon: string;\n\tisConnected: boolean;\n\tconnect: () => Promise<void>;\n\tdisconnect: () => Promise<void>;\n};\n\n/** Narrows a wallet to the platform-less {@link WalletConnectWallet}. */\nexport const isWalletConnectWallet = (\n\twallet: BaseWallet | WalletConnectWallet,\n): wallet is WalletConnectWallet => wallet.type === \"walletconnect\";\n\n/**\n * Narrows a wallet to an injected (browser-extension / Wallet Standard) wallet —\n * the complement of {@link isWalletConnectWallet}. `state.wallets` is\n * `(InjectedWallet | WalletConnectWallet)[]`, so use this to recover the\n * injected-only fields when iterating: `platform`, `sourceId`, and the SDK\n * handle (`provider` on Ethereum, `extension` on Polkadot, `wallet` on Solana).\n *\n * @example\n * ```ts\n * for (const wallet of wallets.filter(isInjectedWallet)) {\n * console.log(wallet.platform, wallet.sourceId); // typed, no WC widening\n * }\n * ```\n */\nexport const isInjectedWallet = <W extends BaseWallet | WalletConnectWallet>(\n\twallet: W,\n): wallet is Exclude<W, WalletConnectWallet> => wallet.type === \"injected\";\n\n/**\n * Dapp metadata shown in the WalletConnect modal. Mirrors WalletConnect's\n * `Metadata`, declared locally so core doesn't depend on\n * `@walletconnect/universal-provider`.\n */\nexport type WalletConnectMetadata = {\n\tname: string;\n\tdescription: string;\n\turl: string;\n\ticons: string[];\n};\n\nexport type WalletConnectConfig = {\n\tprojectId: string;\n\tmetadata: WalletConnectMetadata;\n\t/** Defaults to wss://relay.walletconnect.com */\n\trelayUrl?: string;\n\t/**\n\t * Networks AppKit should enable. Pass `AppKitNetwork[]` from\n\t * `@reown/appkit/networks` (see\n\t * https://docs.reown.com/advanced/multichain/polkadot/dapp-integration-guide#walletconnect-code%2Fcomponent-setup).\n\t * Loosely typed (`unknown`) so core doesn't depend on `@reown/appkit`'s\n\t * types — the value is forwarded to AppKit as-is.\n\t */\n\tnetworks: [unknown, ...unknown[]];\n\tthemeMode?: \"light\" | \"dark\";\n\tthemeVariables?: Record<string, string | number>;\n};\n\n/**\n * Context passed to a platform plugin's `getWallets$`. Carries the shared store\n * and the resolved core config (for WalletConnect / debug).\n */\nexport type PlatformContext = {\n\tstore: KheopskitStore;\n\tconfig: KheopskitConfig;\n};\n\n/**\n * A platform plugin. Created by the per-platform factories exported from\n * `@kheopskit/core/polkadot`, `/ethereum`, `/solana`. Core iterates plugins\n * generically and never imports a platform SDK itself.\n *\n * @typeParam TPlatform - the platform discriminant\n * @typeParam TWallet - the platform's wallet type (extends {@link BaseWallet})\n * @typeParam TAccount - the platform's account type (extends {@link BaseWalletAccount})\n */\nexport type KheopskitPlatform<\n\tTPlatform extends WalletPlatform = WalletPlatform,\n\tTWallet extends BaseWallet = BaseWallet,\n\tTAccount extends BaseWalletAccount = BaseWalletAccount,\n> = {\n\treadonly platform: TPlatform;\n\t// Declared as methods (not arrow properties) so parameters are checked\n\t// bivariantly — this lets a specific `KheopskitPlatform<\"polkadot\", …>` be\n\t// assigned to the base `KheopskitPlatform` despite the contravariant\n\t// `wallets$` parameter.\n\tgetWallets$(ctx: PlatformContext): Observable<TWallet[]>;\n\t// Receives this platform's (injected) wallets plus the shared, platform-less\n\t// WalletConnect connector — the plugin derives its injected accounts and, if\n\t// the WC session carries its namespace, its WalletConnect accounts.\n\tgetAccounts$(\n\t\twallets$: Observable<(TWallet | WalletConnectWallet)[]>,\n\t): Observable<TAccount[]>;\n\t/**\n\t * Optional hydration filter. Cached accounts for which this returns false are\n\t * dropped during SSR hydration (Polkadot uses it to honour `accountTypes`).\n\t */\n\tacceptsCachedAccount?(cached: CachedAccount): boolean;\n};\n\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n/** The account type produced by a plugin (inferred from its `getAccounts$`). */\nexport type AccountOf<T> = T extends {\n\tgetAccounts$: (wallets$: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\n/** The wallet type produced by a plugin (inferred from its `getWallets$`). */\nexport type WalletOf<T> = T extends {\n\tgetWallets$: (ctx: never) => Observable<infer R>;\n}\n\t? ElementOf<R>\n\t: never;\n\nexport type KheopskitConfig<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\tautoReconnect: boolean;\n\t/**\n\t * Platform plugins to enable, e.g. `[polkadot(), solana({ chain })]`.\n\t * Import factories from `@kheopskit/core/<platform>`.\n\t */\n\tplatforms: P;\n\twalletConnect?: WalletConnectConfig;\n\tdebug: boolean;\n\t/**\n\t * Custom storage key for persisting wallet connection state.\n\t * Useful when running multiple kheopskit instances on the same domain\n\t * to prevent state conflicts between different dapps.\n\t *\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey: string;\n\t/**\n\t * Grace period in milliseconds to wait for wallets to inject before\n\t * syncing to actual state. During this period, cached wallet/account\n\t * state from storage is preserved to prevent UI flashing.\n\t *\n\t * Set to 0 to disable hydration buffering.\n\t *\n\t * @default 500\n\t */\n\thydrationGracePeriod: number;\n};\n\n/**\n * The current kheopskit state.\n *\n * @remarks\n * While {@link KheopskitState.isHydrating} is `true`, `wallets` and `accounts`\n * may contain cached placeholders restored from storage. The **SDK handles** the\n * platform types advertise (e.g. `account.signer` / `getSigner` on Solana,\n * `account.client` on Ethereum, `wallet.provider` / `extension`) are **absent at\n * runtime even though the types claim them**, and placeholder wallets throw if\n * `connect`/`disconnect` is called. Guard all access to those behind\n * `!isHydrating`.\n *\n * The plain, serializable platform data that is persisted in the cache IS\n * restored on the placeholders (Ethereum `chainId`, Polkadot key `type`), so it\n * renders immediately on reload without flashing. Solana `chains` is not cached,\n * so it remains absent until the live account loads.\n */\nexport type KheopskitState<\n\tP extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n> = {\n\twallets: (WalletOf<P[number]> | WalletConnectWallet)[];\n\taccounts: AccountOf<P[number]>[];\n\tconfig: KheopskitConfig<P>;\n\t/**\n\t * Whether the state is still being hydrated from cache.\n\t *\n\t * During hydration, cached wallets/accounts may be displayed before the\n\t * actual wallet extensions have injected. See the type-level remarks: while\n\t * this is `true`, SDK-typed fields (signer/client/provider/extension) are not\n\t * present at runtime — guard all access behind `!isHydrating`.\n\t */\n\tisHydrating: boolean;\n};\n\n/** Shape of the persisted store data (localStorage, or cookies in compact form). */\nexport type KheopskitStoreData = {\n\tautoReconnect?: WalletId[];\n\t/** Cached wallet state for SSR hydration to prevent UI flash */\n\tcachedWallets?: CachedWallet[];\n\t/** Cached account state for SSR hydration to prevent UI flash */\n\tcachedAccounts?: CachedAccount[];\n};\n\n/**\n * The persisted settings store shared between core and framework bindings.\n * Declared structurally here (implemented by `createKheopskitStore`) so modules\n * can depend on the interface without importing the implementation.\n */\nexport type KheopskitStore = {\n\tobservable: Observable<KheopskitStoreData>;\n\taddEnabledWalletId: (walletId: WalletId) => void;\n\tremoveEnabledWalletId: (walletId: WalletId) => void;\n\tgetCachedState: () => { wallets: CachedWallet[]; accounts: CachedAccount[] };\n\tsetCachedState: (wallets: CachedWallet[], accounts: CachedAccount[]) => void;\n};\n\n/**\n * Serializable wallet data for SSR hydration cache.\n * Contains only the data needed to render wallet UI without flash.\n * Note: icon is NOT stored to save cookie space - it's looked up at hydration time.\n */\nexport type CachedWallet = {\n\tid: WalletId;\n\t/** Absent for the platform-less WalletConnect connector. */\n\tplatform?: WalletPlatform;\n\ttype: WalletType;\n\tname: string;\n\tisConnected: boolean;\n};\n\n/**\n * Serializable account data for SSR hydration cache.\n * Contains only the data needed to render account UI without flash.\n */\nexport type CachedAccount = {\n\tid: string;\n\tplatform: WalletPlatform;\n\taddress: string;\n\tname?: string;\n\t/** Cached chain ID for Ethereum accounts. */\n\tchainId?: number;\n\t/** Cached key type for Polkadot accounts. */\n\tpolkadotAccountType?: PolkadotAccountType;\n\twalletId: WalletId;\n\twalletName: string;\n};\n"]}
@@ -1,6 +1,10 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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; }var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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
+ var _chunkD3EQMFZ2js = require('./chunk-D3EQMFZ2.js');
4
+
5
+
6
+
7
+ var _chunkP7BPHHVVjs = require('./chunk-P7BPHHVV.js');
4
8
 
5
9
  // src/utils/storage.ts
6
10
  var noopStorage = {
@@ -133,68 +137,121 @@ var cookieStorage = (initialCookies) => {
133
137
  };
134
138
  };
135
139
 
136
- // src/utils/isWalletPlatform.ts
137
- var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum", "solana"].includes(platform);
138
-
139
- // src/utils/WalletId.ts
140
- var WALLET_CONNECT_WALLET_ID = "walletconnect";
141
- var getWalletId = (platform, identifier) => {
142
- if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
143
- if (!identifier) throw new Error("Invalid name");
144
- return `${platform}:${identifier}`;
140
+ // src/utils/hydrateState.ts
141
+ var lookupWalletIcon = (platform, identifier) => {
142
+ if (platform === "polkadot") {
143
+ return _nullishCoalesce(_optionalChain([_chunkD3EQMFZ2js.POLKADOT_EXTENSIONS, 'access', _11 => _11[identifier], 'optionalAccess', _12 => _12.icon]), () => ( ""));
144
+ }
145
+ return "";
145
146
  };
146
- var parseWalletId = (walletId) => {
147
- if (!walletId) throw new Error("Invalid walletId");
148
- const [platform, identifier] = walletId.split(":");
149
- if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
150
- if (!identifier) throw new Error("Invalid address");
151
- return { platform, identifier };
147
+ var PendingWalletError = class extends Error {
148
+ constructor(walletId) {
149
+ super(
150
+ `Wallet ${walletId} is still loading. Wait for isHydrating to be false before calling connect/disconnect.`
151
+ );
152
+ this.name = "PendingWalletError";
153
+ }
152
154
  };
153
- var isValidWalletId = (walletId) => {
154
- if (typeof walletId !== "string" || !walletId) return false;
155
- if (walletId === WALLET_CONNECT_WALLET_ID) return true;
156
- const [platform, identifier] = walletId.split(":");
157
- return isWalletPlatform(platform) && !!identifier;
155
+ var hydrateWallet = (cached) => {
156
+ const throwPending = () => {
157
+ throw new PendingWalletError(cached.id);
158
+ };
159
+ if (cached.type === "walletconnect") {
160
+ return {
161
+ id: cached.id,
162
+ type: "walletconnect",
163
+ platforms: [],
164
+ name: cached.name,
165
+ icon: "",
166
+ isConnected: cached.isConnected,
167
+ connect: throwPending,
168
+ disconnect: throwPending
169
+ };
170
+ }
171
+ const { platform, identifier } = _chunkP7BPHHVVjs.parseWalletId.call(void 0, cached.id);
172
+ return {
173
+ id: cached.id,
174
+ platform: cached.platform,
175
+ type: cached.type,
176
+ name: cached.name,
177
+ icon: lookupWalletIcon(platform, identifier),
178
+ isConnected: cached.isConnected,
179
+ connect: throwPending,
180
+ disconnect: throwPending
181
+ };
158
182
  };
183
+ var hydrateAccount = (cached) => ({
184
+ id: cached.id,
185
+ platform: cached.platform,
186
+ address: cached.address,
187
+ name: cached.name,
188
+ walletId: cached.walletId,
189
+ walletName: cached.walletName,
190
+ // Spread (not direct keys) so the extra platform fields don't trip the
191
+ // excess-property check against BaseWalletAccount; they're read back via the
192
+ // platform-specific account types once narrowed by `platform`.
193
+ ...cached.platform === "ethereum" && { chainId: cached.chainId },
194
+ ...cached.platform === "polkadot" && {
195
+ type: cached.polkadotAccountType
196
+ }
197
+ });
198
+ var serializeWallet = (wallet) => ({
199
+ id: wallet.id,
200
+ // The WalletConnect connector has no platform.
201
+ platform: _chunkP7BPHHVVjs.isWalletConnectWallet.call(void 0, wallet) ? void 0 : wallet.platform,
202
+ type: wallet.type,
203
+ name: wallet.name,
204
+ // Note: icon is NOT stored to save cookie space
205
+ isConnected: wallet.isConnected
206
+ });
207
+ var serializeAccount = (account) => ({
208
+ id: account.id,
209
+ platform: account.platform,
210
+ address: account.address,
211
+ name: account.name,
212
+ chainId: account.platform === "ethereum" ? account.chainId : void 0,
213
+ polkadotAccountType: account.platform === "polkadot" ? account.type : void 0,
214
+ walletId: account.walletId,
215
+ walletName: account.walletName
216
+ });
159
217
 
160
- // src/utils/getCachedObservable.ts
161
- var CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.observableCache");
162
- var getCache = () => {
163
- const g = globalThis;
164
- let cache = g[CACHE_SYMBOL];
165
- if (!cache) {
166
- cache = /* @__PURE__ */ new Map();
167
- g[CACHE_SYMBOL] = cache;
218
+ // src/utils/iconCache.ts
219
+ var ICON_CACHE_KEY = "kheopskit-icons";
220
+ var memoryCache = null;
221
+ var loadCache = () => {
222
+ if (memoryCache !== null) return memoryCache;
223
+ try {
224
+ const stored = safeLocalStorage.getItem(ICON_CACHE_KEY);
225
+ memoryCache = stored ? JSON.parse(stored) : {};
226
+ } catch (e4) {
227
+ memoryCache = {};
168
228
  }
169
- return cache;
229
+ return memoryCache;
170
230
  };
171
- var getCachedObservable$ = (key, create) => {
172
- const cache = getCache();
173
- if (!cache.has(key)) cache.set(key, create());
174
- return cache.get(key);
231
+ var saveCache = (cache) => {
232
+ try {
233
+ safeLocalStorage.setItem(ICON_CACHE_KEY, JSON.stringify(cache));
234
+ memoryCache = cache;
235
+ } catch (e5) {
236
+ }
175
237
  };
176
- var clearCachedObservable = (key) => {
177
- getCache().delete(key);
238
+ var getCachedIcon = (walletId) => {
239
+ const cache = loadCache();
240
+ return cache[walletId] || void 0;
178
241
  };
179
- var clearCachedObservablesByPrefix = (prefix) => {
180
- const cache = getCache();
181
- for (const key of cache.keys()) {
182
- if (key.startsWith(prefix)) cache.delete(key);
242
+ var setCachedIcons = (icons) => {
243
+ const cache = loadCache();
244
+ let changed = false;
245
+ for (const [walletId, icon] of Object.entries(icons)) {
246
+ if (icon && cache[walletId] !== icon) {
247
+ cache[walletId] = icon;
248
+ changed = true;
249
+ }
250
+ }
251
+ if (changed) {
252
+ saveCache(cache);
183
253
  }
184
254
  };
185
- var clearAllCachedObservables = () => {
186
- getCache().clear();
187
- };
188
-
189
- // src/api/types.ts
190
- var isWalletConnectWallet = (wallet) => wallet.type === "walletconnect";
191
- var isInjectedWallet = (wallet) => wallet.type === "injected";
192
-
193
-
194
-
195
-
196
-
197
-
198
255
 
199
256
 
200
257
 
@@ -206,5 +263,5 @@ var isInjectedWallet = (wallet) => wallet.type === "injected";
206
263
 
207
264
 
208
265
 
209
- exports.__publicField = __publicField; exports.getSafeLocalStorage = getSafeLocalStorage; exports.safeLocalStorage = safeLocalStorage; exports.cookieStorage = cookieStorage; exports.isWalletPlatform = isWalletPlatform; exports.WALLET_CONNECT_WALLET_ID = WALLET_CONNECT_WALLET_ID; exports.getWalletId = getWalletId; exports.parseWalletId = parseWalletId; exports.isValidWalletId = isValidWalletId; exports.getCachedObservable$ = getCachedObservable$; exports.clearCachedObservable = clearCachedObservable; exports.clearCachedObservablesByPrefix = clearCachedObservablesByPrefix; exports.clearAllCachedObservables = clearAllCachedObservables; exports.isWalletConnectWallet = isWalletConnectWallet; exports.isInjectedWallet = isInjectedWallet;
210
- //# sourceMappingURL=chunk-4ENHC7G4.js.map
266
+ exports.getSafeLocalStorage = getSafeLocalStorage; exports.safeLocalStorage = safeLocalStorage; exports.cookieStorage = cookieStorage; exports.hydrateWallet = hydrateWallet; exports.hydrateAccount = hydrateAccount; exports.serializeWallet = serializeWallet; exports.serializeAccount = serializeAccount; exports.getCachedIcon = getCachedIcon; exports.setCachedIcons = setCachedIcons;
267
+ //# sourceMappingURL=chunk-SO64R7Z6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-SO64R7Z6.js","../src/utils/storage.ts","../src/utils/hydrateState.ts","../src/utils/iconCache.ts"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACF,sDAA4B;AAC5B;AACA;ACgBO,IAAM,YAAA,EAA+B;AAAA,EAC3C,OAAA,EAAS,CAAA,EAAA,GAAM,IAAA;AAAA,EACf,OAAA,EAAS,CAAA,EAAA,GAAM;AAAA,EAAC,CAAA;AAAA,EAChB,UAAA,EAAY,CAAA,EAAA,GAAM;AAAA,EAAC;AACpB,CAAA;AAMA,IAAI,kBAAA,EAA4C,IAAA;AAMhD,IAAM,uBAAA,EAAyB,CAAA,EAAA,GAAuB;AACrD,EAAA,GAAA,CAAI,OAAO,OAAA,IAAW,WAAA,EAAa,OAAO,WAAA;AAE1C,EAAA,IAAI;AAEH,IAAA,MAAM,QAAA,EAAU,oBAAA;AAChB,IAAA,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,OAAA,EAAS,OAAO,CAAA;AAC5C,IAAA,MAAA,CAAO,YAAA,CAAa,UAAA,CAAW,OAAO,CAAA;AAEtC,IAAA,OAAO;AAAA,MACN,OAAA,EAAS,CAAC,GAAA,EAAA,GAAgB,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAAA,MACzD,OAAA,EAAS,CAAC,GAAA,EAAa,KAAA,EAAA,GACtB,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AAAA,MACvC,UAAA,EAAY,CAAC,GAAA,EAAA,GAAgB,MAAA,CAAO,YAAA,CAAa,UAAA,CAAW,GAAG,CAAA;AAAA,MAC/D,SAAA,EAAW,CAAC,GAAA,EAAa,QAAA,EAAA,GAA6C;AACrE,QAAA,MAAM,QAAA,EAAU,CAAC,KAAA,EAAA,GAAwB;AACxC,UAAA,GAAA,CAAI,KAAA,CAAM,IAAA,IAAQ,GAAA,EAAK;AACtB,YAAA,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA;AAAA,UACxB;AAAA,QACD,CAAA;AACA,QAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,OAAO,CAAA;AAC1C,QAAA,OAAO,CAAA,EAAA,GAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AAAA,MAC3D;AAAA,IACD,CAAA;AAAA,EACD,EAAA,UAAQ;AACP,IAAA,OAAO,WAAA;AAAA,EACR;AACD,CAAA;AASO,IAAM,oBAAA,EAAsB,CAAA,EAAA,GAAuB;AACzD,EAAA,GAAA,CAAI,kBAAA,IAAsB,IAAA,EAAM;AAC/B,IAAA,kBAAA,EAAoB,sBAAA,CAAuB,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,iBAAA;AACR,CAAA;AAMO,IAAM,iBAAA,EAAoC;AAAA,EAChD,OAAA,EAAS,CAAC,GAAA,EAAA,GAAgB,mBAAA,CAAoB,CAAA,CAAE,OAAA,CAAQ,GAAG,CAAA;AAAA,EAC3D,OAAA,EAAS,CAAC,GAAA,EAAa,KAAA,EAAA,GACtB,mBAAA,CAAoB,CAAA,CAAE,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AAAA,EACzC,UAAA,EAAY,CAAC,GAAA,EAAA,GAAgB,mBAAA,CAAoB,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA;AAAA,EACjE,SAAA,EAAW,CAAC,GAAA,EAAa,QAAA,EAAA,GAA6C;AACrE,IAAA,MAAM,QAAA,EAAU,mBAAA,CAAoB,CAAA;AACpC,IAAA,wCAAO,OAAA,mBAAQ,SAAA,0BAAA,CAAY,GAAA,EAAK,QAAQ,GAAA,UAAA,CAAM,CAAA,EAAA,GAAM;AAAA,IAAC,CAAA,GAAA;AAAA,EACtD;AACD,CAAA;AAQO,IAAM,YAAA,EAAc,CAC1B,YAAA,EACA,GAAA,EAAA,GACmB;AACnB,EAAA,GAAA,CAAI,CAAC,YAAA,EAAc,OAAO,IAAA;AAE1B,EAAA,IAAA,CAAA,MAAW,OAAA,GAAU,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,EAAG;AAC7C,IAAA,MAAM,CAAC,CAAA,EAAG,GAAG,CAAC,EAAA,EAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAClC,IAAA,MAAM,UAAA,kBAAY,CAAA,6BAAG,IAAA,mBAAK,GAAA;AAC1B,IAAA,GAAA,CAAI,UAAA,IAAc,GAAA,EAAK;AACtB,MAAA,IAAI;AACH,QAAA,OAAO,kBAAA,CAAmB,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA;AAAA,MAC7C,EAAA,WAAQ;AACP,QAAA,OAAO,IAAA;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,EAAA,OAAO,IAAA;AACR,CAAA;AAgBO,IAAM,gBAAA,EAAkB,EAAA,EAAI,IAAA;AAKnC,IAAM,uBAAA,EAAyB,wBAAA;AAM/B,IAAI,uBAAA,EAAkD,IAAA;AAEtD,IAAM,oBAAA,EAAsB,CAAA,EAAA,GAA+B;AAC1D,EAAA,GAAA,CAAI,sBAAA,EAAwB,OAAO,sBAAA;AACnC,EAAA,GAAA,CAAI,OAAO,iBAAA,IAAqB,WAAA,EAAa,OAAO,IAAA;AAEpD,EAAA,IAAI;AACH,IAAA,uBAAA,EAAyB,IAAI,gBAAA,CAAiB,sBAAsB,CAAA;AAAA,EACrE,EAAA,WAAQ;AAAA,EAER;AACA,EAAA,OAAO,sBAAA;AACR,CAAA;AAMA,IAAM,mBAAA,EAAqB,CAAA,EAAA,GAC1B,OAAO,OAAA,IAAW,YAAA,GAAe,MAAA,CAAO,QAAA,CAAS,SAAA,IAAa,QAAA;AAcxD,IAAM,cAAA,EAAgB,CAAC,cAAA,EAAA,GAA6C;AAC1E,EAAA,OAAO;AAAA,IACN,OAAA,EAAS,CAAC,GAAA,EAAA,GAAgB;AAEzB,MAAA,MAAM,aAAA,EACL,OAAO,SAAA,IAAa,YAAA,EAAc,QAAA,CAAS,OAAA,EAAS,cAAA;AACrD,MAAA,OAAO,WAAA,CAAY,YAAA,EAAc,GAAG,CAAA;AAAA,IACrC,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,GAAA,EAAa,KAAA,EAAA,GAAkB;AACxC,MAAA,GAAA,CAAI,OAAO,SAAA,IAAa,WAAA,EAAa,MAAA;AAGrC,MAAA,MAAM,aAAA,EAAe,kBAAA,CAAmB,KAAK,CAAA;AAC7C,MAAA,GAAA,CAAI,YAAA,CAAa,OAAA,EAAS,eAAA,EAAiB;AAC1C,QAAA,OAAA,CAAQ,IAAA;AAAA,UACP,CAAA,8BAAA,EAAiC,GAAG,CAAA,kCAAA,EAAqC,YAAA,CAAa,MAAM,CAAA,GAAA,EAAM,eAAe,CAAA,sGAAA;AAAA,QAElH,CAAA;AAAA,MACD;AAGA,MAAA,MAAM,QAAA,kBAAU,IAAI,IAAA,CAAK,CAAA;AACzB,MAAA,OAAA,CAAQ,WAAA,CAAY,OAAA,CAAQ,WAAA,CAAY,EAAA,EAAI,CAAC,CAAA;AAG7C,MAAA,IAAI,UAAA,EAAY,CAAA,EAAA;AACZ,MAAA;AACU,QAAA;AACd,MAAA;AAGS,MAAA;AAGT,sBAAA;AACD,IAAA;AACa,IAAA;AACD,MAAA;AAGK,MAAA;AACZ,MAAA;AACU,QAAA;AACd,MAAA;AAGS,MAAA;AAGT,sBAAA;AACD,IAAA;AACyB,IAAA;AACR,MAAA;AACF,MAAA;AAAc,MAAA;AAEX,MAAA;AACH,QAAA;AAKJ,QAAA;AACC,UAAA;AACC,YAAA;AACC,UAAA;AACD,YAAA;AACV,UAAA;AACD,QAAA;AACD,MAAA;AAEQ,MAAA;AACK,MAAA;AACJ,QAAA;AACT,MAAA;AACD,IAAA;AACD,EAAA;AACD;ADzHuB;AACA;AErHE;AAEP,EAAA;AACT,IAAA;AACR,EAAA;AAEO,EAAA;AACR;AAKM;AACO,EAAA;AACX,IAAA;AACW,MAAA;AACX,IAAA;AACY,IAAA;AACb,EAAA;AACD;AAUC;AAEqB,EAAA;AACV,IAAA;AACX,EAAA;AAKoB,EAAA;AACZ,IAAA;AACK,MAAA;AACL,MAAA;AACM,MAAA;AACC,MAAA;AACP,MAAA;AACO,MAAA;AACJ,MAAA;AACG,MAAA;AACb,IAAA;AACD,EAAA;AAEkB,EAAA;AAEX,EAAA;AACK,IAAA;AACM,IAAA;AACJ,IAAA;AACA,IAAA;AACP,IAAA;AACO,IAAA;AACJ,IAAA;AACG,IAAA;AACb,EAAA;AACD;AAY+B;AACnB,EAAA;AACM,EAAA;AACD,EAAA;AACH,EAAA;AACI,EAAA;AACE,EAAA;AAAA;AAAA;AAAA;AAIR,EAAA;AACA,EAAA;AACG,IAAA;AACd,EAAA;AACD;AAOC;AAEW,EAAA;AAAA;AAED,EAAA;AACG,EAAA;AACA,EAAA;AAAA;AAEO,EAAA;AACrB;AAQgC;AAGnB,EAAA;AACM,EAAA;AACD,EAAA;AACH,EAAA;AAEL,EAAA;AAIR,EAAA;AAGiB,EAAA;AACE,EAAA;AACrB;AFgEuB;AACA;AGpNA;AAUa;AAKD;AACd,EAAA;AAEhB,EAAA;AACY,IAAA;AACD,IAAA;AACP,EAAA;AACQ,IAAA;AAChB,EAAA;AACO,EAAA;AACR;AAKmB;AACd,EAAA;AACc,IAAA;AACH,IAAA;AACP,EAAA;AAER,EAAA;AACD;AAO8B;AACf,EAAA;AACO,EAAA;AACtB;AAO+B;AAChB,EAAA;AACA,EAAA;AAEF,EAAA;AACO,IAAA;AACH,MAAA;AACJ,MAAA;AACX,IAAA;AACD,EAAA;AAEa,EAAA;AACG,IAAA;AAChB,EAAA;AACD;AHqLuB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-SO64R7Z6.js","sourcesContent":[null,"export type Storage = {\n\tgetItem: (key: string) => string | null;\n\tsetItem: (key: string, value: string) => void;\n\tremoveItem: (key: string) => void;\n};\n\n/**\n * Extended storage interface with cross-tab sync support.\n */\nexport type SyncableStorage = Storage & {\n\t/**\n\t * Subscribe to storage changes from other tabs.\n\t * Returns an unsubscribe function.\n\t */\n\tsubscribe?: (\n\t\tkey: string,\n\t\tcallback: (value: string | null) => void,\n\t) => () => void;\n};\n\n/**\n * A no-op storage implementation that does nothing.\n * Useful for testing or SSR environments where no storage is needed.\n */\nexport const noopStorage: SyncableStorage = {\n\tgetItem: () => null,\n\tsetItem: () => {},\n\tremoveItem: () => {},\n};\n\n/**\n * Cached localStorage wrapper instance.\n * Lazily initialized on first access to avoid SSR issues.\n */\nlet _safeLocalStorage: SyncableStorage | null = null;\n\n/**\n * Creates the localStorage wrapper, testing for availability.\n * Returns noopStorage if localStorage is unavailable (SSR, private browsing, etc.)\n */\nconst createSafeLocalStorage = (): SyncableStorage => {\n\tif (typeof window === \"undefined\") return noopStorage;\n\n\ttry {\n\t\t// Test that localStorage is accessible (may throw in private browsing)\n\t\tconst testKey = \"__kheopskit_test__\";\n\t\twindow.localStorage.setItem(testKey, testKey);\n\t\twindow.localStorage.removeItem(testKey);\n\n\t\treturn {\n\t\t\tgetItem: (key: string) => window.localStorage.getItem(key),\n\t\t\tsetItem: (key: string, value: string) =>\n\t\t\t\twindow.localStorage.setItem(key, value),\n\t\t\tremoveItem: (key: string) => window.localStorage.removeItem(key),\n\t\t\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\t\t\tconst handler = (event: StorageEvent) => {\n\t\t\t\t\tif (event.key === key) {\n\t\t\t\t\t\tcallback(event.newValue);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\twindow.addEventListener(\"storage\", handler);\n\t\t\t\treturn () => window.removeEventListener(\"storage\", handler);\n\t\t\t},\n\t\t};\n\t} catch {\n\t\treturn noopStorage;\n\t}\n};\n\n/**\n * A safe localStorage wrapper that falls back to noopStorage\n * when localStorage is not available (e.g., during SSR).\n * Includes cross-tab sync via the native 'storage' event.\n *\n * Lazily initialized on first access to be SSR-safe.\n */\nexport const getSafeLocalStorage = (): SyncableStorage => {\n\tif (_safeLocalStorage === null) {\n\t\t_safeLocalStorage = createSafeLocalStorage();\n\t}\n\treturn _safeLocalStorage;\n};\n\n/**\n * @deprecated Use getSafeLocalStorage() instead. This is kept for backward compatibility.\n * Returns a proxy that lazily initializes on first method call.\n */\nexport const safeLocalStorage: SyncableStorage = {\n\tgetItem: (key: string) => getSafeLocalStorage().getItem(key),\n\tsetItem: (key: string, value: string) =>\n\t\tgetSafeLocalStorage().setItem(key, value),\n\tremoveItem: (key: string) => getSafeLocalStorage().removeItem(key),\n\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\tconst storage = getSafeLocalStorage();\n\t\treturn storage.subscribe?.(key, callback) ?? (() => {});\n\t},\n};\n\n/**\n * Parse a cookie string to extract the value for a specific key.\n * @param cookieString - The full cookie header string (e.g., document.cookie or req.headers.cookie)\n * @param key - The cookie key to find\n * @returns The cookie value or null if not found\n */\nexport const parseCookie = (\n\tcookieString: string | undefined,\n\tkey: string,\n): string | null => {\n\tif (!cookieString) return null;\n\n\tfor (const cookie of cookieString.split(\";\")) {\n\t\tconst [k, ...v] = cookie.split(\"=\");\n\t\tconst cookieKey = k?.trim();\n\t\tif (cookieKey === key) {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(v.join(\"=\").trim());\n\t\t\t} catch {\n\t\t\t\treturn null; // Malformed cookie value\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n};\n\n/**\n * Maximum recommended size for cookie storage (3KB to stay well under 4KB limit).\n *\n * @remarks\n * Cookie storage is subject to browser limits (typically 4KB per cookie).\n * When users connect many wallets, the auto-reconnect list may exceed this limit.\n * If this happens:\n * - A console warning will be logged\n * - Some browsers may silently reject the cookie\n * - Consider using fewer simultaneous wallet connections\n *\n * The stored data includes wallet IDs in format `platform:identifier`\n * (e.g., `polkadot:talisman`, `ethereum:io.metamask`).\n */\nexport const COOKIE_MAX_SIZE = 3 * 1024;\n\n/**\n * BroadcastChannel name for cross-tab cookie sync.\n */\nconst BROADCAST_CHANNEL_NAME = \"kheopskit-storage-sync\";\n\n/**\n * Singleton BroadcastChannel for cross-tab cookie sync.\n * Created once and shared across all cookieStorage instances.\n */\nlet sharedBroadcastChannel: BroadcastChannel | null = null;\n\nconst getBroadcastChannel = (): BroadcastChannel | null => {\n\tif (sharedBroadcastChannel) return sharedBroadcastChannel;\n\tif (typeof BroadcastChannel === \"undefined\") return null;\n\n\ttry {\n\t\tsharedBroadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n\t} catch {\n\t\t// BroadcastChannel not supported or failed\n\t}\n\treturn sharedBroadcastChannel;\n};\n\n/**\n * Check if the current connection is secure (HTTPS).\n * Must be called at runtime (inside methods) to work correctly after SSR hydration.\n */\nconst isSecureConnection = (): boolean =>\n\ttypeof window !== \"undefined\" && window.location.protocol === \"https:\";\n\n/**\n * A cookie-based storage implementation for SSR environments.\n * Reads cookies from an optional initial cookie string (for SSR hydration),\n * writes to document.cookie on the client.\n *\n * Features:\n * - Secure flag automatically added for HTTPS connections\n * - Cross-tab synchronization via BroadcastChannel API\n * - Size limit warning when data exceeds recommended limits\n *\n * @param initialCookies - Optional cookie string for server-side hydration\n */\nexport const cookieStorage = (initialCookies?: string): SyncableStorage => {\n\treturn {\n\t\tgetItem: (key: string) => {\n\t\t\t// On server, use initialCookies. On client, read from document.cookie\n\t\t\tconst cookieString =\n\t\t\t\ttypeof document !== \"undefined\" ? document.cookie : initialCookies;\n\t\t\treturn parseCookie(cookieString, key);\n\t\t},\n\t\tsetItem: (key: string, value: string) => {\n\t\t\tif (typeof document === \"undefined\") return;\n\n\t\t\t// Warn if value exceeds recommended size\n\t\t\tconst encodedValue = encodeURIComponent(value);\n\t\t\tif (encodedValue.length > COOKIE_MAX_SIZE) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[kheopskit] Cookie value for \"${key}\" exceeds recommended size limit (${encodedValue.length} > ${COOKIE_MAX_SIZE} bytes). ` +\n\t\t\t\t\t\t\"This may cause issues with cookie storage. Consider reducing the number of connected wallets.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Set cookie with 1 year expiry\n\t\t\tconst expires = new Date();\n\t\t\texpires.setFullYear(expires.getFullYear() + 1);\n\n\t\t\t// Build cookie string with security attributes\n\t\t\tlet cookieStr = `${key}=${encodedValue};expires=${expires.toUTCString()};path=/;SameSite=Lax`;\n\t\t\tif (isSecureConnection()) {\n\t\t\t\tcookieStr += \";Secure\";\n\t\t\t}\n\n\t\t\t// biome-ignore lint: necessary for cookie storage - direct cookie assignment is the standard API\n\t\t\tdocument.cookie = cookieStr;\n\n\t\t\t// Broadcast change to other tabs\n\t\t\tgetBroadcastChannel()?.postMessage({ type: \"set\", key, value });\n\t\t},\n\t\tremoveItem: (key: string) => {\n\t\t\tif (typeof document === \"undefined\") return;\n\n\t\t\t// Build delete cookie string\n\t\t\tlet cookieStr = `${key}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;SameSite=Lax`;\n\t\t\tif (isSecureConnection()) {\n\t\t\t\tcookieStr += \";Secure\";\n\t\t\t}\n\n\t\t\t// biome-ignore lint: necessary for cookie storage - direct cookie assignment is the standard API\n\t\t\tdocument.cookie = cookieStr;\n\n\t\t\t// Broadcast change to other tabs\n\t\t\tgetBroadcastChannel()?.postMessage({ type: \"remove\", key });\n\t\t},\n\t\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\t\tconst channel = getBroadcastChannel();\n\t\t\tif (!channel) return () => {};\n\n\t\t\tconst handler = (event: MessageEvent) => {\n\t\t\t\tconst data = event.data as {\n\t\t\t\t\ttype: string;\n\t\t\t\t\tkey: string;\n\t\t\t\t\tvalue?: string;\n\t\t\t\t};\n\t\t\t\tif (data.key === key) {\n\t\t\t\t\tif (data.type === \"set\") {\n\t\t\t\t\t\tcallback(data.value ?? null);\n\t\t\t\t\t} else if (data.type === \"remove\") {\n\t\t\t\t\t\tcallback(null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tchannel.addEventListener(\"message\", handler);\n\t\t\treturn () => {\n\t\t\t\tchannel.removeEventListener(\"message\", handler);\n\t\t\t};\n\t\t},\n\t};\n};\n\n/**\n * Cleanup the shared BroadcastChannel used for cross-tab cookie sync.\n * Call this when you're done using cookie storage (e.g., in tests or when unmounting).\n *\n * @remarks\n * In normal browser usage, you typically don't need to call this -\n * the channel will be cleaned up when the page is closed.\n * This is primarily useful for testing environments where multiple\n * test runs may accumulate channels.\n */\nexport const cleanupBroadcastChannel = (): void => {\n\tif (sharedBroadcastChannel) {\n\t\tsharedBroadcastChannel.close();\n\t\tsharedBroadcastChannel = null;\n\t}\n};\n","import {\n\ttype BaseWallet,\n\ttype BaseWalletAccount,\n\ttype CachedAccount,\n\ttype CachedWallet,\n\tisWalletConnectWallet,\n\ttype PolkadotAccountType,\n\ttype WalletConnectWallet,\n} from \"../api/types\";\nimport { POLKADOT_EXTENSIONS } from \"./polkadotExtensions\";\nimport type { WalletAccountId } from \"./WalletAccountId\";\nimport { parseWalletId, type WalletId } from \"./WalletId\";\n\n/**\n * Looks up the icon for a wallet from known Polkadot extensions only.\n * Ethereum icons will be populated from the localStorage icon cache via the merge function.\n *\n * Note: We DON'T use localStorage icon cache here because hydrateWallet is called\n * during SSR (server) and client hydration. localStorage isn't available on server,\n * so using it would cause a hydration mismatch. Icons for Ethereum wallets will be\n * populated when the hydration buffer merges cached wallets with live wallets.\n */\nconst lookupWalletIcon = (platform: string, identifier: string): string => {\n\t// Only Polkadot extensions have hardcoded icons that are safe for SSR\n\tif (platform === \"polkadot\") {\n\t\treturn POLKADOT_EXTENSIONS[identifier]?.icon ?? \"\";\n\t}\n\t// Ethereum icons come from localStorage or live wallets - not here\n\treturn \"\";\n};\n\n/**\n * Error thrown when trying to use a placeholder wallet that hasn't fully loaded yet.\n */\nclass PendingWalletError extends Error {\n\tconstructor(walletId: string) {\n\t\tsuper(\n\t\t\t`Wallet ${walletId} is still loading. Wait for isHydrating to be false before calling connect/disconnect.`,\n\t\t);\n\t\tthis.name = \"PendingWalletError\";\n\t}\n}\n\n/**\n * Converts a CachedWallet to a placeholder wallet for SSR hydration display.\n *\n * The placeholder carries only the SDK-free {@link BaseWallet} fields; the real\n * wallet (with its injected provider/extension/standard-wallet handle) replaces\n * it once it loads. connect/disconnect throw until then.\n */\nexport const hydrateWallet = (\n\tcached: CachedWallet,\n): BaseWallet | WalletConnectWallet => {\n\tconst throwPending = () => {\n\t\tthrow new PendingWalletError(cached.id);\n\t};\n\n\t// The platform-less WalletConnect connector. `appKit`/`platforms` are SDK\n\t// state absent until the live connector loads (cast like other placeholder\n\t// SDK handles); icon is filled from the localStorage cache by the caller.\n\tif (cached.type === \"walletconnect\") {\n\t\treturn {\n\t\t\tid: cached.id,\n\t\t\ttype: \"walletconnect\",\n\t\t\tplatforms: [],\n\t\t\tname: cached.name,\n\t\t\ticon: \"\",\n\t\t\tisConnected: cached.isConnected,\n\t\t\tconnect: throwPending,\n\t\t\tdisconnect: throwPending,\n\t\t} as unknown as WalletConnectWallet;\n\t}\n\n\tconst { platform, identifier } = parseWalletId(cached.id);\n\n\treturn {\n\t\tid: cached.id,\n\t\tplatform: cached.platform as BaseWallet[\"platform\"],\n\t\ttype: cached.type,\n\t\tname: cached.name,\n\t\ticon: lookupWalletIcon(platform, identifier),\n\t\tisConnected: cached.isConnected,\n\t\tconnect: throwPending,\n\t\tdisconnect: throwPending,\n\t};\n};\n\n/**\n * Converts a CachedAccount to a placeholder account for SSR hydration display.\n *\n * The placeholder carries the SDK-free {@link BaseWalletAccount} fields plus the\n * plain, serializable platform data that lives in the cache — Ethereum `chainId`\n * and the Polkadot key `type`. Those render immediately on reload (no blank →\n * value flicker) and match what the live account will report. Only the SDK\n * handles (`client`/`signer`/`polkadotSigner`) are absent until the real account\n * replaces this placeholder; signing stays gated on `isHydrating` until then.\n */\nexport const hydrateAccount = (cached: CachedAccount): BaseWalletAccount => ({\n\tid: cached.id as WalletAccountId,\n\tplatform: cached.platform,\n\taddress: cached.address,\n\tname: cached.name,\n\twalletId: cached.walletId,\n\twalletName: cached.walletName,\n\t// Spread (not direct keys) so the extra platform fields don't trip the\n\t// excess-property check against BaseWalletAccount; they're read back via the\n\t// platform-specific account types once narrowed by `platform`.\n\t...(cached.platform === \"ethereum\" && { chainId: cached.chainId }),\n\t...(cached.platform === \"polkadot\" && {\n\t\ttype: cached.polkadotAccountType,\n\t}),\n});\n\n/**\n * Converts a wallet to a CachedWallet for storage.\n * Only extracts the serializable properties needed for hydration.\n */\nexport const serializeWallet = (\n\twallet: BaseWallet | WalletConnectWallet,\n): CachedWallet => ({\n\tid: wallet.id,\n\t// The WalletConnect connector has no platform.\n\tplatform: isWalletConnectWallet(wallet) ? undefined : wallet.platform,\n\ttype: wallet.type,\n\tname: wallet.name,\n\t// Note: icon is NOT stored to save cookie space\n\tisConnected: wallet.isConnected,\n});\n\n/**\n * Converts an account to a CachedAccount for storage.\n * Only extracts the serializable properties needed for hydration. Platform-only\n * fields (Ethereum chainId, Polkadot key type) are read defensively so this\n * stays SDK-free.\n */\nexport const serializeAccount = (\n\taccount: BaseWalletAccount,\n): CachedAccount => ({\n\tid: account.id,\n\tplatform: account.platform,\n\taddress: account.address,\n\tname: account.name,\n\tchainId:\n\t\taccount.platform === \"ethereum\"\n\t\t\t? (account as { chainId?: number }).chainId\n\t\t\t: undefined,\n\tpolkadotAccountType:\n\t\taccount.platform === \"polkadot\"\n\t\t\t? (account as { type?: PolkadotAccountType }).type\n\t\t\t: undefined,\n\twalletId: account.walletId as WalletId,\n\twalletName: account.walletName,\n});\n","import { safeLocalStorage } from \"./storage\";\n\n/**\n * Storage key for the icon cache in localStorage.\n */\nconst ICON_CACHE_KEY = \"kheopskit-icons\";\n\n/**\n * Icon cache type: a map of wallet ID to icon data URI or URL.\n */\ntype IconCache = Record<string, string>;\n\n/**\n * In-memory cache to avoid repeated localStorage reads.\n */\nlet memoryCache: IconCache | null = null;\n\n/**\n * Loads the icon cache from localStorage.\n */\nconst loadCache = (): IconCache => {\n\tif (memoryCache !== null) return memoryCache;\n\n\ttry {\n\t\tconst stored = safeLocalStorage.getItem(ICON_CACHE_KEY);\n\t\tmemoryCache = stored ? (JSON.parse(stored) as IconCache) : {};\n\t} catch {\n\t\tmemoryCache = {};\n\t}\n\treturn memoryCache;\n};\n\n/**\n * Saves the icon cache to localStorage.\n */\nconst saveCache = (cache: IconCache): void => {\n\ttry {\n\t\tsafeLocalStorage.setItem(ICON_CACHE_KEY, JSON.stringify(cache));\n\t\tmemoryCache = cache;\n\t} catch {\n\t\t// localStorage may be full or unavailable\n\t}\n};\n\n/**\n * Gets a cached icon for a wallet.\n * @param walletId - The wallet ID (e.g., \"ethereum:io.talisman\")\n * @returns The cached icon data URI, or undefined if not cached\n */\nexport const getCachedIcon = (walletId: string): string | undefined => {\n\tconst cache = loadCache();\n\treturn cache[walletId] || undefined;\n};\n\n/**\n * Sets multiple cached icons at once.\n * More efficient than calling setCachedIcon multiple times.\n * @param icons - Map of wallet ID to icon\n */\nexport const setCachedIcons = (icons: Record<string, string>): void => {\n\tconst cache = loadCache();\n\tlet changed = false;\n\n\tfor (const [walletId, icon] of Object.entries(icons)) {\n\t\tif (icon && cache[walletId] !== icon) {\n\t\t\tcache[walletId] = icon;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\n\tif (changed) {\n\t\tsaveCache(cache);\n\t}\n};\n"]}
@@ -0,0 +1,76 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/utils/isWalletPlatform.ts
6
+ var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum", "solana"].includes(platform);
7
+
8
+ // src/utils/WalletId.ts
9
+ var WALLET_CONNECT_WALLET_ID = "walletconnect";
10
+ var getWalletId = (platform, identifier) => {
11
+ if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
12
+ if (!identifier) throw new Error("Invalid name");
13
+ return `${platform}:${identifier}`;
14
+ };
15
+ var parseWalletId = (walletId) => {
16
+ if (!walletId) throw new Error("Invalid walletId");
17
+ const [platform, identifier] = walletId.split(":");
18
+ if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
19
+ if (!identifier) throw new Error("Invalid address");
20
+ return { platform, identifier };
21
+ };
22
+ var isValidWalletId = (walletId) => {
23
+ if (typeof walletId !== "string" || !walletId) return false;
24
+ if (walletId === WALLET_CONNECT_WALLET_ID) return true;
25
+ const [platform, identifier] = walletId.split(":");
26
+ return isWalletPlatform(platform) && !!identifier;
27
+ };
28
+
29
+ // src/utils/getCachedObservable.ts
30
+ var CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.observableCache");
31
+ var getCache = () => {
32
+ const g = globalThis;
33
+ let cache = g[CACHE_SYMBOL];
34
+ if (!cache) {
35
+ cache = /* @__PURE__ */ new Map();
36
+ g[CACHE_SYMBOL] = cache;
37
+ }
38
+ return cache;
39
+ };
40
+ var getCachedObservable$ = (key, create) => {
41
+ const cache = getCache();
42
+ if (!cache.has(key)) cache.set(key, create());
43
+ return cache.get(key);
44
+ };
45
+ var clearCachedObservable = (key) => {
46
+ getCache().delete(key);
47
+ };
48
+ var clearCachedObservablesByPrefix = (prefix) => {
49
+ const cache = getCache();
50
+ for (const key of cache.keys()) {
51
+ if (key.startsWith(prefix)) cache.delete(key);
52
+ }
53
+ };
54
+ var clearAllCachedObservables = () => {
55
+ getCache().clear();
56
+ };
57
+
58
+ // src/api/types.ts
59
+ var isWalletConnectWallet = (wallet) => wallet.type === "walletconnect";
60
+ var isInjectedWallet = (wallet) => wallet.type === "injected";
61
+
62
+ export {
63
+ __publicField,
64
+ isWalletPlatform,
65
+ WALLET_CONNECT_WALLET_ID,
66
+ getWalletId,
67
+ parseWalletId,
68
+ isValidWalletId,
69
+ getCachedObservable$,
70
+ clearCachedObservable,
71
+ clearCachedObservablesByPrefix,
72
+ clearAllCachedObservables,
73
+ isWalletConnectWallet,
74
+ isInjectedWallet
75
+ };
76
+ //# sourceMappingURL=chunk-WOPCW2OX.mjs.map