@vue-solana/vue 3.0.0 → 4.0.0-rc.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.
- package/README.md +8 -4
- package/dist/index.d.ts +12 -0
- package/dist/index.mjs +81 -58
- package/dist/shared/{vue.CjSw0Hh1.mjs → vue.4ne5EBD9.mjs} +4 -4
- package/dist/shared/{vue.C9OOmvkD.mjs → vue.BBN9aU6D.mjs} +2 -2
- package/dist/shared/{vue.CsFY1mfz.mjs → vue.BXNjyJ2c.mjs} +1 -1
- package/dist/shared/{vue.DlihC5GG.mjs → vue.BiKE9Xuv.mjs} +6 -4
- package/dist/shared/{vue.CXB4NEMA.mjs → vue.Bu2cQ690.mjs} +47 -17
- package/dist/shared/{vue.CpkwC8Th.mjs → vue.C6OkOK2W.mjs} +1 -1
- package/dist/shared/{vue.B9uRpSDJ.mjs → vue.CAltY57B.mjs} +6 -3
- package/dist/shared/{vue.DDQxNX5q.mjs → vue.CELGI7de.mjs} +9 -9
- package/dist/shared/{vue.BxtOHzY_.mjs → vue.CLAqNcLp.mjs} +1 -1
- package/dist/shared/{vue.hG_FieA3.mjs → vue.CW-1AuSO.mjs} +2 -2
- package/dist/shared/{vue.Mxc8w6Qk.mjs → vue.CZApWQAY.mjs} +1 -1
- package/dist/shared/vue.CbmzveKF.mjs +44 -0
- package/dist/shared/{vue.CQh3AUE8.mjs → vue.CcOZ9858.mjs} +3 -5
- package/dist/shared/{vue.B-xtuLtD.mjs → vue.D2J7_NpQ.mjs} +2 -2
- package/dist/shared/{vue.BsGwt78R.mjs → vue.D8zNWw2t.mjs} +1 -1
- package/dist/shared/{vue.CaAgH2Xt.mjs → vue.DPwdqRO_.mjs} +3 -3
- package/dist/shared/{vue.DNKD6jqM.mjs → vue.DTpvqDyY.mjs} +3 -3
- package/dist/shared/{vue.D218Ow7t.mjs → vue.DY9VadLH.mjs} +1 -8
- package/dist/shared/vue.DZVdVfy1.mjs +7 -0
- package/dist/shared/{vue.CvenSbZZ.mjs → vue.DZhPXLZz.mjs} +4 -4
- package/dist/shared/{vue.o98pAmDg.mjs → vue.DbJG4-ku.mjs} +2 -2
- package/dist/shared/{vue.BFSboXMB.mjs → vue.DbJKnSrl.mjs} +3 -3
- package/dist/shared/{vue.1Qwco2kv.mjs → vue.DcZ_R_RH.mjs} +4 -4
- package/dist/shared/{vue.C_4qJDiF.mjs → vue.DyLgoSbX.mjs} +1 -1
- package/dist/shared/{vue.XlfH_nkc.mjs → vue.FehFeE3w.mjs} +3 -3
- package/dist/shared/{vue.C1JbUTpJ.mjs → vue.UrCjmf0T.mjs} +2 -2
- package/dist/swr.d.ts +7 -1
- package/dist/swr.mjs +16 -4
- package/dist/useAccountInfo.mjs +1 -10
- package/dist/useAction.mjs +0 -2
- package/dist/useAirdrop.mjs +1 -8
- package/dist/useBalance.mjs +1 -9
- package/dist/useClientCapability.d.ts +6 -1
- package/dist/useClientCapability.mjs +1 -5
- package/dist/useConnection.d.ts +8 -1
- package/dist/useConnection.mjs +1 -5
- package/dist/useIdentity.mjs +1 -6
- package/dist/usePayer.mjs +1 -6
- package/dist/usePlanTransaction.mjs +1 -8
- package/dist/usePlanTransactions.mjs +1 -8
- package/dist/useProgramAccounts.mjs +1 -10
- package/dist/useRequest.mjs +0 -4
- package/dist/useRpc.d.ts +6 -0
- package/dist/useRpc.mjs +1 -4
- package/dist/useSelectedWalletAccount.d.ts +3 -0
- package/dist/useSelectedWalletAccount.mjs +0 -2
- package/dist/useSendTransaction.mjs +1 -8
- package/dist/useSendTransactions.mjs +1 -8
- package/dist/useSignAndSendTransaction.mjs +1 -13
- package/dist/useSignAndSendTransactions.mjs +1 -9
- package/dist/useSignIn.mjs +1 -8
- package/dist/useSignMessage.mjs +1 -8
- package/dist/useSignTransactions.mjs +1 -8
- package/dist/useSignatureStatus.d.ts +0 -1
- package/dist/useSignatureStatus.mjs +1 -8
- package/dist/useSolana.mjs +1 -3
- package/dist/useSolanaClient.d.ts +6 -0
- package/dist/useSolanaClient.mjs +1 -4
- package/dist/useSubscription.mjs +0 -2
- package/dist/useTokenAccounts.mjs +1 -10
- package/dist/useTokenBalance.mjs +1 -10
- package/dist/useTrackedData.mjs +0 -3
- package/dist/useTransaction.mjs +0 -4
- package/dist/useTransactionConfirmation.mjs +1 -9
- package/dist/useWallet.mjs +1 -6
- package/dist/useWallets.mjs +1 -4
- package/package.json +8 -5
- package/dist/buffer-polyfill.d.mts +0 -2
- package/dist/index.d.mts +0 -64
- package/dist/kit.d.mts +0 -1
- package/dist/shared/vue.BGGixph-.d.mts +0 -5
- package/dist/shared/vue.Bfu1dCKe.mjs +0 -10
- package/dist/shared/vue.CGv0ip3w.mjs +0 -52
- package/dist/shared/vue.DL3z5PxP.d.mts +0 -21
- package/dist/swr.d.mts +0 -41
- package/dist/useAccountInfo.d.mts +0 -24
- package/dist/useAction.d.mts +0 -45
- package/dist/useAirdrop.d.mts +0 -27
- package/dist/useBalance.d.mts +0 -15
- package/dist/useClientCapability.d.mts +0 -39
- package/dist/useConnection.d.mts +0 -46
- package/dist/useIdentity.d.mts +0 -3
- package/dist/usePayer.d.mts +0 -18
- package/dist/usePlanTransaction.d.mts +0 -44
- package/dist/usePlanTransactions.d.mts +0 -5
- package/dist/useProgramAccounts.d.mts +0 -45
- package/dist/useRequest.d.mts +0 -73
- package/dist/useRpc.d.mts +0 -55
- package/dist/useSelectedWalletAccount.d.mts +0 -117
- package/dist/useSendTransaction.d.mts +0 -50
- package/dist/useSendTransactions.d.mts +0 -5
- package/dist/useSignAndSendTransaction.d.mts +0 -40
- package/dist/useSignAndSendTransactions.d.mts +0 -35
- package/dist/useSignIn.d.mts +0 -23
- package/dist/useSignMessage.d.mts +0 -236
- package/dist/useSignTransactions.d.mts +0 -24
- package/dist/useSignatureStatus.d.mts +0 -26
- package/dist/useSolana.d.mts +0 -9
- package/dist/useSolanaClient.d.mts +0 -45
- package/dist/useSubscription.d.mts +0 -70
- package/dist/useTokenAccounts.d.mts +0 -19
- package/dist/useTokenBalance.d.mts +0 -17
- package/dist/useTrackedData.d.mts +0 -98
- package/dist/useTransaction.d.mts +0 -27
- package/dist/useTransactionConfirmation.d.mts +0 -38
- package/dist/useWallet.d.mts +0 -31
- package/dist/useWallets.d.mts +0 -11
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ createApp(App).use(
|
|
|
98
98
|
|
|
99
99
|
Supported clusters are `mainnet` (legacy alias `mainnet-beta`), `devnet`, `testnet`, and `localnet`. Use `mainnet` for Solana mainnet; this is Solana's official mainnet cluster name.
|
|
100
100
|
|
|
101
|
-
`payer` and `payerSecretKey` are supported by direct Vue/core clients. A client-sent transaction requires a payer. Never put a raw secret or `payerSecretKey` in Nuxt public runtime config, and never ship a funded signing key to an end-user browser. The default `createSolanaPlugin()` client composes
|
|
101
|
+
`payer` and `payerSecretKey` are supported by direct Vue/core clients. A client-sent transaction requires a payer. Never put a raw secret or `payerSecretKey` in Nuxt public runtime config, and never ship a funded signing key to an end-user browser. The default `createSolanaPlugin()` client composes `solanaRpc()` followed by `rpcAirdrop()`; `solanaRpc()` installs `rpcTransactionPlanner()`, `rpcTransactionPlanSigningExecutor()`, and `rpcTransactionPlanSendingExecutor()` itself, so the client exposes RPC reads and subscriptions plus `planTransaction(s)`, `signTransaction(s)`, and `sendTransaction(s)` with no extra plugin. The old custom fallback sender is not used.
|
|
102
102
|
|
|
103
103
|
### Plugin Options
|
|
104
104
|
|
|
@@ -312,7 +312,7 @@ async function signIn() {
|
|
|
312
312
|
</template>
|
|
313
313
|
```
|
|
314
314
|
|
|
315
|
-
Message signing proves wallet ownership for flows like authentication challenges. It does not sign, submit, or authorize Solana transactions. For authentication, issue a server-generated nonce, include domain and expiration details in the message, and verify the returned signature server-side.
|
|
315
|
+
Message signing proves wallet ownership for flows like authentication challenges. It does not sign, submit, or authorize Solana transactions. For authentication, issue a server-generated nonce, include domain and expiration details in the message, and verify the returned signature server-side. The adapter also checks the signature against the account's public key before resolving, where Ed25519 (WebCrypto) is available — a best-effort client-side guard that rejects with `INVALID_SIGNATURE`, not a replacement for server-side verification.
|
|
316
316
|
|
|
317
317
|
## Transaction State
|
|
318
318
|
|
|
@@ -391,7 +391,7 @@ Configure a direct client with `payer` or `payerSecretKey`. `payerSecretKey` is
|
|
|
391
391
|
|
|
392
392
|
Use the client flow for automated or server-backed signing (airdrop faucet, cron jobs, relayer fees paid by your keypair), and the wallet flow when the end user must own and approve each transaction.
|
|
393
393
|
|
|
394
|
-
**Default client composition.** `createSolanaPlugin()` and `createSolanaClient()`
|
|
394
|
+
**Default client composition.** `createSolanaPlugin()` and `createSolanaClient()` compose `solanaRpc()` followed by `rpcAirdrop()` by default; `solanaRpc()` installs `rpcTransactionPlanner()`, `rpcTransactionPlanSigningExecutor()`, and `rpcTransactionPlanSendingExecutor()` itself. The old custom fallback sender is not used, so `useSendTransaction()` and `useSendTransactions()` do not need a second manual plugin installation. The official executor waits for `confirmed` commitment before `execute()` resolves and the composable reports `sent`. A custom client must still provide the planner and sending executor and a `payer`.
|
|
395
395
|
|
|
396
396
|
```ts
|
|
397
397
|
import { useSendTransaction } from "@vue-solana/vue/useSendTransaction";
|
|
@@ -488,6 +488,8 @@ import { useRequestSwr } from "@vue-solana/vue/swr";
|
|
|
488
488
|
const balance = useRequestSwr(["balance", address], () => client.rpc.getBalance(address).send());
|
|
489
489
|
```
|
|
490
490
|
|
|
491
|
+
The SWR cache is module-level and shared across the whole app, including across SSR requests. Namespace cache keys per request (for example by including a request or session id) or call `clearSwrCache()` at the start of each server request to avoid leaking one request's cached data into another. On the client the cache is intentionally shared for stale-while-revalidate seeding.
|
|
492
|
+
|
|
491
493
|
### Cancellation & Timeouts
|
|
492
494
|
|
|
493
495
|
`useRequest()`, `useSubscription()`, and `useTrackedData()` accept a `getAbortSignal` option — a factory called once per attempt (request) or connection (subscription/tracked data). It is the natural place for a timeout:
|
|
@@ -592,7 +594,9 @@ Docs: [Vue Solana Agent Skill](https://vue-solana-docs.vercel.app/agent-skill)
|
|
|
592
594
|
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
593
595
|
| `createSolanaPlugin(options?)` | Installs the Vue Solana context. |
|
|
594
596
|
| `VueSolana` | Alias for `createSolanaPlugin`. |
|
|
595
|
-
| `useSolana()` | Returns the full injected Solana context.
|
|
597
|
+
| `useSolana()` | Returns the full injected Solana context; throws when no plugin context is available. |
|
|
598
|
+
| `tryUseSolana()` | Returns the injected Solana context or `null` when no plugin context is available (SSR-safe). |
|
|
599
|
+
| `MissingClientCapabilityError` | Thrown by `useClientCapability()` (and client-sent composables) when the configured client lacks a required capability. |
|
|
596
600
|
| `useRpc()` | Returns cluster, endpoint, connection status, latest blockhash, the Kit `client`, and `checkConnection()`. |
|
|
597
601
|
| `useSolanaClient()` | Returns the injected Kit client as `{ client, rpc }`. The recommended RPC path. |
|
|
598
602
|
| `useConnection()` | Returns the Kit `client`. Deprecated in favor of `useSolanaClient()`. |
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,18 @@ interface VueSolanaPlugin {
|
|
|
56
56
|
* context to consumers that run outside a component setup.
|
|
57
57
|
*/
|
|
58
58
|
context: VueSolanaContext | null;
|
|
59
|
+
/**
|
|
60
|
+
* Stops the wallet discovery subscription and the deferred bootstrap started
|
|
61
|
+
* by `install`. Vue has no plugin unmount hook, so call this from an app
|
|
62
|
+
* teardown hook (`app.onUnmount` in Nuxt, after `app.unmount()` in Vue).
|
|
63
|
+
* Safe to call more than once and before `install`. Without it the Wallet
|
|
64
|
+
* Standard subscription outlives the app that created it. After `dispose()`,
|
|
65
|
+
* `refreshWallets()` is a no-op, so a late mobile-wallet import or manual
|
|
66
|
+
* call cannot resurrect the subscription. A connected wallet stays
|
|
67
|
+
* connected; `dispose()` does not disconnect it or abort an in-flight
|
|
68
|
+
* `connect()`.
|
|
69
|
+
*/
|
|
70
|
+
dispose(): void;
|
|
59
71
|
}
|
|
60
72
|
declare function createSolanaPlugin(options?: VueSolanaPluginOptions): VueSolanaPlugin;
|
|
61
73
|
declare const VueSolana: typeof createSolanaPlugin;
|
package/dist/index.mjs
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
export { u as useAccountInfo } from './shared/vue.
|
|
1
|
+
export { u as useAccountInfo } from './shared/vue.DZhPXLZz.mjs';
|
|
2
2
|
export { u as useAction } from './shared/vue.DYk0Xfr3.mjs';
|
|
3
|
-
export { u as useAirdrop } from './shared/vue.
|
|
4
|
-
export { u as useBalance } from './shared/vue.
|
|
5
|
-
export { M as MissingClientCapabilityError, u as useClientCapability } from './shared/vue.
|
|
6
|
-
export { u as useConnection } from './shared/vue.
|
|
7
|
-
export { u as usePlanTransaction, a as usePlanTransactions } from './shared/vue.
|
|
8
|
-
export { u as useProgramAccounts } from './shared/vue.
|
|
9
|
-
export { u as useIdentity, a as usePayer } from './shared/vue.
|
|
3
|
+
export { u as useAirdrop } from './shared/vue.CELGI7de.mjs';
|
|
4
|
+
export { u as useBalance } from './shared/vue.DbJKnSrl.mjs';
|
|
5
|
+
export { M as MissingClientCapabilityError, u as useClientCapability } from './shared/vue.CAltY57B.mjs';
|
|
6
|
+
export { u as useConnection } from './shared/vue.C6OkOK2W.mjs';
|
|
7
|
+
export { u as usePlanTransaction, a as usePlanTransactions } from './shared/vue.BXNjyJ2c.mjs';
|
|
8
|
+
export { u as useProgramAccounts } from './shared/vue.DcZ_R_RH.mjs';
|
|
9
|
+
export { u as useIdentity, a as usePayer } from './shared/vue.D2J7_NpQ.mjs';
|
|
10
10
|
export { u as useRequest } from './shared/vue.B8VvC8d2.mjs';
|
|
11
|
-
export { u as useRpc } from './shared/vue.
|
|
11
|
+
export { u as useRpc } from './shared/vue.D8zNWw2t.mjs';
|
|
12
12
|
export { S as SelectedWalletAccountProvider, c as createSelectedWalletAccountContext, p as provideSelectedWalletAccount, s as selectedWalletAccountInjectionKey, u as useSelectedWalletAccount } from './shared/vue.BngCaeXJ.mjs';
|
|
13
|
-
export { u as useSendTransaction, a as useSendTransactions } from './shared/vue.
|
|
14
|
-
export { u as useSignMessage } from './shared/vue.
|
|
15
|
-
export { u as useSignAndSendTransaction } from './shared/vue.
|
|
16
|
-
export { u as useSignTransactions } from './shared/vue.
|
|
17
|
-
export { P as PartialSignAndSendError, u as useSignAndSendTransactions } from './shared/vue.
|
|
18
|
-
export { u as useSignatureStatus } from './shared/vue.
|
|
19
|
-
export { u as useSignIn } from './shared/vue.
|
|
20
|
-
export { t as tryUseSolana, u as useSolana } from './shared/vue.
|
|
21
|
-
export { u as useSolanaClient } from './shared/vue.
|
|
13
|
+
export { u as useSendTransaction, a as useSendTransactions } from './shared/vue.CLAqNcLp.mjs';
|
|
14
|
+
export { u as useSignMessage } from './shared/vue.DbJG4-ku.mjs';
|
|
15
|
+
export { u as useSignAndSendTransaction } from './shared/vue.4ne5EBD9.mjs';
|
|
16
|
+
export { u as useSignTransactions } from './shared/vue.CW-1AuSO.mjs';
|
|
17
|
+
export { P as PartialSignAndSendError, u as useSignAndSendTransactions } from './shared/vue.UrCjmf0T.mjs';
|
|
18
|
+
export { u as useSignatureStatus } from './shared/vue.Bu2cQ690.mjs';
|
|
19
|
+
export { u as useSignIn } from './shared/vue.BBN9aU6D.mjs';
|
|
20
|
+
export { t as tryUseSolana, u as useSolana } from './shared/vue.CcOZ9858.mjs';
|
|
21
|
+
export { u as useSolanaClient } from './shared/vue.CZApWQAY.mjs';
|
|
22
22
|
export { u as useSubscription } from './shared/vue.D5pqR5Fa.mjs';
|
|
23
|
-
export { u as useTokenAccounts } from './shared/vue.
|
|
24
|
-
export { u as useTokenBalance } from './shared/vue.
|
|
23
|
+
export { u as useTokenAccounts } from './shared/vue.DTpvqDyY.mjs';
|
|
24
|
+
export { u as useTokenBalance } from './shared/vue.FehFeE3w.mjs';
|
|
25
25
|
export { u as useTrackedData } from './shared/vue.BNJTXSnQ.mjs';
|
|
26
26
|
export { u as useTransaction } from './shared/vue.5euWd6-V.mjs';
|
|
27
|
-
export { g as getConfirmedTransactionStatus, u as useTransactionConfirmation } from './shared/vue.
|
|
28
|
-
export { u as useWallet } from './shared/vue.
|
|
29
|
-
export { u as useWallets } from './shared/vue.
|
|
27
|
+
export { g as getConfirmedTransactionStatus, u as useTransactionConfirmation } from './shared/vue.DPwdqRO_.mjs';
|
|
28
|
+
export { u as useWallet } from './shared/vue.DY9VadLH.mjs';
|
|
29
|
+
export { u as useWallets } from './shared/vue.DyLgoSbX.mjs';
|
|
30
30
|
import { s as solanaInjectionKey } from './shared/vue.D_P5SqqD.mjs';
|
|
31
31
|
import { createSolanaError, normalizeSolanaError } from '@vue-solana/core/errors';
|
|
32
32
|
export { SolanaError, isSolanaError } from '@vue-solana/core/errors';
|
|
33
|
+
import { isSolanaMobileWalletSupported } from '@vue-solana/core/mobile-wallet-support';
|
|
33
34
|
import { createSolanaContext } from '@vue-solana/core/rpc';
|
|
34
35
|
import { withTimeout } from '@vue-solana/core/timeout';
|
|
35
36
|
import { getRegisteredSolanaWallets, getSolanaChain, adaptSolanaStandardWallet, subscribeSolanaWallets } from '@vue-solana/core/wallet-standard';
|
|
@@ -37,16 +38,6 @@ import { shallowRef, ref, triggerRef } from 'vue';
|
|
|
37
38
|
import { handleSolanaIosWalletCallback, getSolanaIosWallets, isSolanaIosWalletInfo, adaptSolanaIosWallet } from '@vue-solana/core/ios-wallet';
|
|
38
39
|
export * from '@vue-solana/core/types';
|
|
39
40
|
export * from '@vue-solana/core/kit';
|
|
40
|
-
import './shared/vue.BwBqla_n.mjs';
|
|
41
|
-
import '@vue-solana/core/address';
|
|
42
|
-
import './shared/vue.Bfu1dCKe.mjs';
|
|
43
|
-
import '@vue-solana/core/action';
|
|
44
|
-
import './shared/vue.CGv0ip3w.mjs';
|
|
45
|
-
import '@vue-solana/core/wallet';
|
|
46
|
-
import './shared/vue.DlihC5GG.mjs';
|
|
47
|
-
import '@vue-solana/core/transaction';
|
|
48
|
-
import 'bs58';
|
|
49
|
-
import '@vue-solana/core/token-accounts';
|
|
50
41
|
|
|
51
42
|
const SELECTED_WALLET_STORAGE_KEY = "vue-solana:selected-wallet";
|
|
52
43
|
function readSelectedWallet() {
|
|
@@ -123,20 +114,39 @@ function getLocalStorage() {
|
|
|
123
114
|
|
|
124
115
|
function createSolanaWalletRegistry(options) {
|
|
125
116
|
const adaptedWallets = /* @__PURE__ */ new WeakMap();
|
|
117
|
+
const adaptedPrimitiveWallets = /* @__PURE__ */ new Map();
|
|
118
|
+
const trackedAdapters = /* @__PURE__ */ new Set();
|
|
119
|
+
function trackAdapter(adapter) {
|
|
120
|
+
trackedAdapters.add(adapter);
|
|
121
|
+
return adapter;
|
|
122
|
+
}
|
|
126
123
|
function getAdaptedWallet(walletInfo) {
|
|
127
124
|
if (isSolanaIosWalletInfo(walletInfo)) {
|
|
128
|
-
|
|
125
|
+
const cachedIosWallet = adaptedWallets.get(walletInfo.wallet);
|
|
126
|
+
if (cachedIosWallet) {
|
|
127
|
+
return cachedIosWallet;
|
|
128
|
+
}
|
|
129
|
+
const iosAdapter = adaptSolanaIosWallet(walletInfo, {
|
|
129
130
|
chain: getSolanaChain(options.cluster),
|
|
130
131
|
cluster: options.cluster,
|
|
131
132
|
onChange: options.onWalletChange,
|
|
132
133
|
...options.iosWallet || {}
|
|
133
134
|
});
|
|
135
|
+
adaptedWallets.set(walletInfo.wallet, iosAdapter);
|
|
136
|
+
return trackAdapter(iosAdapter);
|
|
134
137
|
}
|
|
135
138
|
if (!isObject(walletInfo.wallet)) {
|
|
136
|
-
|
|
139
|
+
const primitiveKey = `${walletInfo.name}::${String(walletInfo.wallet)}`;
|
|
140
|
+
const cachedPrimitiveWallet = adaptedPrimitiveWallets.get(primitiveKey);
|
|
141
|
+
if (cachedPrimitiveWallet) {
|
|
142
|
+
return cachedPrimitiveWallet;
|
|
143
|
+
}
|
|
144
|
+
const primitiveAdapter = adaptSolanaStandardWallet(walletInfo, {
|
|
137
145
|
chain: getSolanaChain(options.cluster),
|
|
138
146
|
onChange: options.onWalletChange
|
|
139
147
|
});
|
|
148
|
+
adaptedPrimitiveWallets.set(primitiveKey, primitiveAdapter);
|
|
149
|
+
return trackAdapter(primitiveAdapter);
|
|
140
150
|
}
|
|
141
151
|
const cachedWallet = adaptedWallets.get(walletInfo.wallet);
|
|
142
152
|
if (cachedWallet) {
|
|
@@ -164,7 +174,7 @@ function createSolanaWalletRegistry(options) {
|
|
|
164
174
|
);
|
|
165
175
|
}
|
|
166
176
|
adaptedWallets.set(walletInfo.wallet, cachedAdapter);
|
|
167
|
-
return cachedAdapter;
|
|
177
|
+
return trackAdapter(cachedAdapter);
|
|
168
178
|
}
|
|
169
179
|
function getDiscoveredWallets() {
|
|
170
180
|
return [
|
|
@@ -180,7 +190,6 @@ function createSolanaWalletRegistry(options) {
|
|
|
180
190
|
try {
|
|
181
191
|
handleSolanaIosWalletCallback({ clearUrl: true });
|
|
182
192
|
} catch (cause) {
|
|
183
|
-
console.error("[Vue Solana] iOS wallet callback failed", cause);
|
|
184
193
|
}
|
|
185
194
|
}
|
|
186
195
|
function* getCachedWallets() {
|
|
@@ -193,10 +202,16 @@ function createSolanaWalletRegistry(options) {
|
|
|
193
202
|
}
|
|
194
203
|
}
|
|
195
204
|
}
|
|
205
|
+
function disposeAllAdaptedWallets() {
|
|
206
|
+
for (const adapter of trackedAdapters) {
|
|
207
|
+
adapter.dispose?.();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
196
210
|
return {
|
|
197
211
|
getAdaptedWallet,
|
|
198
212
|
getDiscoveredWallets,
|
|
199
|
-
handleIosWalletCallback
|
|
213
|
+
handleIosWalletCallback,
|
|
214
|
+
disposeAllAdaptedWallets
|
|
200
215
|
};
|
|
201
216
|
}
|
|
202
217
|
function isObject(value) {
|
|
@@ -205,6 +220,7 @@ function isObject(value) {
|
|
|
205
220
|
|
|
206
221
|
const RPC_CHECK_TIMEOUT_MS = 1e4;
|
|
207
222
|
function createSolanaPlugin(options = {}) {
|
|
223
|
+
let teardown = null;
|
|
208
224
|
const plugin = {
|
|
209
225
|
context: null,
|
|
210
226
|
install(app) {
|
|
@@ -225,15 +241,12 @@ function createSolanaPlugin(options = {}) {
|
|
|
225
241
|
let mobileWalletRegistrationPromise = null;
|
|
226
242
|
let attemptedAutoConnectWallet = null;
|
|
227
243
|
let rpcCheckId = 0;
|
|
244
|
+
let bootstrapId = 0;
|
|
245
|
+
let disposed = false;
|
|
228
246
|
async function checkConnection() {
|
|
229
247
|
const checkId = ++rpcCheckId;
|
|
230
248
|
status.value = "checking";
|
|
231
249
|
error.value = null;
|
|
232
|
-
console.info("[Vue Solana] Checking RPC connection", {
|
|
233
|
-
cluster: context.cluster,
|
|
234
|
-
endpoint: context.endpoint,
|
|
235
|
-
wsEndpoint: context.wsEndpoint
|
|
236
|
-
});
|
|
237
250
|
try {
|
|
238
251
|
const response = await withTimeout(
|
|
239
252
|
context.client.rpc.getLatestBlockhash().send(),
|
|
@@ -248,22 +261,18 @@ function createSolanaPlugin(options = {}) {
|
|
|
248
261
|
}
|
|
249
262
|
latestBlockhash.value = blockhash.blockhash;
|
|
250
263
|
status.value = "connected";
|
|
251
|
-
console.info("[Vue Solana] Connected", {
|
|
252
|
-
cluster: context.cluster,
|
|
253
|
-
endpoint: context.endpoint,
|
|
254
|
-
wsEndpoint: context.wsEndpoint,
|
|
255
|
-
blockhash
|
|
256
|
-
});
|
|
257
264
|
} catch (cause) {
|
|
258
265
|
if (checkId !== rpcCheckId) {
|
|
259
266
|
return;
|
|
260
267
|
}
|
|
261
268
|
status.value = "error";
|
|
262
269
|
error.value = normalizeSolanaError(cause, "RPC_FAILURE");
|
|
263
|
-
console.error("[Vue Solana] Connection failed", cause);
|
|
264
270
|
}
|
|
265
271
|
}
|
|
266
272
|
function refreshWallets() {
|
|
273
|
+
if (disposed) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
267
276
|
unsubscribeWallets ??= subscribeSolanaWallets(refreshWallets);
|
|
268
277
|
walletRegistry.handleIosWalletCallback();
|
|
269
278
|
wallets.value = walletRegistry.getDiscoveredWallets();
|
|
@@ -277,7 +286,6 @@ function createSolanaPlugin(options = {}) {
|
|
|
277
286
|
const persistedWallet = readSelectedWallet();
|
|
278
287
|
if (persistedWallet.error) {
|
|
279
288
|
error.value = persistedWallet.error;
|
|
280
|
-
console.error("[Vue Solana] Selected wallet restoration failed", persistedWallet.error);
|
|
281
289
|
}
|
|
282
290
|
restoredWallet = persistedWallet.wallet ? wallets.value.find(
|
|
283
291
|
(nextWallet) => isSameWallet(nextWallet, persistedWallet.wallet)
|
|
@@ -287,7 +295,7 @@ function createSolanaPlugin(options = {}) {
|
|
|
287
295
|
wallet.value = walletRegistry.getAdaptedWallet(restoredWallet);
|
|
288
296
|
}
|
|
289
297
|
}
|
|
290
|
-
if (options.mobileWallet !== false) {
|
|
298
|
+
if (options.mobileWallet !== false && isSolanaMobileWalletSupported()) {
|
|
291
299
|
registerMobileWallets();
|
|
292
300
|
}
|
|
293
301
|
if (restoredWallet) {
|
|
@@ -295,14 +303,19 @@ function createSolanaPlugin(options = {}) {
|
|
|
295
303
|
}
|
|
296
304
|
}
|
|
297
305
|
function registerMobileWallets() {
|
|
306
|
+
if (disposed) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
298
309
|
mobileWalletRegistrationPromise ??= import('@vue-solana/core/mobile-wallet').then(({ registerSolanaMobileWallet }) => {
|
|
310
|
+
if (disposed) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
299
313
|
registerSolanaMobileWallet({
|
|
300
314
|
chains: [getSolanaChain(context.cluster)],
|
|
301
315
|
...options.mobileWallet || {}
|
|
302
316
|
});
|
|
303
317
|
refreshWallets();
|
|
304
318
|
}).catch((cause) => {
|
|
305
|
-
console.error("[Vue Solana] Mobile wallet registration failed", cause);
|
|
306
319
|
}).finally(() => {
|
|
307
320
|
mobileWalletRegistrationPromise = null;
|
|
308
321
|
});
|
|
@@ -313,7 +326,6 @@ function createSolanaPlugin(options = {}) {
|
|
|
313
326
|
const storageError = writeSelectedWallet(nextWallet);
|
|
314
327
|
if (storageError) {
|
|
315
328
|
error.value = storageError;
|
|
316
|
-
console.error("[Vue Solana] Selected wallet persistence failed", storageError);
|
|
317
329
|
}
|
|
318
330
|
}
|
|
319
331
|
function autoConnectWallet(walletInfo) {
|
|
@@ -327,7 +339,6 @@ function createSolanaPlugin(options = {}) {
|
|
|
327
339
|
}
|
|
328
340
|
attemptedAutoConnectWallet = storageValue;
|
|
329
341
|
void activeWallet.connect().catch((cause) => {
|
|
330
|
-
console.error("[Vue Solana] Wallet auto-connect failed", cause);
|
|
331
342
|
}).finally(() => {
|
|
332
343
|
triggerRef(wallet);
|
|
333
344
|
});
|
|
@@ -349,22 +360,34 @@ function createSolanaPlugin(options = {}) {
|
|
|
349
360
|
const storageError = writeSelectedWallet(null);
|
|
350
361
|
if (storageError) {
|
|
351
362
|
error.value = storageError;
|
|
352
|
-
console.error("[Vue Solana] Selected wallet persistence failed", storageError);
|
|
353
363
|
}
|
|
354
364
|
}
|
|
355
365
|
};
|
|
356
366
|
app.provide(solanaInjectionKey, vueContext);
|
|
357
367
|
plugin.context = vueContext;
|
|
368
|
+
teardown = () => {
|
|
369
|
+
disposed = true;
|
|
370
|
+
if (typeof window !== "undefined") {
|
|
371
|
+
window.clearTimeout(bootstrapId);
|
|
372
|
+
}
|
|
373
|
+
unsubscribeWallets?.();
|
|
374
|
+
unsubscribeWallets = null;
|
|
375
|
+
walletRegistry.disposeAllAdaptedWallets();
|
|
376
|
+
rpcCheckId += 1;
|
|
377
|
+
teardown = null;
|
|
378
|
+
};
|
|
358
379
|
if (typeof window !== "undefined") {
|
|
359
|
-
window.setTimeout(() => {
|
|
380
|
+
bootstrapId = window.setTimeout(() => {
|
|
360
381
|
try {
|
|
361
382
|
refreshWallets();
|
|
362
383
|
} catch (cause) {
|
|
363
|
-
console.error("[Vue Solana] Wallet refresh failed", cause);
|
|
364
384
|
}
|
|
365
385
|
void checkConnection();
|
|
366
386
|
}, 0);
|
|
367
387
|
}
|
|
388
|
+
},
|
|
389
|
+
dispose() {
|
|
390
|
+
teardown?.();
|
|
368
391
|
}
|
|
369
392
|
};
|
|
370
393
|
return plugin;
|
|
@@ -3,13 +3,13 @@ import { withSolanaTimeout } from '@vue-solana/core/timeout';
|
|
|
3
3
|
import { signAndSendTransaction, confirmTransactionSignature } from '@vue-solana/core/transaction';
|
|
4
4
|
import { createNoWalletSelectedError } from '@vue-solana/core/wallet';
|
|
5
5
|
import { ref, computed } from 'vue';
|
|
6
|
-
import { u as
|
|
7
|
-
import { u as useWallet } from './vue.
|
|
8
|
-
import { g as getConfirmedTransactionStatus } from './vue.
|
|
6
|
+
import { u as useSolanaClient } from './vue.CZApWQAY.mjs';
|
|
7
|
+
import { u as useWallet } from './vue.DY9VadLH.mjs';
|
|
8
|
+
import { g as getConfirmedTransactionStatus } from './vue.DPwdqRO_.mjs';
|
|
9
9
|
|
|
10
10
|
const SIGN_AND_SEND_TIMEOUT_MS = 12e4;
|
|
11
11
|
function useSignAndSendTransaction() {
|
|
12
|
-
const client =
|
|
12
|
+
const client = useSolanaClient().client;
|
|
13
13
|
const { wallet } = useWallet();
|
|
14
14
|
const signature = ref(null);
|
|
15
15
|
const confirmation = ref(null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNoWalletSelectedError, assertWalletCanSignIn } from '@vue-solana/core/wallet';
|
|
2
2
|
import { shallowRef } from 'vue';
|
|
3
|
-
import { u as useExecution } from './vue.
|
|
4
|
-
import { u as useWallet } from './vue.
|
|
3
|
+
import { u as useExecution } from './vue.BiKE9Xuv.mjs';
|
|
4
|
+
import { u as useWallet } from './vue.DY9VadLH.mjs';
|
|
5
5
|
|
|
6
6
|
function useSignIn() {
|
|
7
7
|
const { wallet } = useWallet();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as useClientAction } from './vue.
|
|
1
|
+
import { u as useClientAction } from './vue.CbmzveKF.mjs';
|
|
2
2
|
|
|
3
3
|
const PLANNING_PROVIDER_HINT = "Install a planner plugin, e.g. `createClient().use(rpcTransactionPlanner())` from `@solana/kit-plugin-rpc`, and plan with a client that has a `payer` signer \u2014 Kit reads `client.payer` to set the fee payer.";
|
|
4
4
|
const PLAN_STATUSES = {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { normalizeSolanaError } from '@vue-solana/core/errors';
|
|
2
2
|
import { shallowRef, onScopeDispose, computed } from 'vue';
|
|
3
3
|
|
|
4
|
-
function useExecution(busy) {
|
|
5
|
-
const
|
|
4
|
+
function useExecution(busy, statuses = {}) {
|
|
5
|
+
const errorStatus = statuses.error ?? "error";
|
|
6
|
+
const idleStatus = statuses.idle ?? "idle";
|
|
7
|
+
const status = shallowRef(idleStatus);
|
|
6
8
|
const error = shallowRef(null);
|
|
7
9
|
let id = 0;
|
|
8
10
|
async function execute(run, settled) {
|
|
@@ -19,14 +21,14 @@ function useExecution(busy) {
|
|
|
19
21
|
const normalizedError = normalizeSolanaError(cause, "RPC_FAILURE");
|
|
20
22
|
if (currentId === id) {
|
|
21
23
|
error.value = normalizedError;
|
|
22
|
-
status.value =
|
|
24
|
+
status.value = errorStatus;
|
|
23
25
|
}
|
|
24
26
|
throw normalizedError;
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
function reset() {
|
|
28
30
|
id += 1;
|
|
29
|
-
status.value =
|
|
31
|
+
status.value = idleStatus;
|
|
30
32
|
error.value = null;
|
|
31
33
|
}
|
|
32
34
|
onScopeDispose(() => {
|
|
@@ -1,19 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { shallowRef, onMounted,
|
|
4
|
-
import { u as
|
|
5
|
-
import { t as tryUseSolana } from './vue.
|
|
1
|
+
import { getBase58Encoder } from '@vue-solana/core/kit';
|
|
2
|
+
import { createSolanaError, normalizeSolanaError } from '@vue-solana/core/errors';
|
|
3
|
+
import { shallowRef, onMounted, onScopeDispose, watch, toValue } from 'vue';
|
|
4
|
+
import { u as useSolanaClient } from './vue.CZApWQAY.mjs';
|
|
5
|
+
import { t as tryUseSolana } from './vue.CcOZ9858.mjs';
|
|
6
6
|
|
|
7
7
|
function useSignatureStatus(signature, options = {}) {
|
|
8
8
|
const solana = tryUseSolana();
|
|
9
|
-
const client = solana?.client ??
|
|
9
|
+
const client = solana?.client ?? useSolanaClient().client;
|
|
10
10
|
const status = shallowRef(null);
|
|
11
11
|
const loading = shallowRef(false);
|
|
12
12
|
const error = shallowRef(null);
|
|
13
13
|
let refreshId = 0;
|
|
14
|
-
let
|
|
14
|
+
let pollTimer = null;
|
|
15
15
|
let manuallyStoppedPolling = false;
|
|
16
|
+
let refreshInFlight = null;
|
|
16
17
|
async function refresh() {
|
|
18
|
+
const value = toValue(signature);
|
|
19
|
+
const inFlight = refreshInFlight;
|
|
20
|
+
if (inFlight && inFlight.value === value) {
|
|
21
|
+
return inFlight.promise;
|
|
22
|
+
}
|
|
23
|
+
const promise = runRefresh();
|
|
24
|
+
refreshInFlight = { value, promise };
|
|
25
|
+
try {
|
|
26
|
+
return await promise;
|
|
27
|
+
} finally {
|
|
28
|
+
if (refreshInFlight?.promise === promise) {
|
|
29
|
+
refreshInFlight = null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function runRefresh() {
|
|
17
34
|
const requestId = ++refreshId;
|
|
18
35
|
const value = toValue(signature);
|
|
19
36
|
if (!value || !solana) {
|
|
@@ -53,16 +70,22 @@ function useSignatureStatus(signature, options = {}) {
|
|
|
53
70
|
stopCurrentPolling();
|
|
54
71
|
}
|
|
55
72
|
function stopCurrentPolling() {
|
|
56
|
-
if (
|
|
73
|
+
if (pollTimer === null) {
|
|
57
74
|
return;
|
|
58
75
|
}
|
|
59
|
-
|
|
60
|
-
|
|
76
|
+
clearTimeout(pollTimer);
|
|
77
|
+
pollTimer = null;
|
|
61
78
|
}
|
|
62
|
-
function
|
|
79
|
+
function schedulePoll() {
|
|
63
80
|
stopCurrentPolling();
|
|
81
|
+
if (!options.pollIntervalMs || !solana) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (manuallyStoppedPolling) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
64
87
|
const value = toValue(signature);
|
|
65
|
-
if (
|
|
88
|
+
if (!value) {
|
|
66
89
|
return;
|
|
67
90
|
}
|
|
68
91
|
if (options.pollIntervalMs <= 0) {
|
|
@@ -75,15 +98,22 @@ function useSignatureStatus(signature, options = {}) {
|
|
|
75
98
|
error.value = normalizeSolanaError(cause, "RPC_FAILURE");
|
|
76
99
|
return;
|
|
77
100
|
}
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
pollTimer = setTimeout(() => {
|
|
102
|
+
pollTimer = null;
|
|
103
|
+
void refresh().catch(() => void 0).finally(() => {
|
|
104
|
+
schedulePoll();
|
|
105
|
+
});
|
|
80
106
|
}, options.pollIntervalMs);
|
|
81
107
|
}
|
|
108
|
+
function startPolling() {
|
|
109
|
+
manuallyStoppedPolling = false;
|
|
110
|
+
schedulePoll();
|
|
111
|
+
}
|
|
82
112
|
onMounted(() => {
|
|
83
113
|
void refresh().catch(() => void 0);
|
|
84
|
-
|
|
114
|
+
schedulePoll();
|
|
85
115
|
});
|
|
86
|
-
|
|
116
|
+
onScopeDispose(() => {
|
|
87
117
|
refreshId += 1;
|
|
88
118
|
stopPolling();
|
|
89
119
|
});
|
|
@@ -105,7 +135,7 @@ function useSignatureStatus(signature, options = {}) {
|
|
|
105
135
|
function parseTransactionSignature(signature) {
|
|
106
136
|
let decodedSignature;
|
|
107
137
|
try {
|
|
108
|
-
decodedSignature =
|
|
138
|
+
decodedSignature = getBase58Encoder().encode(signature);
|
|
109
139
|
} catch (cause) {
|
|
110
140
|
throw new TypeError("Invalid Solana transaction signature", { cause });
|
|
111
141
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SolanaError } from '@vue-solana/core/errors';
|
|
2
|
+
import { u as useSolanaClient } from './vue.CZApWQAY.mjs';
|
|
2
3
|
|
|
3
|
-
class MissingClientCapabilityError extends
|
|
4
|
+
class MissingClientCapabilityError extends SolanaError {
|
|
4
5
|
/** Name of the hook that requested the capability, e.g. `usePayer`. */
|
|
5
6
|
hookName;
|
|
6
7
|
/** Human guidance for installing the capability on the client. */
|
|
@@ -9,7 +10,9 @@ class MissingClientCapabilityError extends Error {
|
|
|
9
10
|
capabilities;
|
|
10
11
|
constructor(hookName, capabilities, providerHint) {
|
|
11
12
|
super(
|
|
12
|
-
|
|
13
|
+
"MISSING_CLIENT_CAPABILITY",
|
|
14
|
+
`${hookName} requires the ${capabilities.map((capability) => `\`${capability}\``).join(" and ")} capabilit${capabilities.length === 1 ? "y" : "ies"} on the Solana client, but none ${capabilities.length === 1 ? "was" : "were"} found. ` + providerHint,
|
|
15
|
+
{}
|
|
13
16
|
);
|
|
14
17
|
this.name = "MissingClientCapabilityError";
|
|
15
18
|
this.hookName = hookName;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { createSolanaError } from '@vue-solana/core/errors';
|
|
1
2
|
import { u as useAction } from './vue.DYk0Xfr3.mjs';
|
|
2
|
-
import { u as useClientCapability } from './vue.
|
|
3
|
-
import { u as useSolanaClient } from './vue.
|
|
3
|
+
import { u as useClientCapability, M as MissingClientCapabilityError } from './vue.CAltY57B.mjs';
|
|
4
|
+
import { u as useSolanaClient } from './vue.CZApWQAY.mjs';
|
|
4
5
|
|
|
5
6
|
function toReadableAirdropError(error) {
|
|
6
7
|
if (error instanceof Error) {
|
|
@@ -9,23 +10,22 @@ function toReadableAirdropError(error) {
|
|
|
9
10
|
if (!isThrottled) {
|
|
10
11
|
throw error;
|
|
11
12
|
}
|
|
12
|
-
throw
|
|
13
|
+
throw createSolanaError(
|
|
14
|
+
"RPC_FAILURE",
|
|
13
15
|
`${error.message} This likely means the network's airdrop faucet is rate-limited or out of test SOL. Retry later, use https://faucet.solana.com, or point the client at a local validator.`,
|
|
14
16
|
{ cause: error }
|
|
15
17
|
);
|
|
16
18
|
}
|
|
17
|
-
throw
|
|
19
|
+
throw createSolanaError("RPC_FAILURE", `Airdrop failed: ${String(error)}`, { cause: error });
|
|
18
20
|
}
|
|
19
21
|
function useAirdrop() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
providerHint: "Install it by adding the airdrop capability with `createClient().use(solanaRpc({ ... })).use(rpcAirdrop())` from `@solana/kit-plugin-rpc`, on a client that has a `payer` signer to sign the request."
|
|
23
|
-
});
|
|
22
|
+
const providerHint = "Install it by adding the airdrop capability with `createClient().use(solanaRpc({ ... })).use(rpcAirdrop())` from `@solana/kit-plugin-rpc`, on a client that has a `payer` signer to sign the request.";
|
|
23
|
+
useClientCapability("airdrop", { hookName: "useAirdrop", providerHint });
|
|
24
24
|
const { client } = useSolanaClient();
|
|
25
25
|
return useAction((abortSignal, address, amount) => {
|
|
26
26
|
const airdrop = client.airdrop;
|
|
27
27
|
if (!airdrop) {
|
|
28
|
-
throw new
|
|
28
|
+
throw new MissingClientCapabilityError("useAirdrop", ["airdrop"], providerHint);
|
|
29
29
|
}
|
|
30
30
|
return airdrop(address, amount, abortSignal).catch(toReadableAirdropError);
|
|
31
31
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as useClientAction } from './vue.
|
|
1
|
+
import { u as useClientAction } from './vue.CbmzveKF.mjs';
|
|
2
2
|
|
|
3
3
|
const SENDING_PROVIDER_HINT = "Use a client created by `createSolanaClient({ payer })` \u2014 or any client with a `payer` signer. Kit reads `client.payer` when it plans a transaction from an instruction plan.";
|
|
4
4
|
const SEND_STATUSES = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNoWalletSelectedError, assertWalletCanSignTransactions } from '@vue-solana/core/wallet';
|
|
2
2
|
import { shallowRef } from 'vue';
|
|
3
|
-
import { u as useExecution } from './vue.
|
|
4
|
-
import { u as useWallet } from './vue.
|
|
3
|
+
import { u as useExecution } from './vue.BiKE9Xuv.mjs';
|
|
4
|
+
import { u as useWallet } from './vue.DY9VadLH.mjs';
|
|
5
5
|
|
|
6
6
|
function useSignTransactions() {
|
|
7
7
|
const { wallet } = useWallet();
|