@kheopskit/core 5.3.0 → 6.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +426 -0
  2. package/MIGRATING_TO_V6.md +837 -0
  3. package/README.md +628 -12
  4. package/dist/ethereum.d.mts +12 -6
  5. package/dist/ethereum.d.ts +12 -6
  6. package/dist/ethereum.js +13 -10
  7. package/dist/ethereum.js.map +1 -1
  8. package/dist/ethereum.mjs +7 -4
  9. package/dist/ethereum.mjs.map +1 -1
  10. package/dist/{iconCache-pP2ES4pJ.mjs → iconCache-C-U3IEbP.mjs} +21 -40
  11. package/dist/iconCache-C-U3IEbP.mjs.map +1 -0
  12. package/dist/{iconCache-DUtkJlaX.js → iconCache-FR4iy6go.js} +21 -40
  13. package/dist/iconCache-FR4iy6go.js.map +1 -0
  14. package/dist/index.d.mts +17 -63
  15. package/dist/index.d.ts +17 -63
  16. package/dist/index.js +387 -373
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +384 -369
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/injectedWallets-48L-AL1I.mjs +173 -0
  21. package/dist/injectedWallets-48L-AL1I.mjs.map +1 -0
  22. package/dist/injectedWallets-Dy8YGKL-.js +178 -0
  23. package/dist/injectedWallets-Dy8YGKL-.js.map +1 -0
  24. package/dist/internal.d.mts +3 -27
  25. package/dist/internal.d.ts +3 -27
  26. package/dist/internal.js +2 -2
  27. package/dist/internal.mjs +2 -2
  28. package/dist/pageLoad-BZ7o8p5R.mjs +24 -0
  29. package/dist/pageLoad-BZ7o8p5R.mjs.map +1 -0
  30. package/dist/pageLoad-D1wLeuFG.js +28 -0
  31. package/dist/pageLoad-D1wLeuFG.js.map +1 -0
  32. package/dist/platformAccounts-BjIeRcFN.js +321 -0
  33. package/dist/platformAccounts-BjIeRcFN.js.map +1 -0
  34. package/dist/platformAccounts-yyRUrnel.mjs +256 -0
  35. package/dist/platformAccounts-yyRUrnel.mjs.map +1 -0
  36. package/dist/polkadot.d.mts +127 -11
  37. package/dist/polkadot.d.ts +127 -11
  38. package/dist/polkadot.js +170 -106
  39. package/dist/polkadot.js.map +1 -1
  40. package/dist/polkadot.mjs +163 -99
  41. package/dist/polkadot.mjs.map +1 -1
  42. package/dist/solana.d.mts +11 -5
  43. package/dist/solana.d.ts +11 -5
  44. package/dist/solana.js +18 -15
  45. package/dist/solana.js.map +1 -1
  46. package/dist/solana.mjs +7 -4
  47. package/dist/solana.mjs.map +1 -1
  48. package/dist/storage-D3AwNgqc.d.mts +27 -0
  49. package/dist/storage-D3AwNgqc.d.ts +27 -0
  50. package/dist/testing.d.mts +71 -0
  51. package/dist/testing.d.ts +71 -0
  52. package/dist/testing.js +136 -0
  53. package/dist/testing.js.map +1 -0
  54. package/dist/testing.mjs +131 -0
  55. package/dist/testing.mjs.map +1 -0
  56. package/dist/{types-DKU-SNio.js → types-BWHvNFlN.js} +149 -2
  57. package/dist/types-BWHvNFlN.js.map +1 -0
  58. package/dist/types-Dkyt9bf4.d.mts +683 -0
  59. package/dist/types-Dkyt9bf4.d.ts +683 -0
  60. package/dist/types-Yor672md.mjs +215 -0
  61. package/dist/types-Yor672md.mjs.map +1 -0
  62. package/dist/walletconnect.d.mts +41 -0
  63. package/dist/walletconnect.d.ts +41 -0
  64. package/dist/walletconnect.js +219 -0
  65. package/dist/walletconnect.js.map +1 -0
  66. package/dist/walletconnect.mjs +216 -0
  67. package/dist/walletconnect.mjs.map +1 -0
  68. package/package.json +30 -6
  69. package/dist/errors-BLFP1dQI.mjs +0 -181
  70. package/dist/errors-BLFP1dQI.mjs.map +0 -1
  71. package/dist/errors-DYWVPHrR.js +0 -222
  72. package/dist/errors-DYWVPHrR.js.map +0 -1
  73. package/dist/iconCache-DUtkJlaX.js.map +0 -1
  74. package/dist/iconCache-pP2ES4pJ.mjs.map +0 -1
  75. package/dist/injectedWallets-BqR-_aAy.js +0 -148
  76. package/dist/injectedWallets-BqR-_aAy.js.map +0 -1
  77. package/dist/injectedWallets-Uz4hPuoW.mjs +0 -119
  78. package/dist/injectedWallets-Uz4hPuoW.mjs.map +0 -1
  79. package/dist/types-AxUDtkR-.d.mts +0 -338
  80. package/dist/types-AxUDtkR-.d.ts +0 -338
  81. package/dist/types-DKU-SNio.js.map +0 -1
  82. package/dist/types-jnifAAA0.mjs +0 -104
  83. package/dist/types-jnifAAA0.mjs.map +0 -1
