@kheopskit/core 5.0.1 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/errors-Caq2csKx.mjs +181 -0
  2. package/dist/errors-Caq2csKx.mjs.map +1 -0
  3. package/dist/errors-DPw6pc2H.js +222 -0
  4. package/dist/errors-DPw6pc2H.js.map +1 -0
  5. package/dist/ethereum.d.mts +39 -38
  6. package/dist/ethereum.d.ts +39 -38
  7. package/dist/ethereum.js +216 -343
  8. package/dist/ethereum.js.map +1 -1
  9. package/dist/ethereum.mjs +213 -344
  10. package/dist/ethereum.mjs.map +1 -1
  11. package/dist/{getCachedObservable-C4E8dfMp.d.ts → getCachedObservable-LUq9IfEx.d.mts} +5 -2
  12. package/dist/{getCachedObservable-C4E8dfMp.d.mts → getCachedObservable-LUq9IfEx.d.ts} +5 -2
  13. package/dist/iconCache-BSa42Sui.mjs +343 -0
  14. package/dist/iconCache-BSa42Sui.mjs.map +1 -0
  15. package/dist/iconCache-DS4zNiP1.js +396 -0
  16. package/dist/iconCache-DS4zNiP1.js.map +1 -0
  17. package/dist/index.d.mts +98 -36
  18. package/dist/index.d.ts +98 -36
  19. package/dist/index.js +897 -630
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +881 -631
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/injectedWallets-B1MCxAE9.js +148 -0
  24. package/dist/injectedWallets-B1MCxAE9.js.map +1 -0
  25. package/dist/injectedWallets-B3Vysfvr.mjs +119 -0
  26. package/dist/injectedWallets-B3Vysfvr.mjs.map +1 -0
  27. package/dist/internal.d.mts +18 -53
  28. package/dist/internal.d.ts +18 -53
  29. package/dist/internal.js +9 -32
  30. package/dist/internal.mjs +3 -32
  31. package/dist/polkadot.d.mts +37 -36
  32. package/dist/polkadot.d.ts +37 -36
  33. package/dist/polkadot.js +179 -294
  34. package/dist/polkadot.js.map +1 -1
  35. package/dist/polkadot.mjs +176 -295
  36. package/dist/polkadot.mjs.map +1 -1
  37. package/dist/polkadotExtensions-BoVKhNU_.mjs +23 -0
  38. package/dist/polkadotExtensions-BoVKhNU_.mjs.map +1 -0
  39. package/dist/polkadotExtensions-y4J9UzYl.js +28 -0
  40. package/dist/polkadotExtensions-y4J9UzYl.js.map +1 -0
  41. package/dist/solana.d.mts +50 -48
  42. package/dist/solana.d.ts +50 -48
  43. package/dist/solana.js +323 -449
  44. package/dist/solana.js.map +1 -1
  45. package/dist/solana.mjs +316 -449
  46. package/dist/solana.mjs.map +1 -1
  47. package/dist/types-Cb-vuEru.d.mts +330 -0
  48. package/dist/types-Cb-vuEru.d.ts +330 -0
  49. package/dist/types-DKU-SNio.js +169 -0
  50. package/dist/types-DKU-SNio.js.map +1 -0
  51. package/dist/types-jnifAAA0.mjs +104 -0
  52. package/dist/types-jnifAAA0.mjs.map +1 -0
  53. package/package.json +12 -12
  54. package/dist/chunk-4ENHC7G4.js +0 -210
  55. package/dist/chunk-4ENHC7G4.js.map +0 -1
  56. package/dist/chunk-6XAZANB5.mjs +0 -450
  57. package/dist/chunk-6XAZANB5.mjs.map +0 -1
  58. package/dist/chunk-7QSGAJ4A.mjs +0 -210
  59. package/dist/chunk-7QSGAJ4A.mjs.map +0 -1
  60. package/dist/chunk-B4L6GAYD.js +0 -179
  61. package/dist/chunk-B4L6GAYD.js.map +0 -1
  62. package/dist/chunk-BWUUHUDK.mjs +0 -24
  63. package/dist/chunk-BWUUHUDK.mjs.map +0 -1
  64. package/dist/chunk-D3EQMFZ2.js +0 -24
  65. package/dist/chunk-D3EQMFZ2.js.map +0 -1
  66. package/dist/chunk-XQWJM3KC.js +0 -450
  67. package/dist/chunk-XQWJM3KC.js.map +0 -1
  68. package/dist/chunk-YDLCHYHH.mjs +0 -179
  69. package/dist/chunk-YDLCHYHH.mjs.map +0 -1
  70. package/dist/internal.js.map +0 -1
  71. package/dist/internal.mjs.map +0 -1
  72. package/dist/types-C7V7DGlg.d.mts +0 -349
  73. package/dist/types-C7V7DGlg.d.ts +0 -349
