@vue-solana/vue 0.1.2 → 0.2.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 +53 -47
- package/dist/index.cjs +95 -6
- package/dist/index.d.cts +16 -3
- package/dist/index.d.mts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.mjs +97 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@ New to Solana? Start with the official docs and the project concepts guide:
|
|
|
9
9
|
- [Solana Documentation](https://solana.com/docs)
|
|
10
10
|
- [Solana RPC Methods](https://solana.com/docs/rpc)
|
|
11
11
|
- [Solana Clusters](https://solana.com/docs/references/clusters)
|
|
12
|
-
- [Vue Solana Concepts Guide](https://
|
|
13
|
-
- [`@vue-solana/vue` docs](https://
|
|
12
|
+
- [Vue Solana Concepts Guide](https://vue-solana-docs.vercel.app/concepts/solana-for-vue-developers)
|
|
13
|
+
- [`@vue-solana/vue` docs](https://vue-solana-docs.vercel.app/packages/vue)
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -25,25 +25,29 @@ npm install @vue-solana/vue @vue-solana/core @solana/web3-compat
|
|
|
25
25
|
## Plugin Setup
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import { createApp } from
|
|
29
|
-
import { createSolanaPlugin } from
|
|
30
|
-
import App from
|
|
28
|
+
import { createApp } from "vue";
|
|
29
|
+
import { createSolanaPlugin } from "@vue-solana/vue";
|
|
30
|
+
import App from "./App.vue";
|
|
31
31
|
|
|
32
32
|
createApp(App)
|
|
33
|
-
.use(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
.use(
|
|
34
|
+
createSolanaPlugin({
|
|
35
|
+
cluster: "devnet",
|
|
36
|
+
}),
|
|
37
|
+
)
|
|
38
|
+
.mount("#app");
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
You can also pass a custom RPC endpoint:
|
|
40
42
|
|
|
41
43
|
```ts
|
|
42
|
-
createApp(App).use(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
createApp(App).use(
|
|
45
|
+
createSolanaPlugin({
|
|
46
|
+
cluster: "mainnet-beta",
|
|
47
|
+
endpoint: "https://your-rpc.example.com",
|
|
48
|
+
commitment: "confirmed",
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
47
51
|
```
|
|
48
52
|
|
|
49
53
|
Supported clusters are `mainnet-beta`, `devnet`, `testnet`, and `localnet`. Use `mainnet-beta` for Solana mainnet; this is Solana's official cluster name.
|
|
@@ -58,16 +62,9 @@ https://faucet.solana.com
|
|
|
58
62
|
|
|
59
63
|
```vue
|
|
60
64
|
<script setup lang="ts">
|
|
61
|
-
import { useRpc } from
|
|
62
|
-
|
|
63
|
-
const {
|
|
64
|
-
cluster,
|
|
65
|
-
endpoint,
|
|
66
|
-
status,
|
|
67
|
-
error,
|
|
68
|
-
latestBlockhash,
|
|
69
|
-
checkConnection
|
|
70
|
-
} = useRpc()
|
|
65
|
+
import { useRpc } from "@vue-solana/vue";
|
|
66
|
+
|
|
67
|
+
const { cluster, endpoint, status, error, latestBlockhash, checkConnection } = useRpc();
|
|
71
68
|
</script>
|
|
72
69
|
|
|
73
70
|
<template>
|
|
@@ -86,11 +83,11 @@ const {
|
|
|
86
83
|
|
|
87
84
|
```vue
|
|
88
85
|
<script setup lang="ts">
|
|
89
|
-
import { ref } from
|
|
90
|
-
import { useBalance } from
|
|
86
|
+
import { ref } from "vue";
|
|
87
|
+
import { useBalance } from "@vue-solana/vue";
|
|
91
88
|
|
|
92
|
-
const address = ref(
|
|
93
|
-
const { balance, loading, error, refresh } = useBalance(address)
|
|
89
|
+
const address = ref("PASTE_A_SOLANA_ADDRESS");
|
|
90
|
+
const { balance, loading, error, refresh } = useBalance(address);
|
|
94
91
|
</script>
|
|
95
92
|
|
|
96
93
|
<template>
|
|
@@ -107,34 +104,47 @@ const { balance, loading, error, refresh } = useBalance(address)
|
|
|
107
104
|
|
|
108
105
|
```vue
|
|
109
106
|
<script setup lang="ts">
|
|
110
|
-
import { useWallet } from
|
|
107
|
+
import { useWallet, useWallets } from "@vue-solana/vue";
|
|
111
108
|
|
|
112
|
-
const {
|
|
109
|
+
const { wallets, selectedWallet, selectWallet, refreshWallets } = useWallets();
|
|
110
|
+
const { publicKey, connected, connecting, connect, disconnect } = useWallet();
|
|
113
111
|
</script>
|
|
114
112
|
|
|
115
113
|
<template>
|
|
116
114
|
<section>
|
|
115
|
+
<button type="button" @click="refreshWallets">Refresh Wallets</button>
|
|
116
|
+
<button
|
|
117
|
+
v-for="wallet in wallets"
|
|
118
|
+
:key="wallet.name"
|
|
119
|
+
type="button"
|
|
120
|
+
@click="selectWallet(wallet)"
|
|
121
|
+
>
|
|
122
|
+
{{ wallet.name }}
|
|
123
|
+
</button>
|
|
124
|
+
<p>Selected: {{ selectedWallet?.name ?? "None" }}</p>
|
|
117
125
|
<p>Connected: {{ connected }}</p>
|
|
118
126
|
<p>Public key: {{ publicKey?.toBase58() }}</p>
|
|
119
127
|
<p v-if="connecting">Connecting...</p>
|
|
120
|
-
<button type="button" @click="connect">
|
|
121
|
-
|
|
128
|
+
<button type="button" :disabled="!selectedWallet || connected || connecting" @click="connect">
|
|
129
|
+
Connect
|
|
130
|
+
</button>
|
|
131
|
+
<button type="button" :disabled="!connected" @click="disconnect">Disconnect</button>
|
|
122
132
|
</section>
|
|
123
133
|
</template>
|
|
124
134
|
```
|
|
125
135
|
|
|
126
|
-
Browser
|
|
136
|
+
Browser wallets are discovered through the Solana Wallet Standard. `connect()` works after selecting a discovered wallet or configuring a custom `SolanaWallet`.
|
|
127
137
|
|
|
128
138
|
## Transaction State
|
|
129
139
|
|
|
130
140
|
```ts
|
|
131
|
-
import { useSignAndSendTransaction } from
|
|
141
|
+
import { useSignAndSendTransaction } from "@vue-solana/vue";
|
|
132
142
|
|
|
133
|
-
const { signature, loading, error, execute } = useSignAndSendTransaction()
|
|
143
|
+
const { signature, loading, error, execute } = useSignAndSendTransaction();
|
|
134
144
|
|
|
135
145
|
await execute(transaction, {
|
|
136
|
-
skipPreflight: false
|
|
137
|
-
})
|
|
146
|
+
skipPreflight: false,
|
|
147
|
+
});
|
|
138
148
|
```
|
|
139
149
|
|
|
140
150
|
The current wallet must be connected and support either `signAndSendTransaction` or `signTransaction`.
|
|
@@ -147,7 +157,7 @@ This README includes small snippets for quick reference. For a complete runnable
|
|
|
147
157
|
pnpm dev:vue
|
|
148
158
|
```
|
|
149
159
|
|
|
150
|
-
|
|
160
|
+
Docs: [`examples/vue-vite`](https://vue-solana-docs.vercel.app/examples/vue-vite)
|
|
151
161
|
|
|
152
162
|
## API
|
|
153
163
|
|
|
@@ -168,12 +178,8 @@ Source: [`examples/vue-vite`](https://github.com/vue-solana/vue-solana/tree/main
|
|
|
168
178
|
If TypeScript cannot resolve `@solana/web3-compat`, add `types/web3-compat.d.ts` to your app:
|
|
169
179
|
|
|
170
180
|
```ts
|
|
171
|
-
declare module
|
|
172
|
-
export type {
|
|
173
|
-
Commitment,
|
|
174
|
-
SendOptions,
|
|
175
|
-
TransactionSignature
|
|
176
|
-
} from '@solana/web3.js'
|
|
181
|
+
declare module "@solana/web3-compat" {
|
|
182
|
+
export type { Commitment, SendOptions, TransactionSignature } from "@solana/web3.js";
|
|
177
183
|
export {
|
|
178
184
|
Connection,
|
|
179
185
|
Keypair,
|
|
@@ -181,8 +187,8 @@ declare module '@solana/web3-compat' {
|
|
|
181
187
|
SystemProgram,
|
|
182
188
|
Transaction,
|
|
183
189
|
TransactionInstruction,
|
|
184
|
-
VersionedTransaction
|
|
185
|
-
} from
|
|
190
|
+
VersionedTransaction,
|
|
191
|
+
} from "@solana/web3.js";
|
|
186
192
|
}
|
|
187
193
|
```
|
|
188
194
|
|
|
@@ -190,4 +196,4 @@ Make sure your `tsconfig.json` includes `types/**/*.d.ts` or another pattern tha
|
|
|
190
196
|
|
|
191
197
|
## Status
|
|
192
198
|
|
|
193
|
-
This package is early-stage. RPC and
|
|
199
|
+
This package is early-stage. RPC, balance, wallet, and transaction composables are usable.
|
package/dist/index.cjs
CHANGED
|
@@ -56,9 +56,13 @@ function useBalance(address, commitment) {
|
|
|
56
56
|
loading.value = false;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
vue.watch(
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
vue.watch(
|
|
60
|
+
() => vue.toValue(address),
|
|
61
|
+
() => {
|
|
62
|
+
void refresh().catch(() => void 0);
|
|
63
|
+
},
|
|
64
|
+
{ immediate: true }
|
|
65
|
+
);
|
|
62
66
|
return {
|
|
63
67
|
balance,
|
|
64
68
|
loading,
|
|
@@ -70,14 +74,63 @@ function useBalance(address, commitment) {
|
|
|
70
74
|
function useWallet() {
|
|
71
75
|
const solana = useSolana();
|
|
72
76
|
const wallet = solana.wallet;
|
|
77
|
+
const connecting = vue.ref(false);
|
|
78
|
+
const disconnecting = vue.ref(false);
|
|
79
|
+
async function connect() {
|
|
80
|
+
const activeWallet = wallet.value;
|
|
81
|
+
if (!activeWallet) {
|
|
82
|
+
throw new Error("No Solana wallet is configured");
|
|
83
|
+
}
|
|
84
|
+
connecting.value = true;
|
|
85
|
+
try {
|
|
86
|
+
const connection = activeWallet.connect();
|
|
87
|
+
vue.triggerRef(wallet);
|
|
88
|
+
await connection;
|
|
89
|
+
vue.triggerRef(wallet);
|
|
90
|
+
console.info("[Vue Solana] Wallet connected", {
|
|
91
|
+
publicKey: activeWallet.publicKey?.toBase58() ?? null
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
vue.triggerRef(wallet);
|
|
95
|
+
console.error("[Vue Solana] Wallet connection failed", error);
|
|
96
|
+
throw error;
|
|
97
|
+
} finally {
|
|
98
|
+
connecting.value = false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async function disconnect() {
|
|
102
|
+
const activeWallet = wallet.value;
|
|
103
|
+
if (!activeWallet) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const publicKey = activeWallet.publicKey?.toBase58() ?? null;
|
|
107
|
+
disconnecting.value = true;
|
|
108
|
+
try {
|
|
109
|
+
await activeWallet.disconnect();
|
|
110
|
+
vue.triggerRef(wallet);
|
|
111
|
+
console.info("[Vue Solana] Wallet disconnected", { publicKey });
|
|
112
|
+
} catch (error) {
|
|
113
|
+
vue.triggerRef(wallet);
|
|
114
|
+
console.error("[Vue Solana] Wallet disconnection failed", error);
|
|
115
|
+
throw error;
|
|
116
|
+
} finally {
|
|
117
|
+
disconnecting.value = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const isConnecting = vue.computed(() => Boolean(connecting.value || wallet.value?.connecting));
|
|
121
|
+
const isDisconnecting = vue.computed(
|
|
122
|
+
() => Boolean(disconnecting.value || wallet.value?.disconnecting)
|
|
123
|
+
);
|
|
73
124
|
return {
|
|
74
125
|
wallet,
|
|
75
126
|
publicKey: vue.computed(() => wallet.value?.publicKey ?? null),
|
|
76
127
|
connected: vue.computed(() => Boolean(wallet.value?.connected && wallet.value.publicKey)),
|
|
77
|
-
connecting:
|
|
128
|
+
connecting: isConnecting,
|
|
129
|
+
disconnecting: isDisconnecting,
|
|
130
|
+
loading: vue.computed(() => isConnecting.value || isDisconnecting.value),
|
|
78
131
|
setWallet: solana.setWallet,
|
|
79
|
-
connect
|
|
80
|
-
disconnect
|
|
132
|
+
connect,
|
|
133
|
+
disconnect
|
|
81
134
|
};
|
|
82
135
|
}
|
|
83
136
|
|
|
@@ -117,14 +170,27 @@ function useSignAndSendTransaction() {
|
|
|
117
170
|
});
|
|
118
171
|
}
|
|
119
172
|
|
|
173
|
+
function useWallets() {
|
|
174
|
+
const solana = useSolana();
|
|
175
|
+
return {
|
|
176
|
+
wallets: solana.wallets,
|
|
177
|
+
selectedWallet: solana.selectedWallet,
|
|
178
|
+
refreshWallets: solana.refreshWallets,
|
|
179
|
+
selectWallet: solana.selectWallet
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
120
183
|
function createSolanaPlugin(options = {}) {
|
|
121
184
|
return {
|
|
122
185
|
install(app) {
|
|
123
186
|
const context = core.createSolanaContext(options);
|
|
124
187
|
const wallet = vue.shallowRef(options.wallet ?? null);
|
|
188
|
+
const wallets = vue.shallowRef([]);
|
|
189
|
+
const selectedWallet = vue.shallowRef(null);
|
|
125
190
|
const status = vue.ref("idle");
|
|
126
191
|
const error = vue.ref(null);
|
|
127
192
|
const latestBlockhash = vue.ref(null);
|
|
193
|
+
let unsubscribeWallets = null;
|
|
128
194
|
async function checkConnection() {
|
|
129
195
|
status.value = "checking";
|
|
130
196
|
error.value = null;
|
|
@@ -149,14 +215,36 @@ function createSolanaPlugin(options = {}) {
|
|
|
149
215
|
console.error("[Vue Solana] Connection failed", cause);
|
|
150
216
|
}
|
|
151
217
|
}
|
|
218
|
+
function refreshWallets() {
|
|
219
|
+
unsubscribeWallets ??= core.subscribeSolanaWallets(refreshWallets);
|
|
220
|
+
wallets.value = core.getRegisteredSolanaWallets();
|
|
221
|
+
if (selectedWallet.value) {
|
|
222
|
+
selectedWallet.value = wallets.value.find((nextWallet) => nextWallet.name === selectedWallet.value?.name) ?? null;
|
|
223
|
+
if (!selectedWallet.value) {
|
|
224
|
+
wallet.value = options.wallet ?? null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function selectWallet(nextWallet) {
|
|
229
|
+
selectedWallet.value = nextWallet;
|
|
230
|
+
wallet.value = nextWallet ? core.adaptSolanaStandardWallet(nextWallet, {
|
|
231
|
+
chain: core.getSolanaChain(context.cluster),
|
|
232
|
+
onChange: () => vue.triggerRef(wallet)
|
|
233
|
+
}) : options.wallet ?? null;
|
|
234
|
+
}
|
|
152
235
|
const vueContext = {
|
|
153
236
|
...context,
|
|
154
237
|
wallet,
|
|
155
238
|
status,
|
|
156
239
|
error,
|
|
157
240
|
latestBlockhash,
|
|
241
|
+
wallets,
|
|
242
|
+
selectedWallet,
|
|
158
243
|
checkConnection,
|
|
244
|
+
refreshWallets,
|
|
245
|
+
selectWallet,
|
|
159
246
|
setWallet(nextWallet) {
|
|
247
|
+
selectedWallet.value = null;
|
|
160
248
|
wallet.value = nextWallet;
|
|
161
249
|
}
|
|
162
250
|
};
|
|
@@ -177,3 +265,4 @@ exports.useSignAndSendTransaction = useSignAndSendTransaction;
|
|
|
177
265
|
exports.useSolana = useSolana;
|
|
178
266
|
exports.useTransaction = useTransaction;
|
|
179
267
|
exports.useWallet = useWallet;
|
|
268
|
+
exports.useWallets = useWallets;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import * as vue from 'vue';
|
|
|
2
2
|
import { MaybeRefOrGetter, Ref, InjectionKey, App } from 'vue';
|
|
3
3
|
import { PublicKey, Commitment, TransactionSignature } from '@solana/web3-compat';
|
|
4
4
|
import * as _vue_solana_core from '@vue-solana/core';
|
|
5
|
-
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaConfig } from '@vue-solana/core';
|
|
5
|
+
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaWalletInfo, SolanaConfig } from '@vue-solana/core';
|
|
6
6
|
|
|
7
7
|
declare function useBalance(address: MaybeRefOrGetter<PublicKey | string | null | undefined>, commitment?: Commitment): {
|
|
8
8
|
balance: vue.Ref<number | null, number | null>;
|
|
@@ -45,19 +45,32 @@ declare function useWallet(): {
|
|
|
45
45
|
publicKey: vue.ComputedRef<any>;
|
|
46
46
|
connected: vue.ComputedRef<boolean>;
|
|
47
47
|
connecting: vue.ComputedRef<boolean>;
|
|
48
|
+
disconnecting: vue.ComputedRef<boolean>;
|
|
49
|
+
loading: vue.ComputedRef<boolean>;
|
|
48
50
|
setWallet: (wallet: _vue_solana_core.SolanaWallet | null) => void;
|
|
49
51
|
connect: () => Promise<void>;
|
|
50
52
|
disconnect: () => Promise<void>;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
declare function useWallets(): {
|
|
56
|
+
wallets: vue.Ref<_vue_solana_core.SolanaWalletInfo[], _vue_solana_core.SolanaWalletInfo[]>;
|
|
57
|
+
selectedWallet: vue.Ref<_vue_solana_core.SolanaWalletInfo | null, _vue_solana_core.SolanaWalletInfo | null>;
|
|
58
|
+
refreshWallets: () => void;
|
|
59
|
+
selectWallet: (wallet: _vue_solana_core.SolanaWalletInfo | null) => void;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type SolanaConnectionStatus = "idle" | "checking" | "connected" | "error";
|
|
54
63
|
interface VueSolanaContext extends SolanaContext {
|
|
55
64
|
wallet: Ref<SolanaWallet | null>;
|
|
56
65
|
status: Ref<SolanaConnectionStatus>;
|
|
57
66
|
error: Ref<string | null>;
|
|
58
67
|
latestBlockhash: Ref<string | null>;
|
|
68
|
+
wallets: Ref<SolanaWalletInfo[]>;
|
|
69
|
+
selectedWallet: Ref<SolanaWalletInfo | null>;
|
|
59
70
|
checkConnection: () => Promise<void>;
|
|
60
71
|
setWallet: (wallet: SolanaWallet | null) => void;
|
|
72
|
+
refreshWallets: () => void;
|
|
73
|
+
selectWallet: (wallet: SolanaWalletInfo | null) => void;
|
|
61
74
|
}
|
|
62
75
|
declare const solanaInjectionKey: InjectionKey<VueSolanaContext>;
|
|
63
76
|
|
|
@@ -69,5 +82,5 @@ declare function createSolanaPlugin(options?: VueSolanaPluginOptions): {
|
|
|
69
82
|
};
|
|
70
83
|
declare const VueSolana: typeof createSolanaPlugin;
|
|
71
84
|
|
|
72
|
-
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet };
|
|
85
|
+
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet, useWallets };
|
|
73
86
|
export type { SolanaConnectionStatus, VueSolanaContext, VueSolanaPluginOptions };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as vue from 'vue';
|
|
|
2
2
|
import { MaybeRefOrGetter, Ref, InjectionKey, App } from 'vue';
|
|
3
3
|
import { PublicKey, Commitment, TransactionSignature } from '@solana/web3-compat';
|
|
4
4
|
import * as _vue_solana_core from '@vue-solana/core';
|
|
5
|
-
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaConfig } from '@vue-solana/core';
|
|
5
|
+
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaWalletInfo, SolanaConfig } from '@vue-solana/core';
|
|
6
6
|
|
|
7
7
|
declare function useBalance(address: MaybeRefOrGetter<PublicKey | string | null | undefined>, commitment?: Commitment): {
|
|
8
8
|
balance: vue.Ref<number | null, number | null>;
|
|
@@ -45,19 +45,32 @@ declare function useWallet(): {
|
|
|
45
45
|
publicKey: vue.ComputedRef<any>;
|
|
46
46
|
connected: vue.ComputedRef<boolean>;
|
|
47
47
|
connecting: vue.ComputedRef<boolean>;
|
|
48
|
+
disconnecting: vue.ComputedRef<boolean>;
|
|
49
|
+
loading: vue.ComputedRef<boolean>;
|
|
48
50
|
setWallet: (wallet: _vue_solana_core.SolanaWallet | null) => void;
|
|
49
51
|
connect: () => Promise<void>;
|
|
50
52
|
disconnect: () => Promise<void>;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
declare function useWallets(): {
|
|
56
|
+
wallets: vue.Ref<_vue_solana_core.SolanaWalletInfo[], _vue_solana_core.SolanaWalletInfo[]>;
|
|
57
|
+
selectedWallet: vue.Ref<_vue_solana_core.SolanaWalletInfo | null, _vue_solana_core.SolanaWalletInfo | null>;
|
|
58
|
+
refreshWallets: () => void;
|
|
59
|
+
selectWallet: (wallet: _vue_solana_core.SolanaWalletInfo | null) => void;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type SolanaConnectionStatus = "idle" | "checking" | "connected" | "error";
|
|
54
63
|
interface VueSolanaContext extends SolanaContext {
|
|
55
64
|
wallet: Ref<SolanaWallet | null>;
|
|
56
65
|
status: Ref<SolanaConnectionStatus>;
|
|
57
66
|
error: Ref<string | null>;
|
|
58
67
|
latestBlockhash: Ref<string | null>;
|
|
68
|
+
wallets: Ref<SolanaWalletInfo[]>;
|
|
69
|
+
selectedWallet: Ref<SolanaWalletInfo | null>;
|
|
59
70
|
checkConnection: () => Promise<void>;
|
|
60
71
|
setWallet: (wallet: SolanaWallet | null) => void;
|
|
72
|
+
refreshWallets: () => void;
|
|
73
|
+
selectWallet: (wallet: SolanaWalletInfo | null) => void;
|
|
61
74
|
}
|
|
62
75
|
declare const solanaInjectionKey: InjectionKey<VueSolanaContext>;
|
|
63
76
|
|
|
@@ -69,5 +82,5 @@ declare function createSolanaPlugin(options?: VueSolanaPluginOptions): {
|
|
|
69
82
|
};
|
|
70
83
|
declare const VueSolana: typeof createSolanaPlugin;
|
|
71
84
|
|
|
72
|
-
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet };
|
|
85
|
+
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet, useWallets };
|
|
73
86
|
export type { SolanaConnectionStatus, VueSolanaContext, VueSolanaPluginOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as vue from 'vue';
|
|
|
2
2
|
import { MaybeRefOrGetter, Ref, InjectionKey, App } from 'vue';
|
|
3
3
|
import { PublicKey, Commitment, TransactionSignature } from '@solana/web3-compat';
|
|
4
4
|
import * as _vue_solana_core from '@vue-solana/core';
|
|
5
|
-
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaConfig } from '@vue-solana/core';
|
|
5
|
+
import { SendTransactionOptions, SolanaContext, SolanaWallet, SolanaWalletInfo, SolanaConfig } from '@vue-solana/core';
|
|
6
6
|
|
|
7
7
|
declare function useBalance(address: MaybeRefOrGetter<PublicKey | string | null | undefined>, commitment?: Commitment): {
|
|
8
8
|
balance: vue.Ref<number | null, number | null>;
|
|
@@ -45,19 +45,32 @@ declare function useWallet(): {
|
|
|
45
45
|
publicKey: vue.ComputedRef<any>;
|
|
46
46
|
connected: vue.ComputedRef<boolean>;
|
|
47
47
|
connecting: vue.ComputedRef<boolean>;
|
|
48
|
+
disconnecting: vue.ComputedRef<boolean>;
|
|
49
|
+
loading: vue.ComputedRef<boolean>;
|
|
48
50
|
setWallet: (wallet: _vue_solana_core.SolanaWallet | null) => void;
|
|
49
51
|
connect: () => Promise<void>;
|
|
50
52
|
disconnect: () => Promise<void>;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
declare function useWallets(): {
|
|
56
|
+
wallets: vue.Ref<_vue_solana_core.SolanaWalletInfo[], _vue_solana_core.SolanaWalletInfo[]>;
|
|
57
|
+
selectedWallet: vue.Ref<_vue_solana_core.SolanaWalletInfo | null, _vue_solana_core.SolanaWalletInfo | null>;
|
|
58
|
+
refreshWallets: () => void;
|
|
59
|
+
selectWallet: (wallet: _vue_solana_core.SolanaWalletInfo | null) => void;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type SolanaConnectionStatus = "idle" | "checking" | "connected" | "error";
|
|
54
63
|
interface VueSolanaContext extends SolanaContext {
|
|
55
64
|
wallet: Ref<SolanaWallet | null>;
|
|
56
65
|
status: Ref<SolanaConnectionStatus>;
|
|
57
66
|
error: Ref<string | null>;
|
|
58
67
|
latestBlockhash: Ref<string | null>;
|
|
68
|
+
wallets: Ref<SolanaWalletInfo[]>;
|
|
69
|
+
selectedWallet: Ref<SolanaWalletInfo | null>;
|
|
59
70
|
checkConnection: () => Promise<void>;
|
|
60
71
|
setWallet: (wallet: SolanaWallet | null) => void;
|
|
72
|
+
refreshWallets: () => void;
|
|
73
|
+
selectWallet: (wallet: SolanaWalletInfo | null) => void;
|
|
61
74
|
}
|
|
62
75
|
declare const solanaInjectionKey: InjectionKey<VueSolanaContext>;
|
|
63
76
|
|
|
@@ -69,5 +82,5 @@ declare function createSolanaPlugin(options?: VueSolanaPluginOptions): {
|
|
|
69
82
|
};
|
|
70
83
|
declare const VueSolana: typeof createSolanaPlugin;
|
|
71
84
|
|
|
72
|
-
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet };
|
|
85
|
+
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet, useWallets };
|
|
73
86
|
export type { SolanaConnectionStatus, VueSolanaContext, VueSolanaPluginOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3-compat';
|
|
2
|
-
import { inject, computed, ref, watch, toValue, shallowRef } from 'vue';
|
|
3
|
-
import { signAndSendTransaction, createSolanaContext } from '@vue-solana/core';
|
|
2
|
+
import { inject, computed, ref, watch, toValue, triggerRef, shallowRef } from 'vue';
|
|
3
|
+
import { signAndSendTransaction, createSolanaContext, adaptSolanaStandardWallet, getSolanaChain, subscribeSolanaWallets, getRegisteredSolanaWallets } from '@vue-solana/core';
|
|
4
4
|
|
|
5
5
|
const solanaInjectionKey = Symbol("VueSolana");
|
|
6
6
|
|
|
@@ -54,9 +54,13 @@ function useBalance(address, commitment) {
|
|
|
54
54
|
loading.value = false;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
watch(
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
watch(
|
|
58
|
+
() => toValue(address),
|
|
59
|
+
() => {
|
|
60
|
+
void refresh().catch(() => void 0);
|
|
61
|
+
},
|
|
62
|
+
{ immediate: true }
|
|
63
|
+
);
|
|
60
64
|
return {
|
|
61
65
|
balance,
|
|
62
66
|
loading,
|
|
@@ -68,14 +72,63 @@ function useBalance(address, commitment) {
|
|
|
68
72
|
function useWallet() {
|
|
69
73
|
const solana = useSolana();
|
|
70
74
|
const wallet = solana.wallet;
|
|
75
|
+
const connecting = ref(false);
|
|
76
|
+
const disconnecting = ref(false);
|
|
77
|
+
async function connect() {
|
|
78
|
+
const activeWallet = wallet.value;
|
|
79
|
+
if (!activeWallet) {
|
|
80
|
+
throw new Error("No Solana wallet is configured");
|
|
81
|
+
}
|
|
82
|
+
connecting.value = true;
|
|
83
|
+
try {
|
|
84
|
+
const connection = activeWallet.connect();
|
|
85
|
+
triggerRef(wallet);
|
|
86
|
+
await connection;
|
|
87
|
+
triggerRef(wallet);
|
|
88
|
+
console.info("[Vue Solana] Wallet connected", {
|
|
89
|
+
publicKey: activeWallet.publicKey?.toBase58() ?? null
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
triggerRef(wallet);
|
|
93
|
+
console.error("[Vue Solana] Wallet connection failed", error);
|
|
94
|
+
throw error;
|
|
95
|
+
} finally {
|
|
96
|
+
connecting.value = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function disconnect() {
|
|
100
|
+
const activeWallet = wallet.value;
|
|
101
|
+
if (!activeWallet) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const publicKey = activeWallet.publicKey?.toBase58() ?? null;
|
|
105
|
+
disconnecting.value = true;
|
|
106
|
+
try {
|
|
107
|
+
await activeWallet.disconnect();
|
|
108
|
+
triggerRef(wallet);
|
|
109
|
+
console.info("[Vue Solana] Wallet disconnected", { publicKey });
|
|
110
|
+
} catch (error) {
|
|
111
|
+
triggerRef(wallet);
|
|
112
|
+
console.error("[Vue Solana] Wallet disconnection failed", error);
|
|
113
|
+
throw error;
|
|
114
|
+
} finally {
|
|
115
|
+
disconnecting.value = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const isConnecting = computed(() => Boolean(connecting.value || wallet.value?.connecting));
|
|
119
|
+
const isDisconnecting = computed(
|
|
120
|
+
() => Boolean(disconnecting.value || wallet.value?.disconnecting)
|
|
121
|
+
);
|
|
71
122
|
return {
|
|
72
123
|
wallet,
|
|
73
124
|
publicKey: computed(() => wallet.value?.publicKey ?? null),
|
|
74
125
|
connected: computed(() => Boolean(wallet.value?.connected && wallet.value.publicKey)),
|
|
75
|
-
connecting:
|
|
126
|
+
connecting: isConnecting,
|
|
127
|
+
disconnecting: isDisconnecting,
|
|
128
|
+
loading: computed(() => isConnecting.value || isDisconnecting.value),
|
|
76
129
|
setWallet: solana.setWallet,
|
|
77
|
-
connect
|
|
78
|
-
disconnect
|
|
130
|
+
connect,
|
|
131
|
+
disconnect
|
|
79
132
|
};
|
|
80
133
|
}
|
|
81
134
|
|
|
@@ -115,14 +168,27 @@ function useSignAndSendTransaction() {
|
|
|
115
168
|
});
|
|
116
169
|
}
|
|
117
170
|
|
|
171
|
+
function useWallets() {
|
|
172
|
+
const solana = useSolana();
|
|
173
|
+
return {
|
|
174
|
+
wallets: solana.wallets,
|
|
175
|
+
selectedWallet: solana.selectedWallet,
|
|
176
|
+
refreshWallets: solana.refreshWallets,
|
|
177
|
+
selectWallet: solana.selectWallet
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
118
181
|
function createSolanaPlugin(options = {}) {
|
|
119
182
|
return {
|
|
120
183
|
install(app) {
|
|
121
184
|
const context = createSolanaContext(options);
|
|
122
185
|
const wallet = shallowRef(options.wallet ?? null);
|
|
186
|
+
const wallets = shallowRef([]);
|
|
187
|
+
const selectedWallet = shallowRef(null);
|
|
123
188
|
const status = ref("idle");
|
|
124
189
|
const error = ref(null);
|
|
125
190
|
const latestBlockhash = ref(null);
|
|
191
|
+
let unsubscribeWallets = null;
|
|
126
192
|
async function checkConnection() {
|
|
127
193
|
status.value = "checking";
|
|
128
194
|
error.value = null;
|
|
@@ -147,14 +213,36 @@ function createSolanaPlugin(options = {}) {
|
|
|
147
213
|
console.error("[Vue Solana] Connection failed", cause);
|
|
148
214
|
}
|
|
149
215
|
}
|
|
216
|
+
function refreshWallets() {
|
|
217
|
+
unsubscribeWallets ??= subscribeSolanaWallets(refreshWallets);
|
|
218
|
+
wallets.value = getRegisteredSolanaWallets();
|
|
219
|
+
if (selectedWallet.value) {
|
|
220
|
+
selectedWallet.value = wallets.value.find((nextWallet) => nextWallet.name === selectedWallet.value?.name) ?? null;
|
|
221
|
+
if (!selectedWallet.value) {
|
|
222
|
+
wallet.value = options.wallet ?? null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function selectWallet(nextWallet) {
|
|
227
|
+
selectedWallet.value = nextWallet;
|
|
228
|
+
wallet.value = nextWallet ? adaptSolanaStandardWallet(nextWallet, {
|
|
229
|
+
chain: getSolanaChain(context.cluster),
|
|
230
|
+
onChange: () => triggerRef(wallet)
|
|
231
|
+
}) : options.wallet ?? null;
|
|
232
|
+
}
|
|
150
233
|
const vueContext = {
|
|
151
234
|
...context,
|
|
152
235
|
wallet,
|
|
153
236
|
status,
|
|
154
237
|
error,
|
|
155
238
|
latestBlockhash,
|
|
239
|
+
wallets,
|
|
240
|
+
selectedWallet,
|
|
156
241
|
checkConnection,
|
|
242
|
+
refreshWallets,
|
|
243
|
+
selectWallet,
|
|
157
244
|
setWallet(nextWallet) {
|
|
245
|
+
selectedWallet.value = null;
|
|
158
246
|
wallet.value = nextWallet;
|
|
159
247
|
}
|
|
160
248
|
};
|
|
@@ -165,4 +253,4 @@ function createSolanaPlugin(options = {}) {
|
|
|
165
253
|
}
|
|
166
254
|
const VueSolana = createSolanaPlugin;
|
|
167
255
|
|
|
168
|
-
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet };
|
|
256
|
+
export { VueSolana, createSolanaPlugin, solanaInjectionKey, useBalance, useConnection, useRpc, useSignAndSendTransaction, useSolana, useTransaction, useWallet, useWallets };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue-solana/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Vue plugin and composables for Solana applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@vue-solana/core": "0.
|
|
41
|
+
"@vue-solana/core": "0.2.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@solana/web3-compat": "^0.0.21",
|