@@ -0,0 +1,216 @@
1
+ import { g as clearCachedObservablesByPrefix, l as WALLET_CONNECT_WALLET_ID, n as isWalletConnectWallet, s as toConnectError } from "./types-Yor672md.mjs";
2
+ import { BehaviorSubject, Observable, distinctUntilChanged, from, map, of, shareReplay, switchMap, tap } from "rxjs";
3
+ //#region src/api/walletconnect/plugin.ts
4
+ /**
5
+ * Dynamically import @reown/appkit/core to avoid loading browser-only code
6
+ * during SSR or in edge runtimes like Cloudflare Workers.
7
+ * The AppKit library uses Lit for web components which requires document.
8
+ */
9
+ const loadAppKit = async () => {
10
+ try {
11
+ const { createAppKit } = await import("@reown/appkit/core");
12
+ return createAppKit;
13
+ } catch (cause) {
14
+ 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);
15
+ return null;
16
+ }
17
+ };
18
+ const WALLET_CONNECT_ICON = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+";
19
+ const APPKIT_SYMBOL = Symbol.for("kheopskit.cachedAppKit");
20
+ const APPKIT_PROJECT_ID_SYMBOL = Symbol.for("kheopskit.cachedAppKitProjectId");
21
+ const getCachedAppKit = () => globalThis[APPKIT_SYMBOL];
22
+ const getCachedAppKitProjectId = () => globalThis[APPKIT_PROJECT_ID_SYMBOL];
23
+ const setCachedAppKit = (value, projectId) => {
24
+ globalThis[APPKIT_SYMBOL] = value;
25
+ globalThis[APPKIT_PROJECT_ID_SYMBOL] = projectId;
26
+ };
27
+ /**
28
+ * Clears the cached AppKit observable.
29
+ * Use when configuration changes or for testing purposes.
30
+ * Note: This does NOT destroy the appKit instance created by Reown.
31
+ */
32
+ const resetAppKitCache = () => {
33
+ setCachedAppKit(void 0);
34
+ };
35
+ /**
36
+ * Keys are `accounts:<walletId>:...`; the trailing colon scopes the prefix to
37
+ * this wallet and avoids matching a sibling whose id is a string prefix.
38
+ */
39
+ const dropAccountsCache = (platform) => {
40
+ clearCachedObservablesByPrefix(`accounts:${WALLET_CONNECT_WALLET_ID}:${platform}:`);
41
+ };
42
+ const namespaceOf = {
43
+ polkadot: "polkadot",
44
+ ethereum: "eip155",
45
+ solana: "solana"
46
+ };
47
+ const allPlatforms = [
48
+ "polkadot",
49
+ "ethereum",
50
+ "solana"
51
+ ];
52
+ const createConnector$ = (appKit) => {
53
+ const appKitInstance = appKit;
54
+ const status$ = new BehaviorSubject({
55
+ isPolkadotConnected: false,
56
+ isEthereumConnected: false,
57
+ isSolanaConnected: false,
58
+ opening: false,
59
+ error: void 0
60
+ });
61
+ const syncProviders = (providers) => {
62
+ status$.next({
63
+ ...status$.value,
64
+ isPolkadotConnected: !!providers.polkadot,
65
+ isEthereumConnected: !!providers.eip155,
66
+ isSolanaConnected: !!providers.solana
67
+ });
68
+ };
69
+ const openModal = async () => {
70
+ status$.next({
71
+ ...status$.value,
72
+ opening: true,
73
+ error: void 0
74
+ });
75
+ try {
76
+ await appKit.open();
77
+ } catch (cause) {
78
+ const error = toConnectError(cause, WALLET_CONNECT_WALLET_ID, () => false);
79
+ status$.next({
80
+ ...status$.value,
81
+ opening: false,
82
+ error
83
+ });
84
+ throw error;
85
+ }
86
+ status$.next({
87
+ ...status$.value,
88
+ opening: false
89
+ });
90
+ };
91
+ const enabledPlatforms = allPlatforms.filter((p) => appKit.chainNamespaces.includes(namespaceOf[p]));
92
+ let prevConnected = {
93
+ polkadot: false,
94
+ ethereum: false,
95
+ solana: false
96
+ };
97
+ const wallet$ = status$.pipe(map((s) => ({
98
+ polkadot: s.isPolkadotConnected,
99
+ ethereum: s.isEthereumConnected,
100
+ solana: s.isSolanaConnected,
101
+ opening: s.opening,
102
+ error: s.error
103
+ })), distinctUntilChanged((a, b) => a.polkadot === b.polkadot && a.ethereum === b.ethereum && a.solana === b.solana && a.opening === b.opening && a.error === b.error), tap((connected) => {
104
+ for (const platform of allPlatforms) if (prevConnected[platform] && !connected[platform]) dropAccountsCache(platform);
105
+ prevConnected = connected;
106
+ }), map(({ opening, error, ...connected }) => {
107
+ const platforms = enabledPlatforms.filter((p) => connected[p]);
108
+ const isConnected = platforms.length > 0;
109
+ const walletInfo = appKit.getWalletInfo();
110
+ return {
111
+ id: WALLET_CONNECT_WALLET_ID,
112
+ type: "walletconnect",
113
+ platforms,
114
+ appKit: appKitInstance,
115
+ name: walletInfo?.name ?? "WalletConnect",
116
+ icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
117
+ connect: async () => {
118
+ if (!isConnected) await openModal();
119
+ },
120
+ disconnect: async () => {
121
+ if (isConnected) await appKit.disconnect();
122
+ },
123
+ status: isConnected ? "connected" : opening ? "connecting" : "disconnected",
124
+ error,
125
+ isConnected
126
+ };
127
+ }));
128
+ return new Observable((subscriber) => {
129
+ for (const platform of allPlatforms) dropAccountsCache(platform);
130
+ syncProviders({
131
+ polkadot: appKit.getProvider("polkadot"),
132
+ eip155: appKit.getProvider("eip155"),
133
+ solana: appKit.getProvider("solana")
134
+ });
135
+ const unsubProviders = appKit.subscribeProviders(syncProviders);
136
+ const sub = wallet$.subscribe(subscriber);
137
+ return () => {
138
+ sub.unsubscribe();
139
+ unsubProviders();
140
+ };
141
+ });
142
+ };
143
+ /**
144
+ * @remarks
145
+ * The AppKit instance is a process-wide singleton: a second instance would
146
+ * share AppKit's module-level controller state with the first, so it is
147
+ * created once. The **first** call with a `walletConnect` config wins;
148
+ * later calls with a *different* `walletConnect` config reuse that first
149
+ * instance. Call {@link resetAppKitCache} before re-initialising if the
150
+ * WalletConnect config must change.
151
+ *
152
+ * One WalletConnect session is shared across every namespace, and a namespace
153
+ * can only be established during the initial pairing — it can't be added to a
154
+ * live session afterwards. So this exposes ONE connector (not one per platform):
155
+ * `connect()` opens the modal; the wallet approves whichever namespaces it
156
+ * supports in that single pairing, and `platforms` reflects what the live
157
+ * session carries. Per-namespace accounts are derived by each platform plugin.
158
+ */
159
+ const getWalletConnectWallet$ = (walletConnect, debug) => {
160
+ if (typeof window === "undefined") return of(null);
161
+ const cachedProjectId = getCachedAppKitProjectId();
162
+ 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);
163
+ let cachedAppKit = getCachedAppKit();
164
+ if (!cachedAppKit) {
165
+ cachedAppKit = from(loadAppKit()).pipe(map((createAppKit) => createAppKit ? createConnector$(createAppKit({
166
+ projectId: walletConnect.projectId,
167
+ metadata: walletConnect.metadata,
168
+ networks: walletConnect.networks,
169
+ themeMode: walletConnect.themeMode,
170
+ themeVariables: walletConnect.themeVariables,
171
+ universalProviderConfigOverride: { methods: {
172
+ polkadot: ["polkadot_signTransaction", "polkadot_signMessage"],
173
+ solana: [
174
+ "solana_signTransaction",
175
+ "solana_signMessage",
176
+ "solana_signAndSendTransaction"
177
+ ]
178
+ } },
179
+ allWallets: "HIDE",
180
+ debug,
181
+ allowUnsupportedChain: true
182
+ })) : null), shareReplay({
183
+ refCount: false,
184
+ bufferSize: 1
185
+ })).pipe(switchMap((wallet$) => wallet$ ?? of(null)), shareReplay({
186
+ refCount: true,
187
+ bufferSize: 1
188
+ }));
189
+ setCachedAppKit(cachedAppKit, walletConnect.projectId);
190
+ }
191
+ return cachedAppKit;
192
+ };
193
+ /**
194
+ * The WalletConnect plugin for `config.walletConnect`. Importing this entry is
195
+ * what brings Reown AppKit into a dapp's bundle; a dapp that never imports it
196
+ * ships none of it.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * import { walletConnect } from "@kheopskit/core/walletconnect";
201
+ *
202
+ * getKheopskit$({
203
+ * platforms: [polkadot()],
204
+ * walletConnect: walletConnect({ projectId, metadata, networks }),
205
+ * });
206
+ * ```
207
+ */
208
+ const walletConnect = (options) => ({
209
+ type: "walletconnect",
210
+ metadata: options.metadata,
211
+ getWallet$: ({ config }) => getWalletConnectWallet$(options, config.debug)
212
+ });
213
+ //#endregion
214
+ export { isWalletConnectWallet, resetAppKitCache, walletConnect };
215
+
216
+ //# sourceMappingURL=walletconnect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletconnect.mjs","names":[],"sources":["../src/api/walletconnect/plugin.ts"],"sourcesContent":["import type { AppKit } from \"@reown/appkit/core\";\nimport {\n\tBehaviorSubject,\n\tdistinctUntilChanged,\n\tfrom,\n\tmap,\n\tObservable,\n\tof,\n\tshareReplay,\n\tswitchMap,\n\ttap,\n} from \"rxjs\";\nimport { clearCachedObservablesByPrefix } from \"../../utils/getCachedObservable\";\nimport { WALLET_CONNECT_WALLET_ID } from \"../../utils/WalletId\";\nimport { type KheopskitError, toConnectError } from \"../errors\";\nimport type {\n\tAppKitInstance,\n\tWalletConnectMetadata,\n\tWalletConnectPlugin,\n\tWalletConnectWallet,\n\tWalletPlatform,\n} from \"../types\";\n\nexport type WalletConnectOptions = {\n\tprojectId: string;\n\tmetadata: WalletConnectMetadata;\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 the declarations don't depend on\n\t * `@reown/appkit`'s 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 * Dynamically import @reown/appkit/core to avoid loading browser-only code\n * during SSR or in edge runtimes like Cloudflare Workers.\n * The AppKit library uses Lit for web components which requires document.\n */\nconst loadAppKit = async () => {\n\ttry {\n\t\tconst { createAppKit } = await import(\"@reown/appkit/core\");\n\t\treturn createAppKit;\n\t} catch (cause) {\n\t\tconsole.error(\n\t\t\t\"[kheopskit] WalletConnect is configured but @reown/appkit could not be loaded. \" +\n\t\t\t\t\"Install it with `pnpm add @reown/appkit` (or remove config.walletConnect). \" +\n\t\t\t\t\"WalletConnect wallets are disabled; injected wallets still work.\",\n\t\t\tcause,\n\t\t);\n\t\treturn null;\n\t}\n};\n\nconst WALLET_CONNECT_ICON =\n\t\"data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+\";\n\n// Once it exists, the appKit object should never be recreated. Anchored on\n// globalThis so it stays a single instance even if this module is duplicated\n// across bundle chunks (e.g. CJS subpath entries).\nconst APPKIT_SYMBOL = Symbol.for(\"kheopskit.cachedAppKit\");\n// The projectId AppKit was first initialised with. AppKit is a process-wide\n// singleton, so a later call with a different WalletConnect config is silently\n// ignored — we keep this to warn loudly instead of letting it pass unnoticed.\nconst APPKIT_PROJECT_ID_SYMBOL = Symbol.for(\"kheopskit.cachedAppKitProjectId\");\ntype AppKitGlobal = Record<\n\tsymbol,\n\tObservable<WalletConnectWallet | null> | string | undefined\n>;\nconst getCachedAppKit = ():\n\t| Observable<WalletConnectWallet | null>\n\t| undefined =>\n\t(globalThis as unknown as AppKitGlobal)[APPKIT_SYMBOL] as\n\t\t| Observable<WalletConnectWallet | null>\n\t\t| undefined;\nconst getCachedAppKitProjectId = (): string | undefined =>\n\t(globalThis as unknown as AppKitGlobal)[APPKIT_PROJECT_ID_SYMBOL] as\n\t\t| string\n\t\t| undefined;\nconst setCachedAppKit = (\n\tvalue: Observable<WalletConnectWallet | null> | undefined,\n\tprojectId?: string,\n): void => {\n\t(globalThis as unknown as AppKitGlobal)[APPKIT_SYMBOL] = value;\n\t(globalThis as unknown as AppKitGlobal)[APPKIT_PROJECT_ID_SYMBOL] = projectId;\n};\n\n/**\n * Clears the cached AppKit observable.\n * Use when configuration changes or for testing purposes.\n * Note: This does NOT destroy the appKit instance created by Reown.\n */\nexport const resetAppKitCache = (): void => {\n\tsetCachedAppKit(undefined);\n};\n\n/**\n * Keys are `accounts:<walletId>:...`; the trailing colon scopes the prefix to\n * this wallet and avoids matching a sibling whose id is a string prefix.\n */\nconst dropAccountsCache = (platform: WalletPlatform): void => {\n\tclearCachedObservablesByPrefix(\n\t\t`accounts:${WALLET_CONNECT_WALLET_ID}:${platform}:`,\n\t);\n};\n\nconst namespaceOf: Record<WalletPlatform, string> = {\n\tpolkadot: \"polkadot\",\n\tethereum: \"eip155\",\n\tsolana: \"solana\",\n};\nconst allPlatforms: WalletPlatform[] = [\"polkadot\", \"ethereum\", \"solana\"];\n\nconst createConnector$ = (appKit: AppKit): Observable<WalletConnectWallet> => {\n\t// Exposed on the wallet as the (decoupled) AppKitInstance escape hatch.\n\tconst appKitInstance = appKit as unknown as AppKitInstance;\n\n\tconst status$ = new BehaviorSubject<{\n\t\tisPolkadotConnected: boolean;\n\t\tisEthereumConnected: boolean;\n\t\tisSolanaConnected: boolean;\n\t\topening: boolean;\n\t\terror: KheopskitError | undefined;\n\t}>({\n\t\tisPolkadotConnected: false,\n\t\tisEthereumConnected: false,\n\t\tisSolanaConnected: false,\n\t\topening: false,\n\t\terror: undefined,\n\t});\n\n\tconst syncProviders = (providers: Partial<Record<string, unknown>>) => {\n\t\tstatus$.next({\n\t\t\t...status$.value,\n\t\t\tisPolkadotConnected: !!providers.polkadot,\n\t\t\tisEthereumConnected: !!providers.eip155,\n\t\t\tisSolanaConnected: !!providers.solana,\n\t\t});\n\t};\n\n\tconst openModal = async () => {\n\t\tstatus$.next({ ...status$.value, opening: true, error: undefined });\n\t\ttry {\n\t\t\tawait appKit.open();\n\t\t} catch (cause) {\n\t\t\tconst error = toConnectError(\n\t\t\t\tcause,\n\t\t\t\tWALLET_CONNECT_WALLET_ID,\n\t\t\t\t() => false,\n\t\t\t);\n\t\t\tstatus$.next({ ...status$.value, opening: false, error });\n\t\t\tthrow error;\n\t\t}\n\t\tstatus$.next({ ...status$.value, opening: false });\n\t};\n\n\tconst enabledPlatforms = allPlatforms.filter((p) =>\n\t\t(appKit.chainNamespaces as string[]).includes(namespaceOf[p]),\n\t);\n\n\tlet prevConnected = {\n\t\tpolkadot: false,\n\t\tethereum: false,\n\t\tsolana: false,\n\t};\n\n\tconst wallet$ = status$.pipe(\n\t\tmap((s) => ({\n\t\t\tpolkadot: s.isPolkadotConnected,\n\t\t\tethereum: s.isEthereumConnected,\n\t\t\tsolana: s.isSolanaConnected,\n\t\t\topening: s.opening,\n\t\t\terror: s.error,\n\t\t})),\n\t\tdistinctUntilChanged(\n\t\t\t(a, b) =>\n\t\t\t\ta.polkadot === b.polkadot &&\n\t\t\t\ta.ethereum === b.ethereum &&\n\t\t\t\ta.solana === b.solana &&\n\t\t\t\ta.opening === b.opening &&\n\t\t\t\ta.error === b.error,\n\t\t),\n\t\ttap((connected) => {\n\t\t\t// Drop caches for namespaces that just went disconnected.\n\t\t\tfor (const platform of allPlatforms)\n\t\t\t\tif (prevConnected[platform] && !connected[platform])\n\t\t\t\t\tdropAccountsCache(platform);\n\t\t\tprevConnected = connected;\n\t\t}),\n\t\tmap(({ opening, error, ...connected }): WalletConnectWallet => {\n\t\t\tconst platforms = enabledPlatforms.filter((p) => connected[p]);\n\t\t\tconst isConnected = platforms.length > 0;\n\t\t\tconst walletInfo = appKit.getWalletInfo();\n\t\t\treturn {\n\t\t\t\tid: WALLET_CONNECT_WALLET_ID,\n\t\t\t\ttype: \"walletconnect\",\n\t\t\t\tplatforms,\n\t\t\t\tappKit: appKitInstance,\n\t\t\t\tname: walletInfo?.name ?? \"WalletConnect\",\n\t\t\t\ticon: walletInfo?.icon ?? WALLET_CONNECT_ICON,\n\t\t\t\t// One shared session: connecting opens the modal; the wallet\n\t\t\t\t// approves namespaces in that single pairing. Disconnect is\n\t\t\t\t// session-wide; re-pair to change the approved set.\n\t\t\t\tconnect: async () => {\n\t\t\t\t\tif (!isConnected) await openModal();\n\t\t\t\t},\n\t\t\t\tdisconnect: async () => {\n\t\t\t\t\tif (isConnected) await appKit.disconnect();\n\t\t\t\t},\n\t\t\t\tstatus: isConnected\n\t\t\t\t\t? \"connected\"\n\t\t\t\t\t: opening\n\t\t\t\t\t\t? \"connecting\"\n\t\t\t\t\t\t: \"disconnected\",\n\t\t\t\terror,\n\t\t\t\tisConnected,\n\t\t\t};\n\t\t}),\n\t);\n\n\treturn new Observable<WalletConnectWallet>((subscriber) => {\n\t\tfor (const platform of allPlatforms) dropAccountsCache(platform);\n\t\t// AppKit's subscribeProviders only reports later changes, so read the\n\t\t// state that may have changed while nobody observed.\n\t\tsyncProviders({\n\t\t\tpolkadot: appKit.getProvider(\"polkadot\"),\n\t\t\teip155: appKit.getProvider(\"eip155\"),\n\t\t\tsolana: appKit.getProvider(\"solana\"),\n\t\t});\n\t\tconst unsubProviders = appKit.subscribeProviders(syncProviders);\n\t\tconst sub = wallet$.subscribe(subscriber);\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t\tunsubProviders();\n\t\t};\n\t});\n};\n\n/**\n * @remarks\n * The AppKit instance is a process-wide singleton: a second instance would\n * share AppKit's module-level controller state with the first, so it is\n * created once. The **first** call with a `walletConnect` config wins;\n * later calls with a *different* `walletConnect` config reuse that first\n * instance. Call {@link resetAppKitCache} before re-initialising if the\n * WalletConnect config must change.\n *\n * One WalletConnect session is shared across every namespace, and a namespace\n * can only be established during the initial pairing — it can't be added to a\n * live session afterwards. So this exposes ONE connector (not one per platform):\n * `connect()` opens the modal; the wallet approves whichever namespaces it\n * supports in that single pairing, and `platforms` reflects what the live\n * session carries. Per-namespace accounts are derived by each platform plugin.\n */\nconst getWalletConnectWallet$ = (\n\twalletConnect: WalletConnectOptions,\n\tdebug: boolean,\n): Observable<WalletConnectWallet | null> => {\n\t// SSR guard - don't try to load AppKit on the server\n\tif (typeof window === \"undefined\") return of(null);\n\n\tconst cachedProjectId = getCachedAppKitProjectId();\n\tif (\n\t\tcachedProjectId !== undefined &&\n\t\tcachedProjectId !== walletConnect.projectId\n\t) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] WalletConnect is already initialised with projectId %s; \" +\n\t\t\t\t\"AppKit is a process-wide singleton, so the first configuration wins and \" +\n\t\t\t\t\"projectId %s is ignored. Call resetAppKitCache() before re-initialising \" +\n\t\t\t\t\"if the WalletConnect config must change.\",\n\t\t\tcachedProjectId,\n\t\t\twalletConnect.projectId,\n\t\t);\n\t}\n\n\tlet cachedAppKit = getCachedAppKit();\n\tif (!cachedAppKit) {\n\t\t// Dynamic import avoids loading @reown/appkit at module-eval time (SSR /\n\t\t// edge runtimes like Cloudflare Workers).\n\t\tconst connectorOnce$ = from(loadAppKit()).pipe(\n\t\t\tmap((createAppKit) =>\n\t\t\t\t// @reown/appkit missing (optional peer dep) — degrade gracefully.\n\t\t\t\tcreateAppKit\n\t\t\t\t\t? createConnector$(\n\t\t\t\t\t\t\tcreateAppKit({\n\t\t\t\t\t\t\t\tprojectId: walletConnect.projectId,\n\t\t\t\t\t\t\t\tmetadata: walletConnect.metadata,\n\t\t\t\t\t\t\t\tnetworks: walletConnect.networks as never,\n\t\t\t\t\t\t\t\tthemeMode: walletConnect.themeMode,\n\t\t\t\t\t\t\t\tthemeVariables: walletConnect.themeVariables as never,\n\t\t\t\t\t\t\t\tuniversalProviderConfigOverride: {\n\t\t\t\t\t\t\t\t\tmethods: {\n\t\t\t\t\t\t\t\t\t\tpolkadot: [\n\t\t\t\t\t\t\t\t\t\t\t\"polkadot_signTransaction\",\n\t\t\t\t\t\t\t\t\t\t\t\"polkadot_signMessage\",\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tsolana: [\n\t\t\t\t\t\t\t\t\t\t\t\"solana_signTransaction\",\n\t\t\t\t\t\t\t\t\t\t\t\"solana_signMessage\",\n\t\t\t\t\t\t\t\t\t\t\t\"solana_signAndSendTransaction\",\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tallWallets: \"HIDE\",\n\t\t\t\t\t\t\t\tdebug,\n\t\t\t\t\t\t\t\tallowUnsupportedChain: true,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t: null,\n\t\t\t),\n\t\t\tshareReplay({ refCount: false, bufferSize: 1 }),\n\t\t);\n\t\tcachedAppKit = connectorOnce$.pipe(\n\t\t\tswitchMap((wallet$) => wallet$ ?? of(null)),\n\t\t\tshareReplay({ refCount: true, bufferSize: 1 }),\n\t\t);\n\t\tsetCachedAppKit(cachedAppKit, walletConnect.projectId);\n\t}\n\n\treturn cachedAppKit;\n};\n\n/**\n * The WalletConnect plugin for `config.walletConnect`. Importing this entry is\n * what brings Reown AppKit into a dapp's bundle; a dapp that never imports it\n * ships none of it.\n *\n * @example\n * ```ts\n * import { walletConnect } from \"@kheopskit/core/walletconnect\";\n *\n * getKheopskit$({\n * platforms: [polkadot()],\n * walletConnect: walletConnect({ projectId, metadata, networks }),\n * });\n * ```\n */\nexport const walletConnect = (\n\toptions: WalletConnectOptions,\n): WalletConnectPlugin => ({\n\ttype: \"walletconnect\",\n\tmetadata: options.metadata,\n\tgetWallet$: ({ config }) => getWalletConnectWallet$(options, config.debug),\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@kheopskit/core",
3
- "version": "5.3.0",
4
- "description": "",
3
+ "version": "6.0.0-rc.0",
4
+ "description": "Framework-agnostic wallet and account discovery for Polkadot, Ethereum and Solana dapps. Upgrading from v5? Read MIGRATING_TO_V6.md, shipped in this package.",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "files": [
8
8
  "dist",
9
9
  "README.md",
10
- "MIGRATING_TO_V4.md"
10
+ "MIGRATING_TO_V4.md",
11
+ "MIGRATING_TO_V6.md",
12
+ "CHANGELOG.md"
11
13
  ],
