@phantom/react-sdk 1.0.0-beta.0 → 1.0.0-beta.2
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 +52 -53
- package/dist/index.d.ts +14 -5
- package/dist/index.js +192 -164
- package/dist/index.mjs +193 -165
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -97,7 +97,6 @@ function App() {
|
|
|
97
97
|
embeddedWalletType: "app-wallet", // or 'user-wallet'
|
|
98
98
|
addressTypes: [AddressType.solana, AddressType.ethereum],
|
|
99
99
|
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
100
|
-
organizationId: "your-org-id",
|
|
101
100
|
}}
|
|
102
101
|
>
|
|
103
102
|
<YourApp />
|
|
@@ -153,7 +152,7 @@ await connect({
|
|
|
153
152
|
},
|
|
154
153
|
});
|
|
155
154
|
|
|
156
|
-
// Apple authentication (skips provider selection)
|
|
155
|
+
// Apple authentication (skips provider selection)
|
|
157
156
|
await connect({
|
|
158
157
|
authOptions: {
|
|
159
158
|
provider: "apple",
|
|
@@ -195,7 +194,6 @@ Creates non-custodial wallets embedded in your application.
|
|
|
195
194
|
embeddedWalletType: "app-wallet",
|
|
196
195
|
addressTypes: [AddressType.solana],
|
|
197
196
|
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
198
|
-
organizationId: "your-org-id",
|
|
199
197
|
}}
|
|
200
198
|
>
|
|
201
199
|
<YourApp />
|
|
@@ -215,7 +213,6 @@ Creates non-custodial wallets embedded in your application.
|
|
|
215
213
|
embeddedWalletType: "user-wallet",
|
|
216
214
|
addressTypes: [AddressType.solana, AddressType.ethereum],
|
|
217
215
|
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
218
|
-
organizationId: "your-org-id",
|
|
219
216
|
}}
|
|
220
217
|
>
|
|
221
218
|
<YourApp />
|
|
@@ -233,7 +230,6 @@ When using `AddressType.solana`, you can choose between two Solana libraries:
|
|
|
233
230
|
addressTypes: [AddressType.solana],
|
|
234
231
|
solanaProvider: "web3js", // or 'kit'
|
|
235
232
|
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
236
|
-
organizationId: "your-org-id",
|
|
237
233
|
}}
|
|
238
234
|
>
|
|
239
235
|
<YourApp />
|
|
@@ -378,7 +374,7 @@ function SolanaOperations() {
|
|
|
378
374
|
// Create transaction
|
|
379
375
|
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
380
376
|
const { blockhash } = await connection.getLatestBlockhash();
|
|
381
|
-
|
|
377
|
+
|
|
382
378
|
const fromAddress = await solana.getPublicKey();
|
|
383
379
|
const transferInstruction = SystemProgram.transfer({
|
|
384
380
|
fromPubkey: new PublicKey(fromAddress),
|
|
@@ -400,7 +396,7 @@ function SolanaOperations() {
|
|
|
400
396
|
};
|
|
401
397
|
|
|
402
398
|
const switchNetwork = async () => {
|
|
403
|
-
await solana.switchNetwork(
|
|
399
|
+
await solana.switchNetwork("devnet");
|
|
404
400
|
};
|
|
405
401
|
|
|
406
402
|
return (
|
|
@@ -408,13 +404,14 @@ function SolanaOperations() {
|
|
|
408
404
|
<button onClick={signMessage}>Sign Message</button>
|
|
409
405
|
<button onClick={signAndSendTransaction}>Send Transaction</button>
|
|
410
406
|
<button onClick={switchNetwork}>Switch to Devnet</button>
|
|
411
|
-
<p>Connected: {solana.isConnected ?
|
|
407
|
+
<p>Connected: {solana.isConnected ? "Yes" : "No"}</p>
|
|
412
408
|
</div>
|
|
413
409
|
);
|
|
414
410
|
}
|
|
415
411
|
```
|
|
416
412
|
|
|
417
413
|
**Available methods:**
|
|
414
|
+
|
|
418
415
|
- `signMessage(message)` - Sign a message
|
|
419
416
|
- `signTransaction(transaction)` - Sign without sending
|
|
420
417
|
- `signAndSendTransaction(transaction)` - Sign and send
|
|
@@ -447,32 +444,42 @@ function EthereumOperations() {
|
|
|
447
444
|
{ name: "name", type: "string" },
|
|
448
445
|
{ name: "version", type: "string" },
|
|
449
446
|
{ name: "chainId", type: "uint256" },
|
|
450
|
-
{ name: "verifyingContract", type: "address" }
|
|
447
|
+
{ name: "verifyingContract", type: "address" },
|
|
451
448
|
],
|
|
452
449
|
Mail: [
|
|
453
450
|
{ name: "from", type: "string" },
|
|
454
451
|
{ name: "to", type: "string" },
|
|
455
|
-
{ name: "contents", type: "string" }
|
|
456
|
-
]
|
|
452
|
+
{ name: "contents", type: "string" },
|
|
453
|
+
],
|
|
457
454
|
},
|
|
458
455
|
primaryType: "Mail",
|
|
459
456
|
domain: {
|
|
460
457
|
name: "Ether Mail",
|
|
461
458
|
version: "1",
|
|
462
459
|
chainId: 1,
|
|
463
|
-
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
|
|
460
|
+
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
|
464
461
|
},
|
|
465
462
|
message: {
|
|
466
463
|
from: "Alice",
|
|
467
464
|
to: "Bob",
|
|
468
|
-
contents: "Hello!"
|
|
469
|
-
}
|
|
465
|
+
contents: "Hello!",
|
|
466
|
+
},
|
|
470
467
|
};
|
|
471
468
|
|
|
472
469
|
const signature = await ethereum.signTypedData(typedData);
|
|
473
470
|
console.log("Typed data signature:", signature);
|
|
474
471
|
};
|
|
475
472
|
|
|
473
|
+
const signTransaction = async () => {
|
|
474
|
+
const signedTx = await ethereum.signTransaction({
|
|
475
|
+
to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
|
|
476
|
+
value: "1000000000000000000", // 1 ETH in wei
|
|
477
|
+
gas: "21000",
|
|
478
|
+
});
|
|
479
|
+
console.log("Transaction signed:", signedTx);
|
|
480
|
+
// Transaction is signed but not sent - you can broadcast it later
|
|
481
|
+
};
|
|
482
|
+
|
|
476
483
|
const sendTransaction = async () => {
|
|
477
484
|
const result = await ethereum.sendTransaction({
|
|
478
485
|
to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
|
|
@@ -490,19 +497,22 @@ function EthereumOperations() {
|
|
|
490
497
|
<div>
|
|
491
498
|
<button onClick={signPersonalMessage}>Sign Personal Message</button>
|
|
492
499
|
<button onClick={signTypedData}>Sign Typed Data</button>
|
|
493
|
-
<button onClick={
|
|
500
|
+
<button onClick={signTransaction}>Sign Transaction</button>
|
|
501
|
+
<button onClick={sendTransaction}>Sign & Send Transaction</button>
|
|
494
502
|
<button onClick={switchChain}>Switch to Polygon</button>
|
|
495
|
-
<p>Connected: {ethereum.isConnected ?
|
|
503
|
+
<p>Connected: {ethereum.isConnected ? "Yes" : "No"}</p>
|
|
496
504
|
</div>
|
|
497
505
|
);
|
|
498
506
|
}
|
|
499
507
|
```
|
|
500
508
|
|
|
501
509
|
**Available methods:**
|
|
510
|
+
|
|
502
511
|
- `request(args)` - EIP-1193 requests
|
|
503
512
|
- `signPersonalMessage(message, address)` - Sign personal message
|
|
504
513
|
- `signTypedData(typedData)` - Sign EIP-712 typed data
|
|
505
|
-
- `
|
|
514
|
+
- `signTransaction(transaction)` - Sign transaction without sending
|
|
515
|
+
- `sendTransaction(transaction)` - Sign and send transaction
|
|
506
516
|
- `switchChain(chainId)` - Switch chains
|
|
507
517
|
- `getChainId()` - Get current chain ID
|
|
508
518
|
- `getAccounts()` - Get connected accounts
|
|
@@ -521,21 +531,13 @@ Hook for managing auto-confirm functionality with the Phantom extension. Auto-co
|
|
|
521
531
|
import { useAutoConfirm, NetworkId } from "@phantom/react-sdk";
|
|
522
532
|
|
|
523
533
|
function AutoConfirmControls() {
|
|
524
|
-
const {
|
|
525
|
-
enable,
|
|
526
|
-
disable,
|
|
527
|
-
status,
|
|
528
|
-
supportedChains,
|
|
529
|
-
isLoading,
|
|
530
|
-
error,
|
|
531
|
-
refetch,
|
|
532
|
-
} = useAutoConfirm();
|
|
534
|
+
const { enable, disable, status, supportedChains, isLoading, error, refetch } = useAutoConfirm();
|
|
533
535
|
|
|
534
536
|
const handleEnable = async () => {
|
|
535
537
|
try {
|
|
536
538
|
// Enable auto-confirm for specific chains
|
|
537
539
|
const result = await enable({
|
|
538
|
-
chains: [NetworkId.SOLANA_DEVNET, NetworkId.ETHEREUM_MAINNET]
|
|
540
|
+
chains: [NetworkId.SOLANA_DEVNET, NetworkId.ETHEREUM_MAINNET],
|
|
539
541
|
});
|
|
540
542
|
console.log("Auto-confirm enabled:", result);
|
|
541
543
|
} catch (err) {
|
|
@@ -563,14 +565,14 @@ function AutoConfirmControls() {
|
|
|
563
565
|
return (
|
|
564
566
|
<div>
|
|
565
567
|
<h3>Auto-Confirm Settings</h3>
|
|
566
|
-
|
|
568
|
+
|
|
567
569
|
<div>
|
|
568
570
|
<strong>Status:</strong> {status?.enabled ? "Enabled" : "Disabled"}
|
|
569
571
|
{status?.chains && (
|
|
570
572
|
<div>
|
|
571
573
|
<strong>Active Chains:</strong>
|
|
572
574
|
<ul>
|
|
573
|
-
{status.chains.map(
|
|
575
|
+
{status.chains.map(chain => (
|
|
574
576
|
<li key={chain}>{chain}</li>
|
|
575
577
|
))}
|
|
576
578
|
</ul>
|
|
@@ -582,7 +584,7 @@ function AutoConfirmControls() {
|
|
|
582
584
|
<strong>Supported Chains:</strong>
|
|
583
585
|
{supportedChains?.chains && (
|
|
584
586
|
<ul>
|
|
585
|
-
{supportedChains.chains.map(
|
|
587
|
+
{supportedChains.chains.map(chain => (
|
|
586
588
|
<li key={chain}>{chain}</li>
|
|
587
589
|
))}
|
|
588
590
|
</ul>
|
|
@@ -635,7 +637,7 @@ interface AutoConfirmSupportedChainsResult {
|
|
|
635
637
|
**Available Methods:**
|
|
636
638
|
|
|
637
639
|
- `enable(params)` - Enable auto-confirm for specific chains
|
|
638
|
-
- `disable()` - Disable auto-confirm completely
|
|
640
|
+
- `disable()` - Disable auto-confirm completely
|
|
639
641
|
- `refetch()` - Refresh status and supported chains from extension
|
|
640
642
|
- `status` - Current auto-confirm status (enabled/disabled and active chains)
|
|
641
643
|
- `supportedChains` - List of chains that support auto-confirm
|
|
@@ -778,29 +780,27 @@ function EthereumExample() {
|
|
|
778
780
|
|
|
779
781
|
Quick reference of all available hooks:
|
|
780
782
|
|
|
781
|
-
| Hook
|
|
782
|
-
|
|
|
783
|
-
| `useConnect`
|
|
784
|
-
| `useAccounts`
|
|
785
|
-
| `useIsExtensionInstalled`
|
|
786
|
-
| `useDisconnect`
|
|
787
|
-
| `useAutoConfirm`
|
|
788
|
-
| `useSolana`
|
|
789
|
-
| `useEthereum`
|
|
790
|
-
| `usePhantom`
|
|
783
|
+
| Hook | Purpose | Returns |
|
|
784
|
+
| ------------------------- | --------------------------------------- | --------------------------------------------------- |
|
|
785
|
+
| `useConnect` | Connect to wallet | `{ connect, isConnecting, error }` |
|
|
786
|
+
| `useAccounts` | Get wallet addresses | `WalletAddress[]` or `null` |
|
|
787
|
+
| `useIsExtensionInstalled` | Check extension status | `{ isLoading, isInstalled }` |
|
|
788
|
+
| `useDisconnect` | Disconnect from wallet | `{ disconnect, isDisconnecting }` |
|
|
789
|
+
| `useAutoConfirm` | Auto-confirm management (injected only) | `{ enable, disable, status, supportedChains, ... }` |
|
|
790
|
+
| `useSolana` | Solana chain operations | `{ signMessage, signAndSendTransaction, ... }` |
|
|
791
|
+
| `useEthereum` | Ethereum chain operations | `{ signPersonalMessage, sendTransaction, ... }` |
|
|
792
|
+
| `usePhantom` | Get provider context | `{ isConnected, isReady }` |
|
|
791
793
|
|
|
792
794
|
## Configuration Reference
|
|
793
795
|
|
|
794
796
|
```typescript
|
|
795
797
|
interface PhantomSDKConfig {
|
|
796
798
|
providerType: "injected" | "embedded";
|
|
797
|
-
appName?: string; // Optional app name for branding
|
|
798
|
-
appLogo?: string; // Optional app logo URL for branding
|
|
799
799
|
addressTypes?: [AddressType, ...AddressType[]]; // Networks to enable (e.g., [AddressType.solana])
|
|
800
800
|
|
|
801
801
|
// Required for embedded provider only
|
|
802
802
|
apiBaseUrl?: string; // Phantom API base URL
|
|
803
|
-
|
|
803
|
+
appId: string; // Your app ID
|
|
804
804
|
authOptions?: {
|
|
805
805
|
authUrl?: string; // Custom auth URL (optional)
|
|
806
806
|
redirectUrl?: string; // Custom redirect URL (optional)
|
|
@@ -819,8 +819,8 @@ The React SDK supports separate debug configuration that can be changed without
|
|
|
819
819
|
|
|
820
820
|
```typescript
|
|
821
821
|
interface PhantomDebugConfig {
|
|
822
|
-
enabled?: boolean;
|
|
823
|
-
level?: DebugLevel;
|
|
822
|
+
enabled?: boolean; // Enable debug logging
|
|
823
|
+
level?: DebugLevel; // Debug level (ERROR, WARN, INFO, DEBUG)
|
|
824
824
|
callback?: DebugCallback; // Custom debug message handler
|
|
825
825
|
}
|
|
826
826
|
```
|
|
@@ -839,7 +839,6 @@ function App() {
|
|
|
839
839
|
// SDK configuration - static, won't change when debug settings change
|
|
840
840
|
const config: PhantomSDKConfig = {
|
|
841
841
|
providerType: "embedded",
|
|
842
|
-
organizationId: "your-org-id",
|
|
843
842
|
// ... other config
|
|
844
843
|
};
|
|
845
844
|
|
|
@@ -866,12 +865,12 @@ Debug callbacks receive a `DebugMessage` object:
|
|
|
866
865
|
|
|
867
866
|
```typescript
|
|
868
867
|
interface DebugMessage {
|
|
869
|
-
timestamp: number;
|
|
870
|
-
level: DebugLevel;
|
|
871
|
-
category: string;
|
|
872
|
-
message: string;
|
|
873
|
-
data?: any;
|
|
868
|
+
timestamp: number; // Unix timestamp
|
|
869
|
+
level: DebugLevel; // Message level
|
|
870
|
+
category: string; // Component category
|
|
871
|
+
message: string; // Debug message text
|
|
872
|
+
data?: any; // Additional debug data (optional)
|
|
874
873
|
}
|
|
875
874
|
```
|
|
876
875
|
|
|
877
|
-
For more details and examples, see the [@phantom/browser-sdk documentation](../browser-sdk/README.md).
|
|
876
|
+
For more details and examples, see the [@phantom/browser-sdk documentation](../browser-sdk/README.md).
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
import { BrowserSDKConfig, DebugConfig, AuthOptions, BrowserSDK, WalletAddress, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult } from '@phantom/browser-sdk';
|
|
4
4
|
export { AddressType, AutoConfirmEnableParams, AutoConfirmResult, AutoConfirmSupportedChainsResult, DebugLevel, DebugMessage, NetworkId, SignedTransaction, WalletAddress, debug } from '@phantom/browser-sdk';
|
|
5
5
|
import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
|
|
6
|
-
import * as _phantom_parsers from '@phantom/parsers';
|
|
7
6
|
import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
|
|
8
7
|
export { EthTransactionRequest, IEthereumChain, ISolanaChain } from '@phantom/chains';
|
|
9
8
|
|
|
@@ -50,6 +49,10 @@ declare function useDisconnect(): {
|
|
|
50
49
|
|
|
51
50
|
declare function useAccounts(): _phantom_embedded_provider_core.WalletAddress[] | null;
|
|
52
51
|
|
|
52
|
+
/**
|
|
53
|
+
* React hook to check if Phantom extension is installed
|
|
54
|
+
* Uses waitForPhantomExtension for proper detection with retry logic
|
|
55
|
+
*/
|
|
53
56
|
declare function useIsExtensionInstalled(): {
|
|
54
57
|
isLoading: boolean;
|
|
55
58
|
isInstalled: boolean;
|
|
@@ -73,16 +76,21 @@ declare function useAutoConfirm(): UseAutoConfirmResult;
|
|
|
73
76
|
*/
|
|
74
77
|
declare function useSolana(): {
|
|
75
78
|
solana: ISolanaChain | null;
|
|
76
|
-
signMessage: (message: string | Uint8Array) => Promise<
|
|
79
|
+
signMessage: (message: string | Uint8Array) => Promise<{
|
|
80
|
+
signature: Uint8Array;
|
|
81
|
+
publicKey: string;
|
|
82
|
+
}>;
|
|
77
83
|
signTransaction: <T>(transaction: T) => Promise<T>;
|
|
78
|
-
signAndSendTransaction: <T>(transaction: T) => Promise<
|
|
84
|
+
signAndSendTransaction: <T>(transaction: T) => Promise<{
|
|
85
|
+
signature: string;
|
|
86
|
+
}>;
|
|
79
87
|
connect: (options?: {
|
|
80
88
|
onlyIfTrusted?: boolean;
|
|
81
89
|
}) => Promise<{
|
|
82
90
|
publicKey: string;
|
|
83
91
|
}>;
|
|
84
92
|
disconnect: () => Promise<void>;
|
|
85
|
-
switchNetwork: (network: "mainnet" | "devnet") => Promise<void>;
|
|
93
|
+
switchNetwork: (network: "mainnet" | "devnet") => Promise<void | undefined>;
|
|
86
94
|
getPublicKey: () => Promise<string | null>;
|
|
87
95
|
isAvailable: boolean;
|
|
88
96
|
isConnected: boolean;
|
|
@@ -101,8 +109,9 @@ declare function useEthereum(): {
|
|
|
101
109
|
}) => Promise<T>;
|
|
102
110
|
signPersonalMessage: (message: string, address: string) => Promise<string>;
|
|
103
111
|
signMessage: (message: string) => Promise<string>;
|
|
112
|
+
signTransaction: (transaction: EthTransactionRequest) => Promise<string>;
|
|
104
113
|
signTypedData: (typedData: any) => Promise<string>;
|
|
105
|
-
sendTransaction: (transaction: EthTransactionRequest) => Promise<
|
|
114
|
+
sendTransaction: (transaction: EthTransactionRequest) => Promise<string>;
|
|
106
115
|
switchChain: (chainId: number) => Promise<void>;
|
|
107
116
|
getChainId: () => Promise<number>;
|
|
108
117
|
getAccounts: () => Promise<string[]>;
|
package/dist/index.js
CHANGED
|
@@ -52,14 +52,6 @@ var import_browser_sdk = require("@phantom/browser-sdk");
|
|
|
52
52
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
53
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
54
54
|
function PhantomProvider({ children, config, debugConfig }) {
|
|
55
|
-
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
56
|
-
const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
|
|
57
|
-
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
58
|
-
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
59
|
-
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
60
|
-
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(config.providerType || null);
|
|
61
|
-
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
62
|
-
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
63
55
|
const memoizedConfig = (0, import_react.useMemo)(() => {
|
|
64
56
|
return {
|
|
65
57
|
...config,
|
|
@@ -67,6 +59,16 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
67
59
|
providerType: config.providerType || "embedded"
|
|
68
60
|
};
|
|
69
61
|
}, [config]);
|
|
62
|
+
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
63
|
+
const [isConnecting, setIsConnecting] = (0, import_react.useState)(false);
|
|
64
|
+
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
65
|
+
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
66
|
+
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
67
|
+
const [currentProviderType, setCurrentProviderType] = (0, import_react.useState)(
|
|
68
|
+
memoizedConfig.providerType || null
|
|
69
|
+
);
|
|
70
|
+
const [isPhantomAvailable, setIsPhantomAvailable] = (0, import_react.useState)(false);
|
|
71
|
+
const [sdk, setSdk] = (0, import_react.useState)(null);
|
|
70
72
|
(0, import_react.useEffect)(() => {
|
|
71
73
|
const sdkInstance = new import_browser_sdk.BrowserSDK(memoizedConfig);
|
|
72
74
|
const handleConnectStart = () => {
|
|
@@ -123,21 +125,21 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
123
125
|
(0, import_react.useEffect)(() => {
|
|
124
126
|
if (!sdk)
|
|
125
127
|
return;
|
|
126
|
-
const initialize = () => {
|
|
128
|
+
const initialize = async () => {
|
|
127
129
|
try {
|
|
128
|
-
const available = import_browser_sdk.BrowserSDK.isPhantomInstalled();
|
|
130
|
+
const available = await import_browser_sdk.BrowserSDK.isPhantomInstalled();
|
|
129
131
|
setIsPhantomAvailable(available);
|
|
130
132
|
} catch (err) {
|
|
131
133
|
console.error("Error checking Phantom extension:", err);
|
|
132
134
|
setIsPhantomAvailable(false);
|
|
133
135
|
}
|
|
134
|
-
if (
|
|
136
|
+
if (memoizedConfig.autoConnect !== false) {
|
|
135
137
|
sdk.autoConnect().catch(() => {
|
|
136
138
|
});
|
|
137
139
|
}
|
|
138
140
|
};
|
|
139
141
|
initialize();
|
|
140
|
-
}, [sdk,
|
|
142
|
+
}, [sdk, memoizedConfig.autoConnect]);
|
|
141
143
|
const value = (0, import_react.useMemo)(
|
|
142
144
|
() => ({
|
|
143
145
|
sdk,
|
|
@@ -149,16 +151,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
149
151
|
currentProviderType,
|
|
150
152
|
isPhantomAvailable
|
|
151
153
|
}),
|
|
152
|
-
[
|
|
153
|
-
sdk,
|
|
154
|
-
isConnected,
|
|
155
|
-
isConnecting,
|
|
156
|
-
connectError,
|
|
157
|
-
addresses,
|
|
158
|
-
walletId,
|
|
159
|
-
currentProviderType,
|
|
160
|
-
isPhantomAvailable
|
|
161
|
-
]
|
|
154
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable]
|
|
162
155
|
);
|
|
163
156
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
|
|
164
157
|
}
|
|
@@ -235,36 +228,33 @@ function useAccounts() {
|
|
|
235
228
|
// src/hooks/useIsExtensionInstalled.ts
|
|
236
229
|
var React = __toESM(require("react"));
|
|
237
230
|
var import_browser_sdk2 = require("@phantom/browser-sdk");
|
|
238
|
-
var cachedIsInstalled = null;
|
|
239
231
|
function useIsExtensionInstalled() {
|
|
240
|
-
const
|
|
241
|
-
const [
|
|
242
|
-
const [isInstalled, setIsInstalled] = React.useState(cachedIsInstalled ?? false);
|
|
232
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
233
|
+
const [isInstalled, setIsInstalled] = React.useState(false);
|
|
243
234
|
React.useEffect(() => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (cachedIsInstalled !== null) {
|
|
249
|
-
setIsInstalled(cachedIsInstalled);
|
|
250
|
-
setIsLoading(false);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const checkExtension = () => {
|
|
235
|
+
let isMounted = true;
|
|
236
|
+
const checkExtension = async () => {
|
|
254
237
|
try {
|
|
255
238
|
setIsLoading(true);
|
|
256
|
-
const result = import_browser_sdk2.
|
|
257
|
-
|
|
258
|
-
|
|
239
|
+
const result = await (0, import_browser_sdk2.waitForPhantomExtension)(3e3);
|
|
240
|
+
if (isMounted) {
|
|
241
|
+
setIsInstalled(result);
|
|
242
|
+
}
|
|
259
243
|
} catch (error) {
|
|
260
|
-
|
|
261
|
-
|
|
244
|
+
if (isMounted) {
|
|
245
|
+
setIsInstalled(false);
|
|
246
|
+
}
|
|
262
247
|
} finally {
|
|
263
|
-
|
|
248
|
+
if (isMounted) {
|
|
249
|
+
setIsLoading(false);
|
|
250
|
+
}
|
|
264
251
|
}
|
|
265
252
|
};
|
|
266
253
|
checkExtension();
|
|
267
|
-
|
|
254
|
+
return () => {
|
|
255
|
+
isMounted = false;
|
|
256
|
+
};
|
|
257
|
+
}, []);
|
|
268
258
|
return { isLoading, isInstalled };
|
|
269
259
|
}
|
|
270
260
|
|
|
@@ -301,53 +291,47 @@ function useAutoConfirm() {
|
|
|
301
291
|
},
|
|
302
292
|
[sdk, isInjected]
|
|
303
293
|
);
|
|
304
|
-
const disable = (0, import_react4.useCallback)(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
} finally {
|
|
346
|
-
setIsLoading(false);
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
[sdk, isInjected]
|
|
350
|
-
);
|
|
294
|
+
const disable = (0, import_react4.useCallback)(async () => {
|
|
295
|
+
if (!sdk) {
|
|
296
|
+
throw new Error("SDK not initialized");
|
|
297
|
+
}
|
|
298
|
+
if (!isInjected) {
|
|
299
|
+
throw new Error("Auto-confirm is only available for injected (extension) providers");
|
|
300
|
+
}
|
|
301
|
+
try {
|
|
302
|
+
setIsLoading(true);
|
|
303
|
+
setError(null);
|
|
304
|
+
await sdk.disableAutoConfirm();
|
|
305
|
+
const newStatus = await sdk.getAutoConfirmStatus();
|
|
306
|
+
setStatus(newStatus);
|
|
307
|
+
} catch (err) {
|
|
308
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
309
|
+
setError(error2);
|
|
310
|
+
throw error2;
|
|
311
|
+
} finally {
|
|
312
|
+
setIsLoading(false);
|
|
313
|
+
}
|
|
314
|
+
}, [sdk, isInjected]);
|
|
315
|
+
const refetch = (0, import_react4.useCallback)(async () => {
|
|
316
|
+
if (!sdk || !isInjected) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
setIsLoading(true);
|
|
321
|
+
setError(null);
|
|
322
|
+
const [statusResult, supportedResult] = await Promise.all([
|
|
323
|
+
sdk.getAutoConfirmStatus(),
|
|
324
|
+
sdk.getSupportedAutoConfirmChains()
|
|
325
|
+
]);
|
|
326
|
+
setStatus(statusResult);
|
|
327
|
+
setSupportedChains(supportedResult);
|
|
328
|
+
} catch (err) {
|
|
329
|
+
const error2 = err instanceof Error ? err : new Error("Failed to fetch auto-confirm data");
|
|
330
|
+
setError(error2);
|
|
331
|
+
} finally {
|
|
332
|
+
setIsLoading(false);
|
|
333
|
+
}
|
|
334
|
+
}, [sdk, isInjected]);
|
|
351
335
|
(0, import_react4.useEffect)(() => {
|
|
352
336
|
if (sdk && isInjected) {
|
|
353
337
|
refetch();
|
|
@@ -372,6 +356,13 @@ function useAutoConfirm() {
|
|
|
372
356
|
var import_react5 = require("react");
|
|
373
357
|
function useSolana() {
|
|
374
358
|
const { sdk, isConnected } = usePhantom();
|
|
359
|
+
const getSolanaChain = (0, import_react5.useCallback)(() => {
|
|
360
|
+
if (!sdk)
|
|
361
|
+
throw new Error("Phantom SDK not initialized.");
|
|
362
|
+
if (!sdk.isConnected())
|
|
363
|
+
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
364
|
+
return sdk.solana;
|
|
365
|
+
}, [sdk]);
|
|
375
366
|
const solanaChain = (0, import_react5.useMemo)(() => {
|
|
376
367
|
if (!sdk || !isConnected)
|
|
377
368
|
return null;
|
|
@@ -381,41 +372,50 @@ function useSolana() {
|
|
|
381
372
|
return null;
|
|
382
373
|
}
|
|
383
374
|
}, [sdk, isConnected]);
|
|
384
|
-
const signMessage = (0, import_react5.useCallback)(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
375
|
+
const signMessage = (0, import_react5.useCallback)(
|
|
376
|
+
async (message) => {
|
|
377
|
+
const chain = getSolanaChain();
|
|
378
|
+
return chain.signMessage(message);
|
|
379
|
+
},
|
|
380
|
+
[getSolanaChain]
|
|
381
|
+
);
|
|
382
|
+
const signTransaction = (0, import_react5.useCallback)(
|
|
383
|
+
async (transaction) => {
|
|
384
|
+
const chain = getSolanaChain();
|
|
385
|
+
return chain.signTransaction(transaction);
|
|
386
|
+
},
|
|
387
|
+
[getSolanaChain]
|
|
388
|
+
);
|
|
389
|
+
const signAndSendTransaction = (0, import_react5.useCallback)(
|
|
390
|
+
async (transaction) => {
|
|
391
|
+
const chain = getSolanaChain();
|
|
392
|
+
return chain.signAndSendTransaction(transaction);
|
|
393
|
+
},
|
|
394
|
+
[getSolanaChain]
|
|
395
|
+
);
|
|
396
|
+
const connect = (0, import_react5.useCallback)(
|
|
397
|
+
async (options) => {
|
|
398
|
+
const chain = getSolanaChain();
|
|
399
|
+
return chain.connect(options);
|
|
400
|
+
},
|
|
401
|
+
[getSolanaChain]
|
|
402
|
+
);
|
|
404
403
|
const disconnect = (0, import_react5.useCallback)(async () => {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
404
|
+
const chain = getSolanaChain();
|
|
405
|
+
return chain.disconnect();
|
|
406
|
+
}, [getSolanaChain]);
|
|
407
|
+
const switchNetwork = (0, import_react5.useCallback)(
|
|
408
|
+
async (network) => {
|
|
409
|
+
const chain = getSolanaChain();
|
|
410
|
+
return chain.switchNetwork?.(network);
|
|
411
|
+
},
|
|
412
|
+
[getSolanaChain]
|
|
413
|
+
);
|
|
414
414
|
const getPublicKey = (0, import_react5.useCallback)(async () => {
|
|
415
|
-
if (!
|
|
415
|
+
if (!sdk || !sdk.isConnected())
|
|
416
416
|
return null;
|
|
417
|
-
return
|
|
418
|
-
}, [
|
|
417
|
+
return sdk.solana.getPublicKey();
|
|
418
|
+
}, [sdk]);
|
|
419
419
|
return {
|
|
420
420
|
// Chain instance for advanced usage
|
|
421
421
|
solana: solanaChain,
|
|
@@ -437,6 +437,13 @@ function useSolana() {
|
|
|
437
437
|
var import_react6 = require("react");
|
|
438
438
|
function useEthereum() {
|
|
439
439
|
const { sdk, isConnected } = usePhantom();
|
|
440
|
+
const getEthereumChain = (0, import_react6.useCallback)(() => {
|
|
441
|
+
if (!sdk)
|
|
442
|
+
throw new Error("Phantom SDK not initialized.");
|
|
443
|
+
if (!sdk.isConnected())
|
|
444
|
+
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
445
|
+
return sdk.ethereum;
|
|
446
|
+
}, [sdk]);
|
|
440
447
|
const ethereumChain = (0, import_react6.useMemo)(() => {
|
|
441
448
|
if (!sdk || !isConnected)
|
|
442
449
|
return null;
|
|
@@ -446,50 +453,70 @@ function useEthereum() {
|
|
|
446
453
|
return null;
|
|
447
454
|
}
|
|
448
455
|
}, [sdk, isConnected]);
|
|
449
|
-
const request = (0, import_react6.useCallback)(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
456
|
+
const request = (0, import_react6.useCallback)(
|
|
457
|
+
async (args) => {
|
|
458
|
+
const chain = getEthereumChain();
|
|
459
|
+
return chain.request(args);
|
|
460
|
+
},
|
|
461
|
+
[getEthereumChain]
|
|
462
|
+
);
|
|
463
|
+
const signPersonalMessage = (0, import_react6.useCallback)(
|
|
464
|
+
async (message, address) => {
|
|
465
|
+
return request({
|
|
466
|
+
method: "personal_sign",
|
|
467
|
+
params: [message, address]
|
|
468
|
+
});
|
|
469
|
+
},
|
|
470
|
+
[request]
|
|
471
|
+
);
|
|
472
|
+
const signTransaction = (0, import_react6.useCallback)(
|
|
473
|
+
async (transaction) => {
|
|
474
|
+
const chain = getEthereumChain();
|
|
475
|
+
return chain.signTransaction(transaction);
|
|
476
|
+
},
|
|
477
|
+
[getEthereumChain]
|
|
478
|
+
);
|
|
479
|
+
const sendTransaction = (0, import_react6.useCallback)(
|
|
480
|
+
async (transaction) => {
|
|
481
|
+
const chain = getEthereumChain();
|
|
482
|
+
return chain.sendTransaction(transaction);
|
|
483
|
+
},
|
|
484
|
+
[getEthereumChain]
|
|
485
|
+
);
|
|
486
|
+
const switchChain = (0, import_react6.useCallback)(
|
|
487
|
+
async (chainId) => {
|
|
488
|
+
const chain = getEthereumChain();
|
|
489
|
+
return chain.switchChain(chainId);
|
|
490
|
+
},
|
|
491
|
+
[getEthereumChain]
|
|
492
|
+
);
|
|
470
493
|
const getChainId = (0, import_react6.useCallback)(async () => {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}, [ethereumChain]);
|
|
494
|
+
const chain = getEthereumChain();
|
|
495
|
+
return chain.getChainId();
|
|
496
|
+
}, [getEthereumChain]);
|
|
475
497
|
const getAccounts = (0, import_react6.useCallback)(async () => {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
498
|
+
const chain = getEthereumChain();
|
|
499
|
+
return chain.getAccounts();
|
|
500
|
+
}, [getEthereumChain]);
|
|
501
|
+
const signMessage = (0, import_react6.useCallback)(
|
|
502
|
+
async (message) => {
|
|
503
|
+
return request({
|
|
504
|
+
method: "eth_sign",
|
|
505
|
+
params: [await getAccounts().then((accounts) => accounts[0]), message]
|
|
506
|
+
});
|
|
507
|
+
},
|
|
508
|
+
[request, getAccounts]
|
|
509
|
+
);
|
|
510
|
+
const signTypedData = (0, import_react6.useCallback)(
|
|
511
|
+
async (typedData) => {
|
|
512
|
+
const accounts = await getAccounts();
|
|
513
|
+
return request({
|
|
514
|
+
method: "eth_signTypedData_v4",
|
|
515
|
+
params: [accounts[0], JSON.stringify(typedData)]
|
|
516
|
+
});
|
|
517
|
+
},
|
|
518
|
+
[request, getAccounts]
|
|
519
|
+
);
|
|
493
520
|
return {
|
|
494
521
|
// Chain instance for advanced usage
|
|
495
522
|
ethereum: ethereumChain,
|
|
@@ -498,6 +525,7 @@ function useEthereum() {
|
|
|
498
525
|
// Convenient methods
|
|
499
526
|
signPersonalMessage,
|
|
500
527
|
signMessage,
|
|
528
|
+
signTransaction,
|
|
501
529
|
signTypedData,
|
|
502
530
|
sendTransaction,
|
|
503
531
|
switchChain,
|
package/dist/index.mjs
CHANGED
|
@@ -4,14 +4,6 @@ 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, debugConfig }) {
|
|
7
|
-
const [isConnected, setIsConnected] = useState(false);
|
|
8
|
-
const [isConnecting, setIsConnecting] = useState(false);
|
|
9
|
-
const [connectError, setConnectError] = useState(null);
|
|
10
|
-
const [addresses, setAddresses] = useState([]);
|
|
11
|
-
const [walletId, setWalletId] = useState(null);
|
|
12
|
-
const [currentProviderType, setCurrentProviderType] = useState(config.providerType || null);
|
|
13
|
-
const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
|
|
14
|
-
const [sdk, setSdk] = useState(null);
|
|
15
7
|
const memoizedConfig = useMemo(() => {
|
|
16
8
|
return {
|
|
17
9
|
...config,
|
|
@@ -19,6 +11,16 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
19
11
|
providerType: config.providerType || "embedded"
|
|
20
12
|
};
|
|
21
13
|
}, [config]);
|
|
14
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
15
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
16
|
+
const [connectError, setConnectError] = useState(null);
|
|
17
|
+
const [addresses, setAddresses] = useState([]);
|
|
18
|
+
const [walletId, setWalletId] = useState(null);
|
|
19
|
+
const [currentProviderType, setCurrentProviderType] = useState(
|
|
20
|
+
memoizedConfig.providerType || null
|
|
21
|
+
);
|
|
22
|
+
const [isPhantomAvailable, setIsPhantomAvailable] = useState(false);
|
|
23
|
+
const [sdk, setSdk] = useState(null);
|
|
22
24
|
useEffect(() => {
|
|
23
25
|
const sdkInstance = new BrowserSDK(memoizedConfig);
|
|
24
26
|
const handleConnectStart = () => {
|
|
@@ -75,21 +77,21 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
75
77
|
useEffect(() => {
|
|
76
78
|
if (!sdk)
|
|
77
79
|
return;
|
|
78
|
-
const initialize = () => {
|
|
80
|
+
const initialize = async () => {
|
|
79
81
|
try {
|
|
80
|
-
const available = BrowserSDK.isPhantomInstalled();
|
|
82
|
+
const available = await BrowserSDK.isPhantomInstalled();
|
|
81
83
|
setIsPhantomAvailable(available);
|
|
82
84
|
} catch (err) {
|
|
83
85
|
console.error("Error checking Phantom extension:", err);
|
|
84
86
|
setIsPhantomAvailable(false);
|
|
85
87
|
}
|
|
86
|
-
if (
|
|
88
|
+
if (memoizedConfig.autoConnect !== false) {
|
|
87
89
|
sdk.autoConnect().catch(() => {
|
|
88
90
|
});
|
|
89
91
|
}
|
|
90
92
|
};
|
|
91
93
|
initialize();
|
|
92
|
-
}, [sdk,
|
|
94
|
+
}, [sdk, memoizedConfig.autoConnect]);
|
|
93
95
|
const value = useMemo(
|
|
94
96
|
() => ({
|
|
95
97
|
sdk,
|
|
@@ -101,16 +103,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
101
103
|
currentProviderType,
|
|
102
104
|
isPhantomAvailable
|
|
103
105
|
}),
|
|
104
|
-
[
|
|
105
|
-
sdk,
|
|
106
|
-
isConnected,
|
|
107
|
-
isConnecting,
|
|
108
|
-
connectError,
|
|
109
|
-
addresses,
|
|
110
|
-
walletId,
|
|
111
|
-
currentProviderType,
|
|
112
|
-
isPhantomAvailable
|
|
113
|
-
]
|
|
106
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, currentProviderType, isPhantomAvailable]
|
|
114
107
|
);
|
|
115
108
|
return /* @__PURE__ */ jsx(PhantomContext.Provider, { value, children });
|
|
116
109
|
}
|
|
@@ -186,37 +179,34 @@ function useAccounts() {
|
|
|
186
179
|
|
|
187
180
|
// src/hooks/useIsExtensionInstalled.ts
|
|
188
181
|
import * as React from "react";
|
|
189
|
-
import {
|
|
190
|
-
var cachedIsInstalled = null;
|
|
182
|
+
import { waitForPhantomExtension } from "@phantom/browser-sdk";
|
|
191
183
|
function useIsExtensionInstalled() {
|
|
192
|
-
const
|
|
193
|
-
const [
|
|
194
|
-
const [isInstalled, setIsInstalled] = React.useState(cachedIsInstalled ?? false);
|
|
184
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
185
|
+
const [isInstalled, setIsInstalled] = React.useState(false);
|
|
195
186
|
React.useEffect(() => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (cachedIsInstalled !== null) {
|
|
201
|
-
setIsInstalled(cachedIsInstalled);
|
|
202
|
-
setIsLoading(false);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const checkExtension = () => {
|
|
187
|
+
let isMounted = true;
|
|
188
|
+
const checkExtension = async () => {
|
|
206
189
|
try {
|
|
207
190
|
setIsLoading(true);
|
|
208
|
-
const result =
|
|
209
|
-
|
|
210
|
-
|
|
191
|
+
const result = await waitForPhantomExtension(3e3);
|
|
192
|
+
if (isMounted) {
|
|
193
|
+
setIsInstalled(result);
|
|
194
|
+
}
|
|
211
195
|
} catch (error) {
|
|
212
|
-
|
|
213
|
-
|
|
196
|
+
if (isMounted) {
|
|
197
|
+
setIsInstalled(false);
|
|
198
|
+
}
|
|
214
199
|
} finally {
|
|
215
|
-
|
|
200
|
+
if (isMounted) {
|
|
201
|
+
setIsLoading(false);
|
|
202
|
+
}
|
|
216
203
|
}
|
|
217
204
|
};
|
|
218
205
|
checkExtension();
|
|
219
|
-
|
|
206
|
+
return () => {
|
|
207
|
+
isMounted = false;
|
|
208
|
+
};
|
|
209
|
+
}, []);
|
|
220
210
|
return { isLoading, isInstalled };
|
|
221
211
|
}
|
|
222
212
|
|
|
@@ -253,53 +243,47 @@ function useAutoConfirm() {
|
|
|
253
243
|
},
|
|
254
244
|
[sdk, isInjected]
|
|
255
245
|
);
|
|
256
|
-
const disable = useCallback3(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
} finally {
|
|
298
|
-
setIsLoading(false);
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
[sdk, isInjected]
|
|
302
|
-
);
|
|
246
|
+
const disable = useCallback3(async () => {
|
|
247
|
+
if (!sdk) {
|
|
248
|
+
throw new Error("SDK not initialized");
|
|
249
|
+
}
|
|
250
|
+
if (!isInjected) {
|
|
251
|
+
throw new Error("Auto-confirm is only available for injected (extension) providers");
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
setIsLoading(true);
|
|
255
|
+
setError(null);
|
|
256
|
+
await sdk.disableAutoConfirm();
|
|
257
|
+
const newStatus = await sdk.getAutoConfirmStatus();
|
|
258
|
+
setStatus(newStatus);
|
|
259
|
+
} catch (err) {
|
|
260
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
261
|
+
setError(error2);
|
|
262
|
+
throw error2;
|
|
263
|
+
} finally {
|
|
264
|
+
setIsLoading(false);
|
|
265
|
+
}
|
|
266
|
+
}, [sdk, isInjected]);
|
|
267
|
+
const refetch = useCallback3(async () => {
|
|
268
|
+
if (!sdk || !isInjected) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
setIsLoading(true);
|
|
273
|
+
setError(null);
|
|
274
|
+
const [statusResult, supportedResult] = await Promise.all([
|
|
275
|
+
sdk.getAutoConfirmStatus(),
|
|
276
|
+
sdk.getSupportedAutoConfirmChains()
|
|
277
|
+
]);
|
|
278
|
+
setStatus(statusResult);
|
|
279
|
+
setSupportedChains(supportedResult);
|
|
280
|
+
} catch (err) {
|
|
281
|
+
const error2 = err instanceof Error ? err : new Error("Failed to fetch auto-confirm data");
|
|
282
|
+
setError(error2);
|
|
283
|
+
} finally {
|
|
284
|
+
setIsLoading(false);
|
|
285
|
+
}
|
|
286
|
+
}, [sdk, isInjected]);
|
|
303
287
|
useEffect3(() => {
|
|
304
288
|
if (sdk && isInjected) {
|
|
305
289
|
refetch();
|
|
@@ -324,6 +308,13 @@ function useAutoConfirm() {
|
|
|
324
308
|
import { useCallback as useCallback4, useMemo as useMemo2 } from "react";
|
|
325
309
|
function useSolana() {
|
|
326
310
|
const { sdk, isConnected } = usePhantom();
|
|
311
|
+
const getSolanaChain = useCallback4(() => {
|
|
312
|
+
if (!sdk)
|
|
313
|
+
throw new Error("Phantom SDK not initialized.");
|
|
314
|
+
if (!sdk.isConnected())
|
|
315
|
+
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
316
|
+
return sdk.solana;
|
|
317
|
+
}, [sdk]);
|
|
327
318
|
const solanaChain = useMemo2(() => {
|
|
328
319
|
if (!sdk || !isConnected)
|
|
329
320
|
return null;
|
|
@@ -333,41 +324,50 @@ function useSolana() {
|
|
|
333
324
|
return null;
|
|
334
325
|
}
|
|
335
326
|
}, [sdk, isConnected]);
|
|
336
|
-
const signMessage = useCallback4(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
327
|
+
const signMessage = useCallback4(
|
|
328
|
+
async (message) => {
|
|
329
|
+
const chain = getSolanaChain();
|
|
330
|
+
return chain.signMessage(message);
|
|
331
|
+
},
|
|
332
|
+
[getSolanaChain]
|
|
333
|
+
);
|
|
334
|
+
const signTransaction = useCallback4(
|
|
335
|
+
async (transaction) => {
|
|
336
|
+
const chain = getSolanaChain();
|
|
337
|
+
return chain.signTransaction(transaction);
|
|
338
|
+
},
|
|
339
|
+
[getSolanaChain]
|
|
340
|
+
);
|
|
341
|
+
const signAndSendTransaction = useCallback4(
|
|
342
|
+
async (transaction) => {
|
|
343
|
+
const chain = getSolanaChain();
|
|
344
|
+
return chain.signAndSendTransaction(transaction);
|
|
345
|
+
},
|
|
346
|
+
[getSolanaChain]
|
|
347
|
+
);
|
|
348
|
+
const connect = useCallback4(
|
|
349
|
+
async (options) => {
|
|
350
|
+
const chain = getSolanaChain();
|
|
351
|
+
return chain.connect(options);
|
|
352
|
+
},
|
|
353
|
+
[getSolanaChain]
|
|
354
|
+
);
|
|
356
355
|
const disconnect = useCallback4(async () => {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
356
|
+
const chain = getSolanaChain();
|
|
357
|
+
return chain.disconnect();
|
|
358
|
+
}, [getSolanaChain]);
|
|
359
|
+
const switchNetwork = useCallback4(
|
|
360
|
+
async (network) => {
|
|
361
|
+
const chain = getSolanaChain();
|
|
362
|
+
return chain.switchNetwork?.(network);
|
|
363
|
+
},
|
|
364
|
+
[getSolanaChain]
|
|
365
|
+
);
|
|
366
366
|
const getPublicKey = useCallback4(async () => {
|
|
367
|
-
if (!
|
|
367
|
+
if (!sdk || !sdk.isConnected())
|
|
368
368
|
return null;
|
|
369
|
-
return
|
|
370
|
-
}, [
|
|
369
|
+
return sdk.solana.getPublicKey();
|
|
370
|
+
}, [sdk]);
|
|
371
371
|
return {
|
|
372
372
|
// Chain instance for advanced usage
|
|
373
373
|
solana: solanaChain,
|
|
@@ -389,6 +389,13 @@ function useSolana() {
|
|
|
389
389
|
import { useCallback as useCallback5, useMemo as useMemo3 } from "react";
|
|
390
390
|
function useEthereum() {
|
|
391
391
|
const { sdk, isConnected } = usePhantom();
|
|
392
|
+
const getEthereumChain = useCallback5(() => {
|
|
393
|
+
if (!sdk)
|
|
394
|
+
throw new Error("Phantom SDK not initialized.");
|
|
395
|
+
if (!sdk.isConnected())
|
|
396
|
+
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
397
|
+
return sdk.ethereum;
|
|
398
|
+
}, [sdk]);
|
|
392
399
|
const ethereumChain = useMemo3(() => {
|
|
393
400
|
if (!sdk || !isConnected)
|
|
394
401
|
return null;
|
|
@@ -398,50 +405,70 @@ function useEthereum() {
|
|
|
398
405
|
return null;
|
|
399
406
|
}
|
|
400
407
|
}, [sdk, isConnected]);
|
|
401
|
-
const request = useCallback5(
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
408
|
+
const request = useCallback5(
|
|
409
|
+
async (args) => {
|
|
410
|
+
const chain = getEthereumChain();
|
|
411
|
+
return chain.request(args);
|
|
412
|
+
},
|
|
413
|
+
[getEthereumChain]
|
|
414
|
+
);
|
|
415
|
+
const signPersonalMessage = useCallback5(
|
|
416
|
+
async (message, address) => {
|
|
417
|
+
return request({
|
|
418
|
+
method: "personal_sign",
|
|
419
|
+
params: [message, address]
|
|
420
|
+
});
|
|
421
|
+
},
|
|
422
|
+
[request]
|
|
423
|
+
);
|
|
424
|
+
const signTransaction = useCallback5(
|
|
425
|
+
async (transaction) => {
|
|
426
|
+
const chain = getEthereumChain();
|
|
427
|
+
return chain.signTransaction(transaction);
|
|
428
|
+
},
|
|
429
|
+
[getEthereumChain]
|
|
430
|
+
);
|
|
431
|
+
const sendTransaction = useCallback5(
|
|
432
|
+
async (transaction) => {
|
|
433
|
+
const chain = getEthereumChain();
|
|
434
|
+
return chain.sendTransaction(transaction);
|
|
435
|
+
},
|
|
436
|
+
[getEthereumChain]
|
|
437
|
+
);
|
|
438
|
+
const switchChain = useCallback5(
|
|
439
|
+
async (chainId) => {
|
|
440
|
+
const chain = getEthereumChain();
|
|
441
|
+
return chain.switchChain(chainId);
|
|
442
|
+
},
|
|
443
|
+
[getEthereumChain]
|
|
444
|
+
);
|
|
422
445
|
const getChainId = useCallback5(async () => {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}, [ethereumChain]);
|
|
446
|
+
const chain = getEthereumChain();
|
|
447
|
+
return chain.getChainId();
|
|
448
|
+
}, [getEthereumChain]);
|
|
427
449
|
const getAccounts = useCallback5(async () => {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
450
|
+
const chain = getEthereumChain();
|
|
451
|
+
return chain.getAccounts();
|
|
452
|
+
}, [getEthereumChain]);
|
|
453
|
+
const signMessage = useCallback5(
|
|
454
|
+
async (message) => {
|
|
455
|
+
return request({
|
|
456
|
+
method: "eth_sign",
|
|
457
|
+
params: [await getAccounts().then((accounts) => accounts[0]), message]
|
|
458
|
+
});
|
|
459
|
+
},
|
|
460
|
+
[request, getAccounts]
|
|
461
|
+
);
|
|
462
|
+
const signTypedData = useCallback5(
|
|
463
|
+
async (typedData) => {
|
|
464
|
+
const accounts = await getAccounts();
|
|
465
|
+
return request({
|
|
466
|
+
method: "eth_signTypedData_v4",
|
|
467
|
+
params: [accounts[0], JSON.stringify(typedData)]
|
|
468
|
+
});
|
|
469
|
+
},
|
|
470
|
+
[request, getAccounts]
|
|
471
|
+
);
|
|
445
472
|
return {
|
|
446
473
|
// Chain instance for advanced usage
|
|
447
474
|
ethereum: ethereumChain,
|
|
@@ -450,6 +477,7 @@ function useEthereum() {
|
|
|
450
477
|
// Convenient methods
|
|
451
478
|
signPersonalMessage,
|
|
452
479
|
signMessage,
|
|
480
|
+
signTransaction,
|
|
453
481
|
signTypedData,
|
|
454
482
|
sendTransaction,
|
|
455
483
|
switchChain,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-sdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"prettier": "prettier --write \"src/**/*.{ts,tsx}\""
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@phantom/browser-sdk": "^1.0.0-beta.
|
|
30
|
-
"@phantom/chains": "^1.0.0-beta.
|
|
31
|
-
"@phantom/constants": "^1.0.0-beta.
|
|
29
|
+
"@phantom/browser-sdk": "^1.0.0-beta.2",
|
|
30
|
+
"@phantom/chains": "^1.0.0-beta.2",
|
|
31
|
+
"@phantom/constants": "^1.0.0-beta.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@testing-library/dom": "^10.4.0",
|