@kheopskit/core 4.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SIUWQBT4.js → chunk-4ENHC7G4.js} +11 -2
- package/dist/chunk-4ENHC7G4.js.map +1 -0
- package/dist/{chunk-KWFQDD7E.mjs → chunk-6XAZANB5.mjs} +58 -186
- package/dist/chunk-6XAZANB5.mjs.map +1 -0
- package/dist/{chunk-PNPPI5CH.mjs → chunk-7QSGAJ4A.mjs} +11 -2
- package/dist/chunk-7QSGAJ4A.mjs.map +1 -0
- package/dist/{chunk-TMAPQWW2.js → chunk-B4L6GAYD.js} +24 -9
- package/dist/chunk-B4L6GAYD.js.map +1 -0
- package/dist/chunk-XQWJM3KC.js +450 -0
- package/dist/chunk-XQWJM3KC.js.map +1 -0
- package/dist/{chunk-4RBYRNY3.mjs → chunk-YDLCHYHH.mjs} +22 -7
- package/dist/chunk-YDLCHYHH.mjs.map +1 -0
- package/dist/ethereum.d.mts +4 -3
- package/dist/ethereum.d.ts +4 -3
- package/dist/ethereum.js +61 -42
- package/dist/ethereum.js.map +1 -1
- package/dist/ethereum.mjs +53 -34
- package/dist/ethereum.mjs.map +1 -1
- package/dist/index.d.mts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +253 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +271 -65
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +4 -4
- package/dist/internal.d.ts +4 -4
- package/dist/internal.js +3 -3
- package/dist/internal.mjs +2 -2
- package/dist/polkadot.d.mts +4 -3
- package/dist/polkadot.d.ts +4 -3
- package/dist/polkadot.js +26 -37
- package/dist/polkadot.js.map +1 -1
- package/dist/polkadot.mjs +13 -24
- package/dist/polkadot.mjs.map +1 -1
- package/dist/solana.d.mts +5 -4
- package/dist/solana.d.ts +5 -4
- package/dist/solana.js +37 -42
- package/dist/solana.js.map +1 -1
- package/dist/solana.mjs +26 -31
- package/dist/solana.mjs.map +1 -1
- package/dist/{types-BNzRUNw-.d.mts → types-C7V7DGlg.d.mts} +47 -17
- package/dist/{types-BNzRUNw-.d.ts → types-C7V7DGlg.d.ts} +47 -17
- package/package.json +42 -16
- package/dist/chunk-4RBYRNY3.mjs.map +0 -1
- package/dist/chunk-FIAL4HTE.js +0 -1
- package/dist/chunk-FIAL4HTE.js.map +0 -1
- package/dist/chunk-KWFQDD7E.mjs.map +0 -1
- package/dist/chunk-NU46D4MZ.js +0 -578
- package/dist/chunk-NU46D4MZ.js.map +0 -1
- package/dist/chunk-PNPPI5CH.mjs.map +0 -1
- package/dist/chunk-SIUWQBT4.js.map +0 -1
- package/dist/chunk-TMAPQWW2.js.map +0 -1
- package/dist/chunk-YFD3IKK5.mjs +0 -1
- package/dist/chunk-YFD3IKK5.mjs.map +0 -1
|
@@ -137,6 +137,7 @@ var cookieStorage = (initialCookies) => {
|
|
|
137
137
|
var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum", "solana"].includes(platform);
|
|
138
138
|
|
|
139
139
|
// src/utils/WalletId.ts
|
|
140
|
+
var WALLET_CONNECT_WALLET_ID = "walletconnect";
|
|
140
141
|
var getWalletId = (platform, identifier) => {
|
|
141
142
|
if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
|
|
142
143
|
if (!identifier) throw new Error("Invalid name");
|
|
@@ -151,6 +152,7 @@ var parseWalletId = (walletId) => {
|
|
|
151
152
|
};
|
|
152
153
|
var isValidWalletId = (walletId) => {
|
|
153
154
|
if (typeof walletId !== "string" || !walletId) return false;
|
|
155
|
+
if (walletId === WALLET_CONNECT_WALLET_ID) return true;
|
|
154
156
|
const [platform, identifier] = walletId.split(":");
|
|
155
157
|
return isWalletPlatform(platform) && !!identifier;
|
|
156
158
|
};
|
|
@@ -184,6 +186,9 @@ var clearAllCachedObservables = () => {
|
|
|
184
186
|
getCache().clear();
|
|
185
187
|
};
|
|
186
188
|
|
|
189
|
+
// src/api/types.ts
|
|
190
|
+
var isWalletConnectWallet = (wallet) => wallet.type === "walletconnect";
|
|
191
|
+
var isInjectedWallet = (wallet) => wallet.type === "injected";
|
|
187
192
|
|
|
188
193
|
|
|
189
194
|
|
|
@@ -197,5 +202,9 @@ var clearAllCachedObservables = () => {
|
|
|
197
202
|
|
|
198
203
|
|
|
199
204
|
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-4ENHC7G4.js","../src/utils/storage.ts","../src/utils/isWalletPlatform.ts","../src/utils/WalletId.ts","../src/utils/getCachedObservable.ts","../src/api/types.ts"],"names":[],"mappings":"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","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/chunk-4ENHC7G4.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 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\";\nimport type { KheopskitStore } from \"./store\";\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/**\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,13 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
WALLET_CONNECT_WALLET_ID,
|
|
2
3
|
__publicField,
|
|
3
|
-
clearCachedObservablesByPrefix,
|
|
4
4
|
cookieStorage,
|
|
5
|
-
getWalletId,
|
|
6
5
|
isValidWalletId,
|
|
7
6
|
isWalletPlatform,
|
|
8
7
|
parseWalletId,
|
|
9
8
|
safeLocalStorage
|
|
10
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7QSGAJ4A.mjs";
|
|
11
10
|
|
|
12
11
|
// src/utils/isEthereumAddress.ts
|
|
13
12
|
import { keccak_256 } from "@noble/hashes/sha3";
|
|
@@ -80,176 +79,12 @@ var getWalletAccountId = (walletId, address) => {
|
|
|
80
79
|
if (!isValidAddress(address)) throw new Error("Invalid address");
|
|
81
80
|
return `${walletId}::${address}`;
|
|
82
81
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
from,
|
|
90
|
-
map,
|
|
91
|
-
Observable,
|
|
92
|
-
of,
|
|
93
|
-
shareReplay,
|
|
94
|
-
switchMap,
|
|
95
|
-
tap
|
|
96
|
-
} from "rxjs";
|
|
97
|
-
var loadAppKit = async () => {
|
|
98
|
-
try {
|
|
99
|
-
const { createAppKit } = await import("@reown/appkit/core");
|
|
100
|
-
return createAppKit;
|
|
101
|
-
} catch (cause) {
|
|
102
|
-
console.error(
|
|
103
|
-
"[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.",
|
|
104
|
-
cause
|
|
105
|
-
);
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
var WALLET_CONNECT_ICON = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+";
|
|
110
|
-
var APPKIT_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.cachedAppKit");
|
|
111
|
-
var getCachedAppKit = () => globalThis[APPKIT_SYMBOL];
|
|
112
|
-
var setCachedAppKit = (value) => {
|
|
113
|
-
globalThis[APPKIT_SYMBOL] = value;
|
|
114
|
-
};
|
|
115
|
-
var resetAppKitCache = () => {
|
|
116
|
-
setCachedAppKit(void 0);
|
|
117
|
-
};
|
|
118
|
-
var clearAccountsCacheOnDisconnect = (platform) => (isConnected) => {
|
|
119
|
-
if (!isConnected)
|
|
120
|
-
clearCachedObservablesByPrefix(
|
|
121
|
-
`accounts:${getWalletId(platform, "walletconnect")}:`
|
|
122
|
-
);
|
|
123
|
-
};
|
|
124
|
-
var getAppKitWallets$ = (config) => {
|
|
125
|
-
if (!config.walletConnect) return of({});
|
|
126
|
-
if (typeof window === "undefined") return of({});
|
|
127
|
-
const walletConnect = config.walletConnect;
|
|
128
|
-
let cachedAppKit = getCachedAppKit();
|
|
129
|
-
if (!cachedAppKit) {
|
|
130
|
-
cachedAppKit = from(loadAppKit()).pipe(
|
|
131
|
-
switchMap((createAppKit) => {
|
|
132
|
-
if (!createAppKit) return of({});
|
|
133
|
-
return new Observable((subscriber) => {
|
|
134
|
-
const appKit = createAppKit({
|
|
135
|
-
projectId: walletConnect.projectId,
|
|
136
|
-
metadata: walletConnect.metadata,
|
|
137
|
-
// Loosely typed in WalletConnectConfig to keep @reown/appkit's
|
|
138
|
-
// types out of core; forwarded to AppKit verbatim.
|
|
139
|
-
networks: walletConnect.networks,
|
|
140
|
-
themeMode: walletConnect.themeMode,
|
|
141
|
-
themeVariables: walletConnect.themeVariables,
|
|
142
|
-
universalProviderConfigOverride: {
|
|
143
|
-
methods: {
|
|
144
|
-
polkadot: ["polkadot_signTransaction", "polkadot_signMessage"],
|
|
145
|
-
solana: [
|
|
146
|
-
"solana_signTransaction",
|
|
147
|
-
"solana_signMessage",
|
|
148
|
-
"solana_signAndSendTransaction"
|
|
149
|
-
]
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
allWallets: "HIDE",
|
|
153
|
-
debug: config.debug,
|
|
154
|
-
allowUnsupportedChain: true
|
|
155
|
-
});
|
|
156
|
-
const appKitInstance = appKit;
|
|
157
|
-
const status$ = new BehaviorSubject({
|
|
158
|
-
isPolkadotConnected: false,
|
|
159
|
-
isEthereumConnected: false,
|
|
160
|
-
isSolanaConnected: false
|
|
161
|
-
});
|
|
162
|
-
const unsubProviders = appKit.subscribeProviders((providers) => {
|
|
163
|
-
status$.next({
|
|
164
|
-
isPolkadotConnected: !!providers.polkadot,
|
|
165
|
-
isEthereumConnected: !!providers.eip155,
|
|
166
|
-
isSolanaConnected: !!providers.solana
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
const polkadotWallet$ = appKit.chainNamespaces.includes("polkadot") ? status$.pipe(
|
|
170
|
-
map((s) => s.isPolkadotConnected),
|
|
171
|
-
distinctUntilChanged(),
|
|
172
|
-
tap(clearAccountsCacheOnDisconnect("polkadot")),
|
|
173
|
-
map((isConnected) => {
|
|
174
|
-
const walletInfo = appKit.getWalletInfo();
|
|
175
|
-
const walletId = getWalletId("polkadot", "walletconnect");
|
|
176
|
-
return {
|
|
177
|
-
id: walletId,
|
|
178
|
-
platform: "polkadot",
|
|
179
|
-
type: "appKit",
|
|
180
|
-
appKit: appKitInstance,
|
|
181
|
-
name: walletInfo?.name ?? "WalletConnect",
|
|
182
|
-
icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
|
|
183
|
-
connect: async () => {
|
|
184
|
-
if (!isConnected) await appKit.open();
|
|
185
|
-
},
|
|
186
|
-
disconnect: async () => {
|
|
187
|
-
if (isConnected) await appKit.disconnect();
|
|
188
|
-
},
|
|
189
|
-
isConnected
|
|
190
|
-
};
|
|
191
|
-
})
|
|
192
|
-
) : of(void 0);
|
|
193
|
-
const ethereumWallet$ = appKit.chainNamespaces.includes("eip155") ? status$.pipe(
|
|
194
|
-
map((s) => s.isEthereumConnected),
|
|
195
|
-
distinctUntilChanged(),
|
|
196
|
-
tap(clearAccountsCacheOnDisconnect("ethereum")),
|
|
197
|
-
map((isConnected) => {
|
|
198
|
-
const walletInfo = appKit.getWalletInfo();
|
|
199
|
-
const walletId = getWalletId("ethereum", "walletconnect");
|
|
200
|
-
return {
|
|
201
|
-
id: walletId,
|
|
202
|
-
platform: "ethereum",
|
|
203
|
-
type: "appKit",
|
|
204
|
-
appKit: appKitInstance,
|
|
205
|
-
name: walletInfo?.name ?? "WalletConnect",
|
|
206
|
-
icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
|
|
207
|
-
connect: () => appKit.open(),
|
|
208
|
-
disconnect: async () => {
|
|
209
|
-
await appKit.disconnect();
|
|
210
|
-
},
|
|
211
|
-
isConnected
|
|
212
|
-
};
|
|
213
|
-
})
|
|
214
|
-
) : of(void 0);
|
|
215
|
-
const solanaWallet$ = appKit.chainNamespaces.includes("solana") ? status$.pipe(
|
|
216
|
-
map((s) => s.isSolanaConnected),
|
|
217
|
-
distinctUntilChanged(),
|
|
218
|
-
tap(clearAccountsCacheOnDisconnect("solana")),
|
|
219
|
-
map((isConnected) => {
|
|
220
|
-
const walletInfo = appKit.getWalletInfo();
|
|
221
|
-
const walletId = getWalletId("solana", "walletconnect");
|
|
222
|
-
return {
|
|
223
|
-
id: walletId,
|
|
224
|
-
platform: "solana",
|
|
225
|
-
type: "appKit",
|
|
226
|
-
appKit: appKitInstance,
|
|
227
|
-
name: walletInfo?.name ?? "WalletConnect",
|
|
228
|
-
icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
|
|
229
|
-
connect: () => appKit.open(),
|
|
230
|
-
disconnect: async () => {
|
|
231
|
-
await appKit.disconnect();
|
|
232
|
-
},
|
|
233
|
-
isConnected
|
|
234
|
-
};
|
|
235
|
-
})
|
|
236
|
-
) : of(void 0);
|
|
237
|
-
const sub = combineLatest({
|
|
238
|
-
polkadot: polkadotWallet$,
|
|
239
|
-
ethereum: ethereumWallet$,
|
|
240
|
-
solana: solanaWallet$
|
|
241
|
-
}).subscribe(subscriber);
|
|
242
|
-
return () => {
|
|
243
|
-
sub.unsubscribe();
|
|
244
|
-
unsubProviders();
|
|
245
|
-
};
|
|
246
|
-
});
|
|
247
|
-
}),
|
|
248
|
-
shareReplay({ refCount: true, bufferSize: 1 })
|
|
249
|
-
);
|
|
250
|
-
setCachedAppKit(cachedAppKit);
|
|
251
|
-
}
|
|
252
|
-
return cachedAppKit;
|
|
82
|
+
var parseWalletAccountId = (accountId) => {
|
|
83
|
+
if (!accountId) throw new Error("Invalid walletAccountId");
|
|
84
|
+
const [walletId, address] = accountId.split("::");
|
|
85
|
+
if (!walletId) throw new Error("Missing walletId");
|
|
86
|
+
if (!address || !isValidAddress(address)) throw new Error("Invalid address");
|
|
87
|
+
return { walletId, address };
|
|
253
88
|
};
|
|
254
89
|
|
|
255
90
|
// src/api/errors.ts
|
|
@@ -295,9 +130,9 @@ var resolveConfig = (config) => {
|
|
|
295
130
|
import { uniq } from "lodash-es";
|
|
296
131
|
|
|
297
132
|
// src/utils/createStore.ts
|
|
298
|
-
import { BehaviorSubject
|
|
133
|
+
import { BehaviorSubject } from "rxjs";
|
|
299
134
|
var createStore = (key, defaultValue, storage = safeLocalStorage) => {
|
|
300
|
-
const subject = new
|
|
135
|
+
const subject = new BehaviorSubject(
|
|
301
136
|
getStoredData(key, defaultValue, storage)
|
|
302
137
|
);
|
|
303
138
|
let unsubscribeStorage;
|
|
@@ -345,7 +180,12 @@ var DEFAULT_SETTINGS = {};
|
|
|
345
180
|
var isValidCachedWallet = (value) => {
|
|
346
181
|
if (!value || typeof value !== "object") return false;
|
|
347
182
|
const w = value;
|
|
348
|
-
|
|
183
|
+
if (!isValidWalletId(w.id)) return false;
|
|
184
|
+
if (typeof w.name !== "string" || typeof w.isConnected !== "boolean")
|
|
185
|
+
return false;
|
|
186
|
+
if (w.type === "walletconnect")
|
|
187
|
+
return w.id === WALLET_CONNECT_WALLET_ID && w.platform === void 0;
|
|
188
|
+
return w.type === "injected" && isWalletPlatform(w.platform);
|
|
349
189
|
};
|
|
350
190
|
var isValidCachedAccount = (value) => {
|
|
351
191
|
if (!value || typeof value !== "object") return false;
|
|
@@ -380,6 +220,28 @@ var fromCompactPolkadotAccountType = (type) => {
|
|
|
380
220
|
return void 0;
|
|
381
221
|
}
|
|
382
222
|
};
|
|
223
|
+
var toCompactPlatform = (platform) => {
|
|
224
|
+
switch (platform) {
|
|
225
|
+
case "polkadot":
|
|
226
|
+
return 0;
|
|
227
|
+
case "ethereum":
|
|
228
|
+
return 1;
|
|
229
|
+
case "solana":
|
|
230
|
+
return 2;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
var fromCompactPlatform = (code) => {
|
|
234
|
+
switch (code) {
|
|
235
|
+
case 0:
|
|
236
|
+
return "polkadot";
|
|
237
|
+
case 1:
|
|
238
|
+
return "ethereum";
|
|
239
|
+
case 2:
|
|
240
|
+
return "solana";
|
|
241
|
+
default:
|
|
242
|
+
return void 0;
|
|
243
|
+
}
|
|
244
|
+
};
|
|
383
245
|
var createKheopskitStore = (options = {}) => {
|
|
384
246
|
const { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;
|
|
385
247
|
const storage = ssrCookies !== void 0 ? createCompactCookieStorage(ssrCookies) : safeLocalStorage;
|
|
@@ -451,7 +313,7 @@ var toCompactStore = (data) => {
|
|
|
451
313
|
wallet.id,
|
|
452
314
|
wallet.name,
|
|
453
315
|
wallet.isConnected ? 1 : 0,
|
|
454
|
-
wallet.type === "
|
|
316
|
+
wallet.type === "walletconnect" ? 1 : 0
|
|
455
317
|
]
|
|
456
318
|
);
|
|
457
319
|
const accounts = data.cachedAccounts?.map(
|
|
@@ -460,7 +322,8 @@ var toCompactStore = (data) => {
|
|
|
460
322
|
account.address,
|
|
461
323
|
account.name ?? null,
|
|
462
324
|
account.chainId ?? null,
|
|
463
|
-
toCompactPolkadotAccountType(account.polkadotAccountType)
|
|
325
|
+
toCompactPolkadotAccountType(account.polkadotAccountType),
|
|
326
|
+
toCompactPlatform(account.platform)
|
|
464
327
|
]
|
|
465
328
|
);
|
|
466
329
|
return {
|
|
@@ -477,12 +340,14 @@ var fromCompactStore = (data) => {
|
|
|
477
340
|
if (!Array.isArray(item)) continue;
|
|
478
341
|
const [id, name, isConnected, type] = item;
|
|
479
342
|
if (!isValidWalletId(id)) continue;
|
|
480
|
-
const
|
|
343
|
+
const isWalletConnect = id === WALLET_CONNECT_WALLET_ID;
|
|
344
|
+
const walletType = type === 1 ? "walletconnect" : "injected";
|
|
345
|
+
if (isWalletConnect !== (walletType === "walletconnect")) continue;
|
|
481
346
|
walletNameMap.set(id, name);
|
|
482
347
|
wallets.push({
|
|
483
348
|
id,
|
|
484
|
-
platform,
|
|
485
|
-
type:
|
|
349
|
+
platform: isWalletConnect ? void 0 : parseWalletId(id).platform,
|
|
350
|
+
type: walletType,
|
|
486
351
|
name,
|
|
487
352
|
isConnected: isConnected === 1
|
|
488
353
|
});
|
|
@@ -490,10 +355,18 @@ var fromCompactStore = (data) => {
|
|
|
490
355
|
const accounts = [];
|
|
491
356
|
for (const item of Array.isArray(data.a) ? data.a : []) {
|
|
492
357
|
if (!Array.isArray(item)) continue;
|
|
493
|
-
const [
|
|
358
|
+
const [
|
|
359
|
+
walletId,
|
|
360
|
+
address,
|
|
361
|
+
name,
|
|
362
|
+
chainId,
|
|
363
|
+
polkadotAccountType,
|
|
364
|
+
platformCode
|
|
365
|
+
] = item;
|
|
494
366
|
if (!isValidWalletId(walletId) || typeof address !== "string" || !address)
|
|
495
367
|
continue;
|
|
496
|
-
const
|
|
368
|
+
const platform = platformCode != null ? fromCompactPlatform(platformCode) : walletId === WALLET_CONNECT_WALLET_ID ? void 0 : parseWalletId(walletId).platform;
|
|
369
|
+
if (!isWalletPlatform(platform)) continue;
|
|
497
370
|
accounts.push({
|
|
498
371
|
id: getWalletAccountId(walletId, address),
|
|
499
372
|
platform,
|
|
@@ -566,8 +439,7 @@ export {
|
|
|
566
439
|
isSolanaAddress,
|
|
567
440
|
isValidAddress,
|
|
568
441
|
getWalletAccountId,
|
|
569
|
-
|
|
570
|
-
getAppKitWallets$,
|
|
442
|
+
parseWalletAccountId,
|
|
571
443
|
KheopskitError,
|
|
572
444
|
DEFAULT_STORAGE_KEY,
|
|
573
445
|
resolveConfig,
|
|
@@ -575,4 +447,4 @@ export {
|
|
|
575
447
|
getDefaultStore,
|
|
576
448
|
store
|
|
577
449
|
};
|
|
578
|
-
//# sourceMappingURL=chunk-
|
|
450
|
+
//# sourceMappingURL=chunk-6XAZANB5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/isEthereumAddress.ts","../src/utils/isSs58Address.ts","../src/utils/isSolanaAddress.ts","../src/utils/isValidAddress.ts","../src/utils/WalletAccountId.ts","../src/api/errors.ts","../src/api/config.ts","../src/api/store.ts","../src/utils/createStore.ts"],"sourcesContent":["import { keccak_256 } from \"@noble/hashes/sha3\";\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 { blake2b } from \"@noble/hashes/blake2b\";\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 { 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 { 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 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","import type { KheopskitConfig, KheopskitPlatform } from \"./types\";\n\n/**\n * Default storage key for persisting wallet connection state.\n * Can be overridden via config.storageKey to avoid conflicts\n * when running multiple dapps on the same domain.\n */\nexport const DEFAULT_STORAGE_KEY = \"kheopskit\";\n\nconst DEFAULTS = {\n\tautoReconnect: true,\n\tdebug: false,\n\tstorageKey: DEFAULT_STORAGE_KEY,\n\thydrationGracePeriod: 500,\n} satisfies Omit<KheopskitConfig, \"platforms\" | \"walletConnect\">;\n\nexport const resolveConfig = <\n\tconst P extends readonly KheopskitPlatform[] = readonly KheopskitPlatform[],\n>(\n\tconfig?: Partial<KheopskitConfig<P>>,\n): KheopskitConfig<P> => {\n\tconst platforms = (config?.platforms ?? []) as P;\n\n\t// Guard the v4 breaking change: platforms are plugin instances, not strings.\n\t// Catches JS callers (no tsc) and gives agents a fix that names the doc.\n\tconst invalidPlatforms = (platforms as readonly unknown[]).filter(\n\t\t(p) =>\n\t\t\ttypeof p !== \"object\" ||\n\t\t\tp === null ||\n\t\t\ttypeof (p as { getWallets$?: unknown }).getWallets$ !== \"function\",\n\t);\n\tif (invalidPlatforms.length > 0) {\n\t\tthrow new Error(\n\t\t\t\"[kheopskit] config.platforms must contain plugin instances created by the \" +\n\t\t\t\t\"per-platform factories (e.g. platforms: [polkadot(), ethereum(), solana()] \" +\n\t\t\t\t'imported from \"@kheopskit/core/<platform>\"). ' +\n\t\t\t\t`Invalid entries: ${JSON.stringify(invalidPlatforms)}. ` +\n\t\t\t\t'String platform names like \"polkadot\" were removed in v4 — see MIGRATING_TO_V4.md.',\n\t\t);\n\t}\n\n\tif (platforms.length === 0) {\n\t\tconsole.warn(\n\t\t\t\"[kheopskit] No platforms configured; wallets and accounts will be empty. \" +\n\t\t\t\t'Pass e.g. platforms: [polkadot()] from \"@kheopskit/core/polkadot\".',\n\t\t);\n\t}\n\n\treturn Object.assign({}, DEFAULTS, config, { platforms });\n};\n","import { uniq } from \"lodash-es\";\nimport { createStore } from \"../utils/createStore\";\nimport { isWalletPlatform } from \"../utils/isWalletPlatform\";\nimport { cookieStorage, safeLocalStorage } from \"../utils/storage\";\nimport { getWalletAccountId } from \"../utils/WalletAccountId\";\nimport {\n\tisValidWalletId,\n\tparseWalletId,\n\tWALLET_CONNECT_WALLET_ID,\n\ttype WalletId,\n} from \"../utils/WalletId\";\nimport { DEFAULT_STORAGE_KEY } from \"./config\";\nimport type { CachedAccount, CachedWallet, WalletPlatform } from \"./types\";\n\ntype 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// wallet type: 0=injected, 1=walletconnect\ntype CompactWalletEntry = [WalletId, string, 0 | 1, 0 | 1];\ntype CompactPolkadotAccountType = 0 | 1 | 2 | 3;\n// platform: 0=polkadot, 1=ethereum, 2=solana\ntype CompactPlatformCode = 0 | 1 | 2;\ntype CompactAccountEntry = [\n\tWalletId,\n\tstring,\n\tstring | null,\n\tnumber | null,\n\tCompactPolkadotAccountType | null,\n\t// Platform code. Newly written entries always include it (the WalletConnect\n\t// connector's walletId is platform-less, so platform can't be derived from\n\t// it); absent in entries written by older versions, where it's derived from\n\t// the walletId instead.\n\t(CompactPlatformCode | null)?,\n];\n\ntype CompactStoreV1 = {\n\tv: 1;\n\t// autoReconnect\n\tr?: WalletId[];\n\t// wallets: [id, name, isConnected(0|1), type(0=injected,1=walletconnect)?]\n\tw?: CompactWalletEntry[];\n\t// accounts: [walletId, address, name?, chainId?, polkadotType?, platform?]\n\ta?: CompactAccountEntry[];\n};\n\nconst DEFAULT_SETTINGS: KheopskitStoreData = {};\n\n/**\n * Validates a cached wallet read from persisted storage. Cached state may have\n * been written by an older (or corrupted) version with a different shape, so we\n * drop anything that wouldn't survive hydration/sort rather than letting it\n * throw at render time. Only the fields downstream code relies on are checked.\n */\nconst isValidCachedWallet = (value: unknown): value is CachedWallet => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst w = value as Record<string, unknown>;\n\tif (!isValidWalletId(w.id)) return false;\n\tif (typeof w.name !== \"string\" || typeof w.isConnected !== \"boolean\")\n\t\treturn false;\n\t// The WalletConnect connector is platform-less with a fixed id; drop stale\n\t// per-platform WC entries written by older versions.\n\tif (w.type === \"walletconnect\")\n\t\treturn w.id === WALLET_CONNECT_WALLET_ID && w.platform === undefined;\n\treturn w.type === \"injected\" && isWalletPlatform(w.platform);\n};\n\n/** Validates a cached account read from persisted storage. See {@link isValidCachedWallet}. */\nconst isValidCachedAccount = (value: unknown): value is CachedAccount => {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst a = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof a.id === \"string\" &&\n\t\t!!a.id &&\n\t\tisWalletPlatform(a.platform) &&\n\t\ttypeof a.address === \"string\" &&\n\t\t!!a.address &&\n\t\tisValidWalletId(a.walletId) &&\n\t\ttypeof a.walletName === \"string\"\n\t);\n};\n\nconst toCompactPolkadotAccountType = (\n\ttype: CachedAccount[\"polkadotAccountType\"],\n): CompactPolkadotAccountType | null => {\n\tswitch (type) {\n\t\tcase \"sr25519\":\n\t\t\treturn 0;\n\t\tcase \"ed25519\":\n\t\t\treturn 1;\n\t\tcase \"ecdsa\":\n\t\t\treturn 2;\n\t\tcase \"ethereum\":\n\t\t\treturn 3;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n};\n\nconst fromCompactPolkadotAccountType = (\n\ttype: CompactPolkadotAccountType | null | undefined,\n): CachedAccount[\"polkadotAccountType\"] => {\n\tswitch (type) {\n\t\tcase 0:\n\t\t\treturn \"sr25519\";\n\t\tcase 1:\n\t\t\treturn \"ed25519\";\n\t\tcase 2:\n\t\t\treturn \"ecdsa\";\n\t\tcase 3:\n\t\t\treturn \"ethereum\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst toCompactPlatform = (platform: WalletPlatform): CompactPlatformCode => {\n\tswitch (platform) {\n\t\tcase \"polkadot\":\n\t\t\treturn 0;\n\t\tcase \"ethereum\":\n\t\t\treturn 1;\n\t\tcase \"solana\":\n\t\t\treturn 2;\n\t}\n};\n\nconst fromCompactPlatform = (\n\tcode: CompactPlatformCode | null | undefined,\n): WalletPlatform | undefined => {\n\tswitch (code) {\n\t\tcase 0:\n\t\t\treturn \"polkadot\";\n\t\tcase 1:\n\t\t\treturn \"ethereum\";\n\t\tcase 2:\n\t\t\treturn \"solana\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\ntype CreateKheopskitStoreOptions = {\n\t/**\n\t * Cookie string for SSR hydration.\n\t * When provided, uses cookieStorage instead of localStorage.\n\t */\n\tssrCookies?: string;\n\t/**\n\t * Custom storage key to namespace the stored data.\n\t * @default \"kheopskit\"\n\t */\n\tstorageKey?: string;\n};\n\n/**\n * Creates a kheopskit store with the appropriate storage backend.\n * Uses cookieStorage when ssrCookies is provided (for SSR hydration),\n * otherwise falls back to safeLocalStorage.\n *\n * @param options - Configuration options for the store\n */\nexport const createKheopskitStore = (\n\toptions: CreateKheopskitStoreOptions = {},\n) => {\n\tconst { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;\n\tconst storage =\n\t\tssrCookies !== undefined\n\t\t\t? createCompactCookieStorage(ssrCookies)\n\t\t\t: safeLocalStorage;\n\tconst store = createStore(storageKey, DEFAULT_SETTINGS, storage);\n\n\tconst addEnabledWalletId = (walletId: WalletId) => {\n\t\tparseWalletId(walletId); // validate walletId\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tautoReconnect: uniq((prev.autoReconnect ?? []).concat(walletId)),\n\t\t}));\n\t};\n\n\tconst removeEnabledWalletId = (walletId: WalletId) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tautoReconnect: uniq(\n\t\t\t\t(prev.autoReconnect ?? []).filter((id) => id !== walletId),\n\t\t\t),\n\t\t}));\n\t};\n\n\tconst getCachedState = () => {\n\t\t// `store.get()` returns whatever JSON was persisted — it may be from an\n\t\t// older version, a different shape, or outright corrupt. Read defensively:\n\t\t// coerce non-objects/arrays to empty and drop any entry that fails\n\t\t// validation, so stale cache degrades to \"start fresh\" instead of throwing\n\t\t// during hydration (which renders eagerly, so a throw blanks the dapp).\n\t\tconst data = store.get() as Partial<KheopskitStoreData> | null | undefined;\n\t\tconst cachedWallets = Array.isArray(data?.cachedWallets)\n\t\t\t? data.cachedWallets\n\t\t\t: [];\n\t\tconst cachedAccounts = Array.isArray(data?.cachedAccounts)\n\t\t\t? data.cachedAccounts\n\t\t\t: [];\n\t\treturn {\n\t\t\twallets: cachedWallets.filter(isValidCachedWallet),\n\t\t\taccounts: cachedAccounts.filter(isValidCachedAccount),\n\t\t};\n\t};\n\n\tconst setCachedState = (\n\t\twallets: CachedWallet[],\n\t\taccounts: CachedAccount[],\n\t) => {\n\t\tstore.mutate((prev) => ({\n\t\t\t...prev,\n\t\t\tcachedWallets: wallets,\n\t\t\tcachedAccounts: accounts,\n\t\t}));\n\t};\n\n\treturn {\n\t\tobservable: store.observable,\n\t\taddEnabledWalletId,\n\t\tremoveEnabledWalletId,\n\t\tgetCachedState,\n\t\tsetCachedState,\n\t};\n};\n\nexport type KheopskitStore = ReturnType<typeof createKheopskitStore>;\n\n/**\n * Cached default store instance, anchored on globalThis so it stays a single\n * instance even if this module is duplicated across bundle chunks (e.g. CJS\n * subpath entries). Lazily initialized on first access to be SSR-safe.\n */\nconst DEFAULT_STORE_SYMBOL = Symbol.for(\"kheopskit.defaultStore\");\n\n/**\n * Gets the default store, creating it on first access.\n * Uses localStorage on client, noop on server.\n * Lazily initialized to avoid SSR issues with module-level code.\n */\nexport const getDefaultStore = (): KheopskitStore => {\n\tconst g = globalThis as unknown as Record<symbol, KheopskitStore | undefined>;\n\tif (!g[DEFAULT_STORE_SYMBOL]) {\n\t\tg[DEFAULT_STORE_SYMBOL] = createKheopskitStore();\n\t}\n\treturn g[DEFAULT_STORE_SYMBOL];\n};\n\n/**\n * @deprecated Use createKheopskitStore() or getDefaultStore() instead.\n * This export is kept for backward compatibility but may cause SSR issues\n * if imported at module level in server environments.\n */\nexport const store = {\n\tget observable() {\n\t\treturn getDefaultStore().observable;\n\t},\n\taddEnabledWalletId: (walletId: WalletId) =>\n\t\tgetDefaultStore().addEnabledWalletId(walletId),\n\tremoveEnabledWalletId: (walletId: WalletId) =>\n\t\tgetDefaultStore().removeEnabledWalletId(walletId),\n\tgetCachedState: () => getDefaultStore().getCachedState(),\n\tsetCachedState: (wallets: CachedWallet[], accounts: CachedAccount[]) =>\n\t\tgetDefaultStore().setCachedState(wallets, accounts),\n};\n\nconst isCompactStore = (value: unknown): value is CompactStoreV1 => {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tif (\"cachedWallets\" in value || \"cachedAccounts\" in value) return false;\n\treturn \"v\" in value || \"w\" in value || \"a\" in value || \"r\" in value;\n};\n\nconst toCompactStore = (data: KheopskitStoreData): CompactStoreV1 => {\n\tconst wallets = data.cachedWallets?.map(\n\t\t(wallet): CompactWalletEntry => [\n\t\t\twallet.id,\n\t\t\twallet.name,\n\t\t\twallet.isConnected ? 1 : 0,\n\t\t\twallet.type === \"walletconnect\" ? 1 : 0,\n\t\t],\n\t);\n\n\tconst accounts = data.cachedAccounts?.map(\n\t\t(account): CompactAccountEntry => [\n\t\t\taccount.walletId,\n\t\t\taccount.address,\n\t\t\taccount.name ?? null,\n\t\t\taccount.chainId ?? null,\n\t\t\ttoCompactPolkadotAccountType(account.polkadotAccountType),\n\t\t\ttoCompactPlatform(account.platform),\n\t\t],\n\t);\n\n\treturn {\n\t\tv: 1,\n\t\tr: data.autoReconnect,\n\t\tw: wallets?.length ? wallets : undefined,\n\t\ta: accounts?.length ? accounts : undefined,\n\t};\n};\n\nconst fromCompactStore = (data: CompactStoreV1): KheopskitStoreData => {\n\tconst walletNameMap = new Map<WalletId, string>();\n\n\t// Decode defensively: a compact payload may be malformed (older/corrupt\n\t// cookie, hand-edited). Skip entries with an unparseable wallet id rather\n\t// than throwing, which would crash store initialisation.\n\tconst wallets: CachedWallet[] = [];\n\tfor (const item of Array.isArray(data.w) ? data.w : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [id, name, isConnected, type] = item;\n\t\tif (!isValidWalletId(id)) continue;\n\t\tconst isWalletConnect = id === WALLET_CONNECT_WALLET_ID;\n\t\tconst walletType = type === 1 ? \"walletconnect\" : \"injected\";\n\t\t// Keep id/type consistent: the platform-less connector uses the fixed WC\n\t\t// id; everything else is a platform-prefixed injected wallet. Drop stale\n\t\t// mismatches (e.g. per-platform WC ids from older versions).\n\t\tif (isWalletConnect !== (walletType === \"walletconnect\")) continue;\n\t\twalletNameMap.set(id, name);\n\t\twallets.push({\n\t\t\tid,\n\t\t\tplatform: isWalletConnect ? undefined : parseWalletId(id).platform,\n\t\t\ttype: walletType,\n\t\t\tname,\n\t\t\tisConnected: isConnected === 1,\n\t\t});\n\t}\n\n\tconst accounts: CachedAccount[] = [];\n\tfor (const item of Array.isArray(data.a) ? data.a : []) {\n\t\tif (!Array.isArray(item)) continue;\n\t\tconst [\n\t\t\twalletId,\n\t\t\taddress,\n\t\t\tname,\n\t\t\tchainId,\n\t\t\tpolkadotAccountType,\n\t\t\tplatformCode,\n\t\t] = item;\n\t\tif (!isValidWalletId(walletId) || typeof address !== \"string\" || !address)\n\t\t\tcontinue;\n\t\t// Prefer the explicit platform code; fall back to deriving it from the\n\t\t// walletId for entries written before the code existed (never WC ones).\n\t\tconst platform =\n\t\t\tplatformCode != null\n\t\t\t\t? fromCompactPlatform(platformCode)\n\t\t\t\t: walletId === WALLET_CONNECT_WALLET_ID\n\t\t\t\t\t? undefined\n\t\t\t\t\t: parseWalletId(walletId).platform;\n\t\tif (!isWalletPlatform(platform)) continue;\n\t\taccounts.push({\n\t\t\tid: getWalletAccountId(walletId, address),\n\t\t\tplatform,\n\t\t\taddress,\n\t\t\tname: name ?? undefined,\n\t\t\tchainId: chainId ?? undefined,\n\t\t\tpolkadotAccountType:\n\t\t\t\tplatform === \"polkadot\"\n\t\t\t\t\t? fromCompactPolkadotAccountType(polkadotAccountType)\n\t\t\t\t\t: undefined,\n\t\t\twalletId,\n\t\t\twalletName: walletNameMap.get(walletId) ?? walletId,\n\t\t});\n\t}\n\n\treturn {\n\t\tautoReconnect: data.r,\n\t\tcachedWallets: wallets,\n\t\tcachedAccounts: accounts,\n\t};\n};\n\nconst decodeStore = (raw: string, fallback: KheopskitStoreData) => {\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\tif (isCompactStore(parsed)) return fromCompactStore(parsed);\n\t\treturn parsed as KheopskitStoreData;\n\t} catch {\n\t\treturn fallback;\n\t}\n};\n\nconst encodeStore = (data: KheopskitStoreData): string =>\n\tJSON.stringify(toCompactStore(data));\n\nconst createCompactCookieStorage = (initialCookies?: string) => {\n\tconst base = cookieStorage(initialCookies);\n\n\treturn {\n\t\tgetItem: (key: string) => {\n\t\t\tconst raw = base.getItem(key);\n\t\t\tif (!raw) return null;\n\t\t\tconst expanded = decodeStore(raw, DEFAULT_SETTINGS);\n\t\t\tif (typeof document !== \"undefined\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\t\t\t\tif (!isCompactStore(parsed)) {\n\t\t\t\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore malformed cookie during migration\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn JSON.stringify(expanded);\n\t\t},\n\t\tsetItem: (key: string, value: string) => {\n\t\t\tconst expanded = decodeStore(value, DEFAULT_SETTINGS);\n\t\t\tbase.setItem(key, encodeStore(expanded));\n\t\t},\n\t\tremoveItem: base.removeItem,\n\t\tsubscribe: (key: string, callback: (value: string | null) => void) => {\n\t\t\tconst unsubscribe = base.subscribe?.(key, (value) => {\n\t\t\t\tif (!value) {\n\t\t\t\t\tcallback(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst expanded = decodeStore(value, DEFAULT_SETTINGS);\n\t\t\t\tcallback(JSON.stringify(expanded));\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tunsubscribe?.();\n\t\t\t};\n\t\t},\n\t};\n};\n","import { BehaviorSubject } from \"rxjs\";\nimport { type SyncableStorage, safeLocalStorage } from \"./storage\";\n\nexport const createStore = <T>(\n\tkey: string,\n\tdefaultValue: T,\n\tstorage: SyncableStorage = safeLocalStorage,\n) => {\n\tconst subject = new BehaviorSubject<T>(\n\t\tgetStoredData(key, defaultValue, storage),\n\t);\n\n\t// Cross-tab sync via storage.subscribe (uses storage event for localStorage, BroadcastChannel for cookies)\n\t// Only subscribe if window is available (client-side) and storage supports it\n\tlet unsubscribeStorage: (() => void) | undefined;\n\tif (typeof window !== \"undefined\" && storage.subscribe) {\n\t\tunsubscribeStorage = storage.subscribe(key, (newValue) => {\n\t\t\tsubject.next(parseData(newValue, defaultValue));\n\t\t});\n\t}\n\n\tconst update = (val: T) => {\n\t\tsetStoredData(key, val, storage);\n\t\tsubject.next(val);\n\t};\n\n\treturn {\n\t\tobservable: subject.asObservable(),\n\t\tset: (val: T) => update(val),\n\t\tmutate: (transform: (prev: T) => T) =>\n\t\t\tupdate(transform(subject.getValue())),\n\t\tget: () => structuredClone(subject.getValue()),\n\t\t/**\n\t\t * Cleanup subscriptions. Call this when the store is no longer needed.\n\t\t */\n\t\tdestroy: () => {\n\t\t\tunsubscribeStorage?.();\n\t\t\tsubject.complete();\n\t\t},\n\t};\n};\n\nconst parseData = <T>(str: string | null, defaultValue: T): T => {\n\ttry {\n\t\tif (str) return JSON.parse(str);\n\t} catch {\n\t\t// invalid data\n\t}\n\treturn defaultValue;\n};\n\nconst getStoredData = <T>(\n\tkey: string,\n\tdefaultValue: T,\n\tstorage: SyncableStorage,\n): T => {\n\tconst str = storage.getItem(key);\n\treturn parseData(str, defaultValue);\n};\n\nconst setStoredData = <T>(key: string, val: T, storage: SyncableStorage) => {\n\tconst str = JSON.stringify(val);\n\tstorage.setItem(key, str);\n};\n"],"mappings":"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","names":["base58","store"]}
|
|
@@ -137,6 +137,7 @@ var cookieStorage = (initialCookies) => {
|
|
|
137
137
|
var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum", "solana"].includes(platform);
|
|
138
138
|
|
|
139
139
|
// src/utils/WalletId.ts
|
|
140
|
+
var WALLET_CONNECT_WALLET_ID = "walletconnect";
|
|
140
141
|
var getWalletId = (platform, identifier) => {
|
|
141
142
|
if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
|
|
142
143
|
if (!identifier) throw new Error("Invalid name");
|
|
@@ -151,6 +152,7 @@ var parseWalletId = (walletId) => {
|
|
|
151
152
|
};
|
|
152
153
|
var isValidWalletId = (walletId) => {
|
|
153
154
|
if (typeof walletId !== "string" || !walletId) return false;
|
|
155
|
+
if (walletId === WALLET_CONNECT_WALLET_ID) return true;
|
|
154
156
|
const [platform, identifier] = walletId.split(":");
|
|
155
157
|
return isWalletPlatform(platform) && !!identifier;
|
|
156
158
|
};
|
|
@@ -184,18 +186,25 @@ var clearAllCachedObservables = () => {
|
|
|
184
186
|
getCache().clear();
|
|
185
187
|
};
|
|
186
188
|
|
|
189
|
+
// src/api/types.ts
|
|
190
|
+
var isWalletConnectWallet = (wallet) => wallet.type === "walletconnect";
|
|
191
|
+
var isInjectedWallet = (wallet) => wallet.type === "injected";
|
|
192
|
+
|
|
187
193
|
export {
|
|
188
194
|
__publicField,
|
|
189
195
|
getSafeLocalStorage,
|
|
190
196
|
safeLocalStorage,
|
|
191
197
|
cookieStorage,
|
|
192
198
|
isWalletPlatform,
|
|
199
|
+
WALLET_CONNECT_WALLET_ID,
|
|
193
200
|
getWalletId,
|
|
194
201
|
parseWalletId,
|
|
195
202
|
isValidWalletId,
|
|
196
203
|
getCachedObservable$,
|
|
197
204
|
clearCachedObservable,
|
|
198
205
|
clearCachedObservablesByPrefix,
|
|
199
|
-
clearAllCachedObservables
|
|
206
|
+
clearAllCachedObservables,
|
|
207
|
+
isWalletConnectWallet,
|
|
208
|
+
isInjectedWallet
|
|
200
209
|
};
|
|
201
|
-
//# sourceMappingURL=chunk-
|
|
210
|
+
//# sourceMappingURL=chunk-7QSGAJ4A.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/storage.ts","../src/utils/isWalletPlatform.ts","../src/utils/WalletId.ts","../src/utils/getCachedObservable.ts","../src/api/types.ts"],"sourcesContent":["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 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\";\nimport type { KheopskitStore } from \"./store\";\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/**\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"],"mappings":"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","names":[]}
|