@phantom/react-native-sdk 0.1.8 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -28
- package/dist/index.d.ts +45 -15
- package/dist/index.js +163 -89
- package/dist/index.mjs +163 -89
- package/package.json +10 -8
package/README.md
CHANGED
|
@@ -113,12 +113,13 @@ export default function App() {
|
|
|
113
113
|
// WalletScreen.tsx
|
|
114
114
|
import React from "react";
|
|
115
115
|
import { View, Button, Text, Alert } from "react-native";
|
|
116
|
-
import { useConnect, useAccounts,
|
|
116
|
+
import { useConnect, useAccounts, useSolana, useEthereum, useDisconnect } from "@phantom/react-native-sdk";
|
|
117
117
|
|
|
118
118
|
export function WalletScreen() {
|
|
119
119
|
const { connect, isConnecting, error: connectError } = useConnect();
|
|
120
120
|
const { addresses, isConnected } = useAccounts();
|
|
121
|
-
const
|
|
121
|
+
const solana = useSolana();
|
|
122
|
+
const ethereum = useEthereum();
|
|
122
123
|
const { disconnect } = useDisconnect();
|
|
123
124
|
|
|
124
125
|
const handleConnect = async () => {
|
|
@@ -130,13 +131,20 @@ export function WalletScreen() {
|
|
|
130
131
|
}
|
|
131
132
|
};
|
|
132
133
|
|
|
133
|
-
const
|
|
134
|
+
const handleSignSolanaMessage = async () => {
|
|
134
135
|
try {
|
|
135
|
-
const signature = await signMessage(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
});
|
|
139
|
-
|
|
136
|
+
const signature = await solana.signMessage("Hello from Solana!");
|
|
137
|
+
Alert.alert("Solana Signed!", `Signature: ${signature.signature.slice(0, 10)}...`);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
Alert.alert("Error", `Failed to sign: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const handleSignEthereumMessage = async () => {
|
|
144
|
+
try {
|
|
145
|
+
const accounts = await ethereum.getAccounts();
|
|
146
|
+
const signature = await ethereum.signPersonalMessage("Hello from Ethereum!", accounts[0]);
|
|
147
|
+
Alert.alert("Ethereum Signed!", `Signature: ${signature.signature.slice(0, 10)}...`);
|
|
140
148
|
} catch (error) {
|
|
141
149
|
Alert.alert("Error", `Failed to sign: ${error.message}`);
|
|
142
150
|
}
|
|
@@ -158,12 +166,21 @@ export function WalletScreen() {
|
|
|
158
166
|
return (
|
|
159
167
|
<View style={{ padding: 20 }}>
|
|
160
168
|
<Text style={{ fontSize: 18, marginBottom: 10 }}>Wallet Connected</Text>
|
|
161
|
-
|
|
169
|
+
{addresses.map((addr, index) => (
|
|
170
|
+
<Text key={index}>
|
|
171
|
+
{addr.addressType}: {addr.address}
|
|
172
|
+
</Text>
|
|
173
|
+
))}
|
|
174
|
+
|
|
175
|
+
<Button
|
|
176
|
+
title="Sign Solana Message"
|
|
177
|
+
onPress={handleSignSolanaMessage}
|
|
178
|
+
style={{ marginTop: 10 }}
|
|
179
|
+
/>
|
|
162
180
|
|
|
163
181
|
<Button
|
|
164
|
-
title=
|
|
165
|
-
onPress={
|
|
166
|
-
disabled={isSigning}
|
|
182
|
+
title="Sign Ethereum Message"
|
|
183
|
+
onPress={handleSignEthereumMessage}
|
|
167
184
|
style={{ marginTop: 10 }}
|
|
168
185
|
/>
|
|
169
186
|
|
|
@@ -232,30 +249,38 @@ const {
|
|
|
232
249
|
} = useAccounts();
|
|
233
250
|
```
|
|
234
251
|
|
|
235
|
-
####
|
|
252
|
+
#### useSolana
|
|
236
253
|
|
|
237
|
-
|
|
254
|
+
Provides access to Solana-specific operations.
|
|
238
255
|
|
|
239
256
|
```typescript
|
|
240
|
-
const
|
|
257
|
+
const solana = useSolana();
|
|
258
|
+
|
|
259
|
+
// Sign a message
|
|
260
|
+
const signature = await solana.signMessage("Hello Solana!");
|
|
241
261
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
networkId: "solana:mainnet", // or 'ethereum:1'
|
|
245
|
-
});
|
|
262
|
+
// Sign and send a transaction
|
|
263
|
+
const result = await solana.signAndSendTransaction(transaction);
|
|
246
264
|
```
|
|
247
265
|
|
|
248
|
-
####
|
|
266
|
+
#### useEthereum
|
|
249
267
|
|
|
250
|
-
|
|
268
|
+
Provides access to Ethereum-specific operations.
|
|
251
269
|
|
|
252
270
|
```typescript
|
|
253
|
-
const
|
|
271
|
+
const ethereum = useEthereum();
|
|
272
|
+
|
|
273
|
+
// Get accounts
|
|
274
|
+
const accounts = await ethereum.getAccounts();
|
|
275
|
+
|
|
276
|
+
// Sign a personal message
|
|
277
|
+
const signature = await ethereum.signPersonalMessage("Hello Ethereum!", accounts[0]);
|
|
278
|
+
|
|
279
|
+
// Send a transaction
|
|
280
|
+
const result = await ethereum.sendTransaction(transactionData);
|
|
254
281
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
networkId: NetworkId.SOLANA_MAINNET,
|
|
258
|
-
});
|
|
282
|
+
// Get current chain ID
|
|
283
|
+
const chainId = await ethereum.getChainId();
|
|
259
284
|
```
|
|
260
285
|
|
|
261
286
|
#### useDisconnect
|
|
@@ -328,7 +353,7 @@ import { PhantomProvider, AddressType } from "@phantom/react-native-sdk";
|
|
|
328
353
|
</PhantomProvider>;
|
|
329
354
|
```
|
|
330
355
|
|
|
331
|
-
###
|
|
356
|
+
### Multi-Chain Configuration
|
|
332
357
|
|
|
333
358
|
```tsx
|
|
334
359
|
import { PhantomProvider, AddressType } from "@phantom/react-native-sdk";
|
|
@@ -340,8 +365,9 @@ import { PhantomProvider, AddressType } from "@phantom/react-native-sdk";
|
|
|
340
365
|
embeddedWalletType: "user-wallet",
|
|
341
366
|
addressTypes: [AddressType.solana, AddressType.ethereum],
|
|
342
367
|
apiBaseUrl: "https://api.phantom.app/v1/wallets",
|
|
368
|
+
solanaProvider: "web3js",
|
|
343
369
|
authOptions: {
|
|
344
|
-
authUrl: "https://
|
|
370
|
+
authUrl: "https://connect.phantom.app",
|
|
345
371
|
redirectUrl: "mycompany-wallet://auth/success",
|
|
346
372
|
},
|
|
347
373
|
}}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import * as _phantom_embedded_provider_core from '@phantom/embedded-provider-core';
|
|
4
|
-
import { EmbeddedProviderConfig, EmbeddedProvider, WalletAddress, ConnectResult
|
|
4
|
+
import { EmbeddedProviderConfig, EmbeddedProvider, WalletAddress, ConnectResult } from '@phantom/embedded-provider-core';
|
|
5
5
|
export { ConnectResult, SignAndSendTransactionParams, SignMessageParams, SignMessageResult, SignedTransaction, WalletAddress } from '@phantom/embedded-provider-core';
|
|
6
|
+
import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
|
|
7
|
+
import { ParsedSignatureResult, ParsedTransactionResult } from '@phantom/parsers';
|
|
6
8
|
export { AddressType } from '@phantom/client';
|
|
7
9
|
export { NetworkId } from '@phantom/constants';
|
|
8
10
|
|
|
@@ -40,14 +42,10 @@ interface PhantomProviderProps {
|
|
|
40
42
|
debugConfig?: PhantomDebugConfig;
|
|
41
43
|
}
|
|
42
44
|
declare function PhantomProvider({ children, config, debugConfig }: PhantomProviderProps): react_jsx_runtime.JSX.Element;
|
|
43
|
-
/**
|
|
44
|
-
* Hook to access the Phantom context
|
|
45
|
-
* Must be used within a PhantomProvider
|
|
46
|
-
*/
|
|
47
45
|
declare function usePhantom(): PhantomContextValue;
|
|
48
46
|
|
|
49
47
|
declare function useConnect(): {
|
|
50
|
-
connect: (
|
|
48
|
+
connect: (_options?: ConnectOptions) => Promise<ConnectResult>;
|
|
51
49
|
isConnecting: boolean;
|
|
52
50
|
error: Error | null;
|
|
53
51
|
};
|
|
@@ -64,16 +62,48 @@ declare function useAccounts(): {
|
|
|
64
62
|
walletId: string | null;
|
|
65
63
|
};
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Hook for Solana chain operations in React Native
|
|
67
|
+
*
|
|
68
|
+
* @returns Solana chain interface and convenient methods
|
|
69
|
+
*/
|
|
70
|
+
declare function useSolana(): {
|
|
71
|
+
solana: ISolanaChain | null;
|
|
72
|
+
signMessage: (message: string | Uint8Array) => Promise<ParsedSignatureResult>;
|
|
73
|
+
signTransaction: <T>(transaction: T) => Promise<T>;
|
|
74
|
+
signAndSendTransaction: <T>(transaction: T) => Promise<ParsedTransactionResult>;
|
|
75
|
+
connect: (options?: {
|
|
76
|
+
onlyIfTrusted?: boolean;
|
|
77
|
+
}) => Promise<{
|
|
78
|
+
publicKey: string;
|
|
79
|
+
}>;
|
|
80
|
+
disconnect: () => Promise<void>;
|
|
81
|
+
switchNetwork: (network: "mainnet" | "devnet") => Promise<void>;
|
|
82
|
+
getPublicKey: () => Promise<string | null>;
|
|
83
|
+
isAvailable: boolean;
|
|
84
|
+
isConnected: boolean;
|
|
71
85
|
};
|
|
72
86
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Hook for Ethereum chain operations in React Native
|
|
89
|
+
*
|
|
90
|
+
* @returns Ethereum chain interface and convenient methods
|
|
91
|
+
*/
|
|
92
|
+
declare function useEthereum(): {
|
|
93
|
+
ethereum: IEthereumChain | null;
|
|
94
|
+
request: <T = any>(args: {
|
|
95
|
+
method: string;
|
|
96
|
+
params?: unknown[];
|
|
97
|
+
}) => Promise<T>;
|
|
98
|
+
signPersonalMessage: (message: string, address: string) => Promise<ParsedSignatureResult>;
|
|
99
|
+
signMessage: (message: string) => Promise<string>;
|
|
100
|
+
signTypedData: (typedData: any) => Promise<ParsedSignatureResult>;
|
|
101
|
+
sendTransaction: (transaction: EthTransactionRequest) => Promise<ParsedTransactionResult>;
|
|
102
|
+
switchChain: (chainId: number) => Promise<void>;
|
|
103
|
+
getChainId: () => Promise<number>;
|
|
104
|
+
getAccounts: () => Promise<string[]>;
|
|
105
|
+
isAvailable: boolean;
|
|
106
|
+
isConnected: boolean;
|
|
77
107
|
};
|
|
78
108
|
|
|
79
|
-
export { ConnectOptions, PhantomDebugConfig, PhantomProvider, PhantomSDKConfig, useAccounts, useConnect, useDisconnect,
|
|
109
|
+
export { ConnectOptions, PhantomDebugConfig, PhantomProvider, PhantomSDKConfig, useAccounts, useConnect, useDisconnect, useEthereum, usePhantom, useSolana };
|
package/dist/index.js
CHANGED
|
@@ -36,9 +36,9 @@ __export(src_exports, {
|
|
|
36
36
|
useAccounts: () => useAccounts,
|
|
37
37
|
useConnect: () => useConnect,
|
|
38
38
|
useDisconnect: () => useDisconnect,
|
|
39
|
+
useEthereum: () => useEthereum,
|
|
39
40
|
usePhantom: () => usePhantom,
|
|
40
|
-
|
|
41
|
-
useSignMessage: () => useSignMessage
|
|
41
|
+
useSolana: () => useSolana
|
|
42
42
|
});
|
|
43
43
|
module.exports = __toCommonJS(src_exports);
|
|
44
44
|
|
|
@@ -261,33 +261,6 @@ var ExpoURLParamsAccessor = class {
|
|
|
261
261
|
}
|
|
262
262
|
};
|
|
263
263
|
|
|
264
|
-
// src/providers/embedded/logger.ts
|
|
265
|
-
var ExpoLogger = class {
|
|
266
|
-
constructor(enabled = false) {
|
|
267
|
-
this.enabled = enabled;
|
|
268
|
-
}
|
|
269
|
-
info(category, message, data) {
|
|
270
|
-
if (this.enabled) {
|
|
271
|
-
console.info(`[${category}] ${message}`, data);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
warn(category, message, data) {
|
|
275
|
-
if (this.enabled) {
|
|
276
|
-
console.warn(`[${category}] ${message}`, data);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
error(category, message, data) {
|
|
280
|
-
if (this.enabled) {
|
|
281
|
-
console.error(`[${category}] ${message}`, data);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
log(category, message, data) {
|
|
285
|
-
if (this.enabled) {
|
|
286
|
-
console.log(`[${category}] ${message}`, data);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
|
|
291
264
|
// src/providers/embedded/stamper.ts
|
|
292
265
|
var SecureStore2 = __toESM(require("expo-secure-store"));
|
|
293
266
|
var import_api_key_stamper = require("@phantom/api-key-stamper");
|
|
@@ -462,6 +435,33 @@ var ReactNativeStamper = class {
|
|
|
462
435
|
}
|
|
463
436
|
};
|
|
464
437
|
|
|
438
|
+
// src/providers/embedded/logger.ts
|
|
439
|
+
var ExpoLogger = class {
|
|
440
|
+
constructor(enabled = false) {
|
|
441
|
+
this.enabled = enabled;
|
|
442
|
+
}
|
|
443
|
+
info(category, message, data) {
|
|
444
|
+
if (this.enabled) {
|
|
445
|
+
console.info(`[${category}] ${message}`, data);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
warn(category, message, data) {
|
|
449
|
+
if (this.enabled) {
|
|
450
|
+
console.warn(`[${category}] ${message}`, data);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
error(category, message, data) {
|
|
454
|
+
if (this.enabled) {
|
|
455
|
+
console.error(`[${category}] ${message}`, data);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
log(category, message, data) {
|
|
459
|
+
if (this.enabled) {
|
|
460
|
+
console.log(`[${category}] ${message}`, data);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
465
|
// src/PhantomProvider.tsx
|
|
466
466
|
var import_react_native2 = require("react-native");
|
|
467
467
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -574,7 +574,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
574
574
|
}
|
|
575
575
|
function usePhantom() {
|
|
576
576
|
const context = (0, import_react.useContext)(PhantomContext);
|
|
577
|
-
if (
|
|
577
|
+
if (context === void 0) {
|
|
578
578
|
throw new Error("usePhantom must be used within a PhantomProvider");
|
|
579
579
|
}
|
|
580
580
|
return context;
|
|
@@ -585,12 +585,12 @@ var import_react2 = require("react");
|
|
|
585
585
|
function useConnect() {
|
|
586
586
|
const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
|
|
587
587
|
const connect = (0, import_react2.useCallback)(
|
|
588
|
-
async (
|
|
588
|
+
async (_options) => {
|
|
589
589
|
if (!sdk) {
|
|
590
590
|
throw new Error("SDK not initialized");
|
|
591
591
|
}
|
|
592
592
|
try {
|
|
593
|
-
const result = await sdk.connect(
|
|
593
|
+
const result = await sdk.connect();
|
|
594
594
|
if (result.status === "completed" && result.walletId) {
|
|
595
595
|
setWalletId(result.walletId);
|
|
596
596
|
}
|
|
@@ -648,69 +648,143 @@ function useAccounts() {
|
|
|
648
648
|
};
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
-
// src/hooks/
|
|
651
|
+
// src/hooks/useSolana.ts
|
|
652
652
|
var import_react4 = require("react");
|
|
653
|
-
function
|
|
654
|
-
const { sdk } = usePhantom();
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
653
|
+
function useSolana() {
|
|
654
|
+
const { sdk, isConnected } = usePhantom();
|
|
655
|
+
const solanaChain = (0, import_react4.useMemo)(() => {
|
|
656
|
+
if (!sdk || !isConnected)
|
|
657
|
+
return null;
|
|
658
|
+
try {
|
|
659
|
+
return sdk.solana;
|
|
660
|
+
} catch {
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
}, [sdk, isConnected]);
|
|
664
|
+
const signMessage = (0, import_react4.useCallback)(async (message) => {
|
|
665
|
+
if (!solanaChain)
|
|
666
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
667
|
+
return await solanaChain.signMessage(message);
|
|
668
|
+
}, [solanaChain]);
|
|
669
|
+
const signTransaction = (0, import_react4.useCallback)(async (transaction) => {
|
|
670
|
+
if (!solanaChain)
|
|
671
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
672
|
+
return await solanaChain.signTransaction(transaction);
|
|
673
|
+
}, [solanaChain]);
|
|
674
|
+
const signAndSendTransaction = (0, import_react4.useCallback)(async (transaction) => {
|
|
675
|
+
if (!solanaChain)
|
|
676
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
677
|
+
return await solanaChain.signAndSendTransaction(transaction);
|
|
678
|
+
}, [solanaChain]);
|
|
679
|
+
const connect = (0, import_react4.useCallback)(async (options) => {
|
|
680
|
+
if (!solanaChain)
|
|
681
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
682
|
+
return await solanaChain.connect(options);
|
|
683
|
+
}, [solanaChain]);
|
|
684
|
+
const disconnect = (0, import_react4.useCallback)(async () => {
|
|
685
|
+
if (!solanaChain)
|
|
686
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
687
|
+
return await solanaChain.disconnect();
|
|
688
|
+
}, [solanaChain]);
|
|
689
|
+
const switchNetwork = (0, import_react4.useCallback)(async (network) => {
|
|
690
|
+
if (!solanaChain)
|
|
691
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
692
|
+
return await solanaChain.switchNetwork(network);
|
|
693
|
+
}, [solanaChain]);
|
|
694
|
+
const getPublicKey = (0, import_react4.useCallback)(async () => {
|
|
695
|
+
if (!solanaChain)
|
|
696
|
+
return null;
|
|
697
|
+
return await solanaChain.getPublicKey();
|
|
698
|
+
}, [solanaChain]);
|
|
677
699
|
return {
|
|
700
|
+
// Chain instance for advanced usage
|
|
701
|
+
solana: solanaChain,
|
|
702
|
+
// Convenient methods
|
|
678
703
|
signMessage,
|
|
679
|
-
|
|
680
|
-
|
|
704
|
+
signTransaction,
|
|
705
|
+
signAndSendTransaction,
|
|
706
|
+
connect,
|
|
707
|
+
disconnect,
|
|
708
|
+
switchNetwork,
|
|
709
|
+
getPublicKey,
|
|
710
|
+
// State
|
|
711
|
+
isAvailable: !!solanaChain,
|
|
712
|
+
isConnected: solanaChain?.isConnected() ?? false
|
|
681
713
|
};
|
|
682
714
|
}
|
|
683
715
|
|
|
684
|
-
// src/hooks/
|
|
716
|
+
// src/hooks/useEthereum.ts
|
|
685
717
|
var import_react5 = require("react");
|
|
686
|
-
function
|
|
687
|
-
const { sdk } = usePhantom();
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
718
|
+
function useEthereum() {
|
|
719
|
+
const { sdk, isConnected } = usePhantom();
|
|
720
|
+
const ethereumChain = (0, import_react5.useMemo)(() => {
|
|
721
|
+
if (!sdk || !isConnected)
|
|
722
|
+
return null;
|
|
723
|
+
try {
|
|
724
|
+
return sdk.ethereum;
|
|
725
|
+
} catch {
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
}, [sdk, isConnected]);
|
|
729
|
+
const request = (0, import_react5.useCallback)(async (args) => {
|
|
730
|
+
if (!ethereumChain)
|
|
731
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
732
|
+
return await ethereumChain.request(args);
|
|
733
|
+
}, [ethereumChain]);
|
|
734
|
+
const signPersonalMessage = (0, import_react5.useCallback)(async (message, address) => {
|
|
735
|
+
if (!ethereumChain)
|
|
736
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
737
|
+
return await ethereumChain.signPersonalMessage(message, address);
|
|
738
|
+
}, [ethereumChain]);
|
|
739
|
+
const sendTransaction = (0, import_react5.useCallback)(async (transaction) => {
|
|
740
|
+
if (!ethereumChain)
|
|
741
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
742
|
+
return await ethereumChain.sendTransaction(transaction);
|
|
743
|
+
}, [ethereumChain]);
|
|
744
|
+
const switchChain = (0, import_react5.useCallback)(async (chainId) => {
|
|
745
|
+
if (!ethereumChain)
|
|
746
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
747
|
+
return await ethereumChain.switchChain(chainId);
|
|
748
|
+
}, [ethereumChain]);
|
|
749
|
+
const getChainId = (0, import_react5.useCallback)(async () => {
|
|
750
|
+
if (!ethereumChain)
|
|
751
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
752
|
+
return await ethereumChain.getChainId();
|
|
753
|
+
}, [ethereumChain]);
|
|
754
|
+
const getAccounts = (0, import_react5.useCallback)(async () => {
|
|
755
|
+
if (!ethereumChain)
|
|
756
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
757
|
+
return await ethereumChain.getAccounts();
|
|
758
|
+
}, [ethereumChain]);
|
|
759
|
+
const signMessage = (0, import_react5.useCallback)(async (message) => {
|
|
760
|
+
const accounts = await getAccounts();
|
|
761
|
+
return await request({
|
|
762
|
+
method: "eth_sign",
|
|
763
|
+
params: [accounts[0], message]
|
|
764
|
+
});
|
|
765
|
+
}, [request, getAccounts]);
|
|
766
|
+
const signTypedData = (0, import_react5.useCallback)(async (typedData) => {
|
|
767
|
+
if (!ethereumChain)
|
|
768
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
769
|
+
const accounts = await getAccounts();
|
|
770
|
+
return await ethereumChain.signTypedData(typedData, accounts[0]);
|
|
771
|
+
}, [ethereumChain, getAccounts]);
|
|
710
772
|
return {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
773
|
+
// Chain instance for advanced usage
|
|
774
|
+
ethereum: ethereumChain,
|
|
775
|
+
// Standard EIP-1193 interface
|
|
776
|
+
request,
|
|
777
|
+
// Convenient methods
|
|
778
|
+
signPersonalMessage,
|
|
779
|
+
signMessage,
|
|
780
|
+
signTypedData,
|
|
781
|
+
sendTransaction,
|
|
782
|
+
switchChain,
|
|
783
|
+
getChainId,
|
|
784
|
+
getAccounts,
|
|
785
|
+
// State
|
|
786
|
+
isAvailable: !!ethereumChain,
|
|
787
|
+
isConnected: ethereumChain?.isConnected() ?? false
|
|
714
788
|
};
|
|
715
789
|
}
|
|
716
790
|
|
|
@@ -725,7 +799,7 @@ var import_constants = require("@phantom/constants");
|
|
|
725
799
|
useAccounts,
|
|
726
800
|
useConnect,
|
|
727
801
|
useDisconnect,
|
|
802
|
+
useEthereum,
|
|
728
803
|
usePhantom,
|
|
729
|
-
|
|
730
|
-
useSignMessage
|
|
804
|
+
useSolana
|
|
731
805
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -217,33 +217,6 @@ var ExpoURLParamsAccessor = class {
|
|
|
217
217
|
}
|
|
218
218
|
};
|
|
219
219
|
|
|
220
|
-
// src/providers/embedded/logger.ts
|
|
221
|
-
var ExpoLogger = class {
|
|
222
|
-
constructor(enabled = false) {
|
|
223
|
-
this.enabled = enabled;
|
|
224
|
-
}
|
|
225
|
-
info(category, message, data) {
|
|
226
|
-
if (this.enabled) {
|
|
227
|
-
console.info(`[${category}] ${message}`, data);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
warn(category, message, data) {
|
|
231
|
-
if (this.enabled) {
|
|
232
|
-
console.warn(`[${category}] ${message}`, data);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
error(category, message, data) {
|
|
236
|
-
if (this.enabled) {
|
|
237
|
-
console.error(`[${category}] ${message}`, data);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
log(category, message, data) {
|
|
241
|
-
if (this.enabled) {
|
|
242
|
-
console.log(`[${category}] ${message}`, data);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
|
|
247
220
|
// src/providers/embedded/stamper.ts
|
|
248
221
|
import * as SecureStore2 from "expo-secure-store";
|
|
249
222
|
import { ApiKeyStamper } from "@phantom/api-key-stamper";
|
|
@@ -418,6 +391,33 @@ var ReactNativeStamper = class {
|
|
|
418
391
|
}
|
|
419
392
|
};
|
|
420
393
|
|
|
394
|
+
// src/providers/embedded/logger.ts
|
|
395
|
+
var ExpoLogger = class {
|
|
396
|
+
constructor(enabled = false) {
|
|
397
|
+
this.enabled = enabled;
|
|
398
|
+
}
|
|
399
|
+
info(category, message, data) {
|
|
400
|
+
if (this.enabled) {
|
|
401
|
+
console.info(`[${category}] ${message}`, data);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
warn(category, message, data) {
|
|
405
|
+
if (this.enabled) {
|
|
406
|
+
console.warn(`[${category}] ${message}`, data);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
error(category, message, data) {
|
|
410
|
+
if (this.enabled) {
|
|
411
|
+
console.error(`[${category}] ${message}`, data);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
log(category, message, data) {
|
|
415
|
+
if (this.enabled) {
|
|
416
|
+
console.log(`[${category}] ${message}`, data);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
421
|
// src/PhantomProvider.tsx
|
|
422
422
|
import { Platform } from "react-native";
|
|
423
423
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -530,7 +530,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
530
530
|
}
|
|
531
531
|
function usePhantom() {
|
|
532
532
|
const context = useContext(PhantomContext);
|
|
533
|
-
if (
|
|
533
|
+
if (context === void 0) {
|
|
534
534
|
throw new Error("usePhantom must be used within a PhantomProvider");
|
|
535
535
|
}
|
|
536
536
|
return context;
|
|
@@ -541,12 +541,12 @@ import { useCallback } from "react";
|
|
|
541
541
|
function useConnect() {
|
|
542
542
|
const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
|
|
543
543
|
const connect = useCallback(
|
|
544
|
-
async (
|
|
544
|
+
async (_options) => {
|
|
545
545
|
if (!sdk) {
|
|
546
546
|
throw new Error("SDK not initialized");
|
|
547
547
|
}
|
|
548
548
|
try {
|
|
549
|
-
const result = await sdk.connect(
|
|
549
|
+
const result = await sdk.connect();
|
|
550
550
|
if (result.status === "completed" && result.walletId) {
|
|
551
551
|
setWalletId(result.walletId);
|
|
552
552
|
}
|
|
@@ -604,69 +604,143 @@ function useAccounts() {
|
|
|
604
604
|
};
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
-
// src/hooks/
|
|
608
|
-
import {
|
|
609
|
-
function
|
|
610
|
-
const { sdk } = usePhantom();
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
607
|
+
// src/hooks/useSolana.ts
|
|
608
|
+
import { useCallback as useCallback3, useMemo as useMemo2 } from "react";
|
|
609
|
+
function useSolana() {
|
|
610
|
+
const { sdk, isConnected } = usePhantom();
|
|
611
|
+
const solanaChain = useMemo2(() => {
|
|
612
|
+
if (!sdk || !isConnected)
|
|
613
|
+
return null;
|
|
614
|
+
try {
|
|
615
|
+
return sdk.solana;
|
|
616
|
+
} catch {
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
}, [sdk, isConnected]);
|
|
620
|
+
const signMessage = useCallback3(async (message) => {
|
|
621
|
+
if (!solanaChain)
|
|
622
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
623
|
+
return await solanaChain.signMessage(message);
|
|
624
|
+
}, [solanaChain]);
|
|
625
|
+
const signTransaction = useCallback3(async (transaction) => {
|
|
626
|
+
if (!solanaChain)
|
|
627
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
628
|
+
return await solanaChain.signTransaction(transaction);
|
|
629
|
+
}, [solanaChain]);
|
|
630
|
+
const signAndSendTransaction = useCallback3(async (transaction) => {
|
|
631
|
+
if (!solanaChain)
|
|
632
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
633
|
+
return await solanaChain.signAndSendTransaction(transaction);
|
|
634
|
+
}, [solanaChain]);
|
|
635
|
+
const connect = useCallback3(async (options) => {
|
|
636
|
+
if (!solanaChain)
|
|
637
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
638
|
+
return await solanaChain.connect(options);
|
|
639
|
+
}, [solanaChain]);
|
|
640
|
+
const disconnect = useCallback3(async () => {
|
|
641
|
+
if (!solanaChain)
|
|
642
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
643
|
+
return await solanaChain.disconnect();
|
|
644
|
+
}, [solanaChain]);
|
|
645
|
+
const switchNetwork = useCallback3(async (network) => {
|
|
646
|
+
if (!solanaChain)
|
|
647
|
+
throw new Error("Solana chain not available. Ensure SDK is connected.");
|
|
648
|
+
return await solanaChain.switchNetwork(network);
|
|
649
|
+
}, [solanaChain]);
|
|
650
|
+
const getPublicKey = useCallback3(async () => {
|
|
651
|
+
if (!solanaChain)
|
|
652
|
+
return null;
|
|
653
|
+
return await solanaChain.getPublicKey();
|
|
654
|
+
}, [solanaChain]);
|
|
633
655
|
return {
|
|
656
|
+
// Chain instance for advanced usage
|
|
657
|
+
solana: solanaChain,
|
|
658
|
+
// Convenient methods
|
|
634
659
|
signMessage,
|
|
635
|
-
|
|
636
|
-
|
|
660
|
+
signTransaction,
|
|
661
|
+
signAndSendTransaction,
|
|
662
|
+
connect,
|
|
663
|
+
disconnect,
|
|
664
|
+
switchNetwork,
|
|
665
|
+
getPublicKey,
|
|
666
|
+
// State
|
|
667
|
+
isAvailable: !!solanaChain,
|
|
668
|
+
isConnected: solanaChain?.isConnected() ?? false
|
|
637
669
|
};
|
|
638
670
|
}
|
|
639
671
|
|
|
640
|
-
// src/hooks/
|
|
641
|
-
import {
|
|
642
|
-
function
|
|
643
|
-
const { sdk } = usePhantom();
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
672
|
+
// src/hooks/useEthereum.ts
|
|
673
|
+
import { useCallback as useCallback4, useMemo as useMemo3 } from "react";
|
|
674
|
+
function useEthereum() {
|
|
675
|
+
const { sdk, isConnected } = usePhantom();
|
|
676
|
+
const ethereumChain = useMemo3(() => {
|
|
677
|
+
if (!sdk || !isConnected)
|
|
678
|
+
return null;
|
|
679
|
+
try {
|
|
680
|
+
return sdk.ethereum;
|
|
681
|
+
} catch {
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
}, [sdk, isConnected]);
|
|
685
|
+
const request = useCallback4(async (args) => {
|
|
686
|
+
if (!ethereumChain)
|
|
687
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
688
|
+
return await ethereumChain.request(args);
|
|
689
|
+
}, [ethereumChain]);
|
|
690
|
+
const signPersonalMessage = useCallback4(async (message, address) => {
|
|
691
|
+
if (!ethereumChain)
|
|
692
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
693
|
+
return await ethereumChain.signPersonalMessage(message, address);
|
|
694
|
+
}, [ethereumChain]);
|
|
695
|
+
const sendTransaction = useCallback4(async (transaction) => {
|
|
696
|
+
if (!ethereumChain)
|
|
697
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
698
|
+
return await ethereumChain.sendTransaction(transaction);
|
|
699
|
+
}, [ethereumChain]);
|
|
700
|
+
const switchChain = useCallback4(async (chainId) => {
|
|
701
|
+
if (!ethereumChain)
|
|
702
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
703
|
+
return await ethereumChain.switchChain(chainId);
|
|
704
|
+
}, [ethereumChain]);
|
|
705
|
+
const getChainId = useCallback4(async () => {
|
|
706
|
+
if (!ethereumChain)
|
|
707
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
708
|
+
return await ethereumChain.getChainId();
|
|
709
|
+
}, [ethereumChain]);
|
|
710
|
+
const getAccounts = useCallback4(async () => {
|
|
711
|
+
if (!ethereumChain)
|
|
712
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
713
|
+
return await ethereumChain.getAccounts();
|
|
714
|
+
}, [ethereumChain]);
|
|
715
|
+
const signMessage = useCallback4(async (message) => {
|
|
716
|
+
const accounts = await getAccounts();
|
|
717
|
+
return await request({
|
|
718
|
+
method: "eth_sign",
|
|
719
|
+
params: [accounts[0], message]
|
|
720
|
+
});
|
|
721
|
+
}, [request, getAccounts]);
|
|
722
|
+
const signTypedData = useCallback4(async (typedData) => {
|
|
723
|
+
if (!ethereumChain)
|
|
724
|
+
throw new Error("Ethereum chain not available. Ensure SDK is connected.");
|
|
725
|
+
const accounts = await getAccounts();
|
|
726
|
+
return await ethereumChain.signTypedData(typedData, accounts[0]);
|
|
727
|
+
}, [ethereumChain, getAccounts]);
|
|
666
728
|
return {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
729
|
+
// Chain instance for advanced usage
|
|
730
|
+
ethereum: ethereumChain,
|
|
731
|
+
// Standard EIP-1193 interface
|
|
732
|
+
request,
|
|
733
|
+
// Convenient methods
|
|
734
|
+
signPersonalMessage,
|
|
735
|
+
signMessage,
|
|
736
|
+
signTypedData,
|
|
737
|
+
sendTransaction,
|
|
738
|
+
switchChain,
|
|
739
|
+
getChainId,
|
|
740
|
+
getAccounts,
|
|
741
|
+
// State
|
|
742
|
+
isAvailable: !!ethereumChain,
|
|
743
|
+
isConnected: ethereumChain?.isConnected() ?? false
|
|
670
744
|
};
|
|
671
745
|
}
|
|
672
746
|
|
|
@@ -680,7 +754,7 @@ export {
|
|
|
680
754
|
useAccounts,
|
|
681
755
|
useConnect,
|
|
682
756
|
useDisconnect,
|
|
757
|
+
useEthereum,
|
|
683
758
|
usePhantom,
|
|
684
|
-
|
|
685
|
-
useSignMessage
|
|
759
|
+
useSolana
|
|
686
760
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-native-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"description": "Phantom Wallet SDK for React Native and Expo applications",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -45,13 +45,15 @@
|
|
|
45
45
|
"directory": "packages/react-native-sdk"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@phantom/api-key-stamper": "^0.
|
|
49
|
-
"@phantom/base64url": "^0.
|
|
50
|
-
"@phantom/
|
|
51
|
-
"@phantom/
|
|
52
|
-
"@phantom/
|
|
53
|
-
"@phantom/
|
|
54
|
-
"@phantom/
|
|
48
|
+
"@phantom/api-key-stamper": "^1.0.0-beta.0",
|
|
49
|
+
"@phantom/base64url": "^1.0.0-beta.0",
|
|
50
|
+
"@phantom/chains": "^1.0.0-beta.0",
|
|
51
|
+
"@phantom/client": "^1.0.0-beta.0",
|
|
52
|
+
"@phantom/constants": "^1.0.0-beta.0",
|
|
53
|
+
"@phantom/crypto": "^1.0.0-beta.0",
|
|
54
|
+
"@phantom/embedded-provider-core": "^1.0.0-beta.0",
|
|
55
|
+
"@phantom/parsers": "^1.0.0-beta.0",
|
|
56
|
+
"@phantom/sdk-types": "^1.0.0-beta.0",
|
|
55
57
|
"@types/bs58": "^5.0.0",
|
|
56
58
|
"bs58": "^6.0.0",
|
|
57
59
|
"buffer": "^6.0.3"
|