@phantom/react-sdk 0.0.2 → 0.0.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.
- package/README.md +253 -32
- package/dist/solana/index.d.ts +71 -2
- package/dist/solana/index.js +190 -2
- package/dist/solana/index.mjs +182 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,10 +11,9 @@ npm install @phantom/react-sdk @phantom/browser-sdk
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
|
-
import React from
|
|
15
|
-
import { PhantomProvider } from
|
|
16
|
-
import { createSolanaPlugin } from
|
|
17
|
-
import { useProvider } from '@phantom/react-sdk/solana';
|
|
14
|
+
import React from "react";
|
|
15
|
+
import { PhantomProvider, useConnect } from "@phantom/react-sdk";
|
|
16
|
+
import { createSolanaPlugin } from "@phantom/browser-sdk/solana";
|
|
18
17
|
|
|
19
18
|
function App() {
|
|
20
19
|
return (
|
|
@@ -25,29 +24,25 @@ function App() {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
function WalletComponent() {
|
|
28
|
-
const {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
</button>
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return null;
|
|
27
|
+
const { connect } = useConnect();
|
|
28
|
+
|
|
29
|
+
const handleConnect = async () => {
|
|
30
|
+
try {
|
|
31
|
+
const connectedAccount = await connect();
|
|
32
|
+
console.log("Wallet connected:", connectedAccount?.publicKey?.toString());
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("Connection failed:", error);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div>
|
|
40
|
+
<button onClick={handleConnect}>Connect to Solana</button>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
50
43
|
}
|
|
44
|
+
|
|
45
|
+
export default App;
|
|
51
46
|
```
|
|
52
47
|
|
|
53
48
|
## API Reference
|
|
@@ -57,15 +52,19 @@ function WalletComponent() {
|
|
|
57
52
|
The PhantomProvider component provides the Phantom context to child components.
|
|
58
53
|
|
|
59
54
|
```tsx
|
|
60
|
-
import { PhantomProvider } from
|
|
61
|
-
import { createSolanaPlugin } from
|
|
55
|
+
import { PhantomProvider } from "@phantom/react-sdk";
|
|
56
|
+
import { createSolanaPlugin } from "@phantom/browser-sdk/solana";
|
|
62
57
|
|
|
63
|
-
<PhantomProvider config={{ chainPlugins: [createSolanaPlugin()] }}>
|
|
64
|
-
{children}
|
|
65
|
-
</PhantomProvider>
|
|
58
|
+
<PhantomProvider config={{ chainPlugins: [createSolanaPlugin()] }}>{children}</PhantomProvider>;
|
|
66
59
|
```
|
|
67
60
|
|
|
68
|
-
###
|
|
61
|
+
### usePhantom
|
|
62
|
+
|
|
63
|
+
The `usePhantom` hoo provides access to the phantom instance. With Phantom instance you can call browser-sdk methods directly.
|
|
64
|
+
|
|
65
|
+
## Solana API Reference
|
|
66
|
+
|
|
67
|
+
### useProvider
|
|
69
68
|
|
|
70
69
|
The `useProvider` hook provides access to the Solana provider with automatic retry logic and state management.
|
|
71
70
|
|
|
@@ -75,3 +74,225 @@ The hook returns an object with the following properties:
|
|
|
75
74
|
|
|
76
75
|
- `status: 'loading' | 'success' | 'error'` - Current status of the provider
|
|
77
76
|
- `provider: NonNullable<unknown> | null` - The Solana provider instance (null when not available)
|
|
77
|
+
|
|
78
|
+
### useConnect (Solana)
|
|
79
|
+
|
|
80
|
+
The `useConnect` hook provides a function to connect to the Phantom wallet for Solana.
|
|
81
|
+
|
|
82
|
+
#### Props
|
|
83
|
+
|
|
84
|
+
- `autoConnect?: boolean` (optional) - If `true`, attempts to connect to the wallet automatically when the component mounts. Defaults to `false`.
|
|
85
|
+
|
|
86
|
+
#### Return Value
|
|
87
|
+
|
|
88
|
+
The hook returns an object with the following property:
|
|
89
|
+
|
|
90
|
+
- `connect: () => Promise<ConnectResponse>` - An asynchronous function that initiates the connection process. Returns a promise that resolves with the connection response (e.g., `{ publicKey: string }`) or rejects if connection fails.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { useConnect } from "@phantom/react-sdk"; // Or '@phantom/react-sdk/solana' if specific
|
|
94
|
+
|
|
95
|
+
function MyComponent() {
|
|
96
|
+
const { connect } = useConnect({ autoConnect: true });
|
|
97
|
+
|
|
98
|
+
const handleConnectClick = async () => {
|
|
99
|
+
try {
|
|
100
|
+
const res = await connect();
|
|
101
|
+
console.log("Connected:", res.publicKey.toString());
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.error("Connection error:", err);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
// ...
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### useDisconnect (Solana)
|
|
111
|
+
|
|
112
|
+
The `useDisconnect` hook provides a function to disconnect from the Phantom wallet for Solana.
|
|
113
|
+
|
|
114
|
+
#### Return Value
|
|
115
|
+
|
|
116
|
+
The hook returns an object with the following property:
|
|
117
|
+
|
|
118
|
+
- `disconnect: () => Promise<void>` - An asynchronous function that initiates the disconnection process. Returns a promise that resolves when disconnection is complete or rejects if disconnection fails.
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { useDisconnect } from "@phantom/react-sdk"; // Or '@phantom/react-sdk/solana' if specific
|
|
122
|
+
|
|
123
|
+
function MyComponent() {
|
|
124
|
+
const { disconnect } = useDisconnect();
|
|
125
|
+
|
|
126
|
+
const handleDisconnectClick = async () => {
|
|
127
|
+
try {
|
|
128
|
+
await disconnect();
|
|
129
|
+
console.log("Disconnected");
|
|
130
|
+
} catch (err) {
|
|
131
|
+
console.error("Disconnection error:", err);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
// ...
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### useAccount
|
|
139
|
+
|
|
140
|
+
The `useAccount` hook provides access the currently connected account state. It is reactive and changes according to the connected account state.
|
|
141
|
+
|
|
142
|
+
#### Return Value
|
|
143
|
+
|
|
144
|
+
The hook returns an object with the following properties:
|
|
145
|
+
|
|
146
|
+
- `status: 'loading' | 'connected' | 'disconnected'` - Current account status
|
|
147
|
+
- `publicKey: string | null` - Current public key of the connected account or null when account is not connected.
|
|
148
|
+
|
|
149
|
+
### useSignIn (Solana)
|
|
150
|
+
|
|
151
|
+
The `useSignIn` hook provides a function to initiate a sign-in request to the Phantom wallet for Solana. This is compliant with SIP-001 (Sign In With Solana).
|
|
152
|
+
|
|
153
|
+
#### Return Value
|
|
154
|
+
|
|
155
|
+
The hook returns an object with the following property:
|
|
156
|
+
|
|
157
|
+
- `signIn: (signInData: SolanaSignInData) => Promise<{ address: string; signature: Uint8Array; signedMessage: Uint8Array }>` - An asynchronous function that initiates the sign-in process. `SolanaSignInData` is a type imported from `@phantom/browser-sdk/solana`. Returns a promise that resolves with the `address` (string), `signature` (Uint8Array), and `signedMessage` (Uint8Array), or rejects if the sign-in fails.
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { useSignIn } from "@phantom/react-sdk"; // Or '@phantom/react-sdk/solana' if specific
|
|
161
|
+
import { SolanaSignInData } from "@phantom/browser-sdk/solana"; // This type might be needed from the browser-sdk
|
|
162
|
+
|
|
163
|
+
function MyComponent() {
|
|
164
|
+
const { signIn } = useSignIn();
|
|
165
|
+
|
|
166
|
+
const handleSignInClick = async () => {
|
|
167
|
+
// Construct SolanaSignInData according to your needs
|
|
168
|
+
// This typically includes the domain and a statement for the user.
|
|
169
|
+
const signInData: SolanaSignInData = {
|
|
170
|
+
domain: window.location.host,
|
|
171
|
+
statement: "Please sign in to access exclusive features.",
|
|
172
|
+
// Other fields like `nonce`, `chainId`, `resources` can be added as per SIP-001
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
const result = await signIn(signInData);
|
|
177
|
+
console.log("Sign In successful. Address:", result.address.toString());
|
|
178
|
+
// You can now verify the signature and signedMessage on your backend
|
|
179
|
+
// Handle successful sign-in (e.g., update UI, set user session)
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error("Sign In error:", err);
|
|
182
|
+
// Handle sign-in error (e.g., show error message to user)
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
return <button onClick={handleSignInClick}>Sign In with Solana</button>;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### useSignMessage (Solana)
|
|
191
|
+
|
|
192
|
+
The `useSignMessage` hook provides a function to prompt the user to sign an arbitrary message with their Solana account.
|
|
193
|
+
|
|
194
|
+
#### Return Value
|
|
195
|
+
|
|
196
|
+
The hook returns an object with the following property:
|
|
197
|
+
|
|
198
|
+
- `signMessage: (message: Uint8Array, display?: 'utf8' | 'hex') => Promise<{ signature: Uint8Array; publicKey: string }>` - An asynchronous function that prompts the user to sign a message. The `message` must be a `Uint8Array`. The optional `display` parameter can be 'utf8' (default) or 'hex' to suggest how the wallet should display the message bytes. Returns a promise that resolves with the `signature` (Uint8Array) and `publicKey` (string) of the signer, or rejects if signing fails.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { useSignMessage } from "@phantom/react-sdk"; // Or '@phantom/react-sdk/solana' if specific
|
|
202
|
+
|
|
203
|
+
function MyComponent() {
|
|
204
|
+
const { signMessage } = useSignMessage();
|
|
205
|
+
|
|
206
|
+
const handleSignMessage = async () => {
|
|
207
|
+
const messageToSign = "Please confirm your action by signing this message.";
|
|
208
|
+
const messageBytes = new TextEncoder().encode(messageToSign);
|
|
209
|
+
try {
|
|
210
|
+
const { signature, publicKey } = await signMessage(messageBytes, "utf8");
|
|
211
|
+
console.log("Message signed successfully!");
|
|
212
|
+
console.log("Signature:", signature);
|
|
213
|
+
console.log("Public Key:", publicKey);
|
|
214
|
+
// You can now verify this signature on a backend or use it as needed.
|
|
215
|
+
} catch (err) {
|
|
216
|
+
console.error("Sign message error:", err);
|
|
217
|
+
// Handle error (e.g., user rejected, wallet error)
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
return <button onClick={handleSignMessage}>Sign Message</button>;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### useSignAndSendTransaction (Solana)
|
|
226
|
+
|
|
227
|
+
The `useSignAndSendTransaction` hook prompts the user to sign **and** send a Kit-style transaction.
|
|
228
|
+
|
|
229
|
+
#### Return Value
|
|
230
|
+
|
|
231
|
+
The hook returns an object with the following property:
|
|
232
|
+
|
|
233
|
+
- `signAndSendTransaction(transaction: Transaction): Promise<{ signature: string; publicKey?: string }>` – accepts a `Transaction` built with **`@solana/kit`** and returns the confirmed signature.
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
import { useSignAndSendTransaction } from "@phantom/react-sdk/solana"; // scoped import is fine
|
|
237
|
+
import {
|
|
238
|
+
createSolanaRpc,
|
|
239
|
+
createTransactionMessage,
|
|
240
|
+
setTransactionMessageFeePayer,
|
|
241
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
242
|
+
pipe,
|
|
243
|
+
address,
|
|
244
|
+
compileTransaction,
|
|
245
|
+
} from "@solana/kit";
|
|
246
|
+
|
|
247
|
+
function MyComponent() {
|
|
248
|
+
const { signAndSendTransaction } = useSignAndSendTransaction();
|
|
249
|
+
|
|
250
|
+
const handlePayment = async (publicKey: string) => {
|
|
251
|
+
// 0️⃣ Ensure the wallet is connected and we have a fee-payer address
|
|
252
|
+
if (!publicKey) return console.error("Wallet not connected");
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
// 1️⃣ Fetch a recent blockhash
|
|
256
|
+
const rpc = createSolanaRpc("https://api.devnet.solana.com");
|
|
257
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
258
|
+
|
|
259
|
+
// 2️⃣ Build a minimal v0 transaction message (no instructions – demo only)
|
|
260
|
+
const txMessage = pipe(
|
|
261
|
+
createTransactionMessage({ version: 0 }),
|
|
262
|
+
tx => setTransactionMessageFeePayer(address(publicKey), tx),
|
|
263
|
+
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
const transaction = compileTransaction(txMessage);
|
|
267
|
+
|
|
268
|
+
// 3️⃣ Prompt the user to sign and send
|
|
269
|
+
const { signature } = await signAndSendTransaction(transaction);
|
|
270
|
+
console.log("Transaction signature:", signature);
|
|
271
|
+
} catch (err) {
|
|
272
|
+
console.error("Transaction error:", err);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
return <button onClick={() => handlePayment("YOUR_CONNECTED_WALLET_PUBLIC_KEY")}>Send 0.001 SOL</button>;
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### useAccountEffect
|
|
281
|
+
|
|
282
|
+
The `useAccountEffect` hook provides easy way to subscribe to events like `connect`, `disconnect` and `accountChanged`. You can subscribe by calling the hook and declaring event callbacks you want to react to.
|
|
283
|
+
|
|
284
|
+
Example:
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
useAccountEffect({
|
|
288
|
+
onConnect: data => {
|
|
289
|
+
console.log("Connected to Phantom with public key:", data.publicKey);
|
|
290
|
+
},
|
|
291
|
+
onDisconnect: () => {
|
|
292
|
+
console.log("Disconnected from Phantom");
|
|
293
|
+
},
|
|
294
|
+
onAccountChanged: data => {
|
|
295
|
+
console.log("Account changed to:", data.publicKey);
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
```
|
package/dist/solana/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { PhantomSolanaProvider, SolanaSignInData } from '@phantom/browser-sdk/solana';
|
|
2
|
+
import { Transaction } from '@solana/kit';
|
|
3
|
+
|
|
1
4
|
type ProviderState = {
|
|
2
5
|
status: "loading";
|
|
3
6
|
provider: null;
|
|
4
7
|
} | {
|
|
5
8
|
status: "success";
|
|
6
|
-
provider:
|
|
9
|
+
provider: PhantomSolanaProvider;
|
|
7
10
|
} | {
|
|
8
11
|
status: "error";
|
|
9
12
|
provider: null;
|
|
@@ -14,4 +17,70 @@ type ProviderState = {
|
|
|
14
17
|
*/
|
|
15
18
|
declare function useProvider(): ProviderState;
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
type UseConnectProps = {
|
|
21
|
+
autoConnect?: boolean;
|
|
22
|
+
};
|
|
23
|
+
declare function useConnect({ autoConnect }?: UseConnectProps): {
|
|
24
|
+
connect: () => Promise<string | undefined>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
declare function useDisconnect(): {
|
|
28
|
+
disconnect: () => Promise<void>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
interface UseSignInResult {
|
|
32
|
+
signIn: (signInData: SolanaSignInData) => Promise<{
|
|
33
|
+
address: string;
|
|
34
|
+
signature: Uint8Array;
|
|
35
|
+
signedMessage: Uint8Array;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
declare function useSignIn(): UseSignInResult;
|
|
39
|
+
|
|
40
|
+
interface UseSignAndSendTransactionResult {
|
|
41
|
+
signAndSendTransaction: (transaction: Transaction) => Promise<{
|
|
42
|
+
signature: string;
|
|
43
|
+
publicKey?: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
declare function useSignAndSendTransaction(): UseSignAndSendTransactionResult;
|
|
47
|
+
|
|
48
|
+
interface UseSignMessageResult {
|
|
49
|
+
signMessage: (message: Uint8Array, display?: "utf8" | "hex") => Promise<{
|
|
50
|
+
signature: Uint8Array;
|
|
51
|
+
address: string;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
declare function useSignMessage(): UseSignMessageResult;
|
|
55
|
+
|
|
56
|
+
type UseAccountResult = {
|
|
57
|
+
status: "connected";
|
|
58
|
+
address: string;
|
|
59
|
+
} | {
|
|
60
|
+
status: "disconnected" | "loading";
|
|
61
|
+
address: null;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* React hook that provides the current account connection status and public key.
|
|
65
|
+
* Automatically updates when the account connects, disconnects, or changes.
|
|
66
|
+
*
|
|
67
|
+
* @returns Object containing status ('connected' | 'disconnected') and address (string | null)
|
|
68
|
+
*/
|
|
69
|
+
declare function useAccount(): UseAccountResult;
|
|
70
|
+
|
|
71
|
+
type UseAccountEffectParameters = {
|
|
72
|
+
onConnect?(data: {
|
|
73
|
+
publicKey: string;
|
|
74
|
+
}): void;
|
|
75
|
+
onDisconnect?(): void;
|
|
76
|
+
onAccountChanged?(data: {
|
|
77
|
+
publicKey: string;
|
|
78
|
+
}): void;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Hook for listening to account lifecycle events.
|
|
82
|
+
* Provides callbacks for connect, disconnect, and account change events.
|
|
83
|
+
*/
|
|
84
|
+
declare function useAccountEffect(parameters?: UseAccountEffectParameters): void;
|
|
85
|
+
|
|
86
|
+
export { useAccount, useAccountEffect, useConnect, useDisconnect, useProvider, useSignAndSendTransaction, useSignIn, useSignMessage };
|
package/dist/solana/index.js
CHANGED
|
@@ -30,7 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/solana/index.ts
|
|
31
31
|
var solana_exports = {};
|
|
32
32
|
__export(solana_exports, {
|
|
33
|
-
|
|
33
|
+
useAccount: () => useAccount,
|
|
34
|
+
useAccountEffect: () => useAccountEffect,
|
|
35
|
+
useConnect: () => useConnect,
|
|
36
|
+
useDisconnect: () => useDisconnect,
|
|
37
|
+
useProvider: () => useProvider,
|
|
38
|
+
useSignAndSendTransaction: () => useSignAndSendTransaction,
|
|
39
|
+
useSignIn: () => useSignIn,
|
|
40
|
+
useSignMessage: () => useSignMessage
|
|
34
41
|
});
|
|
35
42
|
module.exports = __toCommonJS(solana_exports);
|
|
36
43
|
var import_solana = require("@phantom/browser-sdk/solana");
|
|
@@ -117,7 +124,188 @@ function useProvider() {
|
|
|
117
124
|
}, [isReady, tryResolvingProvider]);
|
|
118
125
|
return state;
|
|
119
126
|
}
|
|
127
|
+
|
|
128
|
+
// src/solana/useConnect.ts
|
|
129
|
+
var React3 = __toESM(require("react"));
|
|
130
|
+
function useConnect({ autoConnect = false } = {}) {
|
|
131
|
+
const { phantom } = usePhantom();
|
|
132
|
+
const connect = React3.useCallback(async () => {
|
|
133
|
+
if (!phantom?.solana) {
|
|
134
|
+
throw new Error("Phantom solana plugin not found.");
|
|
135
|
+
}
|
|
136
|
+
return await phantom.solana.connect();
|
|
137
|
+
}, [phantom]);
|
|
138
|
+
React3.useEffect(() => {
|
|
139
|
+
if (autoConnect && phantom?.solana) {
|
|
140
|
+
connect();
|
|
141
|
+
}
|
|
142
|
+
}, [autoConnect, connect, phantom?.solana]);
|
|
143
|
+
return { connect };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/solana/useDisconnect.ts
|
|
147
|
+
var React4 = __toESM(require("react"));
|
|
148
|
+
function useDisconnect() {
|
|
149
|
+
const { phantom } = usePhantom();
|
|
150
|
+
const disconnect = React4.useCallback(async () => {
|
|
151
|
+
if (!phantom?.solana) {
|
|
152
|
+
throw new Error("Phantom solana disconnect method not found.");
|
|
153
|
+
}
|
|
154
|
+
return await phantom.solana.disconnect();
|
|
155
|
+
}, [phantom]);
|
|
156
|
+
return { disconnect };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/solana/useSignIn.ts
|
|
160
|
+
var import_react = require("react");
|
|
161
|
+
function useSignIn() {
|
|
162
|
+
const { phantom } = usePhantom();
|
|
163
|
+
const signIn = (0, import_react.useCallback)(
|
|
164
|
+
async (signInData) => {
|
|
165
|
+
if (!phantom?.solana) {
|
|
166
|
+
throw new Error("Phantom Solana provider not available.");
|
|
167
|
+
}
|
|
168
|
+
const result = await phantom.solana.signIn(signInData);
|
|
169
|
+
return result;
|
|
170
|
+
},
|
|
171
|
+
[phantom]
|
|
172
|
+
);
|
|
173
|
+
return { signIn };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/solana/useSignAndSendTransaction.ts
|
|
177
|
+
var import_react2 = require("react");
|
|
178
|
+
function useSignAndSendTransaction() {
|
|
179
|
+
const { phantom } = usePhantom();
|
|
180
|
+
const signAndSendTransaction = (0, import_react2.useCallback)(
|
|
181
|
+
async (transaction) => {
|
|
182
|
+
if (!phantom?.solana) {
|
|
183
|
+
throw new Error("Phantom Solana provider not available.");
|
|
184
|
+
}
|
|
185
|
+
const result = await phantom.solana.signAndSendTransaction(transaction);
|
|
186
|
+
return result;
|
|
187
|
+
},
|
|
188
|
+
[phantom]
|
|
189
|
+
);
|
|
190
|
+
return { signAndSendTransaction };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/solana/useSignMessage.ts
|
|
194
|
+
var import_react3 = require("react");
|
|
195
|
+
function useSignMessage() {
|
|
196
|
+
const { phantom } = usePhantom();
|
|
197
|
+
const signMessage = (0, import_react3.useCallback)(
|
|
198
|
+
async (message, display) => {
|
|
199
|
+
if (!phantom?.solana) {
|
|
200
|
+
throw new Error("Phantom Solana provider not available.");
|
|
201
|
+
}
|
|
202
|
+
const result = await phantom.solana.signMessage(message, display);
|
|
203
|
+
return result;
|
|
204
|
+
},
|
|
205
|
+
[phantom]
|
|
206
|
+
);
|
|
207
|
+
return { signMessage };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/solana/useAccount.ts
|
|
211
|
+
var React5 = __toESM(require("react"));
|
|
212
|
+
|
|
213
|
+
// src/solana/assertions.ts
|
|
214
|
+
function assertSolanaConfigured(phantom) {
|
|
215
|
+
if (!phantom?.solana) {
|
|
216
|
+
throw new Error(
|
|
217
|
+
"Phantom solana chain plugin not found. Please ensure the solana chain plugin is installed and configured properly."
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/solana/useAccount.ts
|
|
223
|
+
function useAccount() {
|
|
224
|
+
const { phantom, isReady } = usePhantom();
|
|
225
|
+
const { status: providerStatus, provider } = useProvider();
|
|
226
|
+
const [account, setAccount] = React5.useState(() => {
|
|
227
|
+
if (!isReady)
|
|
228
|
+
return { status: "loading", address: null };
|
|
229
|
+
assertSolanaConfigured(phantom);
|
|
230
|
+
return phantom.solana.getAccount();
|
|
231
|
+
});
|
|
232
|
+
React5.useEffect(() => {
|
|
233
|
+
if (!isReady)
|
|
234
|
+
return;
|
|
235
|
+
assertSolanaConfigured(phantom);
|
|
236
|
+
if (providerStatus !== "success" || !provider)
|
|
237
|
+
return;
|
|
238
|
+
if (account.status === "loading") {
|
|
239
|
+
setAccount(phantom.solana.getAccount());
|
|
240
|
+
}
|
|
241
|
+
const updateAccount = () => {
|
|
242
|
+
setAccount(phantom.solana.getAccount());
|
|
243
|
+
};
|
|
244
|
+
phantom.solana.addEventListener("connect", updateAccount);
|
|
245
|
+
phantom.solana.addEventListener("disconnect", updateAccount);
|
|
246
|
+
phantom.solana.addEventListener("accountChanged", updateAccount);
|
|
247
|
+
return () => {
|
|
248
|
+
phantom.solana.removeEventListener("connect", updateAccount);
|
|
249
|
+
phantom.solana.removeEventListener("disconnect", updateAccount);
|
|
250
|
+
phantom.solana.removeEventListener("accountChanged", updateAccount);
|
|
251
|
+
};
|
|
252
|
+
}, [provider, phantom, providerStatus, isReady, account.status]);
|
|
253
|
+
return account;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/solana/useAccountEffect.ts
|
|
257
|
+
var React6 = __toESM(require("react"));
|
|
258
|
+
function useAccountEffect(parameters = {}) {
|
|
259
|
+
const { onConnect, onDisconnect, onAccountChanged } = parameters;
|
|
260
|
+
const { phantom, isReady } = usePhantom();
|
|
261
|
+
const { status: providerStatus, provider } = useProvider();
|
|
262
|
+
React6.useEffect(() => {
|
|
263
|
+
if (!isReady || providerStatus !== "success" || !provider)
|
|
264
|
+
return;
|
|
265
|
+
assertSolanaConfigured(phantom);
|
|
266
|
+
const handleConnect = (publicKey) => {
|
|
267
|
+
onConnect?.({
|
|
268
|
+
publicKey
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
const handleDisconnect = () => {
|
|
272
|
+
onDisconnect?.();
|
|
273
|
+
};
|
|
274
|
+
const handleAccountChanged = (publicKey) => {
|
|
275
|
+
onAccountChanged?.({
|
|
276
|
+
publicKey
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
if (onConnect) {
|
|
280
|
+
phantom.solana.addEventListener("connect", handleConnect);
|
|
281
|
+
}
|
|
282
|
+
if (onDisconnect) {
|
|
283
|
+
phantom.solana.addEventListener("disconnect", handleDisconnect);
|
|
284
|
+
}
|
|
285
|
+
if (onAccountChanged) {
|
|
286
|
+
phantom.solana.addEventListener("accountChanged", handleAccountChanged);
|
|
287
|
+
}
|
|
288
|
+
return () => {
|
|
289
|
+
if (onConnect) {
|
|
290
|
+
phantom.solana.removeEventListener("connect", handleConnect);
|
|
291
|
+
}
|
|
292
|
+
if (onDisconnect) {
|
|
293
|
+
phantom.solana.removeEventListener("disconnect", handleDisconnect);
|
|
294
|
+
}
|
|
295
|
+
if (onAccountChanged) {
|
|
296
|
+
phantom.solana.removeEventListener("accountChanged", handleAccountChanged);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}, [isReady, providerStatus, provider, phantom, onConnect, onDisconnect, onAccountChanged]);
|
|
300
|
+
}
|
|
120
301
|
// Annotate the CommonJS export names for ESM import in node:
|
|
121
302
|
0 && (module.exports = {
|
|
122
|
-
|
|
303
|
+
useAccount,
|
|
304
|
+
useAccountEffect,
|
|
305
|
+
useConnect,
|
|
306
|
+
useDisconnect,
|
|
307
|
+
useProvider,
|
|
308
|
+
useSignAndSendTransaction,
|
|
309
|
+
useSignIn,
|
|
310
|
+
useSignMessage
|
|
123
311
|
});
|
package/dist/solana/index.mjs
CHANGED
|
@@ -72,6 +72,187 @@ function useProvider() {
|
|
|
72
72
|
}, [isReady, tryResolvingProvider]);
|
|
73
73
|
return state;
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
// src/solana/useConnect.ts
|
|
77
|
+
import * as React2 from "react";
|
|
78
|
+
function useConnect({ autoConnect = false } = {}) {
|
|
79
|
+
const { phantom } = usePhantom();
|
|
80
|
+
const connect = React2.useCallback(async () => {
|
|
81
|
+
if (!phantom?.solana) {
|
|
82
|
+
throw new Error("Phantom solana plugin not found.");
|
|
83
|
+
}
|
|
84
|
+
return await phantom.solana.connect();
|
|
85
|
+
}, [phantom]);
|
|
86
|
+
React2.useEffect(() => {
|
|
87
|
+
if (autoConnect && phantom?.solana) {
|
|
88
|
+
connect();
|
|
89
|
+
}
|
|
90
|
+
}, [autoConnect, connect, phantom?.solana]);
|
|
91
|
+
return { connect };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/solana/useDisconnect.ts
|
|
95
|
+
import * as React3 from "react";
|
|
96
|
+
function useDisconnect() {
|
|
97
|
+
const { phantom } = usePhantom();
|
|
98
|
+
const disconnect = React3.useCallback(async () => {
|
|
99
|
+
if (!phantom?.solana) {
|
|
100
|
+
throw new Error("Phantom solana disconnect method not found.");
|
|
101
|
+
}
|
|
102
|
+
return await phantom.solana.disconnect();
|
|
103
|
+
}, [phantom]);
|
|
104
|
+
return { disconnect };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/solana/useSignIn.ts
|
|
108
|
+
import { useCallback as useCallback4 } from "react";
|
|
109
|
+
function useSignIn() {
|
|
110
|
+
const { phantom } = usePhantom();
|
|
111
|
+
const signIn = useCallback4(
|
|
112
|
+
async (signInData) => {
|
|
113
|
+
if (!phantom?.solana) {
|
|
114
|
+
throw new Error("Phantom Solana provider not available.");
|
|
115
|
+
}
|
|
116
|
+
const result = await phantom.solana.signIn(signInData);
|
|
117
|
+
return result;
|
|
118
|
+
},
|
|
119
|
+
[phantom]
|
|
120
|
+
);
|
|
121
|
+
return { signIn };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/solana/useSignAndSendTransaction.ts
|
|
125
|
+
import { useCallback as useCallback5 } from "react";
|
|
126
|
+
function useSignAndSendTransaction() {
|
|
127
|
+
const { phantom } = usePhantom();
|
|
128
|
+
const signAndSendTransaction = useCallback5(
|
|
129
|
+
async (transaction) => {
|
|
130
|
+
if (!phantom?.solana) {
|
|
131
|
+
throw new Error("Phantom Solana provider not available.");
|
|
132
|
+
}
|
|
133
|
+
const result = await phantom.solana.signAndSendTransaction(transaction);
|
|
134
|
+
return result;
|
|
135
|
+
},
|
|
136
|
+
[phantom]
|
|
137
|
+
);
|
|
138
|
+
return { signAndSendTransaction };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/solana/useSignMessage.ts
|
|
142
|
+
import { useCallback as useCallback6 } from "react";
|
|
143
|
+
function useSignMessage() {
|
|
144
|
+
const { phantom } = usePhantom();
|
|
145
|
+
const signMessage = useCallback6(
|
|
146
|
+
async (message, display) => {
|
|
147
|
+
if (!phantom?.solana) {
|
|
148
|
+
throw new Error("Phantom Solana provider not available.");
|
|
149
|
+
}
|
|
150
|
+
const result = await phantom.solana.signMessage(message, display);
|
|
151
|
+
return result;
|
|
152
|
+
},
|
|
153
|
+
[phantom]
|
|
154
|
+
);
|
|
155
|
+
return { signMessage };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/solana/useAccount.ts
|
|
159
|
+
import * as React4 from "react";
|
|
160
|
+
|
|
161
|
+
// src/solana/assertions.ts
|
|
162
|
+
function assertSolanaConfigured(phantom) {
|
|
163
|
+
if (!phantom?.solana) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"Phantom solana chain plugin not found. Please ensure the solana chain plugin is installed and configured properly."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/solana/useAccount.ts
|
|
171
|
+
function useAccount() {
|
|
172
|
+
const { phantom, isReady } = usePhantom();
|
|
173
|
+
const { status: providerStatus, provider } = useProvider();
|
|
174
|
+
const [account, setAccount] = React4.useState(() => {
|
|
175
|
+
if (!isReady)
|
|
176
|
+
return { status: "loading", address: null };
|
|
177
|
+
assertSolanaConfigured(phantom);
|
|
178
|
+
return phantom.solana.getAccount();
|
|
179
|
+
});
|
|
180
|
+
React4.useEffect(() => {
|
|
181
|
+
if (!isReady)
|
|
182
|
+
return;
|
|
183
|
+
assertSolanaConfigured(phantom);
|
|
184
|
+
if (providerStatus !== "success" || !provider)
|
|
185
|
+
return;
|
|
186
|
+
if (account.status === "loading") {
|
|
187
|
+
setAccount(phantom.solana.getAccount());
|
|
188
|
+
}
|
|
189
|
+
const updateAccount = () => {
|
|
190
|
+
setAccount(phantom.solana.getAccount());
|
|
191
|
+
};
|
|
192
|
+
phantom.solana.addEventListener("connect", updateAccount);
|
|
193
|
+
phantom.solana.addEventListener("disconnect", updateAccount);
|
|
194
|
+
phantom.solana.addEventListener("accountChanged", updateAccount);
|
|
195
|
+
return () => {
|
|
196
|
+
phantom.solana.removeEventListener("connect", updateAccount);
|
|
197
|
+
phantom.solana.removeEventListener("disconnect", updateAccount);
|
|
198
|
+
phantom.solana.removeEventListener("accountChanged", updateAccount);
|
|
199
|
+
};
|
|
200
|
+
}, [provider, phantom, providerStatus, isReady, account.status]);
|
|
201
|
+
return account;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/solana/useAccountEffect.ts
|
|
205
|
+
import * as React5 from "react";
|
|
206
|
+
function useAccountEffect(parameters = {}) {
|
|
207
|
+
const { onConnect, onDisconnect, onAccountChanged } = parameters;
|
|
208
|
+
const { phantom, isReady } = usePhantom();
|
|
209
|
+
const { status: providerStatus, provider } = useProvider();
|
|
210
|
+
React5.useEffect(() => {
|
|
211
|
+
if (!isReady || providerStatus !== "success" || !provider)
|
|
212
|
+
return;
|
|
213
|
+
assertSolanaConfigured(phantom);
|
|
214
|
+
const handleConnect = (publicKey) => {
|
|
215
|
+
onConnect?.({
|
|
216
|
+
publicKey
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
const handleDisconnect = () => {
|
|
220
|
+
onDisconnect?.();
|
|
221
|
+
};
|
|
222
|
+
const handleAccountChanged = (publicKey) => {
|
|
223
|
+
onAccountChanged?.({
|
|
224
|
+
publicKey
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
if (onConnect) {
|
|
228
|
+
phantom.solana.addEventListener("connect", handleConnect);
|
|
229
|
+
}
|
|
230
|
+
if (onDisconnect) {
|
|
231
|
+
phantom.solana.addEventListener("disconnect", handleDisconnect);
|
|
232
|
+
}
|
|
233
|
+
if (onAccountChanged) {
|
|
234
|
+
phantom.solana.addEventListener("accountChanged", handleAccountChanged);
|
|
235
|
+
}
|
|
236
|
+
return () => {
|
|
237
|
+
if (onConnect) {
|
|
238
|
+
phantom.solana.removeEventListener("connect", handleConnect);
|
|
239
|
+
}
|
|
240
|
+
if (onDisconnect) {
|
|
241
|
+
phantom.solana.removeEventListener("disconnect", handleDisconnect);
|
|
242
|
+
}
|
|
243
|
+
if (onAccountChanged) {
|
|
244
|
+
phantom.solana.removeEventListener("accountChanged", handleAccountChanged);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}, [isReady, providerStatus, provider, phantom, onConnect, onDisconnect, onAccountChanged]);
|
|
248
|
+
}
|
|
75
249
|
export {
|
|
76
|
-
|
|
250
|
+
useAccount,
|
|
251
|
+
useAccountEffect,
|
|
252
|
+
useConnect,
|
|
253
|
+
useDisconnect,
|
|
254
|
+
useProvider,
|
|
255
|
+
useSignAndSendTransaction,
|
|
256
|
+
useSignIn,
|
|
257
|
+
useSignMessage
|
|
77
258
|
};
|