@kheopskit/core 1.0.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/MIGRATING_TO_V4.md +259 -0
  2. package/README.md +67 -0
  3. package/dist/chunk-4ENHC7G4.js +210 -0
  4. package/dist/chunk-4ENHC7G4.js.map +1 -0
  5. package/dist/chunk-6XAZANB5.mjs +450 -0
  6. package/dist/chunk-6XAZANB5.mjs.map +1 -0
  7. package/dist/chunk-7QSGAJ4A.mjs +210 -0
  8. package/dist/chunk-7QSGAJ4A.mjs.map +1 -0
  9. package/dist/chunk-B4L6GAYD.js +179 -0
  10. package/dist/chunk-B4L6GAYD.js.map +1 -0
  11. package/dist/chunk-BWUUHUDK.mjs +24 -0
  12. package/dist/chunk-BWUUHUDK.mjs.map +1 -0
  13. package/dist/chunk-D3EQMFZ2.js +24 -0
  14. package/dist/chunk-D3EQMFZ2.js.map +1 -0
  15. package/dist/chunk-XQWJM3KC.js +450 -0
  16. package/dist/chunk-XQWJM3KC.js.map +1 -0
  17. package/dist/chunk-YDLCHYHH.mjs +179 -0
  18. package/dist/chunk-YDLCHYHH.mjs.map +1 -0
  19. package/dist/ethereum.d.mts +61 -0
  20. package/dist/ethereum.d.ts +61 -0
  21. package/dist/ethereum.js +351 -0
  22. package/dist/ethereum.js.map +1 -0
  23. package/dist/ethereum.mjs +351 -0
  24. package/dist/ethereum.mjs.map +1 -0
  25. package/dist/getCachedObservable-C4E8dfMp.d.mts +20 -0
  26. package/dist/getCachedObservable-C4E8dfMp.d.ts +20 -0
  27. package/dist/index.d.mts +55 -267
  28. package/dist/index.d.ts +55 -267
  29. package/dist/index.js +327 -1355
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +263 -1325
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/internal.d.mts +86 -0
  34. package/dist/internal.d.ts +86 -0
  35. package/dist/internal.js +32 -0
  36. package/dist/internal.js.map +1 -0
  37. package/dist/internal.mjs +32 -0
  38. package/dist/internal.mjs.map +1 -0
  39. package/dist/polkadot.d.mts +70 -0
  40. package/dist/polkadot.d.ts +70 -0
  41. package/dist/polkadot.js +303 -0
  42. package/dist/polkadot.js.map +1 -0
  43. package/dist/polkadot.mjs +303 -0
  44. package/dist/polkadot.mjs.map +1 -0
  45. package/dist/solana.d.mts +98 -0
  46. package/dist/solana.d.ts +98 -0
  47. package/dist/solana.js +461 -0
  48. package/dist/solana.js.map +1 -0
  49. package/dist/solana.mjs +461 -0
  50. package/dist/solana.mjs.map +1 -0
  51. package/dist/types-C7V7DGlg.d.mts +349 -0
  52. package/dist/types-C7V7DGlg.d.ts +349 -0
  53. package/package.json +104 -18
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/ethereum.js","../src/api/ethereum/accounts.ts","../src/api/ethereum/wallets.ts","../src/api/ethereum/plugin.ts"],"names":["combineLatest","distinctUntilChanged","map","Observable","shareReplay","providerDetails"],"mappings":"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","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/ethereum.js","sourcesContent":[null,"import {\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tof,\n\tReplaySubject,\n\tshareReplay,\n\tswitchMap,\n} from \"rxjs\";\nimport {\n\tcreateWalletClient,\n\tcustom,\n\ttype EIP1193Provider,\n\tgetAddress,\n} from \"viem\";\nimport { getWalletAccountId } from \"../../utils\";\nimport { getCachedObservable$ } from \"../../utils/getCachedObservable\";\nimport type { WalletConnectWallet } from \"../types\";\nimport { isWalletConnectWallet } from \"../types\";\nimport type {\n\tEthereumAccount,\n\tEthereumInjectedWallet,\n\tEthereumWallet,\n} from \"./types\";\n\nconst normalizeEvmChainId = (value: unknown): number | undefined => {\n\tlet raw = value;\n\n\tif (typeof raw === \"string\" && raw.startsWith(\"eip155:\")) {\n\t\traw = raw.slice(\"eip155:\".length);\n\t}\n\n\tif (typeof raw === \"bigint\") {\n\t\treturn raw >= 0n ? Number(raw) : undefined;\n\t}\n\n\tif (typeof raw === \"number\") {\n\t\treturn Number.isInteger(raw) && raw >= 0 ? raw : undefined;\n\t}\n\n\tif (typeof raw === \"string\") {\n\t\tconst normalized = raw.trim().toLowerCase();\n\t\tif (!normalized) return undefined;\n\t\tconst parsed = normalized.startsWith(\"0x\")\n\t\t\t? Number.parseInt(normalized, 16)\n\t\t\t: Number.parseInt(normalized, 10);\n\t\treturn Number.isNaN(parsed) ? undefined : parsed;\n\t}\n\n\treturn undefined;\n};\n\nconst toCaipNetworkId = (value: unknown): string | undefined => {\n\tconst chainId = normalizeEvmChainId(value);\n\treturn chainId === undefined ? undefined : `eip155:${chainId}`;\n};\n\nconst getInjectedWalletAccounts$ = (\n\twallet: EthereumInjectedWallet,\n): Observable<EthereumAccount[]> => {\n\tif (!wallet.isConnected) return of([]);\n\n\treturn getCachedObservable$(`accounts:${wallet.id}`, () =>\n\t\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\t\tconst addresses$ = new ReplaySubject<string[]>(1);\n\t\t\tconst chainId$ = new ReplaySubject<number | undefined>(1);\n\n\t\t\tconst getAccount = (\n\t\t\t\taddress: string,\n\t\t\t\tchainId: number | undefined,\n\t\t\t): EthereumAccount => {\n\t\t\t\tconst client = createWalletClient({\n\t\t\t\t\taccount: address as `0x${string}`,\n\t\t\t\t\ttransport: custom(wallet.provider as EIP1193Provider),\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\tid: getWalletAccountId(wallet.id, address),\n\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\tclient,\n\t\t\t\t\taddress: getAddress(address),\n\t\t\t\t\tchainId,\n\t\t\t\t\twalletName: wallet.name,\n\t\t\t\t\twalletId: wallet.id,\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tconst handleAccountsChanged = (addrs: string[]) => {\n\t\t\t\taddresses$.next(addrs);\n\t\t\t};\n\n\t\t\tconst handleChainChanged = (chainIdHex: unknown) => {\n\t\t\t\tchainId$.next(normalizeEvmChainId(chainIdHex));\n\t\t\t};\n\n\t\t\tconst handleDisconnect = () => {\n\t\t\t\tchainId$.next(undefined);\n\t\t\t};\n\n\t\t\t// Subscribe to provider events\n\t\t\twallet.provider.on(\"accountsChanged\", handleAccountsChanged);\n\t\t\twallet.provider.on(\"chainChanged\", handleChainChanged);\n\t\t\twallet.provider.on(\"disconnect\", handleDisconnect);\n\n\t\t\t// Fetch initial values\n\t\t\twallet.provider\n\t\t\t\t.request({ method: \"eth_accounts\" })\n\t\t\t\t.then((addrs: string[]) => addresses$.next(addrs))\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(\"Failed to get accounts\", err);\n\t\t\t\t\taddresses$.next([]);\n\t\t\t\t});\n\n\t\t\twallet.provider\n\t\t\t\t.request({ method: \"eth_chainId\" })\n\t\t\t\t.then(handleChainChanged)\n\t\t\t\t.catch(() => chainId$.next(undefined));\n\n\t\t\t// Combine addresses + chainId into account list\n\t\t\tconst sub = combineLatest([addresses$, chainId$])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([addresses, chainId]) =>\n\t\t\t\t\t\taddresses.map((addr) => getAccount(addr, chainId)),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber);\n\n\t\t\treturn () => {\n\t\t\t\twallet.provider.removeListener(\n\t\t\t\t\t\"accountsChanged\",\n\t\t\t\t\thandleAccountsChanged,\n\t\t\t\t);\n\t\t\t\twallet.provider.removeListener(\"chainChanged\", handleChainChanged);\n\t\t\t\twallet.provider.removeListener(\"disconnect\", handleDisconnect);\n\t\t\t\tsub.unsubscribe();\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n\nconst wrapWalletConnectProvider = (\n\tprovider: EIP1193Provider,\n\tsessionTopic: string,\n\tcaipNetworkId: string | undefined,\n): EIP1193Provider => {\n\treturn new Proxy(provider, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (prop !== \"request\") return Reflect.get(target, prop, receiver);\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: EIP-1193 request args\n\t\t\treturn (args: any) => {\n\t\t\t\tif (!args || typeof args !== \"object\" || !args.method)\n\t\t\t\t\treturn target.request(args);\n\t\t\t\t// Build a new object rather than mutating the caller's args: the\n\t\t\t\t// EIP-1193 request object is owned by viem and may be frozen or reused.\n\t\t\t\tconst next = { ...args };\n\t\t\t\tif (next.topic === undefined) next.topic = sessionTopic;\n\t\t\t\tif (next.chainId === undefined && caipNetworkId !== undefined)\n\t\t\t\t\tnext.chainId = caipNetworkId;\n\t\t\t\treturn target.request(next);\n\t\t\t};\n\t\t},\n\t});\n};\n\nconst sameAddresses = (a: string[], b: string[]) =>\n\ta.length === b.length && a.every((addr, i) => addr === b[i]);\n\nconst getWalletConnectAccounts$ = (\n\twallet: WalletConnectWallet,\n): Observable<EthereumAccount[]> => {\n\tconst provider = wallet.appKit.getProvider(\"eip155\");\n\n\tif (!wallet.platforms.includes(\"ethereum\") || !provider?.session)\n\t\treturn of([]);\n\n\treturn getCachedObservable$(`accounts:${wallet.id}:ethereum:`, () =>\n\t\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\t\tconst caipNetworkId$ = new ReplaySubject<string | undefined>(1);\n\t\t\tconst addresses$ = new ReplaySubject<string[]>(1);\n\n\t\t\t// AppKit's getAccount(\"eip155\").allAccounts is empty because this AppKit\n\t\t\t// instance has no native eip155 adapter — eip155 runs through the\n\t\t\t// WalletConnect UniversalProvider, so the session is the source of truth\n\t\t\t// (mirrors the polkadot/solana AppKit paths). Accounts are CAIP-10 strings\n\t\t\t// (\"eip155:<chainRef>:<address>\"), one entry per chain, so dedupe to unique\n\t\t\t// addresses. Read live on each change so switching/adding accounts is\n\t\t\t// reflected.\n\t\t\tconst readAddresses = (): string[] => {\n\t\t\t\tconst session = provider.session;\n\t\t\t\tif (!session) return [];\n\t\t\t\tconst addresses = new Set<string>();\n\t\t\t\tfor (const namespace of Object.values(session.namespaces)) {\n\t\t\t\t\tfor (const account of namespace.accounts ?? []) {\n\t\t\t\t\t\tif (!account.startsWith(\"eip155:\")) continue;\n\t\t\t\t\t\tconst raw = account.split(\":\")[2];\n\t\t\t\t\t\tif (!raw) continue;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\taddresses.add(getAddress(raw));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// skip malformed CAIP-10 address\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn [...addresses];\n\t\t\t};\n\n\t\t\t// Derive the CAIP network id from the session's eip155 CAIP-10 accounts\n\t\t\t// (\"eip155:<ref>:<addr>\") as a synchronous fallback for eth_chainId.\n\t\t\tconst readCaipNetworkId = (): string | undefined => {\n\t\t\t\tconst session = provider.session;\n\t\t\t\tif (!session) return undefined;\n\t\t\t\tfor (const namespace of Object.values(session.namespaces)) {\n\t\t\t\t\tfor (const account of namespace.accounts ?? []) {\n\t\t\t\t\t\tif (!account.startsWith(\"eip155:\")) continue;\n\t\t\t\t\t\tconst ref = account.split(\":\")[1];\n\t\t\t\t\t\tif (ref) return `eip155:${ref}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t};\n\n\t\t\tconst handleChainChanged = (chainId: unknown) => {\n\t\t\t\tconst caipNetworkId = toCaipNetworkId(chainId);\n\t\t\t\tif (caipNetworkId) {\n\t\t\t\t\tcaipNetworkId$.next(caipNetworkId);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleAccountsChanged = () => addresses$.next(readAddresses());\n\n\t\t\tprovider.on(\"chainChanged\", handleChainChanged);\n\t\t\tprovider.on(\"accountsChanged\", handleAccountsChanged);\n\t\t\tprovider.on(\"session_update\", handleAccountsChanged);\n\t\t\t// Seed the chain id from the session synchronously so the account list can\n\t\t\t// surface even if eth_chainId never resolves; eth_chainId then refines it.\n\t\t\t// Without this seed, combineLatest below never fires when eth_chainId\n\t\t\t// rejects or returns an unparseable value, and the accounts silently never\n\t\t\t// appear (the injected path seeds undefined on failure for the same reason).\n\t\t\tcaipNetworkId$.next(readCaipNetworkId());\n\t\t\tprovider\n\t\t\t\t.request({ method: \"eth_chainId\" })\n\t\t\t\t.then(handleChainChanged)\n\t\t\t\t.catch(() => {});\n\t\t\taddresses$.next(readAddresses());\n\n\t\t\tconst sub = combineLatest([\n\t\t\t\tcaipNetworkId$.pipe(distinctUntilChanged()),\n\t\t\t\taddresses$.pipe(distinctUntilChanged(sameAddresses)),\n\t\t\t])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([caipNetworkId, addresses]) => {\n\t\t\t\t\t\tconst chainId = normalizeEvmChainId(caipNetworkId);\n\t\t\t\t\t\tconst transport = custom(\n\t\t\t\t\t\t\twrapWalletConnectProvider(\n\t\t\t\t\t\t\t\tprovider as unknown as EIP1193Provider,\n\t\t\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: legacy\n\t\t\t\t\t\t\t\tprovider.session!.topic,\n\t\t\t\t\t\t\t\tcaipNetworkId,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn addresses.map((addr): EthereumAccount => {\n\t\t\t\t\t\t\tconst client = createWalletClient({\n\t\t\t\t\t\t\t\taccount: addr as `0x${string}`,\n\t\t\t\t\t\t\t\ttransport,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tid: getWalletAccountId(wallet.id, addr),\n\t\t\t\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\t\t\t\twalletName: wallet.name,\n\t\t\t\t\t\t\t\twalletId: wallet.id,\n\t\t\t\t\t\t\t\taddress: addr as `0x${string}`,\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t\tchainId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber);\n\n\t\t\treturn () => {\n\t\t\t\tprovider.off(\"chainChanged\", handleChainChanged);\n\t\t\t\tprovider.off(\"accountsChanged\", handleAccountsChanged);\n\t\t\t\tprovider.off(\"session_update\", handleAccountsChanged);\n\t\t\t\tsub.unsubscribe();\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n\nexport const getEthereumAccounts$ = (\n\tethereumWallets: Observable<(EthereumWallet | WalletConnectWallet)[]>,\n) =>\n\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\tconst sub = ethereumWallets\n\t\t\t.pipe(\n\t\t\t\tmap((wallets) => wallets.filter((w) => w.isConnected)),\n\t\t\t\tswitchMap((wallets) => {\n\t\t\t\t\treturn wallets.length\n\t\t\t\t\t\t? combineLatest([\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter((w) => w.type === \"injected\")\n\t\t\t\t\t\t\t\t\t.map(getInjectedWalletAccounts$),\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter(isWalletConnectWallet)\n\t\t\t\t\t\t\t\t\t.map(getWalletConnectAccounts$),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t: of([]);\n\t\t\t\t}),\n\t\t\t\tmap((accounts) => accounts.flat()),\n\t\t\t\tdistinctUntilChanged(isSameAccountsList),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(\n\t\t// logObservable(\"ethereumAccounts$\", true),\n\t\tshareReplay({ refCount: true, bufferSize: 1 }),\n\t);\n\nconst isSameAccountsList = (a: EthereumAccount[], b: EthereumAccount[]) => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(account, i) =>\n\t\t\taccount.id === b[i]?.id && account.chainId === b[i]?.chainId,\n\t);\n};\n","import {\n\tcreateStore as createMipdStore,\n\ttype EIP6963ProviderDetail,\n} from \"mipd\";\nimport {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n} from \"rxjs\";\nimport type { EIP1193Provider } from \"viem\";\nimport { clearCachedObservable } from \"../../utils/getCachedObservable\";\nimport { getWalletId, type WalletId } from \"../../utils/WalletId\";\nimport { KheopskitError } from \"../errors\";\nimport { store as defaultStore, type KheopskitStore } from \"../store\";\nimport type { EthereumInjectedWallet } from \"./types\";\n\n/**\n * Observable that emits EIP-6963 provider details from injected wallets.\n * Returns empty array during SSR since browser wallet APIs are not available.\n */\nconst providersDetails$ = new Observable<EIP6963ProviderDetail[]>(\n\t(subscriber) => {\n\t\t// Guard against SSR - mipd requires browser APIs\n\t\tif (typeof window === \"undefined\") {\n\t\t\tsubscriber.next([]);\n\t\t\treturn () => {};\n\t\t}\n\n\t\tconst mipdStore = createMipdStore();\n\n\t\tconst unsubscribe = mipdStore.subscribe((providerDetails) => {\n\t\t\tsubscriber.next(providerDetails as EIP6963ProviderDetail[]);\n\t\t});\n\n\t\tconst providerDetails = mipdStore.getProviders();\n\n\t\tsubscriber.next(providerDetails as EIP6963ProviderDetail[]);\n\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tmipdStore.destroy();\n\t\t};\n\t},\n).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n\nconst createEthereumInjectedWallets$ = (store: KheopskitStore) =>\n\tnew Observable<EthereumInjectedWallet[]>((subscriber) => {\n\t\tconst enabledWalletIds$ = new BehaviorSubject<Set<WalletId>>(new Set());\n\n\t\tconst connectWallet = async (\n\t\t\twalletId: WalletId,\n\t\t\tprovider: EIP1193Provider,\n\t\t) => {\n\t\t\tif (enabledWalletIds$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_ALREADY_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is already connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\n\t\t\tawait provider.request({\n\t\t\t\tmethod: \"eth_requestAccounts\",\n\t\t\t});\n\n\t\t\tconst newSet = new Set(enabledWalletIds$.value);\n\t\t\tnewSet.add(walletId);\n\t\t\tenabledWalletIds$.next(newSet);\n\n\t\t\tstore.addEnabledWalletId(walletId);\n\t\t};\n\n\t\tconst disconnectWallet = async (walletId: WalletId) => {\n\t\t\tif (!enabledWalletIds$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_NOT_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is not connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\t\t\tconst newSet = new Set(enabledWalletIds$.value);\n\t\t\tnewSet.delete(walletId);\n\t\t\tenabledWalletIds$.next(newSet);\n\n\t\t\tstore.removeEnabledWalletId(walletId);\n\n\t\t\t// Drop the cached account observable so a later reconnect rebuilds it\n\t\t\t// against the current provider, not a stale closure.\n\t\t\tclearCachedObservable(`accounts:${walletId}`);\n\t\t};\n\n\t\tconst sub = combineLatest([providersDetails$, enabledWalletIds$])\n\t\t\t.pipe(\n\t\t\t\tmap(([providerDetails, enabledWalletIds]) => {\n\t\t\t\t\treturn providerDetails.map((pd): EthereumInjectedWallet => {\n\t\t\t\t\t\tconst walletId = getWalletId(\"ethereum\", pd.info.rdns);\n\t\t\t\t\t\tconst provider = pd.provider as EIP1193Provider;\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\t\t\ttype: \"injected\",\n\t\t\t\t\t\t\tid: walletId,\n\t\t\t\t\t\t\tname: pd.info.name,\n\t\t\t\t\t\t\ticon: pd.info.icon,\n\t\t\t\t\t\t\tprovider,\n\t\t\t\t\t\t\tisConnected: enabledWalletIds.has(walletId),\n\t\t\t\t\t\t\tsourceId: pd.info.rdns,\n\t\t\t\t\t\t\tconnect: () => connectWallet(walletId, provider),\n\t\t\t\t\t\t\tdisconnect: () => disconnectWallet(walletId),\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t\tdistinctUntilChanged(walletsEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n\n// The shared WalletConnect connector is emitted once by core (see\n// `getWallets$`), not per platform — so this returns only injected wallets.\nexport const getEthereumWallets$ = (store: KheopskitStore = defaultStore) =>\n\tcreateEthereumInjectedWallets$(store);\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n */\nconst walletsEqual = (\n\ta: EthereumInjectedWallet[],\n\tb: EthereumInjectedWallet[],\n): boolean => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(w, i) =>\n\t\t\tw.id === b[i]?.id &&\n\t\t\tw.isConnected === b[i]?.isConnected &&\n\t\t\tw.name === b[i]?.name,\n\t);\n};\n","import type { KheopskitPlatform, PlatformContext } from \"../types\";\nimport { getEthereumAccounts$ } from \"./accounts\";\nimport type { EthereumAccount, EthereumWallet } from \"./types\";\nimport { getEthereumWallets$ } from \"./wallets\";\n\n/**\n * Ethereum platform plugin. Pass to `getKheopskit$({ platforms: [ethereum()] })`.\n *\n * @example\n * ```ts\n * import { ethereum } from \"@kheopskit/core/ethereum\";\n * ethereum();\n * ```\n */\nexport const ethereum = (): KheopskitPlatform<\n\t\"ethereum\",\n\tEthereumWallet,\n\tEthereumAccount\n> => ({\n\tplatform: \"ethereum\",\n\tgetWallets$: (ctx: PlatformContext) => getEthereumWallets$(ctx.store),\n\tgetAccounts$: (wallets$) => getEthereumAccounts$(wallets$),\n});\n"]}
@@ -0,0 +1,351 @@
1
+ import {
2
+ KheopskitError,
3
+ getWalletAccountId,
4
+ isEthereumAddress,
5
+ store
6
+ } from "./chunk-6XAZANB5.mjs";
7
+ import {
8
+ clearCachedObservable,
9
+ getCachedObservable$,
10
+ getWalletId,
11
+ isInjectedWallet,
12
+ isWalletConnectWallet
13
+ } from "./chunk-7QSGAJ4A.mjs";
14
+
15
+ // src/api/ethereum/accounts.ts
16
+ import {
17
+ combineLatest,
18
+ distinctUntilChanged,
19
+ map,
20
+ Observable,
21
+ of,
22
+ ReplaySubject,
23
+ shareReplay,
24
+ switchMap
25
+ } from "rxjs";
26
+ import {
27
+ createWalletClient,
28
+ custom,
29
+ getAddress
30
+ } from "viem";
31
+ var normalizeEvmChainId = (value) => {
32
+ let raw = value;
33
+ if (typeof raw === "string" && raw.startsWith("eip155:")) {
34
+ raw = raw.slice("eip155:".length);
35
+ }
36
+ if (typeof raw === "bigint") {
37
+ return raw >= 0n ? Number(raw) : void 0;
38
+ }
39
+ if (typeof raw === "number") {
40
+ return Number.isInteger(raw) && raw >= 0 ? raw : void 0;
41
+ }
42
+ if (typeof raw === "string") {
43
+ const normalized = raw.trim().toLowerCase();
44
+ if (!normalized) return void 0;
45
+ const parsed = normalized.startsWith("0x") ? Number.parseInt(normalized, 16) : Number.parseInt(normalized, 10);
46
+ return Number.isNaN(parsed) ? void 0 : parsed;
47
+ }
48
+ return void 0;
49
+ };
50
+ var toCaipNetworkId = (value) => {
51
+ const chainId = normalizeEvmChainId(value);
52
+ return chainId === void 0 ? void 0 : `eip155:${chainId}`;
53
+ };
54
+ var getInjectedWalletAccounts$ = (wallet) => {
55
+ if (!wallet.isConnected) return of([]);
56
+ return getCachedObservable$(
57
+ `accounts:${wallet.id}`,
58
+ () => new Observable((subscriber) => {
59
+ const addresses$ = new ReplaySubject(1);
60
+ const chainId$ = new ReplaySubject(1);
61
+ const getAccount = (address, chainId) => {
62
+ const client = createWalletClient({
63
+ account: address,
64
+ transport: custom(wallet.provider)
65
+ });
66
+ return {
67
+ id: getWalletAccountId(wallet.id, address),
68
+ platform: "ethereum",
69
+ client,
70
+ address: getAddress(address),
71
+ chainId,
72
+ walletName: wallet.name,
73
+ walletId: wallet.id
74
+ };
75
+ };
76
+ const handleAccountsChanged = (addrs) => {
77
+ addresses$.next(addrs);
78
+ };
79
+ const handleChainChanged = (chainIdHex) => {
80
+ chainId$.next(normalizeEvmChainId(chainIdHex));
81
+ };
82
+ const handleDisconnect = () => {
83
+ chainId$.next(void 0);
84
+ };
85
+ wallet.provider.on("accountsChanged", handleAccountsChanged);
86
+ wallet.provider.on("chainChanged", handleChainChanged);
87
+ wallet.provider.on("disconnect", handleDisconnect);
88
+ wallet.provider.request({ method: "eth_accounts" }).then((addrs) => addresses$.next(addrs)).catch((err) => {
89
+ console.error("Failed to get accounts", err);
90
+ addresses$.next([]);
91
+ });
92
+ wallet.provider.request({ method: "eth_chainId" }).then(handleChainChanged).catch(() => chainId$.next(void 0));
93
+ const sub = combineLatest([addresses$, chainId$]).pipe(
94
+ map(
95
+ ([addresses, chainId]) => addresses.map((addr) => getAccount(addr, chainId))
96
+ )
97
+ ).subscribe(subscriber);
98
+ return () => {
99
+ wallet.provider.removeListener(
100
+ "accountsChanged",
101
+ handleAccountsChanged
102
+ );
103
+ wallet.provider.removeListener("chainChanged", handleChainChanged);
104
+ wallet.provider.removeListener("disconnect", handleDisconnect);
105
+ sub.unsubscribe();
106
+ };
107
+ }).pipe(shareReplay({ refCount: true, bufferSize: 1 }))
108
+ );
109
+ };
110
+ var wrapWalletConnectProvider = (provider, sessionTopic, caipNetworkId) => {
111
+ return new Proxy(provider, {
112
+ get(target, prop, receiver) {
113
+ if (prop !== "request") return Reflect.get(target, prop, receiver);
114
+ return (args) => {
115
+ if (!args || typeof args !== "object" || !args.method)
116
+ return target.request(args);
117
+ const next = { ...args };
118
+ if (next.topic === void 0) next.topic = sessionTopic;
119
+ if (next.chainId === void 0 && caipNetworkId !== void 0)
120
+ next.chainId = caipNetworkId;
121
+ return target.request(next);
122
+ };
123
+ }
124
+ });
125
+ };
126
+ var sameAddresses = (a, b) => a.length === b.length && a.every((addr, i) => addr === b[i]);
127
+ var getWalletConnectAccounts$ = (wallet) => {
128
+ const provider = wallet.appKit.getProvider("eip155");
129
+ if (!wallet.platforms.includes("ethereum") || !provider?.session)
130
+ return of([]);
131
+ return getCachedObservable$(
132
+ `accounts:${wallet.id}:ethereum:`,
133
+ () => new Observable((subscriber) => {
134
+ const caipNetworkId$ = new ReplaySubject(1);
135
+ const addresses$ = new ReplaySubject(1);
136
+ const readAddresses = () => {
137
+ const session = provider.session;
138
+ if (!session) return [];
139
+ const addresses = /* @__PURE__ */ new Set();
140
+ for (const namespace of Object.values(session.namespaces)) {
141
+ for (const account of namespace.accounts ?? []) {
142
+ if (!account.startsWith("eip155:")) continue;
143
+ const raw = account.split(":")[2];
144
+ if (!raw) continue;
145
+ try {
146
+ addresses.add(getAddress(raw));
147
+ } catch {
148
+ }
149
+ }
150
+ }
151
+ return [...addresses];
152
+ };
153
+ const readCaipNetworkId = () => {
154
+ const session = provider.session;
155
+ if (!session) return void 0;
156
+ for (const namespace of Object.values(session.namespaces)) {
157
+ for (const account of namespace.accounts ?? []) {
158
+ if (!account.startsWith("eip155:")) continue;
159
+ const ref = account.split(":")[1];
160
+ if (ref) return `eip155:${ref}`;
161
+ }
162
+ }
163
+ return void 0;
164
+ };
165
+ const handleChainChanged = (chainId) => {
166
+ const caipNetworkId = toCaipNetworkId(chainId);
167
+ if (caipNetworkId) {
168
+ caipNetworkId$.next(caipNetworkId);
169
+ }
170
+ };
171
+ const handleAccountsChanged = () => addresses$.next(readAddresses());
172
+ provider.on("chainChanged", handleChainChanged);
173
+ provider.on("accountsChanged", handleAccountsChanged);
174
+ provider.on("session_update", handleAccountsChanged);
175
+ caipNetworkId$.next(readCaipNetworkId());
176
+ provider.request({ method: "eth_chainId" }).then(handleChainChanged).catch(() => {
177
+ });
178
+ addresses$.next(readAddresses());
179
+ const sub = combineLatest([
180
+ caipNetworkId$.pipe(distinctUntilChanged()),
181
+ addresses$.pipe(distinctUntilChanged(sameAddresses))
182
+ ]).pipe(
183
+ map(([caipNetworkId, addresses]) => {
184
+ const chainId = normalizeEvmChainId(caipNetworkId);
185
+ const transport = custom(
186
+ wrapWalletConnectProvider(
187
+ provider,
188
+ // biome-ignore lint/style/noNonNullAssertion: legacy
189
+ provider.session.topic,
190
+ caipNetworkId
191
+ )
192
+ );
193
+ return addresses.map((addr) => {
194
+ const client = createWalletClient({
195
+ account: addr,
196
+ transport
197
+ });
198
+ return {
199
+ id: getWalletAccountId(wallet.id, addr),
200
+ platform: "ethereum",
201
+ walletName: wallet.name,
202
+ walletId: wallet.id,
203
+ address: addr,
204
+ client,
205
+ chainId
206
+ };
207
+ });
208
+ })
209
+ ).subscribe(subscriber);
210
+ return () => {
211
+ provider.off("chainChanged", handleChainChanged);
212
+ provider.off("accountsChanged", handleAccountsChanged);
213
+ provider.off("session_update", handleAccountsChanged);
214
+ sub.unsubscribe();
215
+ };
216
+ }).pipe(shareReplay({ refCount: true, bufferSize: 1 }))
217
+ );
218
+ };
219
+ var getEthereumAccounts$ = (ethereumWallets) => new Observable((subscriber) => {
220
+ const sub = ethereumWallets.pipe(
221
+ map((wallets) => wallets.filter((w) => w.isConnected)),
222
+ switchMap((wallets) => {
223
+ return wallets.length ? combineLatest([
224
+ ...wallets.filter((w) => w.type === "injected").map(getInjectedWalletAccounts$),
225
+ ...wallets.filter(isWalletConnectWallet).map(getWalletConnectAccounts$)
226
+ ]) : of([]);
227
+ }),
228
+ map((accounts) => accounts.flat()),
229
+ distinctUntilChanged(isSameAccountsList)
230
+ ).subscribe(subscriber);
231
+ return () => {
232
+ sub.unsubscribe();
233
+ };
234
+ }).pipe(
235
+ // logObservable("ethereumAccounts$", true),
236
+ shareReplay({ refCount: true, bufferSize: 1 })
237
+ );
238
+ var isSameAccountsList = (a, b) => {
239
+ if (a.length !== b.length) return false;
240
+ return a.every(
241
+ (account, i) => account.id === b[i]?.id && account.chainId === b[i]?.chainId
242
+ );
243
+ };
244
+
245
+ // src/api/ethereum/wallets.ts
246
+ import {
247
+ createStore as createMipdStore
248
+ } from "mipd";
249
+ import {
250
+ BehaviorSubject,
251
+ combineLatest as combineLatest2,
252
+ distinctUntilChanged as distinctUntilChanged2,
253
+ map as map2,
254
+ Observable as Observable2,
255
+ shareReplay as shareReplay2
256
+ } from "rxjs";
257
+ var providersDetails$ = new Observable2(
258
+ (subscriber) => {
259
+ if (typeof window === "undefined") {
260
+ subscriber.next([]);
261
+ return () => {
262
+ };
263
+ }
264
+ const mipdStore = createMipdStore();
265
+ const unsubscribe = mipdStore.subscribe((providerDetails2) => {
266
+ subscriber.next(providerDetails2);
267
+ });
268
+ const providerDetails = mipdStore.getProviders();
269
+ subscriber.next(providerDetails);
270
+ return () => {
271
+ unsubscribe();
272
+ mipdStore.destroy();
273
+ };
274
+ }
275
+ ).pipe(shareReplay2({ refCount: true, bufferSize: 1 }));
276
+ var createEthereumInjectedWallets$ = (store2) => new Observable2((subscriber) => {
277
+ const enabledWalletIds$ = new BehaviorSubject(/* @__PURE__ */ new Set());
278
+ const connectWallet = async (walletId, provider) => {
279
+ if (enabledWalletIds$.value.has(walletId))
280
+ throw new KheopskitError(
281
+ "WALLET_ALREADY_CONNECTED",
282
+ `wallet ${walletId} is already connected`,
283
+ { walletId }
284
+ );
285
+ await provider.request({
286
+ method: "eth_requestAccounts"
287
+ });
288
+ const newSet = new Set(enabledWalletIds$.value);
289
+ newSet.add(walletId);
290
+ enabledWalletIds$.next(newSet);
291
+ store2.addEnabledWalletId(walletId);
292
+ };
293
+ const disconnectWallet = async (walletId) => {
294
+ if (!enabledWalletIds$.value.has(walletId))
295
+ throw new KheopskitError(
296
+ "WALLET_NOT_CONNECTED",
297
+ `wallet ${walletId} is not connected`,
298
+ { walletId }
299
+ );
300
+ const newSet = new Set(enabledWalletIds$.value);
301
+ newSet.delete(walletId);
302
+ enabledWalletIds$.next(newSet);
303
+ store2.removeEnabledWalletId(walletId);
304
+ clearCachedObservable(`accounts:${walletId}`);
305
+ };
306
+ const sub = combineLatest2([providersDetails$, enabledWalletIds$]).pipe(
307
+ map2(([providerDetails, enabledWalletIds]) => {
308
+ return providerDetails.map((pd) => {
309
+ const walletId = getWalletId("ethereum", pd.info.rdns);
310
+ const provider = pd.provider;
311
+ return {
312
+ platform: "ethereum",
313
+ type: "injected",
314
+ id: walletId,
315
+ name: pd.info.name,
316
+ icon: pd.info.icon,
317
+ provider,
318
+ isConnected: enabledWalletIds.has(walletId),
319
+ sourceId: pd.info.rdns,
320
+ connect: () => connectWallet(walletId, provider),
321
+ disconnect: () => disconnectWallet(walletId)
322
+ };
323
+ });
324
+ }),
325
+ distinctUntilChanged2(walletsEqual)
326
+ ).subscribe(subscriber);
327
+ return () => {
328
+ sub.unsubscribe();
329
+ };
330
+ }).pipe(shareReplay2({ refCount: true, bufferSize: 1 }));
331
+ var getEthereumWallets$ = (store2 = store) => createEthereumInjectedWallets$(store2);
332
+ var walletsEqual = (a, b) => {
333
+ if (a.length !== b.length) return false;
334
+ return a.every(
335
+ (w, i) => w.id === b[i]?.id && w.isConnected === b[i]?.isConnected && w.name === b[i]?.name
336
+ );
337
+ };
338
+
339
+ // src/api/ethereum/plugin.ts
340
+ var ethereum = () => ({
341
+ platform: "ethereum",
342
+ getWallets$: (ctx) => getEthereumWallets$(ctx.store),
343
+ getAccounts$: (wallets$) => getEthereumAccounts$(wallets$)
344
+ });
345
+ export {
346
+ ethereum,
347
+ isEthereumAddress,
348
+ isInjectedWallet,
349
+ isWalletConnectWallet
350
+ };
351
+ //# sourceMappingURL=ethereum.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/ethereum/accounts.ts","../src/api/ethereum/wallets.ts","../src/api/ethereum/plugin.ts"],"sourcesContent":["import {\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tof,\n\tReplaySubject,\n\tshareReplay,\n\tswitchMap,\n} from \"rxjs\";\nimport {\n\tcreateWalletClient,\n\tcustom,\n\ttype EIP1193Provider,\n\tgetAddress,\n} from \"viem\";\nimport { getWalletAccountId } from \"../../utils\";\nimport { getCachedObservable$ } from \"../../utils/getCachedObservable\";\nimport type { WalletConnectWallet } from \"../types\";\nimport { isWalletConnectWallet } from \"../types\";\nimport type {\n\tEthereumAccount,\n\tEthereumInjectedWallet,\n\tEthereumWallet,\n} from \"./types\";\n\nconst normalizeEvmChainId = (value: unknown): number | undefined => {\n\tlet raw = value;\n\n\tif (typeof raw === \"string\" && raw.startsWith(\"eip155:\")) {\n\t\traw = raw.slice(\"eip155:\".length);\n\t}\n\n\tif (typeof raw === \"bigint\") {\n\t\treturn raw >= 0n ? Number(raw) : undefined;\n\t}\n\n\tif (typeof raw === \"number\") {\n\t\treturn Number.isInteger(raw) && raw >= 0 ? raw : undefined;\n\t}\n\n\tif (typeof raw === \"string\") {\n\t\tconst normalized = raw.trim().toLowerCase();\n\t\tif (!normalized) return undefined;\n\t\tconst parsed = normalized.startsWith(\"0x\")\n\t\t\t? Number.parseInt(normalized, 16)\n\t\t\t: Number.parseInt(normalized, 10);\n\t\treturn Number.isNaN(parsed) ? undefined : parsed;\n\t}\n\n\treturn undefined;\n};\n\nconst toCaipNetworkId = (value: unknown): string | undefined => {\n\tconst chainId = normalizeEvmChainId(value);\n\treturn chainId === undefined ? undefined : `eip155:${chainId}`;\n};\n\nconst getInjectedWalletAccounts$ = (\n\twallet: EthereumInjectedWallet,\n): Observable<EthereumAccount[]> => {\n\tif (!wallet.isConnected) return of([]);\n\n\treturn getCachedObservable$(`accounts:${wallet.id}`, () =>\n\t\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\t\tconst addresses$ = new ReplaySubject<string[]>(1);\n\t\t\tconst chainId$ = new ReplaySubject<number | undefined>(1);\n\n\t\t\tconst getAccount = (\n\t\t\t\taddress: string,\n\t\t\t\tchainId: number | undefined,\n\t\t\t): EthereumAccount => {\n\t\t\t\tconst client = createWalletClient({\n\t\t\t\t\taccount: address as `0x${string}`,\n\t\t\t\t\ttransport: custom(wallet.provider as EIP1193Provider),\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\tid: getWalletAccountId(wallet.id, address),\n\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\tclient,\n\t\t\t\t\taddress: getAddress(address),\n\t\t\t\t\tchainId,\n\t\t\t\t\twalletName: wallet.name,\n\t\t\t\t\twalletId: wallet.id,\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tconst handleAccountsChanged = (addrs: string[]) => {\n\t\t\t\taddresses$.next(addrs);\n\t\t\t};\n\n\t\t\tconst handleChainChanged = (chainIdHex: unknown) => {\n\t\t\t\tchainId$.next(normalizeEvmChainId(chainIdHex));\n\t\t\t};\n\n\t\t\tconst handleDisconnect = () => {\n\t\t\t\tchainId$.next(undefined);\n\t\t\t};\n\n\t\t\t// Subscribe to provider events\n\t\t\twallet.provider.on(\"accountsChanged\", handleAccountsChanged);\n\t\t\twallet.provider.on(\"chainChanged\", handleChainChanged);\n\t\t\twallet.provider.on(\"disconnect\", handleDisconnect);\n\n\t\t\t// Fetch initial values\n\t\t\twallet.provider\n\t\t\t\t.request({ method: \"eth_accounts\" })\n\t\t\t\t.then((addrs: string[]) => addresses$.next(addrs))\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(\"Failed to get accounts\", err);\n\t\t\t\t\taddresses$.next([]);\n\t\t\t\t});\n\n\t\t\twallet.provider\n\t\t\t\t.request({ method: \"eth_chainId\" })\n\t\t\t\t.then(handleChainChanged)\n\t\t\t\t.catch(() => chainId$.next(undefined));\n\n\t\t\t// Combine addresses + chainId into account list\n\t\t\tconst sub = combineLatest([addresses$, chainId$])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([addresses, chainId]) =>\n\t\t\t\t\t\taddresses.map((addr) => getAccount(addr, chainId)),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber);\n\n\t\t\treturn () => {\n\t\t\t\twallet.provider.removeListener(\n\t\t\t\t\t\"accountsChanged\",\n\t\t\t\t\thandleAccountsChanged,\n\t\t\t\t);\n\t\t\t\twallet.provider.removeListener(\"chainChanged\", handleChainChanged);\n\t\t\t\twallet.provider.removeListener(\"disconnect\", handleDisconnect);\n\t\t\t\tsub.unsubscribe();\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n\nconst wrapWalletConnectProvider = (\n\tprovider: EIP1193Provider,\n\tsessionTopic: string,\n\tcaipNetworkId: string | undefined,\n): EIP1193Provider => {\n\treturn new Proxy(provider, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (prop !== \"request\") return Reflect.get(target, prop, receiver);\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: EIP-1193 request args\n\t\t\treturn (args: any) => {\n\t\t\t\tif (!args || typeof args !== \"object\" || !args.method)\n\t\t\t\t\treturn target.request(args);\n\t\t\t\t// Build a new object rather than mutating the caller's args: the\n\t\t\t\t// EIP-1193 request object is owned by viem and may be frozen or reused.\n\t\t\t\tconst next = { ...args };\n\t\t\t\tif (next.topic === undefined) next.topic = sessionTopic;\n\t\t\t\tif (next.chainId === undefined && caipNetworkId !== undefined)\n\t\t\t\t\tnext.chainId = caipNetworkId;\n\t\t\t\treturn target.request(next);\n\t\t\t};\n\t\t},\n\t});\n};\n\nconst sameAddresses = (a: string[], b: string[]) =>\n\ta.length === b.length && a.every((addr, i) => addr === b[i]);\n\nconst getWalletConnectAccounts$ = (\n\twallet: WalletConnectWallet,\n): Observable<EthereumAccount[]> => {\n\tconst provider = wallet.appKit.getProvider(\"eip155\");\n\n\tif (!wallet.platforms.includes(\"ethereum\") || !provider?.session)\n\t\treturn of([]);\n\n\treturn getCachedObservable$(`accounts:${wallet.id}:ethereum:`, () =>\n\t\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\t\tconst caipNetworkId$ = new ReplaySubject<string | undefined>(1);\n\t\t\tconst addresses$ = new ReplaySubject<string[]>(1);\n\n\t\t\t// AppKit's getAccount(\"eip155\").allAccounts is empty because this AppKit\n\t\t\t// instance has no native eip155 adapter — eip155 runs through the\n\t\t\t// WalletConnect UniversalProvider, so the session is the source of truth\n\t\t\t// (mirrors the polkadot/solana AppKit paths). Accounts are CAIP-10 strings\n\t\t\t// (\"eip155:<chainRef>:<address>\"), one entry per chain, so dedupe to unique\n\t\t\t// addresses. Read live on each change so switching/adding accounts is\n\t\t\t// reflected.\n\t\t\tconst readAddresses = (): string[] => {\n\t\t\t\tconst session = provider.session;\n\t\t\t\tif (!session) return [];\n\t\t\t\tconst addresses = new Set<string>();\n\t\t\t\tfor (const namespace of Object.values(session.namespaces)) {\n\t\t\t\t\tfor (const account of namespace.accounts ?? []) {\n\t\t\t\t\t\tif (!account.startsWith(\"eip155:\")) continue;\n\t\t\t\t\t\tconst raw = account.split(\":\")[2];\n\t\t\t\t\t\tif (!raw) continue;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\taddresses.add(getAddress(raw));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// skip malformed CAIP-10 address\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn [...addresses];\n\t\t\t};\n\n\t\t\t// Derive the CAIP network id from the session's eip155 CAIP-10 accounts\n\t\t\t// (\"eip155:<ref>:<addr>\") as a synchronous fallback for eth_chainId.\n\t\t\tconst readCaipNetworkId = (): string | undefined => {\n\t\t\t\tconst session = provider.session;\n\t\t\t\tif (!session) return undefined;\n\t\t\t\tfor (const namespace of Object.values(session.namespaces)) {\n\t\t\t\t\tfor (const account of namespace.accounts ?? []) {\n\t\t\t\t\t\tif (!account.startsWith(\"eip155:\")) continue;\n\t\t\t\t\t\tconst ref = account.split(\":\")[1];\n\t\t\t\t\t\tif (ref) return `eip155:${ref}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t};\n\n\t\t\tconst handleChainChanged = (chainId: unknown) => {\n\t\t\t\tconst caipNetworkId = toCaipNetworkId(chainId);\n\t\t\t\tif (caipNetworkId) {\n\t\t\t\t\tcaipNetworkId$.next(caipNetworkId);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst handleAccountsChanged = () => addresses$.next(readAddresses());\n\n\t\t\tprovider.on(\"chainChanged\", handleChainChanged);\n\t\t\tprovider.on(\"accountsChanged\", handleAccountsChanged);\n\t\t\tprovider.on(\"session_update\", handleAccountsChanged);\n\t\t\t// Seed the chain id from the session synchronously so the account list can\n\t\t\t// surface even if eth_chainId never resolves; eth_chainId then refines it.\n\t\t\t// Without this seed, combineLatest below never fires when eth_chainId\n\t\t\t// rejects or returns an unparseable value, and the accounts silently never\n\t\t\t// appear (the injected path seeds undefined on failure for the same reason).\n\t\t\tcaipNetworkId$.next(readCaipNetworkId());\n\t\t\tprovider\n\t\t\t\t.request({ method: \"eth_chainId\" })\n\t\t\t\t.then(handleChainChanged)\n\t\t\t\t.catch(() => {});\n\t\t\taddresses$.next(readAddresses());\n\n\t\t\tconst sub = combineLatest([\n\t\t\t\tcaipNetworkId$.pipe(distinctUntilChanged()),\n\t\t\t\taddresses$.pipe(distinctUntilChanged(sameAddresses)),\n\t\t\t])\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(([caipNetworkId, addresses]) => {\n\t\t\t\t\t\tconst chainId = normalizeEvmChainId(caipNetworkId);\n\t\t\t\t\t\tconst transport = custom(\n\t\t\t\t\t\t\twrapWalletConnectProvider(\n\t\t\t\t\t\t\t\tprovider as unknown as EIP1193Provider,\n\t\t\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: legacy\n\t\t\t\t\t\t\t\tprovider.session!.topic,\n\t\t\t\t\t\t\t\tcaipNetworkId,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn addresses.map((addr): EthereumAccount => {\n\t\t\t\t\t\t\tconst client = createWalletClient({\n\t\t\t\t\t\t\t\taccount: addr as `0x${string}`,\n\t\t\t\t\t\t\t\ttransport,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tid: getWalletAccountId(wallet.id, addr),\n\t\t\t\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\t\t\t\twalletName: wallet.name,\n\t\t\t\t\t\t\t\twalletId: wallet.id,\n\t\t\t\t\t\t\t\taddress: addr as `0x${string}`,\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t\tchainId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe(subscriber);\n\n\t\t\treturn () => {\n\t\t\t\tprovider.off(\"chainChanged\", handleChainChanged);\n\t\t\t\tprovider.off(\"accountsChanged\", handleAccountsChanged);\n\t\t\t\tprovider.off(\"session_update\", handleAccountsChanged);\n\t\t\t\tsub.unsubscribe();\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n\nexport const getEthereumAccounts$ = (\n\tethereumWallets: Observable<(EthereumWallet | WalletConnectWallet)[]>,\n) =>\n\tnew Observable<EthereumAccount[]>((subscriber) => {\n\t\tconst sub = ethereumWallets\n\t\t\t.pipe(\n\t\t\t\tmap((wallets) => wallets.filter((w) => w.isConnected)),\n\t\t\t\tswitchMap((wallets) => {\n\t\t\t\t\treturn wallets.length\n\t\t\t\t\t\t? combineLatest([\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter((w) => w.type === \"injected\")\n\t\t\t\t\t\t\t\t\t.map(getInjectedWalletAccounts$),\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter(isWalletConnectWallet)\n\t\t\t\t\t\t\t\t\t.map(getWalletConnectAccounts$),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t: of([]);\n\t\t\t\t}),\n\t\t\t\tmap((accounts) => accounts.flat()),\n\t\t\t\tdistinctUntilChanged(isSameAccountsList),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(\n\t\t// logObservable(\"ethereumAccounts$\", true),\n\t\tshareReplay({ refCount: true, bufferSize: 1 }),\n\t);\n\nconst isSameAccountsList = (a: EthereumAccount[], b: EthereumAccount[]) => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(account, i) =>\n\t\t\taccount.id === b[i]?.id && account.chainId === b[i]?.chainId,\n\t);\n};\n","import {\n\tcreateStore as createMipdStore,\n\ttype EIP6963ProviderDetail,\n} from \"mipd\";\nimport {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n} from \"rxjs\";\nimport type { EIP1193Provider } from \"viem\";\nimport { clearCachedObservable } from \"../../utils/getCachedObservable\";\nimport { getWalletId, type WalletId } from \"../../utils/WalletId\";\nimport { KheopskitError } from \"../errors\";\nimport { store as defaultStore, type KheopskitStore } from \"../store\";\nimport type { EthereumInjectedWallet } from \"./types\";\n\n/**\n * Observable that emits EIP-6963 provider details from injected wallets.\n * Returns empty array during SSR since browser wallet APIs are not available.\n */\nconst providersDetails$ = new Observable<EIP6963ProviderDetail[]>(\n\t(subscriber) => {\n\t\t// Guard against SSR - mipd requires browser APIs\n\t\tif (typeof window === \"undefined\") {\n\t\t\tsubscriber.next([]);\n\t\t\treturn () => {};\n\t\t}\n\n\t\tconst mipdStore = createMipdStore();\n\n\t\tconst unsubscribe = mipdStore.subscribe((providerDetails) => {\n\t\t\tsubscriber.next(providerDetails as EIP6963ProviderDetail[]);\n\t\t});\n\n\t\tconst providerDetails = mipdStore.getProviders();\n\n\t\tsubscriber.next(providerDetails as EIP6963ProviderDetail[]);\n\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tmipdStore.destroy();\n\t\t};\n\t},\n).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n\nconst createEthereumInjectedWallets$ = (store: KheopskitStore) =>\n\tnew Observable<EthereumInjectedWallet[]>((subscriber) => {\n\t\tconst enabledWalletIds$ = new BehaviorSubject<Set<WalletId>>(new Set());\n\n\t\tconst connectWallet = async (\n\t\t\twalletId: WalletId,\n\t\t\tprovider: EIP1193Provider,\n\t\t) => {\n\t\t\tif (enabledWalletIds$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_ALREADY_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is already connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\n\t\t\tawait provider.request({\n\t\t\t\tmethod: \"eth_requestAccounts\",\n\t\t\t});\n\n\t\t\tconst newSet = new Set(enabledWalletIds$.value);\n\t\t\tnewSet.add(walletId);\n\t\t\tenabledWalletIds$.next(newSet);\n\n\t\t\tstore.addEnabledWalletId(walletId);\n\t\t};\n\n\t\tconst disconnectWallet = async (walletId: WalletId) => {\n\t\t\tif (!enabledWalletIds$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_NOT_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is not connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\t\t\tconst newSet = new Set(enabledWalletIds$.value);\n\t\t\tnewSet.delete(walletId);\n\t\t\tenabledWalletIds$.next(newSet);\n\n\t\t\tstore.removeEnabledWalletId(walletId);\n\n\t\t\t// Drop the cached account observable so a later reconnect rebuilds it\n\t\t\t// against the current provider, not a stale closure.\n\t\t\tclearCachedObservable(`accounts:${walletId}`);\n\t\t};\n\n\t\tconst sub = combineLatest([providersDetails$, enabledWalletIds$])\n\t\t\t.pipe(\n\t\t\t\tmap(([providerDetails, enabledWalletIds]) => {\n\t\t\t\t\treturn providerDetails.map((pd): EthereumInjectedWallet => {\n\t\t\t\t\t\tconst walletId = getWalletId(\"ethereum\", pd.info.rdns);\n\t\t\t\t\t\tconst provider = pd.provider as EIP1193Provider;\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tplatform: \"ethereum\",\n\t\t\t\t\t\t\ttype: \"injected\",\n\t\t\t\t\t\t\tid: walletId,\n\t\t\t\t\t\t\tname: pd.info.name,\n\t\t\t\t\t\t\ticon: pd.info.icon,\n\t\t\t\t\t\t\tprovider,\n\t\t\t\t\t\t\tisConnected: enabledWalletIds.has(walletId),\n\t\t\t\t\t\t\tsourceId: pd.info.rdns,\n\t\t\t\t\t\t\tconnect: () => connectWallet(walletId, provider),\n\t\t\t\t\t\t\tdisconnect: () => disconnectWallet(walletId),\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t\tdistinctUntilChanged(walletsEqual),\n\t\t\t)\n\t\t\t.subscribe(subscriber);\n\n\t\treturn () => {\n\t\t\tsub.unsubscribe();\n\t\t};\n\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 }));\n\n// The shared WalletConnect connector is emitted once by core (see\n// `getWallets$`), not per platform — so this returns only injected wallets.\nexport const getEthereumWallets$ = (store: KheopskitStore = defaultStore) =>\n\tcreateEthereumInjectedWallets$(store);\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n */\nconst walletsEqual = (\n\ta: EthereumInjectedWallet[],\n\tb: EthereumInjectedWallet[],\n): boolean => {\n\tif (a.length !== b.length) return false;\n\treturn a.every(\n\t\t(w, i) =>\n\t\t\tw.id === b[i]?.id &&\n\t\t\tw.isConnected === b[i]?.isConnected &&\n\t\t\tw.name === b[i]?.name,\n\t);\n};\n","import type { KheopskitPlatform, PlatformContext } from \"../types\";\nimport { getEthereumAccounts$ } from \"./accounts\";\nimport type { EthereumAccount, EthereumWallet } from \"./types\";\nimport { getEthereumWallets$ } from \"./wallets\";\n\n/**\n * Ethereum platform plugin. Pass to `getKheopskit$({ platforms: [ethereum()] })`.\n *\n * @example\n * ```ts\n * import { ethereum } from \"@kheopskit/core/ethereum\";\n * ethereum();\n * ```\n */\nexport const ethereum = (): KheopskitPlatform<\n\t\"ethereum\",\n\tEthereumWallet,\n\tEthereumAccount\n> => ({\n\tplatform: \"ethereum\",\n\tgetWallets$: (ctx: PlatformContext) => getEthereumWallets$(ctx.store),\n\tgetAccounts$: (wallets$) => getEthereumAccounts$(wallets$),\n});\n"],"mappings":"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","names":["combineLatest","distinctUntilChanged","map","Observable","shareReplay","Observable","providerDetails","shareReplay","store","combineLatest","map","distinctUntilChanged"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Clears an observable from the cache.
3
+ * Use when a wallet disconnects or configuration changes.
4
+ */
5
+ declare const clearCachedObservable: (key: string) => void;
6
+ /**
7
+ * Clears all cached observables whose key starts with `prefix`.
8
+ *
9
+ * Used to drop a wallet's account observables when it disconnects, so a later
10
+ * reconnect rebuilds them against the current wallet handle instead of a stale
11
+ * closure — and to keep the cache from growing unbounded across connect cycles.
12
+ */
13
+ declare const clearCachedObservablesByPrefix: (prefix: string) => void;
14
+ /**
15
+ * Clears all cached observables.
16
+ * Use when resetting the entire kheopskit state.
17
+ */
18
+ declare const clearAllCachedObservables: () => void;
19
+
20
+ export { clearCachedObservable as a, clearCachedObservablesByPrefix as b, clearAllCachedObservables as c };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Clears an observable from the cache.
3
+ * Use when a wallet disconnects or configuration changes.
4
+ */
5
+ declare const clearCachedObservable: (key: string) => void;
6
+ /**
7
+ * Clears all cached observables whose key starts with `prefix`.
8
+ *
9
+ * Used to drop a wallet's account observables when it disconnects, so a later
10
+ * reconnect rebuilds them against the current wallet handle instead of a stale
11
+ * closure — and to keep the cache from growing unbounded across connect cycles.
12
+ */
13
+ declare const clearCachedObservablesByPrefix: (prefix: string) => void;
14
+ /**
15
+ * Clears all cached observables.
16
+ * Use when resetting the entire kheopskit state.
17
+ */
18
+ declare const clearAllCachedObservables: () => void;
19
+
20
+ export { clearCachedObservable as a, clearCachedObservablesByPrefix as b, clearAllCachedObservables as c };