12
14
  "main": "./dist/index.js",
13
15
  "module": "./dist/index.mjs",
@@ -53,6 +55,16 @@
53
55
  "default": "./dist/solana.js"
54
56
  }
55
57
  },
58
+ "./walletconnect": {
59
+ "import": {
60
+ "types": "./dist/walletconnect.d.mts",
61
+ "default": "./dist/walletconnect.mjs"
62
+ },
63
+ "require": {
64
+ "types": "./dist/walletconnect.d.ts",
65
+ "default": "./dist/walletconnect.js"
66
+ }
67
+ },
56
68
  "./internal": {
57
69
  "import": {
58
70
  "types": "./dist/internal.d.mts",
@@ -63,6 +75,16 @@
63
75
  "default": "./dist/internal.js"
64
76
  }
65
77
  },
78
+ "./testing": {
79
+ "import": {
80
+ "types": "./dist/testing.d.mts",
81
+ "default": "./dist/testing.mjs"
82
+ },
83
+ "require": {
84
+ "types": "./dist/testing.d.ts",
85
+ "default": "./dist/testing.js"
86
+ }
87
+ },
66
88
  "./package.json": "./package.json"
67
89
  },
68
90
  "publishConfig": {
@@ -122,9 +144,9 @@
122
144
  "@wallet-standard/base": "^1.1.1",
123
145
  "@wallet-standard/features": "^1.1.1",
124
146
  "mipd": "^0.0.7",
125
- "polkadot-api": "^3.2.0",
147
+ "polkadot-api": "^3.2.1",
126
148
  "rxjs": "^7.8.2",
127
- "viem": "^2.57.0"
149
+ "viem": "^2.57.3"
128
150
  },
