@solana/react-hooks 1.1.2 → 1.1.4

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