@solana/react-hooks 0.0.0 → 0.1.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.
@@ -0,0 +1,1294 @@
1
+ import { createClient, toAddress, toAddressString, stableStringify, createSolTransferController, createSplTransferController, getWalletStandardConnectors, watchWalletStandardConnectors, createTransactionPoolController, createInitialAsyncState, createAsyncState, normalizeSignature, SIGNATURE_STATUS_TIMEOUT_MS, deriveConfirmationStatus, confirmationMeetsCommitment } from '@solana/client';
2
+ import { createContext, useMemo, useEffect, useContext, useCallback, useRef, useSyncExternalStore, useState } from 'react';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import useSWR, { SWRConfig } from 'swr';
5
+ import { useStore } from 'zustand';
6
+ import { getBase64EncodedWireTransaction } from '@solana/kit';
7
+ import { address } from '@solana/addresses';
8
+ import { SolanaError, SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED } from '@solana/errors';
9
+ import { getAbortablePromise } from '@solana/promises';
10
+ import { getCompiledTransactionMessageDecoder } from '@solana/transaction-messages';
11
+ import { getTransactionCodec, assertIsTransactionWithinSizeLimit, getTransactionLifetimeConstraintFromCompiledTransactionMessage, getTransactionEncoder } from '@solana/transactions';
12
+ import { SolanaSignAndSendTransaction, SolanaSignIn, SolanaSignMessage, SolanaSignTransaction } from '@solana/wallet-standard-features';
13
+ import { WalletStandardError, WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED } from '@wallet-standard/errors';
14
+ import { getWalletAccountFeature, getWalletFeature } from '@wallet-standard/ui';
15
+ import { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, getOrCreateUiWalletAccountForStandardWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';
16
+
17
+ var __defProp = Object.defineProperty;
18
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
19
+ var SolanaClientContext = createContext(null);
20
+ function SolanaClientProvider({ children, client: providedClient, config }) {
21
+ const client = useMemo(() => {
22
+ if (providedClient) {
23
+ return providedClient;
24
+ }
25
+ if (!config) {
26
+ throw new Error("SolanaClientProvider requires either a `client` or `config` prop.");
27
+ }
28
+ return createClient(config);
29
+ }, [config, providedClient]);
30
+ useEffect(() => {
31
+ if (providedClient) {
32
+ return;
33
+ }
34
+ return () => {
35
+ client.destroy();
36
+ };
37
+ }, [client, providedClient]);
38
+ return /* @__PURE__ */ jsx(SolanaClientContext.Provider, { value: client, children });
39
+ }
40
+ __name(SolanaClientProvider, "SolanaClientProvider");
41
+ function useSolanaClient() {
42
+ const client = useContext(SolanaClientContext);
43
+ if (!client) {
44
+ throw new Error("useSolanaClient must be used within a SolanaClientProvider.");
45
+ }
46
+ return client;
47
+ }
48
+ __name(useSolanaClient, "useSolanaClient");
49
+ var QuerySuspenseContext = createContext(void 0);
50
+ function useQuerySuspensePreference() {
51
+ return useContext(QuerySuspenseContext);
52
+ }
53
+ __name(useQuerySuspensePreference, "useQuerySuspensePreference");
54
+ var identitySelector = /* @__PURE__ */ __name((state) => state, "identitySelector");
55
+ function useClientStore(selector) {
56
+ const client = useSolanaClient();
57
+ const appliedSelector = selector ?? identitySelector;
58
+ const slice = useStore(client.store, appliedSelector);
59
+ return selector ? slice : slice;
60
+ }
61
+ __name(useClientStore, "useClientStore");
62
+
63
+ // src/query.ts
64
+ var QUERY_NAMESPACE = "@solana/react-hooks";
65
+ function useSolanaRpcQuery(scope, args, fetcher, options = {}) {
66
+ const client = useSolanaClient();
67
+ const cluster = useClientStore((state) => state.cluster);
68
+ const { disabled = false, ...restOptions } = options;
69
+ const providerSuspensePreference = useQuerySuspensePreference();
70
+ const suspenseEnabled = !disabled && Boolean(providerSuspensePreference);
71
+ const swrOptions = {
72
+ ...restOptions,
73
+ suspense: suspenseEnabled
74
+ };
75
+ const key = useMemo(() => {
76
+ if (disabled) {
77
+ return null;
78
+ }
79
+ return [QUERY_NAMESPACE, scope, cluster.endpoint, cluster.commitment, ...args];
80
+ }, [cluster.commitment, cluster.endpoint, args, scope, disabled]);
81
+ const swr = useSWR(key, () => fetcher(client), swrOptions);
82
+ const [dataUpdatedAt, setDataUpdatedAt] = useState(
83
+ () => swr.data !== void 0 ? Date.now() : void 0
84
+ );
85
+ useEffect(() => {
86
+ if (swr.data !== void 0) {
87
+ setDataUpdatedAt(Date.now());
88
+ }
89
+ }, [swr.data]);
90
+ const status = swr.error ? "error" : swr.isLoading ? "loading" : swr.data !== void 0 ? "success" : "idle";
91
+ const refresh = useCallback(() => swr.mutate(void 0, { revalidate: true }), [swr.mutate]);
92
+ return {
93
+ data: swr.data,
94
+ dataUpdatedAt,
95
+ error: swr.error ?? null,
96
+ isError: status === "error",
97
+ isLoading: swr.isLoading,
98
+ isSuccess: status === "success",
99
+ isValidating: swr.isValidating,
100
+ mutate: swr.mutate,
101
+ refresh,
102
+ status
103
+ };
104
+ }
105
+ __name(useSolanaRpcQuery, "useSolanaRpcQuery");
106
+ var DEFAULT_BLOCKHASH_REFRESH_INTERVAL = 3e4;
107
+ function useLatestBlockhash(options) {
108
+ const { commitment, minContextSlot, refreshInterval = DEFAULT_BLOCKHASH_REFRESH_INTERVAL, ...rest } = options ?? {};
109
+ const normalizedMinContextSlot = useMemo(() => {
110
+ if (minContextSlot === void 0) {
111
+ return void 0;
112
+ }
113
+ return typeof minContextSlot === "bigint" ? minContextSlot : BigInt(Math.floor(minContextSlot));
114
+ }, [minContextSlot]);
115
+ const keyArgs = useMemo(
116
+ () => [commitment ?? null, normalizedMinContextSlot ?? null],
117
+ [commitment, normalizedMinContextSlot]
118
+ );
119
+ const fetcher = useCallback(
120
+ async (client) => {
121
+ const fallbackCommitment = commitment ?? client.store.getState().cluster.commitment;
122
+ const plan = client.runtime.rpc.getLatestBlockhash({
123
+ commitment: fallbackCommitment,
124
+ minContextSlot: normalizedMinContextSlot
125
+ });
126
+ return plan.send({ abortSignal: AbortSignal.timeout(15e3) });
127
+ },
128
+ [commitment, normalizedMinContextSlot]
129
+ );
130
+ const query = useSolanaRpcQuery("latestBlockhash", keyArgs, fetcher, {
131
+ refreshInterval,
132
+ ...rest
133
+ });
134
+ return {
135
+ ...query,
136
+ blockhash: query.data?.value.blockhash ?? null,
137
+ contextSlot: query.data?.context.slot,
138
+ lastValidBlockHeight: query.data?.value.lastValidBlockHeight ?? null
139
+ };
140
+ }
141
+ __name(useLatestBlockhash, "useLatestBlockhash");
142
+ function useProgramAccounts(programAddress, options) {
143
+ const { commitment, config, ...queryOptions } = options ?? {};
144
+ const { disabled: disabledOption, ...restQueryOptions } = queryOptions;
145
+ const address2 = useMemo(() => programAddress ? toAddress(programAddress) : void 0, [programAddress]);
146
+ const addressKey = useMemo(() => address2 ? toAddressString(address2) : null, [address2]);
147
+ const configKey = useMemo(() => stableStringify(config ?? null), [config]);
148
+ const fetcher = useCallback(
149
+ async (client) => {
150
+ if (!address2) {
151
+ throw new Error("Provide a program address before querying program accounts.");
152
+ }
153
+ const fallbackCommitment = commitment ?? config?.commitment ?? client.store.getState().cluster.commitment;
154
+ const mergedConfig = {
155
+ ...config ?? {},
156
+ commitment: fallbackCommitment
157
+ };
158
+ const plan = client.runtime.rpc.getProgramAccounts(address2, mergedConfig);
159
+ return plan.send({ abortSignal: AbortSignal.timeout(2e4) });
160
+ },
161
+ [address2, commitment, config]
162
+ );
163
+ const disabled = disabledOption ?? !address2;
164
+ const query = useSolanaRpcQuery("programAccounts", [addressKey, configKey], fetcher, {
165
+ ...restQueryOptions,
166
+ disabled
167
+ });
168
+ return {
169
+ ...query,
170
+ accounts: query.data ?? []
171
+ };
172
+ }
173
+ __name(useProgramAccounts, "useProgramAccounts");
174
+ function useSimulateTransaction(transaction, options) {
175
+ const { commitment, config, refreshInterval, ...rest } = options ?? {};
176
+ const { disabled: disabledOption, revalidateIfStale, revalidateOnFocus, ...queryOptions } = rest;
177
+ const wire = useMemo(() => {
178
+ if (!transaction) {
179
+ return null;
180
+ }
181
+ if (typeof transaction === "string") {
182
+ return transaction;
183
+ }
184
+ return getBase64EncodedWireTransaction(transaction);
185
+ }, [transaction]);
186
+ const configKey = useMemo(() => stableStringify(config ?? null), [config]);
187
+ const fetcher = useCallback(
188
+ async (client) => {
189
+ if (!wire) {
190
+ throw new Error("Provide a transaction payload before simulating.");
191
+ }
192
+ const resolvedConfig = {
193
+ ...config ?? {},
194
+ commitment: commitment ?? config?.commitment ?? client.store.getState().cluster.commitment
195
+ };
196
+ const plan = client.runtime.rpc.simulateTransaction(wire, resolvedConfig);
197
+ return plan.send({ abortSignal: AbortSignal.timeout(2e4) });
198
+ },
199
+ [commitment, config, wire]
200
+ );
201
+ const disabled = disabledOption ?? !wire;
202
+ const query = useSolanaRpcQuery("simulateTransaction", [wire, configKey], fetcher, {
203
+ ...queryOptions,
204
+ refreshInterval,
205
+ disabled,
206
+ revalidateIfStale: revalidateIfStale ?? false,
207
+ revalidateOnFocus: revalidateOnFocus ?? false
208
+ });
209
+ return {
210
+ ...query,
211
+ logs: query.data?.value.logs ?? []
212
+ };
213
+ }
214
+ __name(useSimulateTransaction, "useSimulateTransaction");
215
+
216
+ // src/hooks.ts
217
+ function createClusterSelector() {
218
+ return (state) => state.cluster;
219
+ }
220
+ __name(createClusterSelector, "createClusterSelector");
221
+ function createClusterStatusSelector() {
222
+ return (state) => state.cluster.status;
223
+ }
224
+ __name(createClusterStatusSelector, "createClusterStatusSelector");
225
+ function createWalletSelector() {
226
+ return (state) => state.wallet;
227
+ }
228
+ __name(createWalletSelector, "createWalletSelector");
229
+ function createAccountSelector(key) {
230
+ return (state) => key ? state.accounts[key] : void 0;
231
+ }
232
+ __name(createAccountSelector, "createAccountSelector");
233
+ function useClusterState() {
234
+ const selector = useMemo(createClusterSelector, []);
235
+ return useClientStore(selector);
236
+ }
237
+ __name(useClusterState, "useClusterState");
238
+ function useClusterStatus() {
239
+ const selector = useMemo(createClusterStatusSelector, []);
240
+ return useClientStore(selector);
241
+ }
242
+ __name(useClusterStatus, "useClusterStatus");
243
+ function useWallet() {
244
+ const selector = useMemo(createWalletSelector, []);
245
+ return useClientStore(selector);
246
+ }
247
+ __name(useWallet, "useWallet");
248
+ function useWalletSession() {
249
+ const wallet = useWallet();
250
+ if (wallet.status === "connected") {
251
+ return wallet.session;
252
+ }
253
+ return void 0;
254
+ }
255
+ __name(useWalletSession, "useWalletSession");
256
+ function useWalletActions() {
257
+ const client = useSolanaClient();
258
+ return client.actions;
259
+ }
260
+ __name(useWalletActions, "useWalletActions");
261
+ function useConnectWallet() {
262
+ const client = useSolanaClient();
263
+ return useCallback(
264
+ (connectorId, options) => client.actions.connectWallet(connectorId, options),
265
+ [client]
266
+ );
267
+ }
268
+ __name(useConnectWallet, "useConnectWallet");
269
+ function useDisconnectWallet() {
270
+ const client = useSolanaClient();
271
+ return useCallback(() => client.actions.disconnectWallet(), [client]);
272
+ }
273
+ __name(useDisconnectWallet, "useDisconnectWallet");
274
+ function useSolTransfer() {
275
+ const client = useSolanaClient();
276
+ const session = useWalletSession();
277
+ const helper = client.solTransfer;
278
+ const sessionRef = useRef(session);
279
+ useEffect(() => {
280
+ sessionRef.current = session;
281
+ }, [session]);
282
+ const controller = useMemo(
283
+ () => createSolTransferController({
284
+ authorityProvider: /* @__PURE__ */ __name(() => sessionRef.current, "authorityProvider"),
285
+ helper
286
+ }),
287
+ [helper]
288
+ );
289
+ const state = useSyncExternalStore(
290
+ controller.subscribe,
291
+ controller.getState,
292
+ controller.getState
293
+ );
294
+ const send = useCallback(
295
+ (config, options) => controller.send(config, options),
296
+ [controller]
297
+ );
298
+ return {
299
+ error: state.error ?? null,
300
+ helper,
301
+ isSending: state.status === "loading",
302
+ reset: controller.reset,
303
+ send,
304
+ signature: state.data ?? null,
305
+ status: state.status
306
+ };
307
+ }
308
+ __name(useSolTransfer, "useSolTransfer");
309
+ function useSplToken(mint, options = {}) {
310
+ const client = useSolanaClient();
311
+ const session = useWalletSession();
312
+ const normalizedMint = useMemo(() => String(mint), [mint]);
313
+ const helperConfig = useMemo(
314
+ () => ({
315
+ commitment: options.commitment,
316
+ mint: normalizedMint,
317
+ ...options.config ?? {}
318
+ }),
319
+ [normalizedMint, options.commitment, options.config]
320
+ );
321
+ const helper = useMemo(() => client.splToken(helperConfig), [client, helperConfig]);
322
+ const ownerRaw = options.owner ?? session?.account.address;
323
+ const owner = useMemo(() => ownerRaw ? String(ownerRaw) : null, [ownerRaw]);
324
+ const balanceKey = owner ? ["spl-balance", normalizedMint, owner, options.commitment ?? null] : null;
325
+ const fetchBalance = useCallback(() => {
326
+ if (!owner) {
327
+ throw new Error("Unable to fetch SPL balance without an owner.");
328
+ }
329
+ return helper.fetchBalance(owner, options.commitment);
330
+ }, [helper, owner, options.commitment]);
331
+ const { data, error, isLoading, isValidating, mutate } = useSWR(balanceKey, fetchBalance, {
332
+ revalidateOnFocus: options.revalidateOnFocus ?? false
333
+ });
334
+ const sessionRef = useRef(session);
335
+ useEffect(() => {
336
+ sessionRef.current = session;
337
+ }, [session]);
338
+ const ownerRef = useRef(owner);
339
+ useEffect(() => {
340
+ ownerRef.current = owner;
341
+ }, [owner]);
342
+ const controller = useMemo(
343
+ () => createSplTransferController({
344
+ authorityProvider: /* @__PURE__ */ __name(() => sessionRef.current ?? void 0, "authorityProvider"),
345
+ helper,
346
+ sourceOwnerProvider: /* @__PURE__ */ __name(() => ownerRef.current ?? void 0, "sourceOwnerProvider")
347
+ }),
348
+ [helper]
349
+ );
350
+ const sendState = useSyncExternalStore(
351
+ controller.subscribe,
352
+ controller.getState,
353
+ controller.getState
354
+ );
355
+ const refresh = useCallback(() => {
356
+ if (!owner) {
357
+ return Promise.resolve(void 0);
358
+ }
359
+ return mutate(() => helper.fetchBalance(owner, options.commitment), { revalidate: false });
360
+ }, [helper, mutate, owner, options.commitment]);
361
+ const send = useCallback(
362
+ async (config, sendOptions) => {
363
+ const signature = await controller.send(config, sendOptions);
364
+ if (owner) {
365
+ await mutate(() => helper.fetchBalance(owner, options.commitment), { revalidate: false });
366
+ }
367
+ return signature;
368
+ },
369
+ [controller, helper, mutate, options.commitment, owner]
370
+ );
371
+ const resetSend = useCallback(() => {
372
+ controller.reset();
373
+ }, [controller]);
374
+ const status = owner === null ? "disconnected" : error ? "error" : isLoading && !data ? "loading" : "ready";
375
+ return {
376
+ balance: data ?? null,
377
+ error: error ?? null,
378
+ helper,
379
+ isFetching: Boolean(owner) && (isLoading || isValidating),
380
+ isSending: sendState.status === "loading",
381
+ owner,
382
+ refresh,
383
+ refreshing: Boolean(owner) && isValidating,
384
+ resetSend,
385
+ send,
386
+ sendError: sendState.error ?? null,
387
+ sendSignature: sendState.data ?? null,
388
+ sendStatus: sendState.status,
389
+ status
390
+ };
391
+ }
392
+ __name(useSplToken, "useSplToken");
393
+ function useAccount(addressLike, options = {}) {
394
+ const client = useSolanaClient();
395
+ const shouldSkip = options.skip ?? !addressLike;
396
+ const address2 = useMemo(() => {
397
+ if (shouldSkip || !addressLike) {
398
+ return void 0;
399
+ }
400
+ return toAddress(addressLike);
401
+ }, [addressLike, shouldSkip]);
402
+ const accountKey = useMemo(() => address2?.toString(), [address2]);
403
+ const selector = useMemo(() => createAccountSelector(accountKey), [accountKey]);
404
+ const account = useClientStore(selector);
405
+ useEffect(() => {
406
+ if (!address2) {
407
+ return;
408
+ }
409
+ const commitment = options.commitment;
410
+ if (options.fetch !== false) {
411
+ void client.actions.fetchAccount(address2, commitment).catch(() => void 0);
412
+ }
413
+ if (options.watch) {
414
+ const subscription = client.watchers.watchAccount({ address: address2, commitment }, () => void 0);
415
+ return () => {
416
+ subscription.abort();
417
+ };
418
+ }
419
+ return void 0;
420
+ }, [address2, client, options.commitment, options.fetch, options.watch]);
421
+ return account;
422
+ }
423
+ __name(useAccount, "useAccount");
424
+ function useBalance(addressLike, options = {}) {
425
+ const mergedOptions = useMemo(
426
+ () => ({
427
+ commitment: options.commitment,
428
+ fetch: options.fetch ?? true,
429
+ skip: options.skip,
430
+ watch: options.watch ?? true
431
+ }),
432
+ [options.commitment, options.fetch, options.skip, options.watch]
433
+ );
434
+ const client = useSolanaClient();
435
+ const shouldSkip = mergedOptions.skip ?? !addressLike;
436
+ const address2 = useMemo(() => {
437
+ if (shouldSkip || !addressLike) {
438
+ return void 0;
439
+ }
440
+ return toAddress(addressLike);
441
+ }, [addressLike, shouldSkip]);
442
+ const accountKey = useMemo(() => address2?.toString(), [address2]);
443
+ const selector = useMemo(() => createAccountSelector(accountKey), [accountKey]);
444
+ const account = useClientStore(selector);
445
+ useEffect(() => {
446
+ if (!address2) {
447
+ return;
448
+ }
449
+ const commitment = mergedOptions.commitment;
450
+ if (mergedOptions.fetch !== false) {
451
+ void client.actions.fetchBalance(address2, commitment).catch(() => void 0);
452
+ }
453
+ if (mergedOptions.watch) {
454
+ const watcher = client.watchers.watchBalance({ address: address2, commitment }, () => void 0);
455
+ return () => {
456
+ watcher.abort();
457
+ };
458
+ }
459
+ return void 0;
460
+ }, [address2, client, mergedOptions.commitment, mergedOptions.fetch, mergedOptions.watch]);
461
+ const lamports = account?.lamports ?? null;
462
+ const fetching = account?.fetching ?? false;
463
+ const slot = account?.slot;
464
+ const error = account?.error;
465
+ return useMemo(
466
+ () => ({
467
+ account,
468
+ error,
469
+ fetching,
470
+ lamports,
471
+ slot
472
+ }),
473
+ [account, error, fetching, lamports, slot]
474
+ );
475
+ }
476
+ __name(useBalance, "useBalance");
477
+ function useWalletStandardConnectors(options) {
478
+ const overrides = options?.overrides;
479
+ const memoisedOptions = useMemo(() => overrides ? { overrides } : void 0, [overrides]);
480
+ const [connectors, setConnectors] = useState(
481
+ () => getWalletStandardConnectors(memoisedOptions ?? {})
482
+ );
483
+ useEffect(() => {
484
+ setConnectors(getWalletStandardConnectors(memoisedOptions ?? {}));
485
+ const unwatch = watchWalletStandardConnectors(setConnectors, memoisedOptions ?? {});
486
+ return () => {
487
+ unwatch();
488
+ };
489
+ }, [memoisedOptions]);
490
+ return connectors;
491
+ }
492
+ __name(useWalletStandardConnectors, "useWalletStandardConnectors");
493
+ function useTransactionPool(config = {}) {
494
+ const initialInstructions = useMemo(
495
+ () => config.instructions ?? [],
496
+ [config.instructions]
497
+ );
498
+ const client = useSolanaClient();
499
+ const helper = client.helpers.transaction;
500
+ const blockhashMaxAgeMs = config.latestBlockhash?.refreshInterval ?? 3e4;
501
+ const controller = useMemo(
502
+ () => createTransactionPoolController({
503
+ blockhashMaxAgeMs,
504
+ helper,
505
+ initialInstructions
506
+ }),
507
+ [blockhashMaxAgeMs, helper, initialInstructions]
508
+ );
509
+ const latestBlockhash = useLatestBlockhash(config.latestBlockhash);
510
+ useEffect(() => {
511
+ const value = latestBlockhash.data?.value;
512
+ if (!value) {
513
+ controller.setLatestBlockhashCache(void 0);
514
+ return;
515
+ }
516
+ const cache = {
517
+ updatedAt: latestBlockhash.dataUpdatedAt ?? Date.now(),
518
+ value
519
+ };
520
+ controller.setLatestBlockhashCache(cache);
521
+ }, [controller, latestBlockhash.data, latestBlockhash.dataUpdatedAt]);
522
+ const instructions = useSyncExternalStore(
523
+ controller.subscribeInstructions,
524
+ controller.getInstructions,
525
+ controller.getInstructions
526
+ );
527
+ const prepared = useSyncExternalStore(
528
+ controller.subscribePrepared,
529
+ controller.getPrepared,
530
+ controller.getPrepared
531
+ );
532
+ const prepareState = useSyncExternalStore(
533
+ controller.subscribePrepareState,
534
+ controller.getPrepareState,
535
+ controller.getPrepareState
536
+ );
537
+ const sendState = useSyncExternalStore(
538
+ controller.subscribeSendState,
539
+ controller.getSendState,
540
+ controller.getSendState
541
+ );
542
+ return {
543
+ addInstruction: controller.addInstruction,
544
+ addInstructions: controller.addInstructions,
545
+ clearInstructions: controller.clearInstructions,
546
+ instructions,
547
+ isPreparing: prepareState.status === "loading",
548
+ isSending: sendState.status === "loading",
549
+ prepared,
550
+ prepare: controller.prepare,
551
+ prepareError: prepareState.error ?? null,
552
+ prepareStatus: prepareState.status,
553
+ removeInstruction: controller.removeInstruction,
554
+ replaceInstructions: controller.replaceInstructions,
555
+ reset: controller.reset,
556
+ send: controller.send,
557
+ sendError: sendState.error ?? null,
558
+ sendSignature: sendState.data ?? null,
559
+ sendStatus: sendState.status,
560
+ prepareAndSend: controller.prepareAndSend,
561
+ sign: controller.sign,
562
+ toWire: controller.toWire,
563
+ latestBlockhash
564
+ };
565
+ }
566
+ __name(useTransactionPool, "useTransactionPool");
567
+ function useSendTransaction() {
568
+ const client = useSolanaClient();
569
+ const helper = client.transaction;
570
+ const session = useWalletSession();
571
+ const [state, setState] = useState(
572
+ () => createInitialAsyncState()
573
+ );
574
+ const execute = useCallback(
575
+ async (operation) => {
576
+ setState(createAsyncState("loading"));
577
+ try {
578
+ const signature = await operation();
579
+ setState(createAsyncState("success", { data: signature }));
580
+ return signature;
581
+ } catch (error) {
582
+ setState(createAsyncState("error", { error }));
583
+ throw error;
584
+ }
585
+ },
586
+ []
587
+ );
588
+ const ensureAuthority = useCallback(
589
+ (request) => {
590
+ if (request.authority) {
591
+ return request;
592
+ }
593
+ if (!session) {
594
+ throw new Error("Connect a wallet or supply an `authority` before sending transactions.");
595
+ }
596
+ return { ...request, authority: session };
597
+ },
598
+ [session]
599
+ );
600
+ const send = useCallback(
601
+ async (request, options) => {
602
+ const normalizedRequest = ensureAuthority(request);
603
+ return execute(() => helper.prepareAndSend(normalizedRequest, options));
604
+ },
605
+ [ensureAuthority, execute, helper]
606
+ );
607
+ const sendPrepared = useCallback(
608
+ async (prepared, options) => execute(() => helper.send(prepared, options)),
609
+ [execute, helper]
610
+ );
611
+ const reset = useCallback(() => {
612
+ setState(createInitialAsyncState());
613
+ }, []);
614
+ return {
615
+ error: state.error ?? null,
616
+ isSending: state.status === "loading",
617
+ reset,
618
+ send,
619
+ sendPrepared,
620
+ signature: state.data ?? null,
621
+ status: state.status
622
+ };
623
+ }
624
+ __name(useSendTransaction, "useSendTransaction");
625
+ function useSignatureStatus(signatureInput, options = {}) {
626
+ const { config, ...queryOptions } = options;
627
+ const signature = useMemo(() => normalizeSignature(signatureInput), [signatureInput]);
628
+ const signatureKey = signature?.toString() ?? null;
629
+ const configKey = useMemo(() => JSON.stringify(config ?? null), [config]);
630
+ const fetcher = useCallback(
631
+ async (client) => {
632
+ if (!signatureKey) {
633
+ throw new Error("Provide a signature before querying its status.");
634
+ }
635
+ if (!signature) {
636
+ throw new Error("Provide a signature before querying its status.");
637
+ }
638
+ const plan = client.runtime.rpc.getSignatureStatuses([signature], config);
639
+ const response = await plan.send({ abortSignal: AbortSignal.timeout(SIGNATURE_STATUS_TIMEOUT_MS) });
640
+ return response.value[0] ?? null;
641
+ },
642
+ [config, signature, signatureKey]
643
+ );
644
+ const disabled = queryOptions.disabled ?? !signatureKey;
645
+ const query = useSolanaRpcQuery(
646
+ "signatureStatus",
647
+ [signatureKey, configKey],
648
+ fetcher,
649
+ {
650
+ ...queryOptions,
651
+ disabled
652
+ }
653
+ );
654
+ const confirmationStatus = deriveConfirmationStatus(query.data ?? null);
655
+ return {
656
+ ...query,
657
+ confirmationStatus,
658
+ signatureStatus: query.data ?? null
659
+ };
660
+ }
661
+ __name(useSignatureStatus, "useSignatureStatus");
662
+ function useWaitForSignature(signatureInput, options = {}) {
663
+ const {
664
+ commitment = "confirmed",
665
+ disabled: disabledOption,
666
+ subscribe = true,
667
+ watchCommitment,
668
+ ...signatureStatusOptions
669
+ } = options;
670
+ const { refreshInterval, ...restStatusOptions } = signatureStatusOptions;
671
+ const subscribeCommitment = watchCommitment ?? commitment;
672
+ const client = useSolanaClient();
673
+ const normalizedSignature = useMemo(() => normalizeSignature(signatureInput), [signatureInput]);
674
+ const disabled = disabledOption ?? !normalizedSignature;
675
+ const statusQuery = useSignatureStatus(signatureInput, {
676
+ ...restStatusOptions,
677
+ refreshInterval: refreshInterval ?? 2e3,
678
+ disabled
679
+ });
680
+ const [subscriptionSettled, setSubscriptionSettled] = useState(false);
681
+ useEffect(() => {
682
+ if (normalizedSignature === void 0) {
683
+ setSubscriptionSettled(false);
684
+ return;
685
+ }
686
+ setSubscriptionSettled(false);
687
+ }, [normalizedSignature]);
688
+ useEffect(() => {
689
+ if (!normalizedSignature || disabled || !subscribe) {
690
+ return;
691
+ }
692
+ const subscription = client.watchers.watchSignature(
693
+ {
694
+ commitment: subscribeCommitment,
695
+ enableReceivedNotification: true,
696
+ signature: normalizedSignature
697
+ },
698
+ () => {
699
+ setSubscriptionSettled(true);
700
+ }
701
+ );
702
+ return () => {
703
+ subscription.abort();
704
+ };
705
+ }, [client, disabled, normalizedSignature, subscribe, subscribeCommitment]);
706
+ const hasSignature = Boolean(normalizedSignature) && !disabled;
707
+ const signatureError = statusQuery.signatureStatus?.err ?? null;
708
+ const waitError = statusQuery.error ?? signatureError ?? null;
709
+ const meetsCommitment = confirmationMeetsCommitment(statusQuery.confirmationStatus, commitment);
710
+ const settled = subscriptionSettled || meetsCommitment;
711
+ let waitStatus = "idle";
712
+ if (!hasSignature) {
713
+ waitStatus = "idle";
714
+ } else if (waitError) {
715
+ waitStatus = "error";
716
+ } else if (settled) {
717
+ waitStatus = "success";
718
+ } else {
719
+ waitStatus = "waiting";
720
+ }
721
+ return {
722
+ ...statusQuery,
723
+ isError: waitStatus === "error",
724
+ isSuccess: waitStatus === "success",
725
+ isWaiting: waitStatus === "waiting",
726
+ waitError,
727
+ waitStatus
728
+ };
729
+ }
730
+ __name(useWaitForSignature, "useWaitForSignature");
731
+ var createCache = /* @__PURE__ */ __name(() => /* @__PURE__ */ new Map(), "createCache");
732
+ var DEFAULT_QUERY_CONFIG = Object.freeze({
733
+ dedupingInterval: 1e3,
734
+ focusThrottleInterval: 1e3,
735
+ provider: /* @__PURE__ */ __name(() => createCache(), "provider"),
736
+ revalidateOnFocus: false,
737
+ revalidateOnReconnect: true
738
+ });
739
+ function SolanaQueryProvider({
740
+ children,
741
+ config,
742
+ resetOnClusterChange = true,
743
+ suspense
744
+ }) {
745
+ const cluster = useClientStore((state) => state.cluster);
746
+ const cacheRegistryRef = useRef(/* @__PURE__ */ new Map());
747
+ const cacheKey = resetOnClusterChange ? `${cluster.endpoint}|${cluster.commitment}` : "global";
748
+ const cache = useMemo(() => {
749
+ const registry = cacheRegistryRef.current;
750
+ if (!resetOnClusterChange) {
751
+ const existing = registry.get("global");
752
+ if (existing) {
753
+ return existing;
754
+ }
755
+ const next2 = createCache();
756
+ registry.set("global", next2);
757
+ return next2;
758
+ }
759
+ const next = createCache();
760
+ registry.set(cacheKey, next);
761
+ return next;
762
+ }, [cacheKey, resetOnClusterChange]);
763
+ const value = useMemo(() => {
764
+ const base = {
765
+ ...DEFAULT_QUERY_CONFIG,
766
+ ...config
767
+ };
768
+ if (!config?.provider) {
769
+ base.provider = () => cache;
770
+ }
771
+ if (base.suspense === void 0 && suspense !== void 0) {
772
+ base.suspense = suspense;
773
+ }
774
+ return base;
775
+ }, [cache, config, suspense]);
776
+ return /* @__PURE__ */ jsx(QuerySuspenseContext.Provider, { value: suspense, children: /* @__PURE__ */ jsx(SWRConfig, { value, children }) });
777
+ }
778
+ __name(SolanaQueryProvider, "SolanaQueryProvider");
779
+ function SolanaProvider({ children, client, config, query, walletPersistence }) {
780
+ const shouldIncludeQueryLayer = query !== false && query?.disabled !== true;
781
+ const queryProps = shouldIncludeQueryLayer && query ? query : {};
782
+ const persistenceConfig = walletPersistence === false ? void 0 : walletPersistence ?? {};
783
+ const content = shouldIncludeQueryLayer ? /* @__PURE__ */ jsx(
784
+ SolanaQueryProvider,
785
+ {
786
+ config: queryProps.config,
787
+ resetOnClusterChange: queryProps.resetOnClusterChange,
788
+ suspense: queryProps.suspense,
789
+ children
790
+ }
791
+ ) : children;
792
+ return /* @__PURE__ */ jsxs(SolanaClientProvider, { client, config, children: [
793
+ persistenceConfig ? /* @__PURE__ */ jsx(WalletPersistence, { ...persistenceConfig }) : null,
794
+ content
795
+ ] });
796
+ }
797
+ __name(SolanaProvider, "SolanaProvider");
798
+ var DEFAULT_STORAGE_KEY = "solana:last-connector";
799
+ function WalletPersistence({ autoConnect = true, storage, storageKey = DEFAULT_STORAGE_KEY }) {
800
+ const wallet = useWallet();
801
+ const connectWallet = useConnectWallet();
802
+ const client = useSolanaClient();
803
+ const storageRef = useRef(storage ?? getDefaultStorage());
804
+ const [hasAttemptedAutoConnect, setHasAttemptedAutoConnect] = useState(false);
805
+ const hasPersistedConnectorRef = useRef(false);
806
+ const clientRef = useRef(null);
807
+ useEffect(() => {
808
+ storageRef.current = storage ?? getDefaultStorage();
809
+ }, [storage]);
810
+ useEffect(() => {
811
+ if (clientRef.current !== client) {
812
+ clientRef.current = client;
813
+ setHasAttemptedAutoConnect(false);
814
+ }
815
+ }, [client]);
816
+ useEffect(() => {
817
+ const activeStorage = storageRef.current;
818
+ if (!activeStorage) return;
819
+ if ("connectorId" in wallet && wallet.connectorId) {
820
+ const connectorId = wallet.connectorId;
821
+ if (connectorId) {
822
+ safelyWrite(() => activeStorage.setItem(storageKey, connectorId));
823
+ hasPersistedConnectorRef.current = true;
824
+ return;
825
+ }
826
+ }
827
+ if (wallet.status === "disconnected" && hasPersistedConnectorRef.current) {
828
+ safelyWrite(() => activeStorage.removeItem(storageKey));
829
+ hasPersistedConnectorRef.current = false;
830
+ }
831
+ }, [storageKey, wallet]);
832
+ useEffect(() => {
833
+ if (!autoConnect || hasAttemptedAutoConnect) {
834
+ return;
835
+ }
836
+ if (wallet.status === "connected" || wallet.status === "connecting") {
837
+ setHasAttemptedAutoConnect(true);
838
+ return;
839
+ }
840
+ const activeStorage = storageRef.current;
841
+ if (!activeStorage) {
842
+ setHasAttemptedAutoConnect(true);
843
+ return;
844
+ }
845
+ let cancelled = false;
846
+ const connectorId = safelyRead(() => activeStorage.getItem(storageKey));
847
+ if (!connectorId) {
848
+ setHasAttemptedAutoConnect(true);
849
+ return;
850
+ }
851
+ const connector = client.connectors.get(connectorId);
852
+ if (!connector) {
853
+ return;
854
+ }
855
+ void (async () => {
856
+ try {
857
+ await connectWallet(connectorId, { autoConnect: true });
858
+ } catch {
859
+ } finally {
860
+ if (!cancelled) {
861
+ setHasAttemptedAutoConnect(true);
862
+ }
863
+ }
864
+ })();
865
+ return () => {
866
+ cancelled = true;
867
+ };
868
+ }, [autoConnect, client, connectWallet, hasAttemptedAutoConnect, storageKey, wallet.status]);
869
+ return null;
870
+ }
871
+ __name(WalletPersistence, "WalletPersistence");
872
+ function safelyRead(reader) {
873
+ try {
874
+ return reader();
875
+ } catch {
876
+ return null;
877
+ }
878
+ }
879
+ __name(safelyRead, "safelyRead");
880
+ function safelyWrite(writer) {
881
+ try {
882
+ writer();
883
+ } catch {
884
+ }
885
+ }
886
+ __name(safelyWrite, "safelyWrite");
887
+ function getDefaultStorage() {
888
+ if (typeof globalThis !== "object" || globalThis === null) {
889
+ return null;
890
+ }
891
+ const candidate = globalThis.localStorage;
892
+ if (!candidate) {
893
+ return null;
894
+ }
895
+ return candidate;
896
+ }
897
+ __name(getDefaultStorage, "getDefaultStorage");
898
+ function useWalletConnection(options = {}) {
899
+ const wallet = useWallet();
900
+ const connectWallet = useConnectWallet();
901
+ const disconnectWallet = useDisconnectWallet();
902
+ const discovered = useWalletStandardConnectors(options.discoveryOptions);
903
+ const connectors = options.connectors ?? discovered;
904
+ const connect = useCallback(
905
+ (connectorId, connectOptions) => connectWallet(connectorId, connectOptions),
906
+ [connectWallet]
907
+ );
908
+ const disconnect = useCallback(() => disconnectWallet(), [disconnectWallet]);
909
+ const state = useMemo(() => {
910
+ const connectorId = "connectorId" in wallet ? wallet.connectorId : void 0;
911
+ const session = wallet.status === "connected" ? wallet.session : void 0;
912
+ const error = wallet.status === "error" ? wallet.error ?? null : null;
913
+ return {
914
+ connect,
915
+ connected: wallet.status === "connected",
916
+ connecting: wallet.status === "connecting",
917
+ connectors,
918
+ connectorId,
919
+ disconnect,
920
+ error,
921
+ status: wallet.status,
922
+ wallet: session
923
+ };
924
+ }, [connect, connectors, disconnect, wallet]);
925
+ return state;
926
+ }
927
+ __name(useWalletConnection, "useWalletConnection");
928
+ function WalletConnectionManager({ children, connectors, discoveryOptions }) {
929
+ const state = useWalletConnection({ connectors, discoveryOptions });
930
+ return /* @__PURE__ */ jsx(Fragment, { children: children(state) });
931
+ }
932
+ __name(WalletConnectionManager, "WalletConnectionManager");
933
+ function useWalletModalState(options = {}) {
934
+ const connection = useWalletConnection(options);
935
+ const [isOpen, setIsOpen] = useState(options.initialOpen ?? false);
936
+ const [selectedConnector, setSelectedConnector] = useState(null);
937
+ const closeOnConnect = options.closeOnConnect ?? true;
938
+ const open = useCallback(() => setIsOpen(true), []);
939
+ const close = useCallback(() => setIsOpen(false), []);
940
+ const toggle = useCallback(() => setIsOpen((value) => !value), []);
941
+ const select = useCallback((connectorId) => setSelectedConnector(connectorId), []);
942
+ const connect = useCallback(
943
+ async (connectorId, connectOptions) => {
944
+ await connection.connect(connectorId, connectOptions);
945
+ setSelectedConnector(connectorId);
946
+ if (closeOnConnect) {
947
+ setIsOpen(false);
948
+ }
949
+ },
950
+ [closeOnConnect, connection]
951
+ );
952
+ return {
953
+ ...connection,
954
+ close,
955
+ connect,
956
+ isOpen,
957
+ open,
958
+ selectedConnector,
959
+ select,
960
+ toggle
961
+ };
962
+ }
963
+ __name(useWalletModalState, "useWalletModalState");
964
+ function useSignAndSendTransaction(uiWalletAccount, chain) {
965
+ const signAndSendTransactions = useSignAndSendTransactions(uiWalletAccount, chain);
966
+ return useCallback(
967
+ async (input) => {
968
+ const [result] = await signAndSendTransactions(input);
969
+ return result;
970
+ },
971
+ [signAndSendTransactions]
972
+ );
973
+ }
974
+ __name(useSignAndSendTransaction, "useSignAndSendTransaction");
975
+ function useSignAndSendTransactions(uiWalletAccount, chain) {
976
+ if (!uiWalletAccount.chains.includes(chain)) {
977
+ throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {
978
+ address: uiWalletAccount.address,
979
+ chain,
980
+ featureName: SolanaSignAndSendTransaction,
981
+ supportedChains: [...uiWalletAccount.chains],
982
+ supportedFeatures: [...uiWalletAccount.features]
983
+ });
984
+ }
985
+ const signAndSendTransactionFeature = getWalletAccountFeature(
986
+ uiWalletAccount,
987
+ SolanaSignAndSendTransaction
988
+ );
989
+ const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
990
+ return useCallback(
991
+ async (...inputs) => {
992
+ const inputsWithChainAndAccount = inputs.map(({ options, ...rest }) => {
993
+ const minContextSlot = options?.minContextSlot;
994
+ return {
995
+ ...rest,
996
+ account,
997
+ chain,
998
+ ...minContextSlot != null ? {
999
+ options: {
1000
+ minContextSlot: Number(minContextSlot)
1001
+ }
1002
+ } : null
1003
+ };
1004
+ });
1005
+ const results = await signAndSendTransactionFeature.signAndSendTransaction(...inputsWithChainAndAccount);
1006
+ return results;
1007
+ },
1008
+ [account, chain, signAndSendTransactionFeature]
1009
+ );
1010
+ }
1011
+ __name(useSignAndSendTransactions, "useSignAndSendTransactions");
1012
+ function useSignIn(uiWalletHandle) {
1013
+ const signIns = useSignIns(uiWalletHandle);
1014
+ return useCallback(
1015
+ async (input) => {
1016
+ const [result] = await signIns(input);
1017
+ return result;
1018
+ },
1019
+ [signIns]
1020
+ );
1021
+ }
1022
+ __name(useSignIn, "useSignIn");
1023
+ function useSignIns(uiWalletHandle) {
1024
+ let signMessageFeature;
1025
+ if ("address" in uiWalletHandle && typeof uiWalletHandle.address === "string") {
1026
+ getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle);
1027
+ signMessageFeature = getWalletAccountFeature(
1028
+ uiWalletHandle,
1029
+ SolanaSignIn
1030
+ );
1031
+ } else {
1032
+ signMessageFeature = getWalletFeature(uiWalletHandle, SolanaSignIn);
1033
+ }
1034
+ const wallet = getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle);
1035
+ return useCallback(
1036
+ async (...inputs) => {
1037
+ const inputsWithAddressAndChainId = inputs.map((input) => ({
1038
+ ...input,
1039
+ // Prioritize the `UiWalletAccount` address if it exists.
1040
+ ..."address" in uiWalletHandle ? { address: uiWalletHandle.address } : null
1041
+ }));
1042
+ const results = await signMessageFeature.signIn(...inputsWithAddressAndChainId);
1043
+ const resultsWithoutSignatureType = results.map(
1044
+ ({
1045
+ account,
1046
+ signatureType: _signatureType,
1047
+ // Solana signatures are always of type `ed25519` so drop this property.
1048
+ ...rest
1049
+ }) => ({
1050
+ ...rest,
1051
+ account: getOrCreateUiWalletAccountForStandardWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(
1052
+ wallet,
1053
+ account
1054
+ )
1055
+ })
1056
+ );
1057
+ return resultsWithoutSignatureType;
1058
+ },
1059
+ [signMessageFeature, uiWalletHandle, wallet]
1060
+ );
1061
+ }
1062
+ __name(useSignIns, "useSignIns");
1063
+ function useSignMessage(...config) {
1064
+ const signMessages = useSignMessages(...config);
1065
+ return useCallback(
1066
+ async (input) => {
1067
+ const [result] = await signMessages(input);
1068
+ return result;
1069
+ },
1070
+ [signMessages]
1071
+ );
1072
+ }
1073
+ __name(useSignMessage, "useSignMessage");
1074
+ function useSignMessages(uiWalletAccount) {
1075
+ const signMessageFeature = getWalletAccountFeature(
1076
+ uiWalletAccount,
1077
+ SolanaSignMessage
1078
+ );
1079
+ const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
1080
+ return useCallback(
1081
+ async (...inputs) => {
1082
+ const inputsWithAccount = inputs.map((input) => ({ ...input, account }));
1083
+ const results = await signMessageFeature.signMessage(...inputsWithAccount);
1084
+ const resultsWithoutSignatureType = results.map(
1085
+ ({
1086
+ signatureType: _signatureType,
1087
+ // Solana signatures are always of type `ed25519` so drop this property.
1088
+ ...rest
1089
+ }) => rest
1090
+ );
1091
+ return resultsWithoutSignatureType;
1092
+ },
1093
+ [signMessageFeature, account]
1094
+ );
1095
+ }
1096
+ __name(useSignMessages, "useSignMessages");
1097
+ function useSignTransaction(uiWalletAccount, chain) {
1098
+ const signTransactions = useSignTransactions(uiWalletAccount, chain);
1099
+ return useCallback(
1100
+ async (input) => {
1101
+ const [result] = await signTransactions(input);
1102
+ return result;
1103
+ },
1104
+ [signTransactions]
1105
+ );
1106
+ }
1107
+ __name(useSignTransaction, "useSignTransaction");
1108
+ function useSignTransactions(uiWalletAccount, chain) {
1109
+ if (!uiWalletAccount.chains.includes(chain)) {
1110
+ throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {
1111
+ address: uiWalletAccount.address,
1112
+ chain,
1113
+ featureName: SolanaSignAndSendTransaction,
1114
+ supportedChains: [...uiWalletAccount.chains],
1115
+ supportedFeatures: [...uiWalletAccount.features]
1116
+ });
1117
+ }
1118
+ const signTransactionFeature = getWalletAccountFeature(
1119
+ uiWalletAccount,
1120
+ SolanaSignTransaction
1121
+ );
1122
+ const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
1123
+ return useCallback(
1124
+ async (...inputs) => {
1125
+ const inputsWithAccountAndChain = inputs.map(({ options, ...rest }) => {
1126
+ const minContextSlot = options?.minContextSlot;
1127
+ return {
1128
+ ...rest,
1129
+ account,
1130
+ chain,
1131
+ ...minContextSlot != null ? {
1132
+ options: {
1133
+ minContextSlot: Number(minContextSlot)
1134
+ }
1135
+ } : null
1136
+ };
1137
+ });
1138
+ const results = await signTransactionFeature.signTransaction(...inputsWithAccountAndChain);
1139
+ return results;
1140
+ },
1141
+ [signTransactionFeature, account, chain]
1142
+ );
1143
+ }
1144
+ __name(useSignTransactions, "useSignTransactions");
1145
+ function useWalletAccountMessageSigner(uiWalletAccount) {
1146
+ const signMessage = useSignMessage(uiWalletAccount);
1147
+ return useMemo(
1148
+ () => ({
1149
+ address: address(uiWalletAccount.address),
1150
+ async modifyAndSignMessages(messages, config) {
1151
+ config?.abortSignal?.throwIfAborted();
1152
+ if (messages.length > 1) {
1153
+ throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
1154
+ }
1155
+ if (messages.length === 0) {
1156
+ return messages;
1157
+ }
1158
+ const { content: originalMessage, signatures: originalSignatureMap } = messages[0];
1159
+ const input = {
1160
+ message: originalMessage
1161
+ };
1162
+ const { signedMessage, signature } = await getAbortablePromise(signMessage(input), config?.abortSignal);
1163
+ const messageWasModified = originalMessage.length !== signedMessage.length || originalMessage.some((originalByte, ii) => originalByte !== signedMessage[ii]);
1164
+ const originalSignature = originalSignatureMap[uiWalletAccount.address];
1165
+ const signatureIsNew = !originalSignature?.every((originalByte, ii) => originalByte === signature[ii]);
1166
+ if (!signatureIsNew && !messageWasModified) {
1167
+ return messages;
1168
+ }
1169
+ const nextSignatureMap = messageWasModified ? { [uiWalletAccount.address]: signature } : { ...originalSignatureMap, [uiWalletAccount.address]: signature };
1170
+ const outputMessages = Object.freeze([
1171
+ Object.freeze({
1172
+ content: signedMessage,
1173
+ signatures: Object.freeze(nextSignatureMap)
1174
+ })
1175
+ ]);
1176
+ return outputMessages;
1177
+ }
1178
+ }),
1179
+ [uiWalletAccount, signMessage]
1180
+ );
1181
+ }
1182
+ __name(useWalletAccountMessageSigner, "useWalletAccountMessageSigner");
1183
+ function useWalletAccountTransactionSigner(uiWalletAccount, chain) {
1184
+ const encoderRef = useRef(null);
1185
+ const signTransaction = useSignTransaction(uiWalletAccount, chain);
1186
+ return useMemo(
1187
+ () => ({
1188
+ address: address(uiWalletAccount.address),
1189
+ async modifyAndSignTransactions(transactions, config = {}) {
1190
+ const { abortSignal, ...options } = config;
1191
+ abortSignal?.throwIfAborted();
1192
+ let transactionCodec = encoderRef.current;
1193
+ if (!transactionCodec) {
1194
+ transactionCodec = getTransactionCodec();
1195
+ encoderRef.current = transactionCodec;
1196
+ }
1197
+ if (transactions.length > 1) {
1198
+ throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
1199
+ }
1200
+ if (transactions.length === 0) {
1201
+ return transactions;
1202
+ }
1203
+ const [transaction] = transactions;
1204
+ const wireTransactionBytes = transactionCodec.encode(transaction);
1205
+ const inputWithOptions = {
1206
+ ...options,
1207
+ transaction: wireTransactionBytes
1208
+ };
1209
+ const { signedTransaction } = await getAbortablePromise(signTransaction(inputWithOptions), abortSignal);
1210
+ const decodedSignedTransaction = transactionCodec.decode(
1211
+ signedTransaction
1212
+ );
1213
+ assertIsTransactionWithinSizeLimit(decodedSignedTransaction);
1214
+ const existingLifetime = "lifetimeConstraint" in transaction ? transaction.lifetimeConstraint : void 0;
1215
+ if (existingLifetime) {
1216
+ if (uint8ArraysEqual(decodedSignedTransaction.messageBytes, transaction.messageBytes)) {
1217
+ return Object.freeze([
1218
+ {
1219
+ ...decodedSignedTransaction,
1220
+ lifetimeConstraint: existingLifetime
1221
+ }
1222
+ ]);
1223
+ }
1224
+ const compiledTransactionMessage2 = getCompiledTransactionMessageDecoder().decode(
1225
+ decodedSignedTransaction.messageBytes
1226
+ );
1227
+ const currentToken = "blockhash" in existingLifetime ? existingLifetime.blockhash : existingLifetime.nonce;
1228
+ if (compiledTransactionMessage2.lifetimeToken === currentToken) {
1229
+ return Object.freeze([
1230
+ {
1231
+ ...decodedSignedTransaction,
1232
+ lifetimeConstraint: existingLifetime
1233
+ }
1234
+ ]);
1235
+ }
1236
+ }
1237
+ const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(
1238
+ decodedSignedTransaction.messageBytes
1239
+ );
1240
+ const lifetimeConstraint = await getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage);
1241
+ return Object.freeze([
1242
+ {
1243
+ ...decodedSignedTransaction,
1244
+ lifetimeConstraint
1245
+ }
1246
+ ]);
1247
+ }
1248
+ }),
1249
+ [uiWalletAccount.address, signTransaction]
1250
+ );
1251
+ }
1252
+ __name(useWalletAccountTransactionSigner, "useWalletAccountTransactionSigner");
1253
+ function uint8ArraysEqual(arr1, arr2) {
1254
+ return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
1255
+ }
1256
+ __name(uint8ArraysEqual, "uint8ArraysEqual");
1257
+ function useWalletAccountTransactionSendingSigner(uiWalletAccount, chain) {
1258
+ const encoderRef = useRef(null);
1259
+ const signAndSendTransaction = useSignAndSendTransaction(uiWalletAccount, chain);
1260
+ return useMemo(
1261
+ () => ({
1262
+ address: address(uiWalletAccount.address),
1263
+ async signAndSendTransactions(transactions, config = {}) {
1264
+ const { abortSignal, ...options } = config;
1265
+ abortSignal?.throwIfAborted();
1266
+ let transactionEncoder = encoderRef.current;
1267
+ if (!transactionEncoder) {
1268
+ transactionEncoder = getTransactionEncoder();
1269
+ encoderRef.current = transactionEncoder;
1270
+ }
1271
+ if (transactions.length > 1) {
1272
+ throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
1273
+ }
1274
+ if (transactions.length === 0) {
1275
+ return [];
1276
+ }
1277
+ const [transaction] = transactions;
1278
+ const wireTransactionBytes = transactionEncoder.encode(transaction);
1279
+ const inputWithOptions = {
1280
+ ...options,
1281
+ transaction: wireTransactionBytes
1282
+ };
1283
+ const { signature } = await getAbortablePromise(signAndSendTransaction(inputWithOptions), abortSignal);
1284
+ return Object.freeze([signature]);
1285
+ }
1286
+ }),
1287
+ [signAndSendTransaction, uiWalletAccount.address]
1288
+ );
1289
+ }
1290
+ __name(useWalletAccountTransactionSendingSigner, "useWalletAccountTransactionSendingSigner");
1291
+
1292
+ export { SolanaClientProvider, SolanaProvider, SolanaQueryProvider, WalletConnectionManager, useAccount, useBalance, useClientStore, useClusterState, useClusterStatus, useConnectWallet, useDisconnectWallet, useLatestBlockhash, useProgramAccounts, useSendTransaction, useSignAndSendTransaction, useSignIn, useSignMessage, useSignTransaction, useSignatureStatus, useSimulateTransaction, useSolTransfer, useSolanaClient, useSplToken, useTransactionPool, useWaitForSignature, useWallet, useWalletAccountMessageSigner, useWalletAccountTransactionSendingSigner, useWalletAccountTransactionSigner, useWalletActions, useWalletConnection, useWalletModalState, useWalletSession, useWalletStandardConnectors };
1293
+ //# sourceMappingURL=index.native.mjs.map
1294
+ //# sourceMappingURL=index.native.mjs.map