129
151
  "tsdown": {
130
152
  "entry": [
@@ -132,7 +154,9 @@
132
154
  "src/polkadot.ts",
133
155
  "src/ethereum.ts",
134
156
  "src/solana.ts",
135
- "src/internal.ts"
157
+ "src/walletconnect.ts",
158
+ "src/internal.ts",
159
+ "src/testing.ts"
136
160
  ],
137
161
  "tsconfig": "tsconfig.build.json",
138
162
  "fixedExtension": false,
@@ -1,181 +0,0 @@
1
- import { keccak_256 } from "@noble/hashes/sha3.js";
2
- import { base58 } from "@scure/base";
3
- import { blake2b } from "@noble/hashes/blake2.js";
4
- //#region src/utils/isEthereumAddress.ts
5
- const HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
6
- const encoder = new TextEncoder();
7
- /**
8
- * Verifies the EIP-55 mixed-case checksum of an Ethereum address.
9
- * Dependency-free (keccak via @noble/hashes) so core stays decoupled from viem.
10
- */
11
- const isChecksumValid = (address) => {
12
- const hex = address.slice(2);
13
- const hash = keccak_256(encoder.encode(hex.toLowerCase()));
14
- for (let i = 0; i < 40; i++) {
15
- const char = hex.charAt(i);
16
- if (!(char >= "a" && char <= "f" || char >= "A" && char <= "F")) continue;
17
- const byte = hash[i >> 1] ?? 0;
18
- const nibble = i % 2 === 0 ? byte >> 4 : byte & 15;
19
- if (char <= "F" !== nibble >= 8) return false;
20
- }
21
- return true;
22
- };
23
- /**
24
- * Returns true if `address` is a valid Ethereum address.
25
- *
26
- * Mirrors viem's `isAddress` (strict): the shape must be `0x` + 40 hex, and a
27
- * mixed-case address must pass the EIP-55 checksum. All-lowercase addresses are
28
- * accepted as non-checksummed.
29
- */
30
- const isEthereumAddress = (address) => {
31
- if (!HEX_ADDRESS.test(address)) return false;
32
- if (address === address.toLowerCase()) return true;
33
- return isChecksumValid(address);
34
- };
35
- //#endregion
36
- //#region src/utils/isSolanaAddress.ts
37
- /**
38
- * Returns true if the value is a valid Solana address: a base58-encoded
39
- * 32-byte ed25519 public key.
40
- *
41
- * Solana addresses carry no checksum, so this is a pure base58 + length check.
42
- * Dependency-free (base58 via @scure/base) so core stays decoupled from
43
- * @solana/kit.
44
- */
45
- const isSolanaAddress = (address) => {
46
- if (!address) return false;
47
- try {
48
- return base58.decode(address).length === 32;
49
- } catch {
50
- return false;
51
- }
52
- };
53
- //#endregion
54
- //#region src/utils/isSs58Address.ts
55
- const SS58PRE = new Uint8Array([
56
- 83,
57
- 83,
58
- 53,
59
- 56,
60
- 80,
61
- 82,
62
- 69
63
- ]);
64
- /**
65
- * Returns true if `address` is a valid SS58-encoded 32-byte account id (the
66
- * only form Substrate wallets inject), verifying the blake2b-512 checksum.
67
- *
68
- * Dependency-free (base58 via @scure/base, blake2b via @noble/hashes) so core
69
- * stays decoupled from polkadot-api.
70
- */
71
- const isSs58Address = (address) => {
72
- if (!address) return false;
73
- let decoded;
74
- try {
75
- decoded = base58.decode(address);
76
- } catch {
77
- return false;
78
- }
79
- const firstByte = decoded[0];
80
- if (firstByte === void 0 || firstByte & 128) return false;
81
- const prefixLength = firstByte & 64 ? 2 : 1;
82
- if (decoded.length !== prefixLength + 32 + 2) return false;
83
- const body = decoded.subarray(0, decoded.length - 2);
84
- const preimage = new Uint8Array(SS58PRE.length + body.length);
85
- preimage.set(SS58PRE);
86
- preimage.set(body, SS58PRE.length);
87
- const hash = blake2b(preimage, { dkLen: 64 });
88
- return decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1];
89
- };
90
- //#endregion
91
- //#region src/utils/isValidAddress.ts
92
- const isValidAddress = (address) => {
93
- if (address.startsWith("0x")) return isEthereumAddress(address);
94
- return isSs58Address(address) || isSolanaAddress(address);
95
- };
96
- //#endregion
97
- //#region src/utils/WalletAccountId.ts
98
- const getWalletAccountId = (walletId, address) => {
99
- if (!walletId) throw new Error("Missing walletId");
100
- if (!isValidAddress(address)) throw new Error("Invalid address");
101
- return `${walletId}::${address}`;
102
- };
103
- const parseWalletAccountId = (accountId) => {
104
- if (!accountId) throw new Error("Invalid walletAccountId");
105
- const [walletId, address] = accountId.split("::");
106
- if (!walletId) throw new Error("Missing walletId");
107
- if (!address || !isValidAddress(address)) throw new Error("Invalid address");
108
- return {
109
- walletId,
110
- address
111
- };
112
- };
113
- //#endregion
114
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
115
- function _typeof(o) {
116
- "@babel/helpers - typeof";
117
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
118
- return typeof o;
119
- } : function(o) {
120
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
121
- }, _typeof(o);
122
- }
123
- //#endregion
124
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
125
- function toPrimitive(t, r) {
126
- if ("object" != _typeof(t) || !t) return t;
127
- var e = t[Symbol.toPrimitive];
128
- if (void 0 !== e) {
129
- var i = e.call(t, r || "default");
130
- if ("object" != _typeof(i)) return i;
131
- throw new TypeError("@@toPrimitive must return a primitive value.");
132
- }
133
- return ("string" === r ? String : Number)(t);
134
- }
135
- //#endregion
136
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
137
- function toPropertyKey(t) {
138
- var i = toPrimitive(t, "string");
139
- return "symbol" == _typeof(i) ? i : i + "";
140
- }
141
- //#endregion
142
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
143
- function _defineProperty(e, r, t) {
144
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
145
- value: t,
146
- enumerable: !0,
147
- configurable: !0,
148
- writable: !0
149
- }) : e[r] = t, e;
150
- }
151
- //#endregion
152
- //#region src/api/errors.ts
153
- /**
154
- * Error thrown by kheopskit wallet/account operations. Carries a stable
155
- * {@link KheopskitErrorCode} and, when relevant, the offending wallet id.
156
- *
157
- * @example
158
- * ```ts
159
- * try {
160
- * await wallet.connect();
161
- * } catch (error) {
162
- * if (error instanceof KheopskitError && error.code === "WALLET_ALREADY_CONNECTED") {
163
- * // ignore
164
- * } else throw error;
165
- * }
166
- * ```
167
- */
168
- var KheopskitError = class extends Error {
169
- constructor(code, message, options) {
170
- super(`[kheopskit] ${message}`, { cause: options?.cause });
171
- _defineProperty(this, "code", void 0);
172
- _defineProperty(this, "walletId", void 0);
173
- this.name = "KheopskitError";
174
- this.code = code;
175
- this.walletId = options?.walletId;
176
- }
177
- };
178
- //#endregion
179
- export { isSs58Address as a, isValidAddress as i, getWalletAccountId as n, isSolanaAddress as o, parseWalletAccountId as r, isEthereumAddress as s, KheopskitError as t };
180
-
181
- //# sourceMappingURL=errors-BLFP1dQI.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-BLFP1dQI.mjs","names":[],"sources":["../src/utils/isEthereumAddress.ts","../src/utils/isSolanaAddress.ts","../src/utils/isSs58Address.ts","../src/utils/isValidAddress.ts","../src/utils/WalletAccountId.ts","../src/api/errors.ts"],"sourcesContent":["import { keccak_256 } from \"@noble/hashes/sha3.js\";\n\nconst HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;\nconst encoder = new TextEncoder();\n\n/**\n * Verifies the EIP-55 mixed-case checksum of an Ethereum address.\n * Dependency-free (keccak via @noble/hashes) so core stays decoupled from viem.\n */\nconst isChecksumValid = (address: string): boolean => {\n\tconst hex = address.slice(2);\n\tconst hash = keccak_256(encoder.encode(hex.toLowerCase()));\n\tfor (let i = 0; i < 40; i++) {\n\t\tconst char = hex.charAt(i);\n\t\tconst isLetter =\n\t\t\t(char >= \"a\" && char <= \"f\") || (char >= \"A\" && char <= \"F\");\n\t\tif (!isLetter) continue;\n\t\tconst byte = hash[i >> 1] ?? 0;\n\t\tconst nibble = i % 2 === 0 ? byte >> 4 : byte & 0x0f;\n\t\tconst isUpper = char <= \"F\";\n\t\tif (isUpper !== nibble >= 8) return false;\n\t}\n\treturn true;\n};\n\n/**\n * Returns true if `address` is a valid Ethereum address.\n *\n * Mirrors viem's `isAddress` (strict): the shape must be `0x` + 40 hex, and a\n * mixed-case address must pass the EIP-55 checksum. All-lowercase addresses are\n * accepted as non-checksummed.\n */\nexport const isEthereumAddress = (address: string): boolean => {\n\tif (!HEX_ADDRESS.test(address)) return false;\n\tif (address === address.toLowerCase()) return true;\n\treturn isChecksumValid(address);\n};\n","import { base58 } from \"@scure/base\";\n\n/**\n * Returns true if the value is a valid Solana address: a base58-encoded\n * 32-byte ed25519 public key.\n *\n * Solana addresses carry no checksum, so this is a pure base58 + length check.\n * Dependency-free (base58 via @scure/base) so core stays decoupled from\n * @solana/kit.\n */\nexport const isSolanaAddress = (address: string): boolean => {\n\tif (!address) return false;\n\ttry {\n\t\treturn base58.decode(address).length === 32;\n\t} catch {\n\t\treturn false;\n\t}\n};\n","import { blake2b } from \"@noble/hashes/blake2.js\";\nimport { base58 } from \"@scure/base\";\n\n// The \"SS58PRE\" prefix used in the SS58 checksum preimage.\nconst SS58PRE = new Uint8Array([0x53, 0x53, 0x35, 0x38, 0x50, 0x52, 0x45]);\n\n/**\n * Returns true if `address` is a valid SS58-encoded 32-byte account id (the\n * only form Substrate wallets inject), verifying the blake2b-512 checksum.\n *\n * Dependency-free (base58 via @scure/base, blake2b via @noble/hashes) so core\n * stays decoupled from polkadot-api.\n */\nexport const isSs58Address = (address: string): boolean => {\n\tif (!address) return false;\n\n\tlet decoded: Uint8Array;\n\ttry {\n\t\tdecoded = base58.decode(address);\n\t} catch {\n\t\treturn false;\n\t}\n\n\t// First byte encodes the network prefix; the high bit is reserved/invalid.\n\tconst firstByte = decoded[0];\n\tif (firstByte === undefined || firstByte & 0b1000_0000) return false;\n\t// The 0b0100_0000 bit marks a 2-byte prefix.\n\tconst prefixLength = firstByte & 0b0100_0000 ? 2 : 1;\n\n\t// AccountId32 layout: prefix + 32-byte pubkey + 2-byte checksum.\n\tif (decoded.length !== prefixLength + 32 + 2) return false;\n\n\tconst body = decoded.subarray(0, decoded.length - 2);\n\tconst preimage = new Uint8Array(SS58PRE.length + body.length);\n\tpreimage.set(SS58PRE);\n\tpreimage.set(body, SS58PRE.length);\n\tconst hash = blake2b(preimage, { dkLen: 64 });\n\n\treturn (\n\t\tdecoded[decoded.length - 2] === hash[0] &&\n\t\tdecoded[decoded.length - 1] === hash[1]\n\t);\n};\n","import { isEthereumAddress } from \"./isEthereumAddress\";\nimport { isSolanaAddress } from \"./isSolanaAddress\";\nimport { isSs58Address } from \"./isSs58Address\";\n\nexport const isValidAddress = (address: string): boolean => {\n\tif (address.startsWith(\"0x\")) return isEthereumAddress(address);\n\t// SS58 (checksummed) and Solana (base58, no checksum) are disjoint: a\n\t// 32-byte Solana pubkey fails SS58 decoding, and an SS58 address decodes to\n\t// more than 32 bytes so it fails the Solana length check.\n\treturn isSs58Address(address) || isSolanaAddress(address);\n};\n","import { isValidAddress } from \"./isValidAddress\";\n\nexport type WalletAccountId = string;\n\nexport const getWalletAccountId = (\n\twalletId: string,\n\taddress: string,\n): WalletAccountId => {\n\tif (!walletId) throw new Error(\"Missing walletId\");\n\tif (!isValidAddress(address)) throw new Error(\"Invalid address\");\n\treturn `${walletId}::${address}`;\n};\n\nexport const parseWalletAccountId = (accountId: string) => {\n\tif (!accountId) throw new Error(\"Invalid walletAccountId\");\n\tconst [walletId, address] = accountId.split(\"::\");\n\tif (!walletId) throw new Error(\"Missing walletId\");\n\tif (!address || !isValidAddress(address)) throw new Error(\"Invalid address\");\n\treturn { walletId, address };\n};\n","import type { WalletId } from \"../utils/WalletId\";\n\n/**\n * Stable error codes thrown by kheopskit. Catch a {@link KheopskitError} and\n * branch on `error.code` instead of matching message strings.\n */\nexport type KheopskitErrorCode =\n\t/** `connect()` called on a wallet that is already connected. */\n\t| \"WALLET_ALREADY_CONNECTED\"\n\t/** `disconnect()` called on a wallet that is not connected. */\n\t| \"WALLET_NOT_CONNECTED\"\n\t/** The wallet does not advertise a capability kheopskit needs to proceed. */\n\t| \"FEATURE_NOT_SUPPORTED\"\n\t/** No active WalletConnect session for the requested operation. */\n\t| \"NO_SESSION\"\n\t/** No provider available for the requested namespace. */\n\t| \"NO_PROVIDER\"\n\t/** The installed polkadot-api version exposes neither `getTxCreatorFromPjs` (v3) nor `getPolkadotSignerFromPjs` (v2). */\n\t| \"UNSUPPORTED_VERSION\"\n\t/** The requested chain cannot be used for this operation (e.g. a Solana cluster with no CAIP-2 id over WalletConnect). */\n\t| \"UNSUPPORTED_CHAIN\";\n\n/**\n * Error thrown by kheopskit wallet/account operations. Carries a stable\n * {@link KheopskitErrorCode} and, when relevant, the offending wallet id.\n *\n * @example\n * ```ts\n * try {\n * await wallet.connect();\n * } catch (error) {\n * if (error instanceof KheopskitError && error.code === \"WALLET_ALREADY_CONNECTED\") {\n * // ignore\n * } else throw error;\n * }\n * ```\n */\nexport class KheopskitError extends Error {\n\treadonly code: KheopskitErrorCode;\n\t/** The wallet id this error relates to, when applicable. */\n\treadonly walletId?: WalletId;\n\n\tconstructor(\n\t\tcode: KheopskitErrorCode,\n\t\tmessage: string,\n\t\toptions?: { walletId?: WalletId; cause?: unknown },\n\t) {\n\t\tsuper(`[kheopskit] ${message}`, { cause: options?.cause });\n\t\tthis.name = \"KheopskitError\";\n\t\tthis.code = code;\n\t\tthis.walletId = options?.walletId;\n\t}\n}\n"],"mappings":";;;;AAEA,MAAM,cAAc;AACpB,MAAM,UAAU,IAAI,YAAY;;;;;AAMhC,MAAM,mBAAmB,YAA6B;CACrD,MAAM,MAAM,QAAQ,MAAM,CAAC;CAC3B,MAAM,OAAO,WAAW,QAAQ,OAAO,IAAI,YAAY,CAAC,CAAC;CACzD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC5B,MAAM,OAAO,IAAI,OAAO,CAAC;EAGzB,IAAI,EADF,QAAQ,OAAO,QAAQ,OAAS,QAAQ,OAAO,QAAQ,MAC1C;EACf,MAAM,OAAO,KAAK,KAAK,MAAM;EAC7B,MAAM,SAAS,IAAI,MAAM,IAAI,QAAQ,IAAI,OAAO;EAEhD,IADgB,QAAQ,QACR,UAAU,GAAG,OAAO;CACrC;CACA,OAAO;AACR;;;;;;;;AASA,MAAa,qBAAqB,YAA6B;CAC9D,IAAI,CAAC,YAAY,KAAK,OAAO,GAAG,OAAO;CACvC,IAAI,YAAY,QAAQ,YAAY,GAAG,OAAO;CAC9C,OAAO,gBAAgB,OAAO;AAC/B;;;;;;;;;;;AC1BA,MAAa,mBAAmB,YAA6B;CAC5D,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI;EACH,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,WAAW;CAC1C,QAAQ;EACP,OAAO;CACR;AACD;;;ACbA,MAAM,UAAU,IAAI,WAAW;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAAI,CAAC;;;;;;;;AASzE,MAAa,iBAAiB,YAA6B;CAC1D,IAAI,CAAC,SAAS,OAAO;CAErB,IAAI;CACJ,IAAI;EACH,UAAU,OAAO,OAAO,OAAO;CAChC,QAAQ;EACP,OAAO;CACR;CAGA,MAAM,YAAY,QAAQ;CAC1B,IAAI,cAAc,KAAA,KAAa,YAAY,KAAa,OAAO;CAE/D,MAAM,eAAe,YAAY,KAAc,IAAI;CAGnD,IAAI,QAAQ,WAAW,eAAe,KAAK,GAAG,OAAO;CAErD,MAAM,OAAO,QAAQ,SAAS,GAAG,QAAQ,SAAS,CAAC;CACnD,MAAM,WAAW,IAAI,WAAW,QAAQ,SAAS,KAAK,MAAM;CAC5D,SAAS,IAAI,OAAO;CACpB,SAAS,IAAI,MAAM,QAAQ,MAAM;CACjC,MAAM,OAAO,QAAQ,UAAU,EAAE,OAAO,GAAG,CAAC;CAE5C,OACC,QAAQ,QAAQ,SAAS,OAAO,KAAK,MACrC,QAAQ,QAAQ,SAAS,OAAO,KAAK;AAEvC;;;ACtCA,MAAa,kBAAkB,YAA6B;CAC3D,IAAI,QAAQ,WAAW,IAAI,GAAG,OAAO,kBAAkB,OAAO;CAI9D,OAAO,cAAc,OAAO,KAAK,gBAAgB,OAAO;AACzD;;;ACNA,MAAa,sBACZ,UACA,YACqB;CACrB,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,kBAAkB;CACjD,IAAI,CAAC,eAAe,OAAO,GAAG,MAAM,IAAI,MAAM,iBAAiB;CAC/D,OAAO,GAAG,SAAS,IAAI;AACxB;AAEA,MAAa,wBAAwB,cAAsB;CAC1D,IAAI,CAAC,WAAW,MAAM,IAAI,MAAM,yBAAyB;CACzD,MAAM,CAAC,UAAU,WAAW,UAAU,MAAM,IAAI;CAChD,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,kBAAkB;CACjD,IAAI,CAAC,WAAW,CAAC,eAAe,OAAO,GAAG,MAAM,IAAI,MAAM,iBAAiB;CAC3E,OAAO;EAAE;EAAU;CAAQ;AAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACkBA,IAAa,iBAAb,cAAoC,MAAM;CAKzC,YACC,MACA,SACA,SACC;EACD,MAAM,eAAe,WAAW,EAAE,OAAO,SAAS,MAAM,CAAC;EATjD,gBAAA,MAAA,QAAA,KAAA,CAAA;EAEA,gBAAA,MAAA,YAAA,KAAA,CAAA;EAQR,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,WAAW,SAAS;CAC1B;AACD"}