@phantom/react-sdk 0.2.2 → 0.3.1
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 +73 -31
- package/dist/index.d.ts +8 -11
- package/dist/index.js +41 -64
- package/dist/index.mjs +43 -66
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ function App() {
|
|
|
67
67
|
providerType: "embedded",
|
|
68
68
|
embeddedWalletType: "app-wallet", // or 'user-wallet'
|
|
69
69
|
addressTypes: [AddressType.solana, AddressType.ethereum],
|
|
70
|
-
apiBaseUrl: "https://api.phantom.
|
|
70
|
+
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
71
71
|
organizationId: "your-org-id",
|
|
72
72
|
}}
|
|
73
73
|
>
|
|
@@ -109,7 +109,7 @@ Creates non-custodial wallets embedded in your application.
|
|
|
109
109
|
providerType: "embedded",
|
|
110
110
|
embeddedWalletType: "app-wallet",
|
|
111
111
|
addressTypes: [AddressType.solana],
|
|
112
|
-
apiBaseUrl: "https://api.phantom.
|
|
112
|
+
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
113
113
|
organizationId: "your-org-id",
|
|
114
114
|
}}
|
|
115
115
|
>
|
|
@@ -129,7 +129,7 @@ Creates non-custodial wallets embedded in your application.
|
|
|
129
129
|
providerType: "embedded",
|
|
130
130
|
embeddedWalletType: "user-wallet",
|
|
131
131
|
addressTypes: [AddressType.solana, AddressType.ethereum],
|
|
132
|
-
apiBaseUrl: "https://api.phantom.
|
|
132
|
+
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
133
133
|
organizationId: "your-org-id",
|
|
134
134
|
}}
|
|
135
135
|
>
|
|
@@ -147,7 +147,7 @@ When using `AddressType.solana`, you can choose between two Solana libraries:
|
|
|
147
147
|
providerType: "embedded",
|
|
148
148
|
addressTypes: [AddressType.solana],
|
|
149
149
|
solanaProvider: "web3js", // or 'kit'
|
|
150
|
-
apiBaseUrl: "https://api.phantom.
|
|
150
|
+
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
151
151
|
organizationId: "your-org-id",
|
|
152
152
|
}}
|
|
153
153
|
>
|
|
@@ -318,25 +318,43 @@ function SignMessage() {
|
|
|
318
318
|
|
|
319
319
|
```tsx
|
|
320
320
|
import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
|
|
321
|
-
import {
|
|
321
|
+
import {
|
|
322
|
+
VersionedTransaction,
|
|
323
|
+
TransactionMessage,
|
|
324
|
+
SystemProgram,
|
|
325
|
+
PublicKey,
|
|
326
|
+
LAMPORTS_PER_SOL,
|
|
327
|
+
Connection,
|
|
328
|
+
} from "@solana/web3.js";
|
|
322
329
|
|
|
323
330
|
function SendSolanaTransaction() {
|
|
324
331
|
const { signAndSendTransaction, isLoading, error } = useSignAndSendTransaction();
|
|
325
332
|
|
|
326
333
|
const handleSend = async () => {
|
|
327
|
-
//
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
334
|
+
// Get recent blockhash
|
|
335
|
+
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
336
|
+
const { blockhash } = await connection.getLatestBlockhash();
|
|
337
|
+
|
|
338
|
+
// Create transfer instruction
|
|
339
|
+
const transferInstruction = SystemProgram.transfer({
|
|
340
|
+
fromPubkey: new PublicKey(fromAddress),
|
|
341
|
+
toPubkey: new PublicKey(toAddress),
|
|
342
|
+
lamports: 0.001 * LAMPORTS_PER_SOL,
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// Create VersionedTransaction
|
|
346
|
+
const messageV0 = new TransactionMessage({
|
|
347
|
+
payerKey: new PublicKey(fromAddress),
|
|
348
|
+
recentBlockhash: blockhash,
|
|
349
|
+
instructions: [transferInstruction],
|
|
350
|
+
}).compileToV0Message();
|
|
351
|
+
|
|
352
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
335
353
|
|
|
336
354
|
try {
|
|
337
355
|
const result = await signAndSendTransaction({
|
|
338
356
|
networkId: NetworkId.SOLANA_MAINNET,
|
|
339
|
-
transaction: transaction, // Native
|
|
357
|
+
transaction: transaction, // Native VersionedTransaction object!
|
|
340
358
|
});
|
|
341
359
|
console.log("Transaction sent:", result.rawTransaction);
|
|
342
360
|
} catch (err) {
|
|
@@ -430,20 +448,32 @@ The SDK automatically determines the transaction type from the NetworkId:
|
|
|
430
448
|
### Solana with @solana/web3.js
|
|
431
449
|
|
|
432
450
|
```tsx
|
|
433
|
-
import {
|
|
451
|
+
import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey, Connection } from "@solana/web3.js";
|
|
434
452
|
import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
|
|
435
453
|
|
|
436
454
|
function SolanaExample() {
|
|
437
455
|
const { signAndSendTransaction } = useSignAndSendTransaction();
|
|
438
456
|
|
|
439
457
|
const sendTransaction = async () => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
458
|
+
// Get recent blockhash
|
|
459
|
+
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
460
|
+
const { blockhash } = await connection.getLatestBlockhash();
|
|
461
|
+
|
|
462
|
+
// Create transfer instruction
|
|
463
|
+
const transferInstruction = SystemProgram.transfer({
|
|
464
|
+
fromPubkey: new PublicKey(fromAddress),
|
|
465
|
+
toPubkey: new PublicKey(toAddress),
|
|
466
|
+
lamports: 1000000, // 0.001 SOL
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// Create VersionedTransaction
|
|
470
|
+
const messageV0 = new TransactionMessage({
|
|
471
|
+
payerKey: new PublicKey(fromAddress),
|
|
472
|
+
recentBlockhash: blockhash,
|
|
473
|
+
instructions: [transferInstruction],
|
|
474
|
+
}).compileToV0Message();
|
|
475
|
+
|
|
476
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
447
477
|
|
|
448
478
|
// No serialization or encoding needed!
|
|
449
479
|
const result = await signAndSendTransaction({
|
|
@@ -537,20 +567,32 @@ function EthereumExample() {
|
|
|
537
567
|
|
|
538
568
|
```tsx
|
|
539
569
|
import { useSignAndSendTransaction, NetworkId } from "@phantom/react-sdk";
|
|
540
|
-
import {
|
|
570
|
+
import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey, Connection } from "@solana/web3.js";
|
|
541
571
|
import { parseEther } from "viem";
|
|
542
572
|
|
|
543
573
|
function MultiChainWallet() {
|
|
544
574
|
const { signAndSendTransaction } = useSignAndSendTransaction();
|
|
545
575
|
|
|
546
576
|
const sendSolana = async () => {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
577
|
+
// Get recent blockhash
|
|
578
|
+
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
579
|
+
const { blockhash } = await connection.getLatestBlockhash();
|
|
580
|
+
|
|
581
|
+
// Create transfer instruction
|
|
582
|
+
const transferInstruction = SystemProgram.transfer({
|
|
583
|
+
fromPubkey: new PublicKey(solanaAddress),
|
|
584
|
+
toPubkey: new PublicKey(recipient),
|
|
585
|
+
lamports: 1000000,
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// Create VersionedTransaction
|
|
589
|
+
const messageV0 = new TransactionMessage({
|
|
590
|
+
payerKey: new PublicKey(solanaAddress),
|
|
591
|
+
recentBlockhash: blockhash,
|
|
592
|
+
instructions: [transferInstruction],
|
|
593
|
+
}).compileToV0Message();
|
|
594
|
+
|
|
595
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
554
596
|
|
|
555
597
|
return await signAndSendTransaction({
|
|
556
598
|
networkId: NetworkId.SOLANA_MAINNET,
|
|
@@ -591,7 +633,7 @@ Quick reference of all available hooks:
|
|
|
591
633
|
| `useSignMessage` | Sign text messages | `{ signMessage, isSigning, error }` |
|
|
592
634
|
| `useSignAndSendTransaction` | Sign and send transactions | `{ signAndSendTransaction, isSigning, error }` |
|
|
593
635
|
| `useCreateUserOrganization` | Create user organization (embedded) | `{ createUserOrganization, isCreating, error }` |
|
|
594
|
-
| `usePhantom` | Get provider context | `{ isConnected, isReady
|
|
636
|
+
| `usePhantom` | Get provider context | `{ isConnected, isReady }` |
|
|
595
637
|
|
|
596
638
|
## Configuration Reference
|
|
597
639
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { BrowserSDKConfig, AuthOptions, BrowserSDK, WalletAddress, SignMessageParams, SignMessageResult, SignAndSendTransactionParams, SignedTransaction, CreateUserOrganizationParams, CreateUserOrganizationResult } from '@phantom/browser-sdk';
|
|
4
|
+
export { AddressType, CreateUserOrganizationParams, CreateUserOrganizationResult, DebugLevel, DebugMessage, NetworkId, SignAndSendTransactionParams, SignMessageParams, SignMessageResult, SignedTransaction, WalletAddress, debug } from '@phantom/browser-sdk';
|
|
5
|
+
import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
|
|
6
6
|
|
|
7
7
|
interface PhantomSDKConfig extends BrowserSDKConfig {
|
|
8
8
|
}
|
|
9
9
|
interface ConnectOptions {
|
|
10
10
|
providerType?: "injected" | "embedded";
|
|
11
11
|
embeddedWalletType?: "app-wallet" | "user-wallet";
|
|
12
|
+
authOptions?: AuthOptions;
|
|
12
13
|
}
|
|
13
14
|
interface PhantomContextValue {
|
|
14
|
-
sdk: BrowserSDK
|
|
15
|
+
sdk: BrowserSDK;
|
|
15
16
|
isConnected: boolean;
|
|
16
17
|
addresses: WalletAddress[];
|
|
17
18
|
walletId: string | null;
|
|
18
|
-
isReady: boolean;
|
|
19
19
|
error: Error | null;
|
|
20
20
|
currentProviderType: "injected" | "embedded" | null;
|
|
21
21
|
isPhantomAvailable: boolean;
|
|
@@ -29,10 +29,7 @@ declare function PhantomProvider({ children, config }: PhantomProviderProps): re
|
|
|
29
29
|
declare function usePhantom(): PhantomContextValue;
|
|
30
30
|
|
|
31
31
|
declare function useConnect(): {
|
|
32
|
-
connect: (options?: ConnectOptions) => Promise<
|
|
33
|
-
switchProvider: (type: "injected" | "embedded", options?: {
|
|
34
|
-
embeddedWalletType?: "app-wallet" | "user-wallet";
|
|
35
|
-
}) => Promise<void>;
|
|
32
|
+
connect: (options?: ConnectOptions) => Promise<_phantom_embedded_provider_core.ConnectResult>;
|
|
36
33
|
isConnecting: boolean;
|
|
37
34
|
error: Error | null;
|
|
38
35
|
currentProviderType: "injected" | "embedded" | null;
|
|
@@ -46,7 +43,7 @@ declare function useDisconnect(): {
|
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
declare function useSignMessage(): {
|
|
49
|
-
signMessage: (params: SignMessageParams) => Promise<
|
|
46
|
+
signMessage: (params: SignMessageParams) => Promise<SignMessageResult>;
|
|
50
47
|
isSigning: boolean;
|
|
51
48
|
error: Error | null;
|
|
52
49
|
};
|
|
@@ -57,7 +54,7 @@ declare function useSignAndSendTransaction(): {
|
|
|
57
54
|
error: Error | null;
|
|
58
55
|
};
|
|
59
56
|
|
|
60
|
-
declare function useAccounts():
|
|
57
|
+
declare function useAccounts(): _phantom_embedded_provider_core.WalletAddress[] | null;
|
|
61
58
|
|
|
62
59
|
declare function useCreateUserOrganization(): {
|
|
63
60
|
createUserOrganization: (params: CreateUserOrganizationParams) => Promise<CreateUserOrganizationResult>;
|
package/dist/index.js
CHANGED
|
@@ -31,8 +31,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AddressType: () => import_browser_sdk2.AddressType,
|
|
34
|
+
DebugLevel: () => import_browser_sdk2.DebugLevel,
|
|
34
35
|
NetworkId: () => import_browser_sdk2.NetworkId,
|
|
35
36
|
PhantomProvider: () => PhantomProvider,
|
|
37
|
+
debug: () => import_browser_sdk2.debug,
|
|
36
38
|
useAccounts: () => useAccounts,
|
|
37
39
|
useConnect: () => useConnect,
|
|
38
40
|
useCreateUserOrganization: () => useCreateUserOrganization,
|
|
@@ -50,71 +52,61 @@ var import_browser_sdk = require("@phantom/browser-sdk");
|
|
|
50
52
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
51
53
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
52
54
|
function PhantomProvider({ children, config }) {
|
|
53
|
-
const
|
|
55
|
+
const sdk = (0, import_react.useMemo)(
|
|
56
|
+
() => new import_browser_sdk.BrowserSDK({
|
|
57
|
+
...config,
|
|
58
|
+
// Use providerType if provided, default to embedded
|
|
59
|
+
providerType: config.providerType || "embedded"
|
|
60
|
+
}),
|
|
61
|
+
[config]
|
|
62
|
+
);
|
|
54
63
|
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
55
64
|
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
56
65
|
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
57
|
-
const [isReady, setIsReady] = (0, import_react.useState)(false);
|
|
58
66
|
const [error, setError] = (0, import_react.useState)(null);
|
|
59
67
|
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(null);
|
|
60
68
|
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
61
|
-
(0, import_react.
|
|
69
|
+
const updateConnectionState = (0, import_react.useCallback)(async () => {
|
|
62
70
|
try {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
76
|
-
checkPhantom();
|
|
77
|
-
setIsReady(true);
|
|
71
|
+
const connected = sdk.isConnected();
|
|
72
|
+
setIsConnected(connected);
|
|
73
|
+
const providerInfo = sdk.getCurrentProviderInfo();
|
|
74
|
+
setCurrentProviderType(providerInfo?.type || null);
|
|
75
|
+
if (connected) {
|
|
76
|
+
const addrs = await sdk.getAddresses();
|
|
77
|
+
setAddresses(addrs);
|
|
78
|
+
setWalletId(sdk.getWalletId());
|
|
79
|
+
} else {
|
|
80
|
+
setAddresses([]);
|
|
81
|
+
setWalletId(null);
|
|
82
|
+
}
|
|
78
83
|
} catch (err) {
|
|
84
|
+
console.error("Error updating connection state:", err);
|
|
79
85
|
setError(err);
|
|
80
|
-
setIsReady(true);
|
|
81
86
|
}
|
|
82
|
-
}, [
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
}, [sdk]);
|
|
88
|
+
(0, import_react.useEffect)(() => {
|
|
89
|
+
const checkPhantomExtension = async () => {
|
|
85
90
|
try {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
const providerInfo = sdk.getCurrentProviderInfo();
|
|
89
|
-
setCurrentProviderType(providerInfo?.type || null);
|
|
90
|
-
if (connected) {
|
|
91
|
-
const addrs = await sdk.getAddresses();
|
|
92
|
-
setAddresses(addrs);
|
|
93
|
-
setWalletId(sdk.getWalletId());
|
|
94
|
-
} else {
|
|
95
|
-
setAddresses([]);
|
|
96
|
-
setWalletId(null);
|
|
97
|
-
}
|
|
91
|
+
const available = await sdk.waitForPhantomExtension(1e3);
|
|
92
|
+
setIsPhantomAvailable(available);
|
|
98
93
|
} catch (err) {
|
|
99
|
-
console.error("Error
|
|
94
|
+
console.error("Error checking Phantom extension:", err);
|
|
95
|
+
setIsPhantomAvailable(false);
|
|
100
96
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
97
|
+
};
|
|
98
|
+
checkPhantomExtension();
|
|
99
|
+
updateConnectionState();
|
|
100
|
+
}, [sdk, updateConnectionState]);
|
|
103
101
|
(0, import_react.useEffect)(() => {
|
|
104
102
|
updateConnectionState();
|
|
105
103
|
}, [updateConnectionState]);
|
|
106
|
-
(0, import_react.useEffect)(() => {
|
|
107
|
-
if (sdk) {
|
|
108
|
-
sdk._updateConnectionState = updateConnectionState;
|
|
109
|
-
}
|
|
110
|
-
}, [sdk, updateConnectionState]);
|
|
111
104
|
const value = {
|
|
112
105
|
sdk,
|
|
113
106
|
isConnected,
|
|
114
107
|
addresses,
|
|
115
108
|
updateConnectionState,
|
|
116
109
|
walletId,
|
|
117
|
-
isReady,
|
|
118
110
|
error,
|
|
119
111
|
currentProviderType,
|
|
120
112
|
isPhantomAvailable
|
|
@@ -137,16 +129,14 @@ function useConnect() {
|
|
|
137
129
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
138
130
|
const connect = (0, import_react2.useCallback)(
|
|
139
131
|
async (options) => {
|
|
140
|
-
if (!context.sdk
|
|
132
|
+
if (!context.sdk) {
|
|
141
133
|
throw new Error("SDK not initialized");
|
|
142
134
|
}
|
|
143
135
|
setIsConnecting(true);
|
|
144
136
|
setError(null);
|
|
145
137
|
try {
|
|
146
138
|
const result = await context.sdk.connect(options);
|
|
147
|
-
|
|
148
|
-
await context.sdk._updateConnectionState();
|
|
149
|
-
}
|
|
139
|
+
await context.updateConnectionState();
|
|
150
140
|
return result;
|
|
151
141
|
} catch (err) {
|
|
152
142
|
console.error("Error connecting to Phantom:", err);
|
|
@@ -156,23 +146,10 @@ function useConnect() {
|
|
|
156
146
|
setIsConnecting(false);
|
|
157
147
|
}
|
|
158
148
|
},
|
|
159
|
-
[context
|
|
160
|
-
);
|
|
161
|
-
const switchProvider = (0, import_react2.useCallback)(
|
|
162
|
-
async (type, options) => {
|
|
163
|
-
if (!context.sdk || !context.isReady) {
|
|
164
|
-
throw new Error("SDK not initialized");
|
|
165
|
-
}
|
|
166
|
-
await context.sdk.switchProvider(type, options);
|
|
167
|
-
if (context.sdk._updateConnectionState) {
|
|
168
|
-
await context.sdk._updateConnectionState();
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
[context.sdk, context.isReady]
|
|
149
|
+
[context]
|
|
172
150
|
);
|
|
173
151
|
return {
|
|
174
152
|
connect,
|
|
175
|
-
switchProvider,
|
|
176
153
|
isConnecting,
|
|
177
154
|
error,
|
|
178
155
|
currentProviderType: context.currentProviderType,
|
|
@@ -183,11 +160,11 @@ function useConnect() {
|
|
|
183
160
|
// src/hooks/useDisconnect.ts
|
|
184
161
|
var import_react3 = require("react");
|
|
185
162
|
function useDisconnect() {
|
|
186
|
-
const { sdk,
|
|
163
|
+
const { sdk, updateConnectionState } = usePhantom();
|
|
187
164
|
const [isDisconnecting, setIsDisconnecting] = (0, import_react3.useState)(false);
|
|
188
165
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
189
166
|
const disconnect = (0, import_react3.useCallback)(async () => {
|
|
190
|
-
if (!sdk
|
|
167
|
+
if (!sdk) {
|
|
191
168
|
throw new Error("SDK not initialized");
|
|
192
169
|
}
|
|
193
170
|
setIsDisconnecting(true);
|
|
@@ -201,7 +178,7 @@ function useDisconnect() {
|
|
|
201
178
|
} finally {
|
|
202
179
|
setIsDisconnecting(false);
|
|
203
180
|
}
|
|
204
|
-
}, [sdk,
|
|
181
|
+
}, [sdk, updateConnectionState]);
|
|
205
182
|
return {
|
|
206
183
|
disconnect,
|
|
207
184
|
isDisconnecting,
|
package/dist/index.mjs
CHANGED
|
@@ -1,74 +1,64 @@
|
|
|
1
1
|
// src/PhantomProvider.tsx
|
|
2
|
-
import { createContext, useContext, useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { createContext, useContext, useState, useEffect, useCallback, useMemo } from "react";
|
|
3
3
|
import { BrowserSDK } from "@phantom/browser-sdk";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
var PhantomContext = createContext(void 0);
|
|
6
6
|
function PhantomProvider({ children, config }) {
|
|
7
|
-
const
|
|
7
|
+
const sdk = useMemo(
|
|
8
|
+
() => new BrowserSDK({
|
|
9
|
+
...config,
|
|
10
|
+
// Use providerType if provided, default to embedded
|
|
11
|
+
providerType: config.providerType || "embedded"
|
|
12
|
+
}),
|
|
13
|
+
[config]
|
|
14
|
+
);
|
|
8
15
|
const [isConnected, setIsConnected] = useState(false);
|
|
9
16
|
const [addresses, setAddresses] = useState([]);
|
|
10
17
|
const [walletId, setWalletId] = useState(null);
|
|
11
|
-
const [isReady, setIsReady] = useState(false);
|
|
12
18
|
const [error, setError] = useState(null);
|
|
13
19
|
const [currentProviderType, setCurrentProviderType] = useState(null);
|
|
14
20
|
const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
|
|
15
|
-
|
|
21
|
+
const updateConnectionState = useCallback(async () => {
|
|
16
22
|
try {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
checkPhantom();
|
|
31
|
-
setIsReady(true);
|
|
23
|
+
const connected = sdk.isConnected();
|
|
24
|
+
setIsConnected(connected);
|
|
25
|
+
const providerInfo = sdk.getCurrentProviderInfo();
|
|
26
|
+
setCurrentProviderType(providerInfo?.type || null);
|
|
27
|
+
if (connected) {
|
|
28
|
+
const addrs = await sdk.getAddresses();
|
|
29
|
+
setAddresses(addrs);
|
|
30
|
+
setWalletId(sdk.getWalletId());
|
|
31
|
+
} else {
|
|
32
|
+
setAddresses([]);
|
|
33
|
+
setWalletId(null);
|
|
34
|
+
}
|
|
32
35
|
} catch (err) {
|
|
36
|
+
console.error("Error updating connection state:", err);
|
|
33
37
|
setError(err);
|
|
34
|
-
setIsReady(true);
|
|
35
38
|
}
|
|
36
|
-
}, [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
}, [sdk]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const checkPhantomExtension = async () => {
|
|
39
42
|
try {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const providerInfo = sdk.getCurrentProviderInfo();
|
|
43
|
-
setCurrentProviderType(providerInfo?.type || null);
|
|
44
|
-
if (connected) {
|
|
45
|
-
const addrs = await sdk.getAddresses();
|
|
46
|
-
setAddresses(addrs);
|
|
47
|
-
setWalletId(sdk.getWalletId());
|
|
48
|
-
} else {
|
|
49
|
-
setAddresses([]);
|
|
50
|
-
setWalletId(null);
|
|
51
|
-
}
|
|
43
|
+
const available = await sdk.waitForPhantomExtension(1e3);
|
|
44
|
+
setIsPhantomAvailable(available);
|
|
52
45
|
} catch (err) {
|
|
53
|
-
console.error("Error
|
|
46
|
+
console.error("Error checking Phantom extension:", err);
|
|
47
|
+
setIsPhantomAvailable(false);
|
|
54
48
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
49
|
+
};
|
|
50
|
+
checkPhantomExtension();
|
|
51
|
+
updateConnectionState();
|
|
52
|
+
}, [sdk, updateConnectionState]);
|
|
57
53
|
useEffect(() => {
|
|
58
54
|
updateConnectionState();
|
|
59
55
|
}, [updateConnectionState]);
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
if (sdk) {
|
|
62
|
-
sdk._updateConnectionState = updateConnectionState;
|
|
63
|
-
}
|
|
64
|
-
}, [sdk, updateConnectionState]);
|
|
65
56
|
const value = {
|
|
66
57
|
sdk,
|
|
67
58
|
isConnected,
|
|
68
59
|
addresses,
|
|
69
60
|
updateConnectionState,
|
|
70
61
|
walletId,
|
|
71
|
-
isReady,
|
|
72
62
|
error,
|
|
73
63
|
currentProviderType,
|
|
74
64
|
isPhantomAvailable
|
|
@@ -91,16 +81,14 @@ function useConnect() {
|
|
|
91
81
|
const [error, setError] = useState2(null);
|
|
92
82
|
const connect = useCallback2(
|
|
93
83
|
async (options) => {
|
|
94
|
-
if (!context.sdk
|
|
84
|
+
if (!context.sdk) {
|
|
95
85
|
throw new Error("SDK not initialized");
|
|
96
86
|
}
|
|
97
87
|
setIsConnecting(true);
|
|
98
88
|
setError(null);
|
|
99
89
|
try {
|
|
100
90
|
const result = await context.sdk.connect(options);
|
|
101
|
-
|
|
102
|
-
await context.sdk._updateConnectionState();
|
|
103
|
-
}
|
|
91
|
+
await context.updateConnectionState();
|
|
104
92
|
return result;
|
|
105
93
|
} catch (err) {
|
|
106
94
|
console.error("Error connecting to Phantom:", err);
|
|
@@ -110,23 +98,10 @@ function useConnect() {
|
|
|
110
98
|
setIsConnecting(false);
|
|
111
99
|
}
|
|
112
100
|
},
|
|
113
|
-
[context
|
|
114
|
-
);
|
|
115
|
-
const switchProvider = useCallback2(
|
|
116
|
-
async (type, options) => {
|
|
117
|
-
if (!context.sdk || !context.isReady) {
|
|
118
|
-
throw new Error("SDK not initialized");
|
|
119
|
-
}
|
|
120
|
-
await context.sdk.switchProvider(type, options);
|
|
121
|
-
if (context.sdk._updateConnectionState) {
|
|
122
|
-
await context.sdk._updateConnectionState();
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
[context.sdk, context.isReady]
|
|
101
|
+
[context]
|
|
126
102
|
);
|
|
127
103
|
return {
|
|
128
104
|
connect,
|
|
129
|
-
switchProvider,
|
|
130
105
|
isConnecting,
|
|
131
106
|
error,
|
|
132
107
|
currentProviderType: context.currentProviderType,
|
|
@@ -137,11 +112,11 @@ function useConnect() {
|
|
|
137
112
|
// src/hooks/useDisconnect.ts
|
|
138
113
|
import { useCallback as useCallback3, useState as useState3 } from "react";
|
|
139
114
|
function useDisconnect() {
|
|
140
|
-
const { sdk,
|
|
115
|
+
const { sdk, updateConnectionState } = usePhantom();
|
|
141
116
|
const [isDisconnecting, setIsDisconnecting] = useState3(false);
|
|
142
117
|
const [error, setError] = useState3(null);
|
|
143
118
|
const disconnect = useCallback3(async () => {
|
|
144
|
-
if (!sdk
|
|
119
|
+
if (!sdk) {
|
|
145
120
|
throw new Error("SDK not initialized");
|
|
146
121
|
}
|
|
147
122
|
setIsDisconnecting(true);
|
|
@@ -155,7 +130,7 @@ function useDisconnect() {
|
|
|
155
130
|
} finally {
|
|
156
131
|
setIsDisconnecting(false);
|
|
157
132
|
}
|
|
158
|
-
}, [sdk,
|
|
133
|
+
}, [sdk, updateConnectionState]);
|
|
159
134
|
return {
|
|
160
135
|
disconnect,
|
|
161
136
|
isDisconnecting,
|
|
@@ -307,11 +282,13 @@ function useIsExtensionInstalled() {
|
|
|
307
282
|
}
|
|
308
283
|
|
|
309
284
|
// src/index.ts
|
|
310
|
-
import { NetworkId, AddressType } from "@phantom/browser-sdk";
|
|
285
|
+
import { NetworkId, AddressType, DebugLevel, debug } from "@phantom/browser-sdk";
|
|
311
286
|
export {
|
|
312
287
|
AddressType,
|
|
288
|
+
DebugLevel,
|
|
313
289
|
NetworkId,
|
|
314
290
|
PhantomProvider,
|
|
291
|
+
debug,
|
|
315
292
|
useAccounts,
|
|
316
293
|
useConnect,
|
|
317
294
|
useCreateUserOrganization,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,31 +21,32 @@
|
|
|
21
21
|
"pack-release": "rimraf ./_release && yarn pack && mkdir ./_release && tar zxvf ./package.tgz --directory ./_release && rm ./package.tgz",
|
|
22
22
|
"dev": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --watch",
|
|
23
23
|
"lint": "tsc --noEmit && eslint --cache . --ext .ts,.tsx",
|
|
24
|
+
"check-types": "tsc --noEmit",
|
|
24
25
|
"test": "jest",
|
|
25
26
|
"prettier": "prettier --write \"src/**/*.{ts,tsx}\""
|
|
26
27
|
},
|
|
27
28
|
"dependencies": {
|
|
28
|
-
"@phantom/browser-sdk": "^0.
|
|
29
|
+
"@phantom/browser-sdk": "^0.3.1"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@testing-library/dom": "^10.4.0",
|
|
32
33
|
"@testing-library/react": "^16.3.0",
|
|
33
34
|
"@types/jest": "^29.5.14",
|
|
34
|
-
"@types/react": "^19.1.
|
|
35
|
-
"@types/react-dom": "^19.1.
|
|
35
|
+
"@types/react": "^19.1.2",
|
|
36
|
+
"@types/react-dom": "^19.1.2",
|
|
36
37
|
"eslint": "8.53.0",
|
|
37
38
|
"jest": "^29.7.0",
|
|
38
39
|
"jest-environment-jsdom": "^29.7.0",
|
|
39
40
|
"prettier": "^3.5.2",
|
|
40
|
-
"react": "
|
|
41
|
-
"react-dom": "
|
|
41
|
+
"react": "19.1.1",
|
|
42
|
+
"react-dom": "19.1.1",
|
|
42
43
|
"rimraf": "^6.0.1",
|
|
43
44
|
"ts-jest": "^29",
|
|
44
45
|
"tsup": "^6.7.0",
|
|
45
46
|
"typescript": "^5.0.4"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"react": ">=
|
|
49
|
+
"react": ">=19.0.0"
|
|
49
50
|
},
|
|
50
51
|
"publishConfig": {
|
|
51
52
|
"directory": "_release/package"
|