@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,86 @@
1
+ import { C as CachedAccount, K as KheopskitPlatform, h as BaseWalletAccount, j as CachedWallet, B as BaseWallet, b as WalletConnectWallet } from './types-C7V7DGlg.js';
2
+ export { a as clearCachedObservable, b as clearCachedObservablesByPrefix } from './getCachedObservable-C4E8dfMp.js';
3
+ import 'rxjs';
4
+
5
+ type Storage = {
6
+ getItem: (key: string) => string | null;
7
+ setItem: (key: string, value: string) => void;
8
+ removeItem: (key: string) => void;
9
+ };
10
+ /**
11
+ * Extended storage interface with cross-tab sync support.
12
+ */
13
+ type SyncableStorage = Storage & {
14
+ /**
15
+ * Subscribe to storage changes from other tabs.
16
+ * Returns an unsubscribe function.
17
+ */
18
+ subscribe?: (key: string, callback: (value: string | null) => void) => () => void;
19
+ };
20
+ /**
21
+ * A safe localStorage wrapper that falls back to noopStorage
22
+ * when localStorage is not available (e.g., during SSR).
23
+ * Includes cross-tab sync via the native 'storage' event.
24
+ *
25
+ * Lazily initialized on first access to be SSR-safe.
26
+ */
27
+ declare const getSafeLocalStorage: () => SyncableStorage;
28
+
29
+ /**
30
+ * Whether a cached account should survive SSR hydration, per its platform
31
+ * plugin's `acceptsCachedAccount` hook. Plugins without the hook (and platforms
32
+ * with no enabled plugin) accept all — matching the pre-plugin behavior where
33
+ * only Polkadot accounts were filtered (by key type).
34
+ */
35
+ declare const acceptsCachedAccount: (cached: CachedAccount, platforms: readonly KheopskitPlatform[]) => boolean;
36
+
37
+ /**
38
+ * Converts a CachedWallet to a placeholder wallet for SSR hydration display.
39
+ *
40
+ * The placeholder carries only the SDK-free {@link BaseWallet} fields; the real
41
+ * wallet (with its injected provider/extension/standard-wallet handle) replaces
42
+ * it once it loads. connect/disconnect throw until then.
43
+ */
44
+ declare const hydrateWallet: (cached: CachedWallet) => BaseWallet | WalletConnectWallet;
45
+ /**
46
+ * Converts a CachedAccount to a placeholder account for SSR hydration display.
47
+ *
48
+ * The placeholder carries the SDK-free {@link BaseWalletAccount} fields plus the
49
+ * plain, serializable platform data that lives in the cache — Ethereum `chainId`
50
+ * and the Polkadot key `type`. Those render immediately on reload (no blank →
51
+ * value flicker) and match what the live account will report. Only the SDK
52
+ * handles (`client`/`signer`/`polkadotSigner`) are absent until the real account
53
+ * replaces this placeholder; signing stays gated on `isHydrating` until then.
54
+ */
55
+ declare const hydrateAccount: (cached: CachedAccount) => BaseWalletAccount;
56
+ /**
57
+ * Converts a wallet to a CachedWallet for storage.
58
+ * Only extracts the serializable properties needed for hydration.
59
+ */
60
+ declare const serializeWallet: (wallet: BaseWallet | WalletConnectWallet) => CachedWallet;
61
+ /**
62
+ * Converts an account to a CachedAccount for storage.
63
+ * Only extracts the serializable properties needed for hydration. Platform-only
64
+ * fields (Ethereum chainId, Polkadot key type) are read defensively so this
65
+ * stays SDK-free.
66
+ */
67
+ declare const serializeAccount: (account: BaseWalletAccount) => CachedAccount;
68
+
69
+ /**
70
+ * Gets a cached icon for a wallet.
71
+ * @param walletId - The wallet ID (e.g., "ethereum:io.talisman")
72
+ * @returns The cached icon data URI, or undefined if not cached
73
+ */
74
+ declare const getCachedIcon: (walletId: string) => string | undefined;
75
+ /**
76
+ * Sets multiple cached icons at once.
77
+ * More efficient than calling setCachedIcon multiple times.
78
+ * @param icons - Map of wallet ID to icon
79
+ */
80
+ declare const setCachedIcons: (icons: Record<string, string>) => void;
81
+
82
+ declare const sortAccounts: (a1: BaseWalletAccount, a2: BaseWalletAccount) => number;
83
+
84
+ declare const sortWallets: (w1: BaseWallet | WalletConnectWallet, w2: BaseWallet | WalletConnectWallet) => number;
85
+
86
+ export { acceptsCachedAccount, getCachedIcon, getSafeLocalStorage, hydrateAccount, hydrateWallet, serializeAccount, serializeWallet, setCachedIcons, sortAccounts, sortWallets };
@@ -0,0 +1,32 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+ var _chunkB4L6GAYDjs = require('./chunk-B4L6GAYD.js');
12
+ require('./chunk-D3EQMFZ2.js');
13
+
14
+
15
+
16
+
17
+ var _chunk4ENHC7G4js = require('./chunk-4ENHC7G4.js');
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ exports.acceptsCachedAccount = _chunkB4L6GAYDjs.acceptsCachedAccount; exports.clearCachedObservable = _chunk4ENHC7G4js.clearCachedObservable; exports.clearCachedObservablesByPrefix = _chunk4ENHC7G4js.clearCachedObservablesByPrefix; exports.getCachedIcon = _chunkB4L6GAYDjs.getCachedIcon; exports.getSafeLocalStorage = _chunk4ENHC7G4js.getSafeLocalStorage; exports.hydrateAccount = _chunkB4L6GAYDjs.hydrateAccount; exports.hydrateWallet = _chunkB4L6GAYDjs.hydrateWallet; exports.serializeAccount = _chunkB4L6GAYDjs.serializeAccount; exports.serializeWallet = _chunkB4L6GAYDjs.serializeWallet; exports.setCachedIcons = _chunkB4L6GAYDjs.setCachedIcons; exports.sortAccounts = _chunkB4L6GAYDjs.sortAccounts; exports.sortWallets = _chunkB4L6GAYDjs.sortWallets;
32
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/internal.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,mvBAAC","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/internal.js"}
@@ -0,0 +1,32 @@
1
+ import {
2
+ acceptsCachedAccount,
3
+ getCachedIcon,
4
+ hydrateAccount,
5
+ hydrateWallet,
6
+ serializeAccount,
7
+ serializeWallet,
8
+ setCachedIcons,
9
+ sortAccounts,
10
+ sortWallets
11
+ } from "./chunk-YDLCHYHH.mjs";
12
+ import "./chunk-BWUUHUDK.mjs";
13
+ import {
14
+ clearCachedObservable,
15
+ clearCachedObservablesByPrefix,
16
+ getSafeLocalStorage
17
+ } from "./chunk-7QSGAJ4A.mjs";
18
+ export {
19
+ acceptsCachedAccount,
20
+ clearCachedObservable,
21
+ clearCachedObservablesByPrefix,
22
+ getCachedIcon,
23
+ getSafeLocalStorage,
24
+ hydrateAccount,
25
+ hydrateWallet,
26
+ serializeAccount,
27
+ serializeWallet,
28
+ setCachedIcons,
29
+ sortAccounts,
30
+ sortWallets
31
+ };
32
+ //# sourceMappingURL=internal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,70 @@
1
+ import { k as PolkadotAccountType, W as WalletAccountId, a as WalletId, K as KheopskitPlatform } from './types-C7V7DGlg.mjs';
2
+ export { b as WalletConnectWallet, i as isInjectedWallet, c as isWalletConnectWallet } from './types-C7V7DGlg.mjs';
3
+ import { InjectedPolkadotAccount, InjectedExtension } from 'polkadot-api/pjs-signer';
4
+ import 'rxjs';
5
+
6
+ /**
7
+ * Returns true if `address` is a valid SS58-encoded 32-byte account id (the
8
+ * only form Substrate wallets inject), verifying the blake2b-512 checksum.
9
+ *
10
+ * Dependency-free (base58 via @scure/base, blake2b via @noble/hashes) so core
11
+ * stays decoupled from polkadot-api.
12
+ */
13
+ declare const isSs58Address: (address: string) => boolean;
14
+
15
+ type PolkadotInjectedWallet = {
16
+ id: WalletId;
17
+ platform: "polkadot";
18
+ type: "injected";
19
+ /**
20
+ * Stable identifier of the underlying wallet source. For Polkadot this is the
21
+ * injected extension identifier. Named consistently across platforms
22
+ * (Ethereum: EIP-6963 rdns; Solana: Wallet Standard name).
23
+ */
24
+ sourceId: string;
25
+ extension: InjectedExtension | undefined;
26
+ name: string;
27
+ icon: string;
28
+ isConnected: boolean;
29
+ connect: () => Promise<void>;
30
+ disconnect: () => Promise<void>;
31
+ };
32
+ type PolkadotWallet = PolkadotInjectedWallet;
33
+ /**
34
+ * A Polkadot account. Inherits the fields of polkadot-api's
35
+ * `InjectedPolkadotAccount` — notably the signing surface **`polkadotSigner`**
36
+ * (a `PolkadotSigner`) — and narrows `type` to {@link PolkadotAccountType}.
37
+ *
38
+ * Per-platform signing surfaces differ: Ethereum exposes `client` (viem),
39
+ * Solana `signer`/`getSigner(chain)`. `polkadotSigner` is absent while
40
+ * `state.isHydrating` is `true`.
41
+ */
42
+ type PolkadotAccount = Omit<InjectedPolkadotAccount, "type"> & {
43
+ type: PolkadotAccountType;
44
+ id: WalletAccountId;
45
+ platform: "polkadot";
46
+ walletName: string;
47
+ walletId: WalletId;
48
+ };
49
+
50
+ type PolkadotPluginOptions = {
51
+ /**
52
+ * Allowed Polkadot account key types. Accounts with other key types are
53
+ * filtered out from kheopskit state.
54
+ *
55
+ * @default ["sr25519", "ed25519", "ecdsa"]
56
+ */
57
+ accountTypes?: PolkadotAccountType[];
58
+ };
59
+ /**
60
+ * Polkadot platform plugin. Pass to `getKheopskit$({ platforms: [polkadot()] })`.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { polkadot } from "@kheopskit/core/polkadot";
65
+ * polkadot({ accountTypes: ["sr25519", "ed25519", "ecdsa"] });
66
+ * ```
67
+ */
68
+ declare const polkadot: (options?: PolkadotPluginOptions) => KheopskitPlatform<"polkadot", PolkadotWallet, PolkadotAccount>;
69
+
70
+ export { type PolkadotAccount, PolkadotAccountType, type PolkadotInjectedWallet, type PolkadotPluginOptions, type PolkadotWallet, isSs58Address, polkadot };
@@ -0,0 +1,70 @@
1
+ import { k as PolkadotAccountType, W as WalletAccountId, a as WalletId, K as KheopskitPlatform } from './types-C7V7DGlg.js';
2
+ export { b as WalletConnectWallet, i as isInjectedWallet, c as isWalletConnectWallet } from './types-C7V7DGlg.js';
3
+ import { InjectedPolkadotAccount, InjectedExtension } from 'polkadot-api/pjs-signer';
4
+ import 'rxjs';
5
+
6
+ /**
7
+ * Returns true if `address` is a valid SS58-encoded 32-byte account id (the
8
+ * only form Substrate wallets inject), verifying the blake2b-512 checksum.
9
+ *
10
+ * Dependency-free (base58 via @scure/base, blake2b via @noble/hashes) so core
11
+ * stays decoupled from polkadot-api.
12
+ */
13
+ declare const isSs58Address: (address: string) => boolean;
14
+
15
+ type PolkadotInjectedWallet = {
16
+ id: WalletId;
17
+ platform: "polkadot";
18
+ type: "injected";
19
+ /**
20
+ * Stable identifier of the underlying wallet source. For Polkadot this is the
21
+ * injected extension identifier. Named consistently across platforms
22
+ * (Ethereum: EIP-6963 rdns; Solana: Wallet Standard name).
23
+ */
24
+ sourceId: string;
25
+ extension: InjectedExtension | undefined;
26
+ name: string;
27
+ icon: string;
28
+ isConnected: boolean;
29
+ connect: () => Promise<void>;
30
+ disconnect: () => Promise<void>;
31
+ };
32
+ type PolkadotWallet = PolkadotInjectedWallet;
33
+ /**
34
+ * A Polkadot account. Inherits the fields of polkadot-api's
35
+ * `InjectedPolkadotAccount` — notably the signing surface **`polkadotSigner`**
36
+ * (a `PolkadotSigner`) — and narrows `type` to {@link PolkadotAccountType}.
37
+ *
38
+ * Per-platform signing surfaces differ: Ethereum exposes `client` (viem),
39
+ * Solana `signer`/`getSigner(chain)`. `polkadotSigner` is absent while
40
+ * `state.isHydrating` is `true`.
41
+ */
42
+ type PolkadotAccount = Omit<InjectedPolkadotAccount, "type"> & {
43
+ type: PolkadotAccountType;
44
+ id: WalletAccountId;
45
+ platform: "polkadot";
46
+ walletName: string;
47
+ walletId: WalletId;
48
+ };
49
+
50
+ type PolkadotPluginOptions = {
51
+ /**
52
+ * Allowed Polkadot account key types. Accounts with other key types are
53
+ * filtered out from kheopskit state.
54
+ *
55
+ * @default ["sr25519", "ed25519", "ecdsa"]
56
+ */
57
+ accountTypes?: PolkadotAccountType[];
58
+ };
59
+ /**
60
+ * Polkadot platform plugin. Pass to `getKheopskit$({ platforms: [polkadot()] })`.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { polkadot } from "@kheopskit/core/polkadot";
65
+ * polkadot({ accountTypes: ["sr25519", "ed25519", "ecdsa"] });
66
+ * ```
67
+ */
68
+ declare const polkadot: (options?: PolkadotPluginOptions) => KheopskitPlatform<"polkadot", PolkadotWallet, PolkadotAccount>;
69
+
70
+ export { type PolkadotAccount, PolkadotAccountType, type PolkadotInjectedWallet, type PolkadotPluginOptions, type PolkadotWallet, isSs58Address, polkadot };
@@ -0,0 +1,303 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkD3EQMFZ2js = require('./chunk-D3EQMFZ2.js');
4
+
5
+
6
+
7
+
8
+
9
+ var _chunkXQWJM3KCjs = require('./chunk-XQWJM3KC.js');
10
+
11
+
12
+
13
+
14
+
15
+
16
+ var _chunk4ENHC7G4js = require('./chunk-4ENHC7G4.js');
17
+
18
+ // src/api/polkadot/accounts.ts
19
+
20
+
21
+ var _pjssigner = require('polkadot-api/pjs-signer');
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+ var _rxjs = require('rxjs');
31
+ var getInjectedWalletAccounts$ = (wallet) => {
32
+ if (!wallet.isConnected) return _rxjs.of.call(void 0, []);
33
+ return new (0, _rxjs.Observable)((subscriber) => {
34
+ const getAccount = (account) => ({
35
+ id: _chunkXQWJM3KCjs.getWalletAccountId.call(void 0, wallet.id, account.address),
36
+ ...account,
37
+ type: _nullishCoalesce(account.type, () => ( "sr25519")),
38
+ platform: "polkadot",
39
+ walletName: wallet.name,
40
+ walletId: wallet.id
41
+ });
42
+ const extension = wallet.extension;
43
+ const unsubscribe = extension.subscribe((accounts) => {
44
+ subscriber.next(accounts.map(getAccount));
45
+ });
46
+ subscriber.next(extension.getAccounts().map(getAccount));
47
+ return () => {
48
+ return unsubscribe();
49
+ };
50
+ });
51
+ };
52
+ var getAppKitPolkadotSigner = (appKit, address) => {
53
+ const provider = appKit.getProvider("polkadot");
54
+ if (!provider) throw new (0, _chunkXQWJM3KCjs.KheopskitError)("NO_PROVIDER", "No provider found");
55
+ if (!provider.session)
56
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)("NO_SESSION", "No session found");
57
+ return _pjssigner.getPolkadotSignerFromPjs.call(void 0,
58
+ address,
59
+ (transactionPayload) => {
60
+ if (!provider.session)
61
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)("NO_SESSION", "No session found");
62
+ return provider.client.request({
63
+ topic: provider.session.topic,
64
+ chainId: `polkadot:${transactionPayload.genesisHash.substring(2, 34)}`,
65
+ request: {
66
+ method: "polkadot_signTransaction",
67
+ params: {
68
+ address,
69
+ transactionPayload
70
+ }
71
+ }
72
+ });
73
+ },
74
+ async ({ address: address2, data }) => {
75
+ if (!provider.session)
76
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)("NO_SESSION", "No session found");
77
+ const networks = appKit.getCaipNetworks("polkadot");
78
+ const chainId = _optionalChain([networks, 'access', _ => _[0], 'optionalAccess', _2 => _2.caipNetworkId]);
79
+ if (!chainId)
80
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)(
81
+ "NO_SESSION",
82
+ "No CAIP network available for polkadot"
83
+ );
84
+ return provider.client.request({
85
+ topic: provider.session.topic,
86
+ chainId,
87
+ request: {
88
+ method: "polkadot_signMessage",
89
+ params: {
90
+ address: address2,
91
+ message: data
92
+ }
93
+ }
94
+ });
95
+ }
96
+ );
97
+ };
98
+ var getWalletConnectAccounts$ = (wallet) => {
99
+ const provider = wallet.appKit.getProvider("polkadot");
100
+ if (!wallet.platforms.includes("polkadot") || !_optionalChain([provider, 'optionalAccess', _3 => _3.session]))
101
+ return _rxjs.of.call(void 0, []);
102
+ return _chunk4ENHC7G4js.getCachedObservable$.call(void 0,
103
+ `accounts:${wallet.id}:polkadot:`,
104
+ () => new (0, _rxjs.Observable)((subscriber) => {
105
+ const buildAccounts = () => {
106
+ const session = provider.session;
107
+ if (!session) return [];
108
+ const addresses = [
109
+ ...new Set(
110
+ Object.values(session.namespaces).flatMap((namespace) => _nullishCoalesce(namespace.accounts, () => ( []))).filter((account) => account.startsWith("polkadot:")).map((account) => account.split(":")[2]).filter((address) => !!address)
111
+ )
112
+ ];
113
+ return addresses.map(
114
+ (address) => ({
115
+ id: _chunkXQWJM3KCjs.getWalletAccountId.call(void 0, wallet.id, address),
116
+ platform: "polkadot",
117
+ walletName: wallet.name,
118
+ walletId: wallet.id,
119
+ address,
120
+ polkadotSigner: getAppKitPolkadotSigner(wallet.appKit, address),
121
+ genesisHash: null,
122
+ name: `${wallet.name} Polkadot`,
123
+ // WalletConnect (Reown AppKit) doesn't expose account key type;
124
+ // default to sr25519, which is the most common Polkadot key type.
125
+ type: "sr25519"
126
+ })
127
+ );
128
+ };
129
+ subscriber.next(buildAccounts());
130
+ const reemit = () => subscriber.next(buildAccounts());
131
+ provider.on("session_update", reemit);
132
+ provider.on("accountsChanged", reemit);
133
+ return () => {
134
+ provider.off("session_update", reemit);
135
+ provider.off("accountsChanged", reemit);
136
+ };
137
+ }).pipe(_rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 }))
138
+ );
139
+ };
140
+ var getPolkadotAccounts$ = (polkadotWallets$, polkadotAccountTypes) => new (0, _rxjs.Observable)((subscriber) => {
141
+ if (polkadotAccountTypes.length === 0) {
142
+ console.warn(
143
+ "[kheopskit] config.polkadotAccountTypes is empty; all Polkadot accounts will be filtered out."
144
+ );
145
+ }
146
+ const sub = polkadotWallets$.pipe(
147
+ _rxjs.map.call(void 0, (wallets) => wallets.filter((w) => w.isConnected)),
148
+ _rxjs.switchMap.call(void 0,
149
+ (wallets) => wallets.length ? _rxjs.combineLatest.call(void 0, [
150
+ ...wallets.filter((w) => w.type === "injected").map(getInjectedWalletAccounts$),
151
+ ...wallets.filter(_chunk4ENHC7G4js.isWalletConnectWallet).map(getWalletConnectAccounts$)
152
+ ]) : _rxjs.of.call(void 0, [])
153
+ ),
154
+ _rxjs.map.call(void 0,
155
+ (accounts) => accounts.flat().filter((account) => polkadotAccountTypes.includes(account.type))
156
+ ),
157
+ _rxjs.distinctUntilChanged.call(void 0, isSameAccountsList)
158
+ ).subscribe(subscriber);
159
+ return () => {
160
+ sub.unsubscribe();
161
+ };
162
+ }).pipe(_rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 }));
163
+ var isSameAccountsList = (a, b) => {
164
+ if (a.length !== b.length) return false;
165
+ return a.every((account, i) => account.id === _optionalChain([b, 'access', _4 => _4[i], 'optionalAccess', _5 => _5.id]));
166
+ };
167
+
168
+ // src/api/polkadot/wallets.ts
169
+ var _lodashes = require('lodash-es');
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+ var getInjectedWalletsIds = () => typeof window === "undefined" ? [] : _pjssigner.getInjectedExtensions.call(void 0, ).map((name) => _chunk4ENHC7G4js.getWalletId.call(void 0, "polkadot", name));
183
+ var createWalletIdsPoller$ = () => {
184
+ return new (0, _rxjs.Observable)((subscriber) => {
185
+ subscriber.next(getInjectedWalletsIds());
186
+ const intervals = [100, 200, 300, 500];
187
+ let index = 0;
188
+ let timer;
189
+ const poll = () => {
190
+ subscriber.next(getInjectedWalletsIds());
191
+ if (index < intervals.length) {
192
+ const delay = intervals[index++];
193
+ timer = setTimeout(poll, delay);
194
+ }
195
+ };
196
+ if (intervals.length > 0) {
197
+ timer = setTimeout(poll, _nullishCoalesce(intervals[index++], () => ( 100)));
198
+ }
199
+ return () => {
200
+ if (timer !== void 0) clearTimeout(timer);
201
+ };
202
+ }).pipe(
203
+ _rxjs.distinctUntilChanged.call(void 0, _lodashes.isEqual),
204
+ _rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 })
205
+ );
206
+ };
207
+ var createPolkadotInjectedWallets$ = (store2) => new (0, _rxjs.Observable)((subscriber) => {
208
+ const enabledExtensions$ = new (0, _rxjs.BehaviorSubject)(/* @__PURE__ */ new Map());
209
+ const connect = async (walletId) => {
210
+ if (enabledExtensions$.value.has(walletId))
211
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)(
212
+ "WALLET_ALREADY_CONNECTED",
213
+ `wallet ${walletId} is already connected`,
214
+ { walletId }
215
+ );
216
+ const { identifier } = _chunk4ENHC7G4js.parseWalletId.call(void 0, walletId);
217
+ const extension = await _pjssigner.connectInjectedExtension.call(void 0, identifier);
218
+ const newMap = new Map(enabledExtensions$.value);
219
+ newMap.set(walletId, extension);
220
+ enabledExtensions$.next(newMap);
221
+ store2.addEnabledWalletId(walletId);
222
+ };
223
+ const disconnect = async (walletId) => {
224
+ if (!enabledExtensions$.value.has(walletId))
225
+ throw new (0, _chunkXQWJM3KCjs.KheopskitError)(
226
+ "WALLET_NOT_CONNECTED",
227
+ `wallet ${walletId} is not connected`,
228
+ { walletId }
229
+ );
230
+ const newMap = new Map(enabledExtensions$.value);
231
+ newMap.delete(walletId);
232
+ enabledExtensions$.next(newMap);
233
+ store2.removeEnabledWalletId(walletId);
234
+ };
235
+ const walletIds$ = createWalletIdsPoller$();
236
+ const subscription = _rxjs.combineLatest.call(void 0, [walletIds$, enabledExtensions$]).pipe(
237
+ _rxjs.map.call(void 0, ([walletIds, enabledExtensions]) => {
238
+ return walletIds.map((id) => {
239
+ const { identifier } = _chunk4ENHC7G4js.parseWalletId.call(void 0, id);
240
+ const extension = enabledExtensions.get(id);
241
+ const extInfo = _chunkD3EQMFZ2js.POLKADOT_EXTENSIONS[identifier];
242
+ return {
243
+ id,
244
+ type: "injected",
245
+ platform: "polkadot",
246
+ name: _nullishCoalesce(_optionalChain([extInfo, 'optionalAccess', _6 => _6.name]), () => ( identifier)),
247
+ icon: _nullishCoalesce(_optionalChain([extInfo, 'optionalAccess', _7 => _7.icon]), () => ( "")),
248
+ sourceId: identifier,
249
+ extension,
250
+ isConnected: !!extension,
251
+ connect: () => connect(id),
252
+ disconnect: () => disconnect(id)
253
+ };
254
+ });
255
+ }),
256
+ _rxjs.distinctUntilChanged.call(void 0, walletsEqual)
257
+ ).subscribe(subscriber);
258
+ return () => {
259
+ subscription.unsubscribe();
260
+ };
261
+ }).pipe(_rxjs.shareReplay.call(void 0, { refCount: true, bufferSize: 1 }));
262
+ var getPolkadotWallets$ = (store2 = _chunkXQWJM3KCjs.store) => createPolkadotInjectedWallets$(store2);
263
+ var walletsEqual = (a, b) => {
264
+ if (a.length !== b.length) return false;
265
+ return a.every(
266
+ (w, i) => w.id === _optionalChain([b, 'access', _8 => _8[i], 'optionalAccess', _9 => _9.id]) && w.isConnected === _optionalChain([b, 'access', _10 => _10[i], 'optionalAccess', _11 => _11.isConnected]) && w.name === _optionalChain([b, 'access', _12 => _12[i], 'optionalAccess', _13 => _13.name])
267
+ );
268
+ };
269
+
270
+ // src/api/polkadot/plugin.ts
271
+ var DEFAULT_ACCOUNT_TYPES = [
272
+ "sr25519",
273
+ "ed25519",
274
+ "ecdsa"
275
+ ];
276
+ var VALID_ACCOUNT_TYPES = /* @__PURE__ */ new Set([
277
+ "sr25519",
278
+ "ed25519",
279
+ "ecdsa",
280
+ "ethereum"
281
+ ]);
282
+ var polkadot = (options = {}) => {
283
+ const accountTypes = _nullishCoalesce(options.accountTypes, () => ( DEFAULT_ACCOUNT_TYPES));
284
+ const invalid = accountTypes.filter((t) => !VALID_ACCOUNT_TYPES.has(t));
285
+ if (invalid.length > 0) {
286
+ console.warn(
287
+ `[kheopskit] Unknown polkadot accountTypes: ${JSON.stringify(invalid)}. Valid values: "sr25519", "ed25519", "ecdsa", "ethereum".`
288
+ );
289
+ }
290
+ return {
291
+ platform: "polkadot",
292
+ getWallets$: (ctx) => getPolkadotWallets$(ctx.store),
293
+ getAccounts$: (wallets$) => getPolkadotAccounts$(wallets$, accountTypes),
294
+ acceptsCachedAccount: (cached) => accountTypes.includes(_nullishCoalesce(cached.polkadotAccountType, () => ( "sr25519")))
295
+ };
296
+ };
297
+
298
+
299
+
300
+
301
+
302
+ exports.isInjectedWallet = _chunk4ENHC7G4js.isInjectedWallet; exports.isSs58Address = _chunkXQWJM3KCjs.isSs58Address; exports.isWalletConnectWallet = _chunk4ENHC7G4js.isWalletConnectWallet; exports.polkadot = polkadot;
303
+ //# sourceMappingURL=polkadot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/kheopskit/kheopskit/packages/core/dist/polkadot.js","../src/api/polkadot/accounts.ts","../src/api/polkadot/wallets.ts","../src/api/polkadot/plugin.ts"],"names":["address","combineLatest","distinctUntilChanged","map","Observable","shareReplay","store"],"mappings":"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","file":"/home/runner/work/kheopskit/kheopskit/packages/core/dist/polkadot.js","sourcesContent":[null,"import {\n\tgetPolkadotSignerFromPjs,\n\ttype InjectedExtension,\n\ttype InjectedPolkadotAccount,\n} from \"polkadot-api/pjs-signer\";\nimport {\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tof,\n\tshareReplay,\n\tswitchMap,\n} from \"rxjs\";\nimport { getWalletAccountId } from \"../../utils\";\nimport { getCachedObservable$ } from \"../../utils/getCachedObservable\";\nimport { KheopskitError } from \"../errors\";\nimport type {\n\tAppKitInstance,\n\tPolkadotAccountType,\n\tWalletConnectWallet,\n} from \"../types\";\nimport { isWalletConnectWallet } from \"../types\";\nimport type {\n\tPolkadotAccount,\n\tPolkadotInjectedWallet,\n\tPolkadotWallet,\n} from \"./types\";\n\nconst getInjectedWalletAccounts$ = (\n\twallet: PolkadotInjectedWallet,\n): Observable<PolkadotAccount[]> => {\n\tif (!wallet.isConnected) return of([]);\n\n\treturn new Observable<PolkadotAccount[]>((subscriber) => {\n\t\tconst getAccount = (account: InjectedPolkadotAccount): PolkadotAccount => ({\n\t\t\tid: getWalletAccountId(wallet.id, account.address),\n\t\t\t...account,\n\t\t\ttype: account.type ?? \"sr25519\",\n\t\t\tplatform: \"polkadot\",\n\t\t\twalletName: wallet.name,\n\t\t\twalletId: wallet.id,\n\t\t});\n\n\t\tconst extension = wallet.extension as InjectedExtension;\n\n\t\t// subscribe to changes\n\t\tconst unsubscribe = extension.subscribe((accounts) => {\n\t\t\tsubscriber.next(accounts.map(getAccount));\n\t\t});\n\n\t\t// initial value\n\t\tsubscriber.next(extension.getAccounts().map(getAccount));\n\n\t\treturn () => {\n\t\t\treturn unsubscribe();\n\t\t};\n\t});\n};\n\nconst getAppKitPolkadotSigner = (appKit: AppKitInstance, address: string) => {\n\tconst provider = appKit.getProvider(\"polkadot\");\n\tif (!provider) throw new KheopskitError(\"NO_PROVIDER\", \"No provider found\");\n\tif (!provider.session)\n\t\tthrow new KheopskitError(\"NO_SESSION\", \"No session found\");\n\n\treturn getPolkadotSignerFromPjs(\n\t\taddress,\n\t\t(transactionPayload) => {\n\t\t\tif (!provider.session)\n\t\t\t\tthrow new KheopskitError(\"NO_SESSION\", \"No session found\");\n\n\t\t\treturn provider.client.request({\n\t\t\t\ttopic: provider.session.topic,\n\t\t\t\tchainId: `polkadot:${transactionPayload.genesisHash.substring(2, 34)}`,\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: \"polkadot_signTransaction\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\ttransactionPayload,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tasync ({ address, data }) => {\n\t\t\tif (!provider.session)\n\t\t\t\tthrow new KheopskitError(\"NO_SESSION\", \"No session found\");\n\t\t\tconst networks = appKit.getCaipNetworks(\"polkadot\");\n\t\t\tconst chainId = networks[0]?.caipNetworkId;\n\t\t\tif (!chainId)\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"NO_SESSION\",\n\t\t\t\t\t\"No CAIP network available for polkadot\",\n\t\t\t\t);\n\n\t\t\treturn provider.client.request({\n\t\t\t\ttopic: provider.session.topic,\n\t\t\t\tchainId,\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: \"polkadot_signMessage\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tmessage: data,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t);\n};\n\nconst getWalletConnectAccounts$ = (\n\twallet: WalletConnectWallet,\n): Observable<PolkadotAccount[]> => {\n\tconst provider = wallet.appKit.getProvider(\"polkadot\");\n\n\tif (!wallet.platforms.includes(\"polkadot\") || !provider?.session)\n\t\treturn of([]);\n\n\treturn getCachedObservable$(`accounts:${wallet.id}:polkadot:`, () =>\n\t\tnew Observable<PolkadotAccount[]>((subscriber) => {\n\t\t\t// AppKit's getAccount(\"polkadot\").allAccounts is always empty because\n\t\t\t// AppKit has no native polkadot adapter; the WalletConnect session is the\n\t\t\t// source of truth. Accounts are CAIP-10 strings\n\t\t\t// (\"polkadot:<chainRef>:<address>\"), one entry per chain, so dedupe to\n\t\t\t// unique addresses.\n\t\t\tconst buildAccounts = (): PolkadotAccount[] => {\n\t\t\t\tconst session = provider.session;\n\t\t\t\tif (!session) return [];\n\n\t\t\t\tconst addresses = [\n\t\t\t\t\t...new Set(\n\t\t\t\t\t\tObject.values(session.namespaces)\n\t\t\t\t\t\t\t.flatMap((namespace) => namespace.accounts ?? [])\n\t\t\t\t\t\t\t.filter((account) => account.startsWith(\"polkadot:\"))\n\t\t\t\t\t\t\t.map((account) => account.split(\":\")[2])\n\t\t\t\t\t\t\t.filter((address): address is string => !!address),\n\t\t\t\t\t),\n\t\t\t\t];\n\n\t\t\t\treturn addresses.map(\n\t\t\t\t\t(address): PolkadotAccount => ({\n\t\t\t\t\t\tid: getWalletAccountId(wallet.id, address),\n\t\t\t\t\t\tplatform: \"polkadot\",\n\t\t\t\t\t\twalletName: wallet.name,\n\t\t\t\t\t\twalletId: wallet.id,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tpolkadotSigner: getAppKitPolkadotSigner(wallet.appKit, address),\n\t\t\t\t\t\tgenesisHash: null,\n\t\t\t\t\t\tname: `${wallet.name} Polkadot`,\n\t\t\t\t\t\t// WalletConnect (Reown AppKit) doesn't expose account key type;\n\t\t\t\t\t\t// default to sr25519, which is the most common Polkadot key type.\n\t\t\t\t\t\ttype: \"sr25519\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tsubscriber.next(buildAccounts());\n\n\t\t\t// Re-derive when the WalletConnect session's accounts change, mirroring\n\t\t\t// the injected extension's subscribe and the Solana AppKit path.\n\t\t\tconst reemit = () => subscriber.next(buildAccounts());\n\t\t\tprovider.on(\"session_update\", reemit);\n\t\t\tprovider.on(\"accountsChanged\", reemit);\n\n\t\t\treturn () => {\n\t\t\t\tprovider.off(\"session_update\", reemit);\n\t\t\t\tprovider.off(\"accountsChanged\", reemit);\n\t\t\t};\n\t\t}).pipe(shareReplay({ refCount: true, bufferSize: 1 })),\n\t);\n};\n\nexport const getPolkadotAccounts$ = (\n\tpolkadotWallets$: Observable<(PolkadotWallet | WalletConnectWallet)[]>,\n\tpolkadotAccountTypes: PolkadotAccountType[],\n) =>\n\tnew Observable<PolkadotAccount[]>((subscriber) => {\n\t\tif (polkadotAccountTypes.length === 0) {\n\t\t\tconsole.warn(\n\t\t\t\t\"[kheopskit] config.polkadotAccountTypes is empty; all Polkadot accounts will be filtered out.\",\n\t\t\t);\n\t\t}\n\n\t\tconst sub = polkadotWallets$\n\t\t\t.pipe(\n\t\t\t\tmap((wallets) => wallets.filter((w) => w.isConnected)),\n\t\t\t\tswitchMap((wallets) =>\n\t\t\t\t\twallets.length\n\t\t\t\t\t\t? combineLatest([\n\t\t\t\t\t\t\t\t...wallets\n\t\t\t\t\t\t\t\t\t.filter((w) => w.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) =>\n\t\t\t\t\taccounts\n\t\t\t\t\t\t.flat()\n\t\t\t\t\t\t.filter((account) => polkadotAccountTypes.includes(account.type)),\n\t\t\t\t),\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(shareReplay({ refCount: true, bufferSize: 1 }));\n\nconst isSameAccountsList = (a: PolkadotAccount[], b: PolkadotAccount[]) => {\n\tif (a.length !== b.length) return false;\n\treturn a.every((account, i) => account.id === b[i]?.id);\n};\n","import { isEqual } from \"lodash-es\";\nimport {\n\tconnectInjectedExtension,\n\tgetInjectedExtensions,\n\ttype InjectedExtension,\n} from \"polkadot-api/pjs-signer\";\nimport {\n\tBehaviorSubject,\n\tcombineLatest,\n\tdistinctUntilChanged,\n\tmap,\n\tObservable,\n\tshareReplay,\n} from \"rxjs\";\nimport { POLKADOT_EXTENSIONS } from \"../../utils/polkadotExtensions\";\nimport {\n\tgetWalletId,\n\tparseWalletId,\n\ttype WalletId,\n} from \"../../utils/WalletId\";\nimport { KheopskitError } from \"../errors\";\nimport { store as defaultStore, type KheopskitStore } from \"../store\";\nimport type { PolkadotInjectedWallet } from \"./types\";\n\nconst getInjectedWalletsIds = () =>\n\ttypeof window === \"undefined\"\n\t\t? []\n\t\t: getInjectedExtensions().map((name) => getWalletId(\"polkadot\", name));\n\n// Create a polling observable that starts immediately and polls at intervals\nconst createWalletIdsPoller$ = () => {\n\treturn new Observable<WalletId[]>((subscriber) => {\n\t\t// Emit immediately on subscribe\n\t\tsubscriber.next(getInjectedWalletsIds());\n\n\t\t// Poll at shorter intervals initially, then slow down\n\t\tconst intervals = [100, 200, 300, 500];\n\t\tlet index = 0;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\t\tconst poll = () => {\n\t\t\tsubscriber.next(getInjectedWalletsIds());\n\t\t\tif (index < intervals.length) {\n\t\t\t\tconst delay = intervals[index++];\n\t\t\t\ttimer = setTimeout(poll, delay);\n\t\t\t}\n\t\t};\n\n\t\t// Start polling after first immediate emission\n\t\tif (intervals.length > 0) {\n\t\t\ttimer = setTimeout(poll, intervals[index++] ?? 100);\n\t\t}\n\n\t\treturn () => {\n\t\t\t// Cancel any pending poll so it can't fire after unsubscribe.\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t};\n\t}).pipe(\n\t\tdistinctUntilChanged<WalletId[]>(isEqual),\n\t\tshareReplay({ refCount: true, bufferSize: 1 }),\n\t);\n};\n\nconst createPolkadotInjectedWallets$ = (store: KheopskitStore) =>\n\tnew Observable<PolkadotInjectedWallet[]>((subscriber) => {\n\t\tconst enabledExtensions$ = new BehaviorSubject<\n\t\t\tMap<WalletId, InjectedExtension>\n\t\t>(new Map());\n\n\t\tconst connect = async (walletId: WalletId) => {\n\t\t\tif (enabledExtensions$.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\t\t\tconst { identifier } = parseWalletId(walletId);\n\t\t\tconst extension = await connectInjectedExtension(identifier);\n\n\t\t\tconst newMap = new Map(enabledExtensions$.value);\n\t\t\tnewMap.set(walletId, extension);\n\t\t\tenabledExtensions$.next(newMap);\n\n\t\t\tstore.addEnabledWalletId(walletId);\n\t\t};\n\n\t\tconst disconnect = async (walletId: WalletId) => {\n\t\t\tif (!enabledExtensions$.value.has(walletId))\n\t\t\t\tthrow new KheopskitError(\n\t\t\t\t\t\"WALLET_NOT_CONNECTED\",\n\t\t\t\t\t`wallet ${walletId} is not connected`,\n\t\t\t\t\t{ walletId },\n\t\t\t\t);\n\n\t\t\tconst newMap = new Map(enabledExtensions$.value);\n\t\t\tnewMap.delete(walletId);\n\t\t\tenabledExtensions$.next(newMap);\n\n\t\t\tstore.removeEnabledWalletId(walletId);\n\t\t};\n\n\t\tconst walletIds$ = createWalletIdsPoller$();\n\n\t\tconst subscription = combineLatest([walletIds$, enabledExtensions$])\n\t\t\t.pipe(\n\t\t\t\tmap(([walletIds, enabledExtensions]) => {\n\t\t\t\t\treturn walletIds.map((id): PolkadotInjectedWallet => {\n\t\t\t\t\t\tconst { identifier } = parseWalletId(id);\n\t\t\t\t\t\tconst extension = enabledExtensions.get(id);\n\t\t\t\t\t\tconst extInfo = POLKADOT_EXTENSIONS[identifier];\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\ttype: \"injected\",\n\t\t\t\t\t\t\tplatform: \"polkadot\",\n\t\t\t\t\t\t\tname: extInfo?.name ?? identifier,\n\t\t\t\t\t\t\ticon: extInfo?.icon ?? \"\",\n\t\t\t\t\t\t\tsourceId: identifier,\n\t\t\t\t\t\t\textension,\n\t\t\t\t\t\t\tisConnected: !!extension,\n\t\t\t\t\t\t\tconnect: () => connect(id),\n\t\t\t\t\t\t\tdisconnect: () => disconnect(id),\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\tsubscription.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 getPolkadotWallets$ = (store: KheopskitStore = defaultStore) =>\n\tcreatePolkadotInjectedWallets$(store);\n\n/**\n * Compare two wallet arrays by their relevant properties (not functions).\n */\nconst walletsEqual = (\n\ta: PolkadotInjectedWallet[],\n\tb: PolkadotInjectedWallet[],\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 {\n\tKheopskitPlatform,\n\tPlatformContext,\n\tPolkadotAccountType,\n} from \"../types\";\nimport { getPolkadotAccounts$ } from \"./accounts\";\nimport type { PolkadotAccount, PolkadotWallet } from \"./types\";\nimport { getPolkadotWallets$ } from \"./wallets\";\n\nconst DEFAULT_ACCOUNT_TYPES: PolkadotAccountType[] = [\n\t\"sr25519\",\n\t\"ed25519\",\n\t\"ecdsa\",\n];\n\nconst VALID_ACCOUNT_TYPES = new Set<string>([\n\t\"sr25519\",\n\t\"ed25519\",\n\t\"ecdsa\",\n\t\"ethereum\",\n]);\n\nexport type PolkadotPluginOptions = {\n\t/**\n\t * Allowed Polkadot account key types. Accounts with other key types are\n\t * filtered out from kheopskit state.\n\t *\n\t * @default [\"sr25519\", \"ed25519\", \"ecdsa\"]\n\t */\n\taccountTypes?: PolkadotAccountType[];\n};\n\n/**\n * Polkadot platform plugin. Pass to `getKheopskit$({ platforms: [polkadot()] })`.\n *\n * @example\n * ```ts\n * import { polkadot } from \"@kheopskit/core/polkadot\";\n * polkadot({ accountTypes: [\"sr25519\", \"ed25519\", \"ecdsa\"] });\n * ```\n */\nexport const polkadot = (\n\toptions: PolkadotPluginOptions = {},\n): KheopskitPlatform<\"polkadot\", PolkadotWallet, PolkadotAccount> => {\n\tconst accountTypes = options.accountTypes ?? DEFAULT_ACCOUNT_TYPES;\n\n\tconst invalid = accountTypes.filter((t) => !VALID_ACCOUNT_TYPES.has(t));\n\tif (invalid.length > 0) {\n\t\tconsole.warn(\n\t\t\t`[kheopskit] Unknown polkadot accountTypes: ${JSON.stringify(invalid)}. Valid values: \"sr25519\", \"ed25519\", \"ecdsa\", \"ethereum\".`,\n\t\t);\n\t}\n\n\treturn {\n\t\tplatform: \"polkadot\",\n\t\tgetWallets$: (ctx: PlatformContext) => getPolkadotWallets$(ctx.store),\n\t\tgetAccounts$: (wallets$) => getPolkadotAccounts$(wallets$, accountTypes),\n\t\tacceptsCachedAccount: (cached) =>\n\t\t\taccountTypes.includes(cached.polkadotAccountType ?? \"sr25519\"),\n\t};\n};\n"]}