@phantom/react-native-sdk 1.0.0-beta.2 → 1.0.0-beta.21
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 +74 -54
- package/dist/index.d.ts +20 -41
- package/dist/index.js +138 -218
- package/dist/index.mjs +132 -212
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// src/PhantomProvider.tsx
|
|
2
2
|
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
|
3
3
|
import { EmbeddedProvider } from "@phantom/embedded-provider-core";
|
|
4
|
+
import { ANALYTICS_HEADERS, DEFAULT_WALLET_API_URL, DEFAULT_EMBEDDED_WALLET_TYPE, DEFAULT_AUTH_URL as DEFAULT_AUTH_URL2 } from "@phantom/constants";
|
|
4
5
|
|
|
5
6
|
// src/providers/embedded/storage.ts
|
|
6
7
|
import * as SecureStore from "expo-secure-store";
|
|
7
8
|
var ExpoSecureStorage = class {
|
|
8
9
|
constructor(requireAuth = false) {
|
|
9
10
|
this.sessionKey = "phantom_session";
|
|
11
|
+
this.logoutFlagKey = "phantom_should_clear_previous_session";
|
|
10
12
|
this.requireAuth = requireAuth;
|
|
11
13
|
}
|
|
12
14
|
async saveSession(session) {
|
|
@@ -41,6 +43,36 @@ var ExpoSecureStorage = class {
|
|
|
41
43
|
console.error("[ExpoSecureStorage] Failed to clear session", { error: error.message });
|
|
42
44
|
}
|
|
43
45
|
}
|
|
46
|
+
async getShouldClearPreviousSession() {
|
|
47
|
+
try {
|
|
48
|
+
const flagData = await SecureStore.getItemAsync(this.logoutFlagKey, {
|
|
49
|
+
requireAuthentication: false
|
|
50
|
+
// Don't require auth for this flag
|
|
51
|
+
});
|
|
52
|
+
if (!flagData) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return flagData === "true";
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("[ExpoSecureStorage] Failed to get shouldClearPreviousSession flag", {
|
|
58
|
+
error: error.message
|
|
59
|
+
});
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async setShouldClearPreviousSession(should) {
|
|
64
|
+
try {
|
|
65
|
+
await SecureStore.setItemAsync(this.logoutFlagKey, should.toString(), {
|
|
66
|
+
requireAuthentication: false,
|
|
67
|
+
// Don't require auth for this flag
|
|
68
|
+
keychainAccessible: SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error("[ExpoSecureStorage] Failed to set shouldClearPreviousSession flag", {
|
|
72
|
+
error: error.message
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
44
76
|
async isAvailable() {
|
|
45
77
|
return await SecureStore.isAvailableAsync();
|
|
46
78
|
}
|
|
@@ -52,29 +84,34 @@ var ExpoSecureStorage = class {
|
|
|
52
84
|
|
|
53
85
|
// src/providers/embedded/auth.ts
|
|
54
86
|
import * as WebBrowser from "expo-web-browser";
|
|
55
|
-
|
|
87
|
+
import { Platform } from "react-native";
|
|
88
|
+
import { DEFAULT_AUTH_URL } from "@phantom/constants";
|
|
56
89
|
var ExpoAuthProvider = class {
|
|
57
90
|
async authenticate(options) {
|
|
58
91
|
if ("jwtToken" in options) {
|
|
59
92
|
return;
|
|
60
93
|
}
|
|
61
94
|
const phantomOptions = options;
|
|
62
|
-
const { authUrl, redirectUrl,
|
|
95
|
+
const { authUrl, redirectUrl, publicKey, sessionId, provider, appId } = phantomOptions;
|
|
63
96
|
if (!redirectUrl) {
|
|
64
97
|
throw new Error("redirectUrl is required for web browser authentication");
|
|
65
98
|
}
|
|
66
|
-
if (!
|
|
67
|
-
throw new Error("
|
|
99
|
+
if (!publicKey || !sessionId || !appId) {
|
|
100
|
+
throw new Error("publicKey, sessionId and appId are required for authentication");
|
|
68
101
|
}
|
|
69
102
|
try {
|
|
70
103
|
const baseUrl = authUrl || DEFAULT_AUTH_URL;
|
|
71
104
|
const params = new URLSearchParams({
|
|
72
|
-
|
|
73
|
-
parent_organization_id: parentOrganizationId,
|
|
105
|
+
public_key: publicKey,
|
|
74
106
|
app_id: appId,
|
|
75
107
|
redirect_uri: redirectUrl,
|
|
76
108
|
session_id: sessionId,
|
|
77
|
-
|
|
109
|
+
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
110
|
+
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
111
|
+
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
112
|
+
sdk_version: "1.0.0-beta.21",
|
|
113
|
+
sdk_type: "react-native",
|
|
114
|
+
platform: Platform.OS
|
|
78
115
|
});
|
|
79
116
|
if (provider) {
|
|
80
117
|
console.log("[ExpoAuthProvider] Provider specified, will skip selection", { provider });
|
|
@@ -83,19 +120,13 @@ var ExpoAuthProvider = class {
|
|
|
83
120
|
console.log("[ExpoAuthProvider] No provider specified, defaulting to Google");
|
|
84
121
|
params.append("provider", "google");
|
|
85
122
|
}
|
|
86
|
-
if (customAuthData) {
|
|
87
|
-
console.log("[ExpoAuthProvider] Adding custom auth data");
|
|
88
|
-
params.append("authData", JSON.stringify(customAuthData));
|
|
89
|
-
}
|
|
90
123
|
const fullAuthUrl = `${baseUrl}?${params.toString()}`;
|
|
91
124
|
console.log("[ExpoAuthProvider] Starting authentication", {
|
|
92
125
|
baseUrl,
|
|
93
126
|
redirectUrl,
|
|
94
|
-
|
|
95
|
-
parentOrganizationId,
|
|
127
|
+
publicKey,
|
|
96
128
|
sessionId,
|
|
97
|
-
provider
|
|
98
|
-
hasCustomData: !!customAuthData
|
|
129
|
+
provider
|
|
99
130
|
});
|
|
100
131
|
await WebBrowser.warmUpAsync();
|
|
101
132
|
const result = await WebBrowser.openAuthSessionAsync(fullAuthUrl, redirectUrl, {
|
|
@@ -109,15 +140,33 @@ var ExpoAuthProvider = class {
|
|
|
109
140
|
if (result.type === "success" && result.url) {
|
|
110
141
|
const url = new URL(result.url);
|
|
111
142
|
const walletId = url.searchParams.get("wallet_id");
|
|
143
|
+
const organizationId = url.searchParams.get("organization_id");
|
|
112
144
|
const provider2 = url.searchParams.get("provider");
|
|
113
145
|
const accountDerivationIndex = url.searchParams.get("selected_account_index");
|
|
146
|
+
const expiresInMs = url.searchParams.get("expires_in_ms");
|
|
147
|
+
const authUserId = url.searchParams.get("auth_user_id");
|
|
114
148
|
if (!walletId) {
|
|
115
149
|
throw new Error("Authentication failed: no walletId in redirect URL");
|
|
116
150
|
}
|
|
151
|
+
if (!organizationId) {
|
|
152
|
+
console.error("[ExpoAuthProvider] Missing organizationId in redirect URL", { url: result.url });
|
|
153
|
+
throw new Error("Authentication failed: no organizationId in redirect URL");
|
|
154
|
+
}
|
|
155
|
+
console.log("[ExpoAuthProvider] Auth redirect parameters", {
|
|
156
|
+
walletId,
|
|
157
|
+
organizationId,
|
|
158
|
+
provider: provider2,
|
|
159
|
+
accountDerivationIndex,
|
|
160
|
+
expiresInMs,
|
|
161
|
+
authUserId
|
|
162
|
+
});
|
|
117
163
|
return {
|
|
118
164
|
walletId,
|
|
165
|
+
organizationId,
|
|
119
166
|
provider: provider2 || void 0,
|
|
120
|
-
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) :
|
|
167
|
+
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
|
|
168
|
+
expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
|
|
169
|
+
authUserId: authUserId || void 0
|
|
121
170
|
};
|
|
122
171
|
} else if (result.type === "cancel") {
|
|
123
172
|
throw new Error("User cancelled authentication");
|
|
@@ -218,7 +267,7 @@ var ReactNativeStamper = class {
|
|
|
218
267
|
this.algorithm = Algorithm.ed25519;
|
|
219
268
|
this.type = "PKI";
|
|
220
269
|
this.keyPrefix = config.keyPrefix || "phantom-rn-stamper";
|
|
221
|
-
this.
|
|
270
|
+
this.appId = config.appId || "default";
|
|
222
271
|
}
|
|
223
272
|
/**
|
|
224
273
|
* Initialize the stamper and generate/load cryptographic keys
|
|
@@ -371,10 +420,10 @@ var ReactNativeStamper = class {
|
|
|
371
420
|
return null;
|
|
372
421
|
}
|
|
373
422
|
getActiveKeyName() {
|
|
374
|
-
return `${this.keyPrefix}-${this.
|
|
423
|
+
return `${this.keyPrefix}-${this.appId}-active`;
|
|
375
424
|
}
|
|
376
425
|
getPendingKeyName() {
|
|
377
|
-
return `${this.keyPrefix}-${this.
|
|
426
|
+
return `${this.keyPrefix}-${this.appId}-pending`;
|
|
378
427
|
}
|
|
379
428
|
};
|
|
380
429
|
|
|
@@ -405,8 +454,22 @@ var ExpoLogger = class {
|
|
|
405
454
|
}
|
|
406
455
|
};
|
|
407
456
|
|
|
457
|
+
// src/providers/embedded/phantom-app.ts
|
|
458
|
+
var ReactNativePhantomAppProvider = class {
|
|
459
|
+
isAvailable() {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
authenticate(_options) {
|
|
463
|
+
return Promise.reject(
|
|
464
|
+
new Error(
|
|
465
|
+
"Phantom app authentication is not available in React Native. Please use other authentication methods like Google, Apple, or JWT."
|
|
466
|
+
)
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
408
471
|
// src/PhantomProvider.tsx
|
|
409
|
-
import { Platform } from "react-native";
|
|
472
|
+
import { Platform as Platform2 } from "react-native";
|
|
410
473
|
import { jsx } from "react/jsx-runtime";
|
|
411
474
|
var PhantomContext = createContext(void 0);
|
|
412
475
|
function PhantomProvider({ children, config, debugConfig }) {
|
|
@@ -415,48 +478,65 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
415
478
|
const [connectError, setConnectError] = useState(null);
|
|
416
479
|
const [addresses, setAddresses] = useState([]);
|
|
417
480
|
const [walletId, setWalletId] = useState(null);
|
|
418
|
-
const [
|
|
481
|
+
const [user, setUser] = useState(null);
|
|
419
482
|
const memoizedConfig = useMemo(() => {
|
|
420
483
|
const redirectUrl = config.authOptions?.redirectUrl || `${config.scheme}://phantom-auth-callback`;
|
|
421
484
|
return {
|
|
422
485
|
...config,
|
|
486
|
+
apiBaseUrl: config.apiBaseUrl || DEFAULT_WALLET_API_URL,
|
|
487
|
+
embeddedWalletType: config.embeddedWalletType || DEFAULT_EMBEDDED_WALLET_TYPE,
|
|
423
488
|
authOptions: {
|
|
424
489
|
...config.authOptions || {},
|
|
425
|
-
redirectUrl
|
|
490
|
+
redirectUrl,
|
|
491
|
+
authUrl: config.authOptions?.authUrl || DEFAULT_AUTH_URL2
|
|
426
492
|
}
|
|
427
493
|
};
|
|
428
494
|
}, [config]);
|
|
429
|
-
|
|
495
|
+
const sdk = useMemo(() => {
|
|
430
496
|
const storage = new ExpoSecureStorage();
|
|
431
497
|
const authProvider = new ExpoAuthProvider();
|
|
432
498
|
const urlParamsAccessor = new ExpoURLParamsAccessor();
|
|
433
499
|
const logger = new ExpoLogger(debugConfig?.enabled || false);
|
|
434
500
|
const stamper = new ReactNativeStamper({
|
|
435
|
-
keyPrefix: `phantom-rn-${memoizedConfig.
|
|
436
|
-
|
|
501
|
+
keyPrefix: `phantom-rn-${memoizedConfig.appId}`,
|
|
502
|
+
appId: memoizedConfig.appId
|
|
437
503
|
});
|
|
504
|
+
const platformName = `${Platform2.OS}-${Platform2.Version}`;
|
|
438
505
|
const platform = {
|
|
439
506
|
storage,
|
|
440
507
|
authProvider,
|
|
441
508
|
urlParamsAccessor,
|
|
442
509
|
stamper,
|
|
443
|
-
|
|
510
|
+
phantomAppProvider: new ReactNativePhantomAppProvider(),
|
|
511
|
+
name: platformName,
|
|
512
|
+
analyticsHeaders: {
|
|
513
|
+
[ANALYTICS_HEADERS.SDK_TYPE]: "react-native",
|
|
514
|
+
[ANALYTICS_HEADERS.PLATFORM]: Platform2.OS,
|
|
515
|
+
[ANALYTICS_HEADERS.PLATFORM_VERSION]: `${Platform2.Version}`,
|
|
516
|
+
[ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
517
|
+
[ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
518
|
+
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.21"
|
|
519
|
+
// Replaced at build time
|
|
520
|
+
}
|
|
444
521
|
};
|
|
445
|
-
|
|
522
|
+
return new EmbeddedProvider(memoizedConfig, platform, logger);
|
|
523
|
+
}, [memoizedConfig, debugConfig, config.appId, config.embeddedWalletType]);
|
|
524
|
+
useEffect(() => {
|
|
446
525
|
const handleConnectStart = () => {
|
|
447
526
|
setIsConnecting(true);
|
|
448
527
|
setConnectError(null);
|
|
449
528
|
};
|
|
450
|
-
const handleConnect = async () => {
|
|
529
|
+
const handleConnect = async (data) => {
|
|
451
530
|
try {
|
|
452
531
|
setIsConnected(true);
|
|
453
532
|
setIsConnecting(false);
|
|
454
|
-
|
|
533
|
+
setUser(data);
|
|
534
|
+
const addrs = await sdk.getAddresses();
|
|
455
535
|
setAddresses(addrs);
|
|
456
536
|
} catch (err) {
|
|
457
537
|
console.error("Error connecting:", err);
|
|
458
538
|
try {
|
|
459
|
-
await
|
|
539
|
+
await sdk.disconnect();
|
|
460
540
|
} catch (err2) {
|
|
461
541
|
console.error("Error disconnecting:", err2);
|
|
462
542
|
}
|
|
@@ -465,6 +545,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
465
545
|
const handleConnectError = (errorData) => {
|
|
466
546
|
setIsConnecting(false);
|
|
467
547
|
setConnectError(new Error(errorData.error || "Connection failed"));
|
|
548
|
+
setAddresses([]);
|
|
468
549
|
};
|
|
469
550
|
const handleDisconnect = () => {
|
|
470
551
|
setIsConnected(false);
|
|
@@ -472,22 +553,20 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
472
553
|
setConnectError(null);
|
|
473
554
|
setAddresses([]);
|
|
474
555
|
setWalletId(null);
|
|
556
|
+
setUser(null);
|
|
475
557
|
};
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
setSdk(sdkInstance);
|
|
558
|
+
sdk.on("connect_start", handleConnectStart);
|
|
559
|
+
sdk.on("connect", handleConnect);
|
|
560
|
+
sdk.on("connect_error", handleConnectError);
|
|
561
|
+
sdk.on("disconnect", handleDisconnect);
|
|
481
562
|
return () => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
563
|
+
sdk.off("connect_start", handleConnectStart);
|
|
564
|
+
sdk.off("connect", handleConnect);
|
|
565
|
+
sdk.off("connect_error", handleConnectError);
|
|
566
|
+
sdk.off("disconnect", handleDisconnect);
|
|
486
567
|
};
|
|
487
|
-
}, [
|
|
568
|
+
}, [sdk]);
|
|
488
569
|
useEffect(() => {
|
|
489
|
-
if (!sdk)
|
|
490
|
-
return;
|
|
491
570
|
if (config.autoConnect !== false) {
|
|
492
571
|
sdk.autoConnect().catch(() => {
|
|
493
572
|
});
|
|
@@ -501,9 +580,10 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
501
580
|
connectError,
|
|
502
581
|
addresses,
|
|
503
582
|
walletId,
|
|
504
|
-
setWalletId
|
|
583
|
+
setWalletId,
|
|
584
|
+
user
|
|
505
585
|
}),
|
|
506
|
-
[sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId]
|
|
586
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId, user]
|
|
507
587
|
);
|
|
508
588
|
return /* @__PURE__ */ jsx(PhantomContext.Provider, { value, children });
|
|
509
589
|
}
|
|
@@ -520,12 +600,12 @@ import { useCallback } from "react";
|
|
|
520
600
|
function useConnect() {
|
|
521
601
|
const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
|
|
522
602
|
const connect = useCallback(
|
|
523
|
-
async (
|
|
603
|
+
async (options) => {
|
|
524
604
|
if (!sdk) {
|
|
525
605
|
throw new Error("SDK not initialized");
|
|
526
606
|
}
|
|
527
607
|
try {
|
|
528
|
-
const result = await sdk.connect();
|
|
608
|
+
const result = await sdk.connect(options);
|
|
529
609
|
if (result.status === "completed" && result.walletId) {
|
|
530
610
|
setWalletId(result.walletId);
|
|
531
611
|
}
|
|
@@ -584,184 +664,24 @@ function useAccounts() {
|
|
|
584
664
|
}
|
|
585
665
|
|
|
586
666
|
// src/hooks/useSolana.ts
|
|
587
|
-
import { useCallback as useCallback3, useMemo as useMemo2 } from "react";
|
|
588
667
|
function useSolana() {
|
|
589
668
|
const { sdk, isConnected } = usePhantom();
|
|
590
|
-
const getSolanaChain = useCallback3(() => {
|
|
591
|
-
if (!sdk)
|
|
592
|
-
throw new Error("Phantom SDK not initialized.");
|
|
593
|
-
if (!sdk.isConnected())
|
|
594
|
-
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
595
|
-
return sdk.solana;
|
|
596
|
-
}, [sdk]);
|
|
597
|
-
const solanaChain = useMemo2(() => {
|
|
598
|
-
if (!sdk || !isConnected)
|
|
599
|
-
return null;
|
|
600
|
-
try {
|
|
601
|
-
return sdk.solana;
|
|
602
|
-
} catch {
|
|
603
|
-
return null;
|
|
604
|
-
}
|
|
605
|
-
}, [sdk, isConnected]);
|
|
606
|
-
const signMessage = useCallback3(
|
|
607
|
-
async (message) => {
|
|
608
|
-
const chain = getSolanaChain();
|
|
609
|
-
return await chain.signMessage(message);
|
|
610
|
-
},
|
|
611
|
-
[getSolanaChain]
|
|
612
|
-
);
|
|
613
|
-
const signTransaction = useCallback3(
|
|
614
|
-
async (transaction) => {
|
|
615
|
-
const chain = getSolanaChain();
|
|
616
|
-
return await chain.signTransaction(transaction);
|
|
617
|
-
},
|
|
618
|
-
[getSolanaChain]
|
|
619
|
-
);
|
|
620
|
-
const signAndSendTransaction = useCallback3(
|
|
621
|
-
async (transaction) => {
|
|
622
|
-
const chain = getSolanaChain();
|
|
623
|
-
return await chain.signAndSendTransaction(transaction);
|
|
624
|
-
},
|
|
625
|
-
[getSolanaChain]
|
|
626
|
-
);
|
|
627
|
-
const connect = useCallback3(
|
|
628
|
-
async (options) => {
|
|
629
|
-
const chain = getSolanaChain();
|
|
630
|
-
return await chain.connect(options);
|
|
631
|
-
},
|
|
632
|
-
[getSolanaChain]
|
|
633
|
-
);
|
|
634
|
-
const disconnect = useCallback3(async () => {
|
|
635
|
-
const chain = getSolanaChain();
|
|
636
|
-
return await chain.disconnect();
|
|
637
|
-
}, [getSolanaChain]);
|
|
638
|
-
const switchNetwork = useCallback3(
|
|
639
|
-
async (network) => {
|
|
640
|
-
const chain = getSolanaChain();
|
|
641
|
-
return await chain.switchNetwork?.(network);
|
|
642
|
-
},
|
|
643
|
-
[getSolanaChain]
|
|
644
|
-
);
|
|
645
|
-
const getPublicKey = useCallback3(async () => {
|
|
646
|
-
if (!sdk || !sdk.isConnected())
|
|
647
|
-
return null;
|
|
648
|
-
return await sdk.solana.getPublicKey();
|
|
649
|
-
}, [sdk]);
|
|
650
669
|
return {
|
|
651
|
-
// Chain instance for
|
|
652
|
-
solana:
|
|
653
|
-
// Convenient methods
|
|
654
|
-
signMessage,
|
|
655
|
-
signTransaction,
|
|
656
|
-
signAndSendTransaction,
|
|
657
|
-
connect,
|
|
658
|
-
disconnect,
|
|
659
|
-
switchNetwork,
|
|
660
|
-
getPublicKey,
|
|
670
|
+
// Chain instance with connection enforcement for signing methods
|
|
671
|
+
solana: sdk.solana,
|
|
661
672
|
// State
|
|
662
|
-
isAvailable: !!
|
|
663
|
-
isConnected: solanaChain?.isConnected() ?? false
|
|
673
|
+
isAvailable: !!isConnected
|
|
664
674
|
};
|
|
665
675
|
}
|
|
666
676
|
|
|
667
677
|
// src/hooks/useEthereum.ts
|
|
668
|
-
import { useCallback as useCallback4, useMemo as useMemo3 } from "react";
|
|
669
678
|
function useEthereum() {
|
|
670
679
|
const { sdk, isConnected } = usePhantom();
|
|
671
|
-
const getEthereumChain = useCallback4(() => {
|
|
672
|
-
if (!sdk)
|
|
673
|
-
throw new Error("Phantom SDK not initialized.");
|
|
674
|
-
if (!sdk.isConnected())
|
|
675
|
-
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
676
|
-
return sdk.ethereum;
|
|
677
|
-
}, [sdk]);
|
|
678
|
-
const ethereumChain = useMemo3(() => {
|
|
679
|
-
if (!sdk || !isConnected)
|
|
680
|
-
return null;
|
|
681
|
-
try {
|
|
682
|
-
return sdk.ethereum;
|
|
683
|
-
} catch {
|
|
684
|
-
return null;
|
|
685
|
-
}
|
|
686
|
-
}, [sdk, isConnected]);
|
|
687
|
-
const request = useCallback4(
|
|
688
|
-
async (args) => {
|
|
689
|
-
const chain = getEthereumChain();
|
|
690
|
-
return await chain.request(args);
|
|
691
|
-
},
|
|
692
|
-
[getEthereumChain]
|
|
693
|
-
);
|
|
694
|
-
const signPersonalMessage = useCallback4(
|
|
695
|
-
async (message, address) => {
|
|
696
|
-
const chain = getEthereumChain();
|
|
697
|
-
return await chain.signPersonalMessage(message, address);
|
|
698
|
-
},
|
|
699
|
-
[getEthereumChain]
|
|
700
|
-
);
|
|
701
|
-
const signTransaction = useCallback4(
|
|
702
|
-
async (transaction) => {
|
|
703
|
-
const chain = getEthereumChain();
|
|
704
|
-
return await chain.signTransaction(transaction);
|
|
705
|
-
},
|
|
706
|
-
[getEthereumChain]
|
|
707
|
-
);
|
|
708
|
-
const sendTransaction = useCallback4(
|
|
709
|
-
async (transaction) => {
|
|
710
|
-
const chain = getEthereumChain();
|
|
711
|
-
return await chain.sendTransaction(transaction);
|
|
712
|
-
},
|
|
713
|
-
[getEthereumChain]
|
|
714
|
-
);
|
|
715
|
-
const switchChain = useCallback4(
|
|
716
|
-
async (chainId) => {
|
|
717
|
-
const chain = getEthereumChain();
|
|
718
|
-
return await chain.switchChain(chainId);
|
|
719
|
-
},
|
|
720
|
-
[getEthereumChain]
|
|
721
|
-
);
|
|
722
|
-
const getChainId = useCallback4(async () => {
|
|
723
|
-
const chain = getEthereumChain();
|
|
724
|
-
return await chain.getChainId();
|
|
725
|
-
}, [getEthereumChain]);
|
|
726
|
-
const getAccounts = useCallback4(async () => {
|
|
727
|
-
const chain = getEthereumChain();
|
|
728
|
-
return await chain.getAccounts();
|
|
729
|
-
}, [getEthereumChain]);
|
|
730
|
-
const signMessage = useCallback4(
|
|
731
|
-
async (message) => {
|
|
732
|
-
const accounts = await getAccounts();
|
|
733
|
-
return await request({
|
|
734
|
-
method: "eth_sign",
|
|
735
|
-
params: [accounts[0], message]
|
|
736
|
-
});
|
|
737
|
-
},
|
|
738
|
-
[request, getAccounts]
|
|
739
|
-
);
|
|
740
|
-
const signTypedData = useCallback4(
|
|
741
|
-
async (typedData) => {
|
|
742
|
-
const chain = getEthereumChain();
|
|
743
|
-
const accounts = await getAccounts();
|
|
744
|
-
return await chain.signTypedData(typedData, accounts[0]);
|
|
745
|
-
},
|
|
746
|
-
[getEthereumChain, getAccounts]
|
|
747
|
-
);
|
|
748
680
|
return {
|
|
749
|
-
// Chain instance for
|
|
750
|
-
ethereum:
|
|
751
|
-
// Standard EIP-1193 interface
|
|
752
|
-
request,
|
|
753
|
-
// Convenient methods
|
|
754
|
-
signPersonalMessage,
|
|
755
|
-
signMessage,
|
|
756
|
-
signTransaction,
|
|
757
|
-
signTypedData,
|
|
758
|
-
sendTransaction,
|
|
759
|
-
switchChain,
|
|
760
|
-
getChainId,
|
|
761
|
-
getAccounts,
|
|
681
|
+
// Chain instance with connection enforcement for signing methods
|
|
682
|
+
ethereum: sdk.ethereum,
|
|
762
683
|
// State
|
|
763
|
-
isAvailable: !!
|
|
764
|
-
isConnected: ethereumChain?.isConnected() ?? false
|
|
684
|
+
isAvailable: !!isConnected
|
|
765
685
|
};
|
|
766
686
|
}
|
|
767
687
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-native-sdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.21",
|
|
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,14 +45,14 @@
|
|
|
45
45
|
"directory": "packages/react-native-sdk"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@phantom/api-key-stamper": "^1.0.0-beta.
|
|
49
|
-
"@phantom/base64url": "^1.0.0-beta.
|
|
50
|
-
"@phantom/
|
|
51
|
-
"@phantom/client": "^1.0.0-beta.
|
|
52
|
-
"@phantom/constants": "^1.0.0-beta.
|
|
53
|
-
"@phantom/crypto": "^1.0.0-beta.
|
|
54
|
-
"@phantom/embedded-provider-core": "^1.0.0-beta.
|
|
55
|
-
"@phantom/sdk-types": "^1.0.0-beta.
|
|
48
|
+
"@phantom/api-key-stamper": "^1.0.0-beta.9",
|
|
49
|
+
"@phantom/base64url": "^1.0.0-beta.9",
|
|
50
|
+
"@phantom/chain-interfaces": "^1.0.0-beta.9",
|
|
51
|
+
"@phantom/client": "^1.0.0-beta.21",
|
|
52
|
+
"@phantom/constants": "^1.0.0-beta.9",
|
|
53
|
+
"@phantom/crypto": "^1.0.0-beta.9",
|
|
54
|
+
"@phantom/embedded-provider-core": "^1.0.0-beta.21",
|
|
55
|
+
"@phantom/sdk-types": "^1.0.0-beta.9",
|
|
56
56
|
"@types/bs58": "^5.0.0",
|
|
57
57
|
"bs58": "^6.0.0",
|
|
58
58
|
"buffer": "^6.0.3"
|