package/dist/solana.mjs CHANGED
@@ -1,461 +1,328 @@
1
- import {
2
- KheopskitError,
3
- getWalletAccountId,
4
- isSolanaAddress,
5
- store
6
- } from "./chunk-6XAZANB5.mjs";
7
- import {
8
- clearCachedObservablesByPrefix,
9
- getCachedObservable$,
10
- getWalletId,
11
- isInjectedWallet,
12
- isWalletConnectWallet
13
- } from "./chunk-7QSGAJ4A.mjs";
14
-
15
- // src/api/solana/chains.ts
16
- var DEFAULT_SOLANA_CHAIN = "solana:mainnet";
17
- var SOLANA_CHAIN_IDS = [
18
- "solana:mainnet",
19
- "solana:devnet",
20
- "solana:testnet",
21
- "solana:localnet"
1
+ import { d as getCachedObservable$, i as getWalletId, n as isWalletConnectWallet, t as isInjectedWallet, u as clearCachedObservablesByPrefix } from "./types-jnifAAA0.mjs";
2
+ import { n as getWalletAccountId, o as isSolanaAddress, t as KheopskitError } from "./errors-Caq2csKx.mjs";
3
+ import { a as getWalletConnectSessionAccounts$, i as getSessionCaip10s, n as createPlatformAccounts$, r as getCaip10Addresses, t as createInjectedWallets$ } from "./injectedWallets-B3Vysfvr.mjs";
4
+ import { Observable, of, shareReplay } from "rxjs";
5
+ import { address, getBase58Decoder, getBase58Encoder, getBase64Decoder, getBase64Encoder, getTransactionDecoder, getTransactionEncoder } from "@solana/kit";
6
+ import { getWallets } from "@wallet-standard/app";
7
+ //#region src/api/solana/chains.ts
8
+ const DEFAULT_SOLANA_CHAIN = "solana:mainnet";
9
+ const SOLANA_CHAIN_IDS = [
10
+ "solana:mainnet",
11
+ "solana:devnet",
12
+ "solana:testnet",
13
+ "solana:localnet"
22
14
  ];
23
- var isSolanaChainId = (value) => typeof value === "string" && SOLANA_CHAIN_IDS.includes(value);
24
- var SOLANA_CHAIN_TO_CAIP2 = {
25
- "solana:mainnet": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
26
- "solana:devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
27
- "solana:testnet": "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
28
- };
29
- var getSolanaCaip2 = (chain) => {
30
- const caip2 = SOLANA_CHAIN_TO_CAIP2[chain];
31
- if (!caip2)
32
- throw new KheopskitError(
33
- "UNSUPPORTED_CHAIN",
34
- `Solana chain "${chain}" cannot be used over WalletConnect (no CAIP-2 id).`
35
- );
36
- return caip2;
15
+ const isSolanaChainId = (value) => typeof value === "string" && SOLANA_CHAIN_IDS.includes(value);
16
+ /**
17
+ * Maps Wallet Standard chain ids to the CAIP-2 chain ids used by WalletConnect.
18
+ *
19
+ * CAIP-2 ids use the first 32 characters of the cluster's genesis hash as the
20
+ * reference. The values below match `@reown/appkit/networks` (solana,
21
+ * solanaDevnet, solanaTestnet), which is what AppKit puts in session namespaces.
22
+ *
23
+ * `localnet` has no canonical CAIP-2 id and cannot be used over WalletConnect.
24
+ */
25
+ const SOLANA_CHAIN_TO_CAIP2 = {
26
+ "solana:mainnet": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
27
+ "solana:devnet": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
28
+ "solana:testnet": "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
37
29
  };
38
- var DEPRECATED_CAIP2_TO_SOLANA_CHAIN = {
39
- "solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ": "solana:mainnet",
40
- "solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K": "solana:devnet"
30
+ /**
31
+ * Returns the CAIP-2 chain id for a Solana chain, for use in WalletConnect
32
+ * requests and when reading WalletConnect session namespaces.
33
+ *
34
+ * @throws if the chain has no canonical CAIP-2 id (e.g. localnet)
35
+ */
36
+ const getSolanaCaip2 = (chain) => {
37
+ const caip2 = SOLANA_CHAIN_TO_CAIP2[chain];
38
+ if (!caip2) throw new KheopskitError("UNSUPPORTED_CHAIN", `Solana chain "${chain}" cannot be used over WalletConnect (no CAIP-2 id).`);
39
+ return caip2;
41
40
  };
42
- var CAIP2_TO_SOLANA_CHAIN = {
43
- ...Object.fromEntries(
44
- Object.entries(SOLANA_CHAIN_TO_CAIP2).map(([chain, caip2]) => [
45
- caip2,
46
- chain
47
- ])
48
- ),
49
- ...DEPRECATED_CAIP2_TO_SOLANA_CHAIN
41
+ /**
42
+ * AppKit's *deprecated* CAIP-2 cluster ids (its `deprecatedCaipNetworkId`
43
+ * values). Some wallets still place accounts in the WC session under these, so
44
+ * map them back to a {@link SolanaChainId} instead of silently falling back to
45
+ * the configured chain. Requests always use the current ids from
46
+ * {@link SOLANA_CHAIN_TO_CAIP2}; testnet has no deprecated id.
47
+ */
48
+ const DEPRECATED_CAIP2_TO_SOLANA_CHAIN = {
49
+ "solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ": "solana:mainnet",
50
+ "solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K": "solana:devnet"
50
51
  };
51
- var getSolanaChainIdFromCaip2 = (caip2) => CAIP2_TO_SOLANA_CHAIN[caip2];
52
-
53
- // src/api/solana/accounts.ts
54
- import {
55
- combineLatest,
56
- distinctUntilChanged,
57
- map,
58
- Observable,
59
- of,
60
- shareReplay,
61
- switchMap
62
- } from "rxjs";
63
-
64
- // src/api/solana/signer.ts
65
- import {
66
- address,
67
- getBase58Decoder,
68
- getBase58Encoder,
69
- getBase64Decoder,
70
- getBase64Encoder,
71
- getTransactionDecoder,
72
- getTransactionEncoder
73
- } from "@solana/kit";
74
- var SOLANA_SIGN_MESSAGE = "solana:signMessage";
75
- var SOLANA_SIGN_TRANSACTION = "solana:signTransaction";
76
- var SOLANA_SIGN_AND_SEND_TRANSACTION = "solana:signAndSendTransaction";
77
- var requireFeature = (wallet, name) => {
78
- const feature = wallet.features[name];
79
- if (!feature)
80
- throw new KheopskitError(
81
- "FEATURE_NOT_SUPPORTED",
82
- `wallet "${wallet.name}" does not support ${name}`
83
- );
84
- return feature;
52
+ const CAIP2_TO_SOLANA_CHAIN = {
53
+ ...Object.fromEntries(Object.entries(SOLANA_CHAIN_TO_CAIP2).map(([chain, caip2]) => [caip2, chain])),
54
+ ...DEPRECATED_CAIP2_TO_SOLANA_CHAIN
85
55
  };
86
- var createInjectedSolanaSigner = (wallet, account, chain) => {
87
- const signerAddress = address(account.address);
88
- return {
89
- address: signerAddress,
90
- modifyAndSignMessages: async (messages) => {
91
- const feature = requireFeature(
92
- wallet,
93
- SOLANA_SIGN_MESSAGE
94
- );
95
- const outputs = await feature.signMessage(
96
- ...messages.map((m) => ({ account, message: m.content }))
97
- );
98
- return messages.map((m, i) => {
99
- const output = outputs[i];
100
- if (!output) throw new Error("[kheopskit] missing signMessage output");
101
- return {
102
- content: output.signedMessage,
103
- signatures: {
104
- ...m.signatures,
105
- [signerAddress]: output.signature
106
- }
107
- };
108
- });
109
- },
110
- modifyAndSignTransactions: async (transactions) => {
111
- const feature = requireFeature(
112
- wallet,
113
- SOLANA_SIGN_TRANSACTION
114
- );
115
- const encoder = getTransactionEncoder();
116
- const decoder = getTransactionDecoder();
117
- const outputs = await feature.signTransaction(
118
- ...transactions.map((tx) => ({
119
- account,
120
- transaction: new Uint8Array(encoder.encode(tx)),
121
- chain
122
- }))
123
- );
124
- return transactions.map((_tx, i) => {
125
- const output = outputs[i];
126
- if (!output)
127
- throw new Error("[kheopskit] missing signTransaction output");
128
- return decoder.decode(output.signedTransaction);
129
- });
130
- },
131
- signAndSendTransactions: async (transactions) => {
132
- const feature = requireFeature(
133
- wallet,
134
- SOLANA_SIGN_AND_SEND_TRANSACTION
135
- );
136
- const encoder = getTransactionEncoder();
137
- const outputs = await feature.signAndSendTransaction(
138
- ...transactions.map((tx) => ({
139
- account,
140
- transaction: new Uint8Array(encoder.encode(tx)),
141
- chain
142
- }))
143
- );
144
- return outputs.map((output) => output.signature);
145
- }
146
- };
56
+ /**
57
+ * Maps a CAIP-2 chain id (as found in WalletConnect session namespaces) back to
58
+ * its {@link SolanaChainId}, or `undefined` if it isn't a recognised cluster.
59
+ */
60
+ const getSolanaChainIdFromCaip2 = (caip2) => CAIP2_TO_SOLANA_CHAIN[caip2];
61
+ //#endregion
62
+ //#region src/api/solana/signer.ts
63
+ const SOLANA_SIGN_MESSAGE = "solana:signMessage";
64
+ const SOLANA_SIGN_TRANSACTION = "solana:signTransaction";
65
+ const SOLANA_SIGN_AND_SEND_TRANSACTION = "solana:signAndSendTransaction";
66
+ const requireFeature = (wallet, name) => {
67
+ const feature = wallet.features[name];
68
+ if (!feature) throw new KheopskitError("FEATURE_NOT_SUPPORTED", `wallet "${wallet.name}" does not support ${name}`);
69
+ return feature;
147
70
  };
148
- var createWalletConnectSolanaSigner = (provider, accountAddress, chain) => {
149
- const signerAddress = address(accountAddress);
150
- const request = (method, params) => {
151
- if (!provider.session)
152
- throw new KheopskitError("NO_SESSION", "No session found");
153
- return provider.client.request({
154
- topic: provider.session.topic,
155
- chainId: getSolanaCaip2(chain),
156
- request: { method, params }
157
- });
158
- };
159
- return {
160
- address: signerAddress,
161
- modifyAndSignMessages: async (messages) => {
162
- const toBase58 = getBase58Decoder();
163
- const fromBase58 = getBase58Encoder();
164
- return Promise.all(
165
- messages.map(async (m) => {
166
- const { signature } = await request(
167
- "solana_signMessage",
168
- { pubkey: accountAddress, message: toBase58.decode(m.content) }
169
- );
170
- return {
171
- content: m.content,
172
- signatures: {
173
- ...m.signatures,
174
- [signerAddress]: fromBase58.encode(signature)
175
- }
176
- };
177
- })
178
- );
179
- },
180
- modifyAndSignTransactions: async (transactions) => {
181
- const encoder = getTransactionEncoder();
182
- const decoder = getTransactionDecoder();
183
- const toBase64 = getBase64Decoder();
184
- const fromBase64 = getBase64Encoder();
185
- const fromBase58 = getBase58Encoder();
186
- const signed = await Promise.all(
187
- transactions.map(async (tx) => {
188
- const result = await request("solana_signTransaction", {
189
- transaction: toBase64.decode(encoder.encode(tx))
190
- });
191
- if (result.transaction)
192
- return decoder.decode(fromBase64.encode(result.transaction));
193
- if (result.signature)
194
- return {
195
- ...tx,
196
- signatures: {
197
- ...tx.signatures,
198
- [signerAddress]: fromBase58.encode(
199
- result.signature
200
- )
201
- }
202
- };
203
- throw new Error(
204
- "[kheopskit] solana_signTransaction returned no transaction or signature"
205
- );
206
- })
207
- );
208
- return signed;
209
- },
210
- signAndSendTransactions: async (transactions) => {
211
- const encoder = getTransactionEncoder();
212
- const toBase64 = getBase64Decoder();
213
- const fromBase58 = getBase58Encoder();
214
- return Promise.all(
215
- transactions.map(async (tx) => {
216
- const { signature } = await request(
217
- "solana_signAndSendTransaction",
218
- { transaction: toBase64.decode(encoder.encode(tx)) }
219
- );
220
- return fromBase58.encode(signature);
221
- })
222
- );
223
- }
224
- };
71
+ /**
72
+ * Builds a {@link SolanaSigner} backed by a Wallet Standard wallet's
73
+ * `solana:*` features (injected wallets).
74
+ *
75
+ * Transactions are exchanged as wire bytes; messages and signatures as raw
76
+ * bytes. Calling a method whose feature the wallet does not advertise throws.
77
+ */
78
+ const createInjectedSolanaSigner = (wallet, account, chain) => {
79
+ const signerAddress = address(account.address);
80
+ return {
81
+ address: signerAddress,
82
+ modifyAndSignMessages: async (messages) => {
83
+ const outputs = await requireFeature(wallet, SOLANA_SIGN_MESSAGE).signMessage(...messages.map((m) => ({
84
+ account,
85
+ message: m.content
86
+ })));
87
+ return messages.map((m, i) => {
88
+ const output = outputs[i];
89
+ if (!output) throw new Error("[kheopskit] missing signMessage output");
90
+ return {
91
+ content: output.signedMessage,
92
+ signatures: {
93
+ ...m.signatures,
94
+ [signerAddress]: output.signature
95
+ }
96
+ };
97
+ });
98
+ },
99
+ modifyAndSignTransactions: async (transactions) => {
100
+ const feature = requireFeature(wallet, SOLANA_SIGN_TRANSACTION);
101
+ const encoder = getTransactionEncoder();
102
+ const decoder = getTransactionDecoder();
103
+ const outputs = await feature.signTransaction(...transactions.map((tx) => ({
104
+ account,
105
+ transaction: new Uint8Array(encoder.encode(tx)),
106
+ chain
107
+ })));
108
+ return transactions.map((_tx, i) => {
109
+ const output = outputs[i];
110
+ if (!output) throw new Error("[kheopskit] missing signTransaction output");
111
+ return decoder.decode(output.signedTransaction);
112
+ });
113
+ },
114
+ signAndSendTransactions: async (transactions) => {
115
+ const feature = requireFeature(wallet, SOLANA_SIGN_AND_SEND_TRANSACTION);
116
+ const encoder = getTransactionEncoder();
117
+ return (await feature.signAndSendTransaction(...transactions.map((tx) => ({
118
+ account,
119
+ transaction: new Uint8Array(encoder.encode(tx)),
120
+ chain
121
+ })))).map((output) => output.signature);
122
+ }
123
+ };
225
124
  };
226
-
227
- // src/api/solana/accounts.ts
228
- var getInjectedWalletAccounts$ = (wallet, chain) => {
229
- if (!wallet.isConnected) return of([]);
230
- return getCachedObservable$(
231
- `accounts:${wallet.id}:${chain}`,
232
- () => new Observable((subscriber) => {
233
- const standardWallet = wallet.wallet;
234
- const buildAccounts = () => standardWallet.accounts.map(
235
- (account) => ({
236
- id: getWalletAccountId(wallet.id, account.address),
237
- platform: "solana",
238
- address: account.address,
239
- chains: wallet.chains,
240
- signer: createInjectedSolanaSigner(standardWallet, account, chain),
241
- getSigner: (c) => createInjectedSolanaSigner(standardWallet, account, c),
242
- walletName: wallet.name,
243
- walletId: wallet.id
244
- })
245
- );
246
- subscriber.next(buildAccounts());
247
- const eventsFeature = standardWallet.features["standard:events"];
248
- const off = eventsFeature?.on(
249
- "change",
250
- () => subscriber.next(buildAccounts())
251
- );
252
- return () => {
253
- off?.();
254
- };
255
- }).pipe(shareReplay({ refCount: true, bufferSize: 1 }))
256
- );
125
+ /**
126
+ * Builds a {@link SolanaSigner} backed by a WalletConnect session, adapting the
127
+ * `solana_*` RPC methods to the same interface as the injected signer.
128
+ *
129
+ * The CAIP-2 chain id is derived from {@link SolanaChainId}; transactions are
130
+ * base64-encoded and messages/signatures base58-encoded, per the WalletConnect
131
+ * Solana spec.
132
+ */
133
+ const createWalletConnectSolanaSigner = (provider, accountAddress, chain) => {
134
+ const signerAddress = address(accountAddress);
135
+ const request = (method, params) => {
136
+ if (!provider.session) throw new KheopskitError("NO_SESSION", "No session found");
137
+ return provider.client.request({
138
+ topic: provider.session.topic,
139
+ chainId: getSolanaCaip2(chain),
140
+ request: {
141
+ method,
142
+ params
143
+ }
144
+ });
145
+ };
146
+ return {
147
+ address: signerAddress,
148
+ modifyAndSignMessages: async (messages) => {
149
+ const toBase58 = getBase58Decoder();
150
+ const fromBase58 = getBase58Encoder();
151
+ return Promise.all(messages.map(async (m) => {
152
+ const { signature } = await request("solana_signMessage", {
153
+ pubkey: accountAddress,
154
+ message: toBase58.decode(m.content)
155
+ });
156
+ return {
157
+ content: m.content,
158
+ signatures: {
159
+ ...m.signatures,
160
+ [signerAddress]: fromBase58.encode(signature)
161
+ }
162
+ };
163
+ }));
164
+ },
165
+ modifyAndSignTransactions: async (transactions) => {
166
+ const encoder = getTransactionEncoder();
167
+ const decoder = getTransactionDecoder();
168
+ const toBase64 = getBase64Decoder();
169
+ const fromBase64 = getBase64Encoder();
170
+ const fromBase58 = getBase58Encoder();
171
+ return await Promise.all(transactions.map(async (tx) => {
172
+ const result = await request("solana_signTransaction", { transaction: toBase64.decode(encoder.encode(tx)) });
173
+ if (result.transaction) return decoder.decode(fromBase64.encode(result.transaction));
174
+ if (result.signature) return {
175
+ ...tx,
176
+ signatures: {
177
+ ...tx.signatures,
178
+ [signerAddress]: fromBase58.encode(result.signature)
179
+ }
180
+ };
181
+ throw new Error("[kheopskit] solana_signTransaction returned no transaction or signature");
182
+ }));
183
+ },
184
+ signAndSendTransactions: async (transactions) => {
185
+ const encoder = getTransactionEncoder();
186
+ const toBase64 = getBase64Decoder();
187
+ const fromBase58 = getBase58Encoder();
188
+ return Promise.all(transactions.map(async (tx) => {
189
+ const { signature } = await request("solana_signAndSendTransaction", { transaction: toBase64.decode(encoder.encode(tx)) });
190
+ return fromBase58.encode(signature);
191
+ }));
192
+ }
193
+ };
257
194
  };
258
- var getWalletConnectAccounts$ = (wallet, chain) => {
259
- const provider = wallet.appKit.getProvider("solana");
260
- if (!wallet.platforms.includes("solana") || !provider?.session) return of([]);
261
- return getCachedObservable$(
262
- `accounts:${wallet.id}:solana:${chain}`,
263
- () => new Observable((subscriber) => {
264
- const buildAccounts = () => {
265
- const session = provider.session;
266
- if (!session) return [];
267
- const solanaCaip10s = Object.values(session.namespaces).flatMap((namespace) => namespace.accounts ?? []).filter((account) => account.startsWith("solana:"));
268
- const addresses = [
269
- ...new Set(
270
- solanaCaip10s.map((account) => account.split(":")[2]).filter((address2) => !!address2)
271
- )
272
- ];
273
- const advertisedChains = [
274
- ...new Set(
275
- solanaCaip10s.map((account) => account.split(":").slice(0, 2).join(":")).map(getSolanaChainIdFromCaip2).filter((c) => !!c)
276
- )
277
- ];
278
- const chains = advertisedChains.length ? advertisedChains : [chain];
279
- return addresses.map(
280
- (accountAddress) => ({
281
- id: getWalletAccountId(wallet.id, accountAddress),
282
- platform: "solana",
283
- address: accountAddress,
284
- chains,
285
- signer: createWalletConnectSolanaSigner(
286
- provider,
287
- accountAddress,
288
- chain
289
- ),
290
- getSigner: (c) => createWalletConnectSolanaSigner(provider, accountAddress, c),
291
- walletName: wallet.name,
292
- walletId: wallet.id
293
- })
294
- );
295
- };
296
- subscriber.next(buildAccounts());
297
- const reemit = () => subscriber.next(buildAccounts());
298
- provider.on("session_update", reemit);
299
- provider.on("accountsChanged", reemit);
300
- return () => {
301
- provider.off("session_update", reemit);
302
- provider.off("accountsChanged", reemit);
303
- };
304
- }).pipe(shareReplay({ refCount: true, bufferSize: 1 }))
305
- );
195
+ //#endregion
196
+ //#region src/api/solana/accounts.ts
197
+ const getInjectedWalletAccounts$ = (wallet, chain) => {
198
+ if (!wallet.isConnected) return of([]);
199
+ return getCachedObservable$(`accounts:${wallet.id}:${chain}`, () => new Observable((subscriber) => {
200
+ const standardWallet = wallet.wallet;
201
+ const buildAccounts = () => standardWallet.accounts.map((account) => ({
202
+ id: getWalletAccountId(wallet.id, account.address),
203
+ platform: "solana",
204
+ address: account.address,
205
+ chains: wallet.chains,
206
+ signer: createInjectedSolanaSigner(standardWallet, account, chain),
207
+ getSigner: (c) => createInjectedSolanaSigner(standardWallet, account, c),
208
+ walletName: wallet.name,
209
+ walletId: wallet.id
210
+ }));
211
+ subscriber.next(buildAccounts());
212
+ const off = standardWallet.features["standard:events"]?.on("change", () => subscriber.next(buildAccounts()));
213
+ return () => {
214
+ off?.();
215
+ };
216
+ }).pipe(shareReplay({
217
+ refCount: true,
218
+ bufferSize: 1
219
+ })));
306
220
  };
307
- var getSolanaAccounts$ = (solanaWallets$, solanaChain) => new Observable((subscriber) => {
308
- const sub = solanaWallets$.pipe(
309
- map((wallets) => wallets.filter((w) => w.isConnected)),
310
- switchMap(
311
- (wallets) => wallets.length ? combineLatest([
312
- ...wallets.filter((w) => w.type === "injected").map((w) => getInjectedWalletAccounts$(w, solanaChain)),
313
- ...wallets.filter(isWalletConnectWallet).map((w) => getWalletConnectAccounts$(w, solanaChain))
314
- ]) : of([])
315
- ),
316
- map((accounts) => accounts.flat()),
317
- distinctUntilChanged(isSameAccountsList)
318
- ).subscribe(subscriber);
319
- return () => {
320
- sub.unsubscribe();
321
- };
322
- }).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
323
- var isSameAccountsList = (a, b) => {
324
- if (a.length !== b.length) return false;
325
- return a.every((account, i) => {
326
- const other = b[i];
327
- if (!other || account.id !== other.id) return false;
328
- if (account.chains.length !== other.chains.length) return false;
329
- return account.chains.every((chain, j) => chain === other.chains[j]);
330
- });
221
+ const getWalletConnectAccounts$ = (wallet, chain) => getWalletConnectSessionAccounts$({
222
+ wallet,
223
+ platform: "solana",
224
+ namespace: "solana",
225
+ cacheKey: `accounts:${wallet.id}:solana:${chain}`,
226
+ buildAccounts: (provider) => {
227
+ const session = provider.session;
228
+ if (!session) return [];
229
+ const solanaCaip10s = getSessionCaip10s(session, "solana");
230
+ const addresses = getCaip10Addresses(solanaCaip10s);
231
+ const advertisedChains = [...new Set(solanaCaip10s.map((account) => account.split(":").slice(0, 2).join(":")).map(getSolanaChainIdFromCaip2).filter((c) => !!c))];
232
+ const chains = advertisedChains.length ? advertisedChains : [chain];
233
+ return addresses.map((accountAddress) => ({
234
+ id: getWalletAccountId(wallet.id, accountAddress),
235
+ platform: "solana",
236
+ address: accountAddress,
237
+ chains,
238
+ signer: createWalletConnectSolanaSigner(provider, accountAddress, chain),
239
+ getSigner: (c) => createWalletConnectSolanaSigner(provider, accountAddress, c),
240
+ walletName: wallet.name,
241
+ walletId: wallet.id
242
+ }));
243
+ }
244
+ });
245
+ const getSolanaAccounts$ = (solanaWallets$, solanaChain) => createPlatformAccounts$({
246
+ wallets$: solanaWallets$,
247
+ getInjectedAccounts$: (wallet) => getInjectedWalletAccounts$(wallet, solanaChain),
248
+ getWalletConnectAccounts$: (wallet) => getWalletConnectAccounts$(wallet, solanaChain),
249
+ accountChangeKey: (account) => `${account.id}|${account.chains.join(",")}`
250
+ });
251
+ //#endregion
252
+ //#region src/api/solana/wallets.ts
253
+ const SOLANA_NAMESPACE_PREFIX = "solana:";
254
+ /** A Wallet Standard wallet is Solana-capable if it advertises a solana chain or feature. */
255
+ const isSolanaWallet = (wallet) => wallet.chains.some((chain) => chain.startsWith(SOLANA_NAMESPACE_PREFIX)) || Object.keys(wallet.features).some((feature) => feature.startsWith(SOLANA_NAMESPACE_PREFIX));
256
+ const getSolanaChains = (wallet) => wallet.chains.filter((chain) => isSolanaChainId(chain));
257
+ /**
258
+ * Observable of Solana-capable Wallet Standard wallets, updated as wallets
259
+ * register/unregister. Returns an empty array during SSR.
260
+ */
261
+ const walletStandardWallets$ = new Observable((subscriber) => {
262
+ if (typeof window === "undefined") {
263
+ subscriber.next([]);
264
+ return () => {};
265
+ }
266
+ const { get, on } = getWallets();
267
+ const emit = () => subscriber.next(get().filter(isSolanaWallet));
268
+ emit();
269
+ const offRegister = on("register", emit);
270
+ const offUnregister = on("unregister", emit);
271
+ return () => {
272
+ offRegister();
273
+ offUnregister();
274
+ };
275
+ }).pipe(shareReplay({
276
+ refCount: true,
277
+ bufferSize: 1
278
+ }));
279
+ const getSolanaWallets$ = (store) => createInjectedWallets$(store, {
280
+ sources$: walletStandardWallets$,
281
+ getWalletId: (wallet) => getWalletId("solana", wallet.name),
282
+ connect: async (wallet, walletId) => {
283
+ const feature = wallet.features["standard:connect"];
284
+ if (!feature) throw new KheopskitError("FEATURE_NOT_SUPPORTED", `wallet ${walletId} does not support standard:connect`, { walletId });
285
+ await feature.connect();
286
+ },
287
+ disconnect: async (wallet) => {
288
+ await wallet.features["standard:disconnect"]?.disconnect();
289
+ },
290
+ onDisconnected: (walletId) => clearCachedObservablesByPrefix(`accounts:${walletId}:`),
291
+ buildWallet: ({ source: wallet, walletId, isConnected, connect, disconnect }) => ({
292
+ platform: "solana",
293
+ type: "injected",
294
+ id: walletId,
295
+ sourceId: wallet.name,
296
+ wallet,
297
+ chains: getSolanaChains(wallet),
298
+ name: wallet.name,
299
+ icon: wallet.icon,
300
+ isConnected,
301
+ connect,
302
+ disconnect
303
+ })
304
+ });
305
+ //#endregion
306
+ //#region src/api/solana/plugin.ts
307
+ /**
308
+ * Solana platform plugin. Pass to `getKheopskit$({ platforms: [solana()] })`.
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * import { solana } from "@kheopskit/core/solana";
313
+ * solana({ chain: "solana:mainnet" });
314
+ * ```
315
+ */
316
+ const solana = (options = {}) => {
317
+ const chain = options.chain ?? "solana:mainnet";
318
+ if (!isSolanaChainId(chain)) console.warn(`[kheopskit] Unknown solana chain: ${JSON.stringify(chain)}. Valid values: "solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet".`);
319
+ return {
320
+ platform: "solana",
321
+ getWallets$: (ctx) => getSolanaWallets$(ctx.store),
322
+ getAccounts$: (wallets$) => getSolanaAccounts$(wallets$, chain)
323
+ };
331
324
  };
325
+ //#endregion
326
+ export { DEFAULT_SOLANA_CHAIN, getSolanaCaip2, isInjectedWallet, isSolanaAddress, isSolanaChainId, isWalletConnectWallet, solana };
332
327
 
333
- // src/api/solana/wallets.ts
334
- import { getWallets } from "@wallet-standard/app";
335
- import {
336
- BehaviorSubject,
337
- combineLatest as combineLatest2,
338
- distinctUntilChanged as distinctUntilChanged2,
339
- map as map2,
340
- Observable as Observable2,
341
- shareReplay as shareReplay2
342
- } from "rxjs";
343
- var SOLANA_NAMESPACE_PREFIX = "solana:";
344
- var isSolanaWallet = (wallet) => wallet.chains.some((chain) => chain.startsWith(SOLANA_NAMESPACE_PREFIX)) || Object.keys(wallet.features).some(
345
- (feature) => feature.startsWith(SOLANA_NAMESPACE_PREFIX)
346
- );
347
- var getSolanaChains = (wallet) => wallet.chains.filter(
348
- (chain) => isSolanaChainId(chain)
349
- );
350
- var walletStandardWallets$ = new Observable2(
351
- (subscriber) => {
352
- if (typeof window === "undefined") {
353
- subscriber.next([]);
354
- return () => {
355
- };
356
- }
357
- const { get, on } = getWallets();
358
- const emit = () => subscriber.next(get().filter(isSolanaWallet));
359
- emit();
360
- const offRegister = on("register", emit);
361
- const offUnregister = on("unregister", emit);
362
- return () => {
363
- offRegister();
364
- offUnregister();
365
- };
366
- }
367
- ).pipe(shareReplay2({ refCount: true, bufferSize: 1 }));
368
- var createSolanaInjectedWallets$ = (store2) => new Observable2((subscriber) => {
369
- const enabledWalletIds$ = new BehaviorSubject(/* @__PURE__ */ new Set());
370
- const connect = async (wallet, walletId) => {
371
- if (enabledWalletIds$.value.has(walletId))
372
- throw new KheopskitError(
373
- "WALLET_ALREADY_CONNECTED",
374
- `wallet ${walletId} is already connected`,
375
- { walletId }
376
- );
377
- const feature = wallet.features["standard:connect"];
378
- if (!feature)
379
- throw new KheopskitError(
380
- "FEATURE_NOT_SUPPORTED",
381
- `wallet ${walletId} does not support standard:connect`,
382
- { walletId }
383
- );
384
- await feature.connect();
385
- const newSet = new Set(enabledWalletIds$.value);
386
- newSet.add(walletId);
387
- enabledWalletIds$.next(newSet);
388
- store2.addEnabledWalletId(walletId);
389
- };
390
- const disconnect = async (wallet, walletId) => {
391
- if (!enabledWalletIds$.value.has(walletId))
392
- throw new KheopskitError(
393
- "WALLET_NOT_CONNECTED",
394
- `wallet ${walletId} is not connected`,
395
- { walletId }
396
- );
397
- const feature = wallet.features["standard:disconnect"];
398
- await feature?.disconnect();
399
- const newSet = new Set(enabledWalletIds$.value);
400
- newSet.delete(walletId);
401
- enabledWalletIds$.next(newSet);
402
- store2.removeEnabledWalletId(walletId);
403
- clearCachedObservablesByPrefix(`accounts:${walletId}:`);
404
- };
405
- const sub = combineLatest2([walletStandardWallets$, enabledWalletIds$]).pipe(
406
- map2(
407
- ([wallets, enabledWalletIds]) => wallets.map((wallet) => {
408
- const walletId = getWalletId("solana", wallet.name);
409
- return {
410
- platform: "solana",
411
- type: "injected",
412
- id: walletId,
413
- sourceId: wallet.name,
414
- wallet,
415
- chains: getSolanaChains(wallet),
416
- name: wallet.name,
417
- icon: wallet.icon,
418
- isConnected: enabledWalletIds.has(walletId),
419
- connect: () => connect(wallet, walletId),
420
- disconnect: () => disconnect(wallet, walletId)
421
- };
422
- })
423
- ),
424
- distinctUntilChanged2(walletsEqual)
425
- ).subscribe(subscriber);
426
- return () => {
427
- sub.unsubscribe();
428
- };
429
- }).pipe(shareReplay2({ refCount: true, bufferSize: 1 }));
430
- var getSolanaWallets$ = (store2 = store) => createSolanaInjectedWallets$(store2);
431
- var walletsEqual = (a, b) => {
432
- if (a.length !== b.length) return false;
433
- return a.every(
434
- (w, i) => w.id === b[i]?.id && w.isConnected === b[i]?.isConnected && w.name === b[i]?.name
435
- );
436
- };
437
-
438
- // src/api/solana/plugin.ts
439
- var solana = (options = {}) => {
440
- const chain = options.chain ?? DEFAULT_SOLANA_CHAIN;
441
- if (!isSolanaChainId(chain)) {
442
- console.warn(
443
- `[kheopskit] Unknown solana chain: ${JSON.stringify(chain)}. Valid values: "solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet".`
444
- );
445
- }
446
- return {
447
- platform: "solana",
448
- getWallets$: (ctx) => getSolanaWallets$(ctx.store),
449
- getAccounts$: (wallets$) => getSolanaAccounts$(wallets$, chain)
450
- };
451
- };
452
- export {
453
- DEFAULT_SOLANA_CHAIN,
454
- getSolanaCaip2,
455
- isInjectedWallet,
456
- isSolanaAddress,
457
- isSolanaChainId,
458
- isWalletConnectWallet,
459
- solana
460
- };
461
328
  //# sourceMappingURL=solana.mjs.map