@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.js
CHANGED
|
@@ -31,7 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AddressType: () => import_client.AddressType,
|
|
34
|
-
NetworkId: () =>
|
|
34
|
+
NetworkId: () => import_constants3.NetworkId,
|
|
35
35
|
PhantomProvider: () => PhantomProvider,
|
|
36
36
|
useAccounts: () => useAccounts,
|
|
37
37
|
useConnect: () => useConnect,
|
|
@@ -45,12 +45,14 @@ module.exports = __toCommonJS(src_exports);
|
|
|
45
45
|
// src/PhantomProvider.tsx
|
|
46
46
|
var import_react = require("react");
|
|
47
47
|
var import_embedded_provider_core = require("@phantom/embedded-provider-core");
|
|
48
|
+
var import_constants2 = require("@phantom/constants");
|
|
48
49
|
|
|
49
50
|
// src/providers/embedded/storage.ts
|
|
50
51
|
var SecureStore = __toESM(require("expo-secure-store"));
|
|
51
52
|
var ExpoSecureStorage = class {
|
|
52
53
|
constructor(requireAuth = false) {
|
|
53
54
|
this.sessionKey = "phantom_session";
|
|
55
|
+
this.logoutFlagKey = "phantom_should_clear_previous_session";
|
|
54
56
|
this.requireAuth = requireAuth;
|
|
55
57
|
}
|
|
56
58
|
async saveSession(session) {
|
|
@@ -85,6 +87,36 @@ var ExpoSecureStorage = class {
|
|
|
85
87
|
console.error("[ExpoSecureStorage] Failed to clear session", { error: error.message });
|
|
86
88
|
}
|
|
87
89
|
}
|
|
90
|
+
async getShouldClearPreviousSession() {
|
|
91
|
+
try {
|
|
92
|
+
const flagData = await SecureStore.getItemAsync(this.logoutFlagKey, {
|
|
93
|
+
requireAuthentication: false
|
|
94
|
+
// Don't require auth for this flag
|
|
95
|
+
});
|
|
96
|
+
if (!flagData) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return flagData === "true";
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error("[ExpoSecureStorage] Failed to get shouldClearPreviousSession flag", {
|
|
102
|
+
error: error.message
|
|
103
|
+
});
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async setShouldClearPreviousSession(should) {
|
|
108
|
+
try {
|
|
109
|
+
await SecureStore.setItemAsync(this.logoutFlagKey, should.toString(), {
|
|
110
|
+
requireAuthentication: false,
|
|
111
|
+
// Don't require auth for this flag
|
|
112
|
+
keychainAccessible: SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("[ExpoSecureStorage] Failed to set shouldClearPreviousSession flag", {
|
|
116
|
+
error: error.message
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
88
120
|
async isAvailable() {
|
|
89
121
|
return await SecureStore.isAvailableAsync();
|
|
90
122
|
}
|
|
@@ -96,29 +128,34 @@ var ExpoSecureStorage = class {
|
|
|
96
128
|
|
|
97
129
|
// src/providers/embedded/auth.ts
|
|
98
130
|
var WebBrowser = __toESM(require("expo-web-browser"));
|
|
99
|
-
var
|
|
131
|
+
var import_react_native = require("react-native");
|
|
132
|
+
var import_constants = require("@phantom/constants");
|
|
100
133
|
var ExpoAuthProvider = class {
|
|
101
134
|
async authenticate(options) {
|
|
102
135
|
if ("jwtToken" in options) {
|
|
103
136
|
return;
|
|
104
137
|
}
|
|
105
138
|
const phantomOptions = options;
|
|
106
|
-
const { authUrl, redirectUrl,
|
|
139
|
+
const { authUrl, redirectUrl, publicKey, sessionId, provider, appId } = phantomOptions;
|
|
107
140
|
if (!redirectUrl) {
|
|
108
141
|
throw new Error("redirectUrl is required for web browser authentication");
|
|
109
142
|
}
|
|
110
|
-
if (!
|
|
111
|
-
throw new Error("
|
|
143
|
+
if (!publicKey || !sessionId || !appId) {
|
|
144
|
+
throw new Error("publicKey, sessionId and appId are required for authentication");
|
|
112
145
|
}
|
|
113
146
|
try {
|
|
114
|
-
const baseUrl = authUrl || DEFAULT_AUTH_URL;
|
|
147
|
+
const baseUrl = authUrl || import_constants.DEFAULT_AUTH_URL;
|
|
115
148
|
const params = new URLSearchParams({
|
|
116
|
-
|
|
117
|
-
parent_organization_id: parentOrganizationId,
|
|
149
|
+
public_key: publicKey,
|
|
118
150
|
app_id: appId,
|
|
119
151
|
redirect_uri: redirectUrl,
|
|
120
152
|
session_id: sessionId,
|
|
121
|
-
|
|
153
|
+
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
154
|
+
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
155
|
+
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
156
|
+
sdk_version: "1.0.0-beta.21",
|
|
157
|
+
sdk_type: "react-native",
|
|
158
|
+
platform: import_react_native.Platform.OS
|
|
122
159
|
});
|
|
123
160
|
if (provider) {
|
|
124
161
|
console.log("[ExpoAuthProvider] Provider specified, will skip selection", { provider });
|
|
@@ -127,19 +164,13 @@ var ExpoAuthProvider = class {
|
|
|
127
164
|
console.log("[ExpoAuthProvider] No provider specified, defaulting to Google");
|
|
128
165
|
params.append("provider", "google");
|
|
129
166
|
}
|
|
130
|
-
if (customAuthData) {
|
|
131
|
-
console.log("[ExpoAuthProvider] Adding custom auth data");
|
|
132
|
-
params.append("authData", JSON.stringify(customAuthData));
|
|
133
|
-
}
|
|
134
167
|
const fullAuthUrl = `${baseUrl}?${params.toString()}`;
|
|
135
168
|
console.log("[ExpoAuthProvider] Starting authentication", {
|
|
136
169
|
baseUrl,
|
|
137
170
|
redirectUrl,
|
|
138
|
-
|
|
139
|
-
parentOrganizationId,
|
|
171
|
+
publicKey,
|
|
140
172
|
sessionId,
|
|
141
|
-
provider
|
|
142
|
-
hasCustomData: !!customAuthData
|
|
173
|
+
provider
|
|
143
174
|
});
|
|
144
175
|
await WebBrowser.warmUpAsync();
|
|
145
176
|
const result = await WebBrowser.openAuthSessionAsync(fullAuthUrl, redirectUrl, {
|
|
@@ -153,15 +184,33 @@ var ExpoAuthProvider = class {
|
|
|
153
184
|
if (result.type === "success" && result.url) {
|
|
154
185
|
const url = new URL(result.url);
|
|
155
186
|
const walletId = url.searchParams.get("wallet_id");
|
|
187
|
+
const organizationId = url.searchParams.get("organization_id");
|
|
156
188
|
const provider2 = url.searchParams.get("provider");
|
|
157
189
|
const accountDerivationIndex = url.searchParams.get("selected_account_index");
|
|
190
|
+
const expiresInMs = url.searchParams.get("expires_in_ms");
|
|
191
|
+
const authUserId = url.searchParams.get("auth_user_id");
|
|
158
192
|
if (!walletId) {
|
|
159
193
|
throw new Error("Authentication failed: no walletId in redirect URL");
|
|
160
194
|
}
|
|
195
|
+
if (!organizationId) {
|
|
196
|
+
console.error("[ExpoAuthProvider] Missing organizationId in redirect URL", { url: result.url });
|
|
197
|
+
throw new Error("Authentication failed: no organizationId in redirect URL");
|
|
198
|
+
}
|
|
199
|
+
console.log("[ExpoAuthProvider] Auth redirect parameters", {
|
|
200
|
+
walletId,
|
|
201
|
+
organizationId,
|
|
202
|
+
provider: provider2,
|
|
203
|
+
accountDerivationIndex,
|
|
204
|
+
expiresInMs,
|
|
205
|
+
authUserId
|
|
206
|
+
});
|
|
161
207
|
return {
|
|
162
208
|
walletId,
|
|
209
|
+
organizationId,
|
|
163
210
|
provider: provider2 || void 0,
|
|
164
|
-
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) :
|
|
211
|
+
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
|
|
212
|
+
expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
|
|
213
|
+
authUserId: authUserId || void 0
|
|
165
214
|
};
|
|
166
215
|
} else if (result.type === "cancel") {
|
|
167
216
|
throw new Error("User cancelled authentication");
|
|
@@ -181,7 +230,7 @@ var ExpoAuthProvider = class {
|
|
|
181
230
|
};
|
|
182
231
|
|
|
183
232
|
// src/providers/embedded/url-params.ts
|
|
184
|
-
var
|
|
233
|
+
var import_react_native2 = require("react-native");
|
|
185
234
|
var ExpoURLParamsAccessor = class {
|
|
186
235
|
constructor() {
|
|
187
236
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -193,7 +242,7 @@ var ExpoURLParamsAccessor = class {
|
|
|
193
242
|
}
|
|
194
243
|
async getInitialParams() {
|
|
195
244
|
try {
|
|
196
|
-
const url = await
|
|
245
|
+
const url = await import_react_native2.Linking.getInitialURL();
|
|
197
246
|
if (!url) {
|
|
198
247
|
return null;
|
|
199
248
|
}
|
|
@@ -209,7 +258,7 @@ var ExpoURLParamsAccessor = class {
|
|
|
209
258
|
if (this.subscription) {
|
|
210
259
|
return;
|
|
211
260
|
}
|
|
212
|
-
this.subscription =
|
|
261
|
+
this.subscription = import_react_native2.Linking.addEventListener("url", ({ url }) => {
|
|
213
262
|
const params = this.parseURLParams(url);
|
|
214
263
|
if (params && Object.keys(params).length > 0) {
|
|
215
264
|
this.currentParams = { ...this.currentParams, ...params };
|
|
@@ -262,7 +311,7 @@ var ReactNativeStamper = class {
|
|
|
262
311
|
this.algorithm = import_sdk_types.Algorithm.ed25519;
|
|
263
312
|
this.type = "PKI";
|
|
264
313
|
this.keyPrefix = config.keyPrefix || "phantom-rn-stamper";
|
|
265
|
-
this.
|
|
314
|
+
this.appId = config.appId || "default";
|
|
266
315
|
}
|
|
267
316
|
/**
|
|
268
317
|
* Initialize the stamper and generate/load cryptographic keys
|
|
@@ -415,10 +464,10 @@ var ReactNativeStamper = class {
|
|
|
415
464
|
return null;
|
|
416
465
|
}
|
|
417
466
|
getActiveKeyName() {
|
|
418
|
-
return `${this.keyPrefix}-${this.
|
|
467
|
+
return `${this.keyPrefix}-${this.appId}-active`;
|
|
419
468
|
}
|
|
420
469
|
getPendingKeyName() {
|
|
421
|
-
return `${this.keyPrefix}-${this.
|
|
470
|
+
return `${this.keyPrefix}-${this.appId}-pending`;
|
|
422
471
|
}
|
|
423
472
|
};
|
|
424
473
|
|
|
@@ -449,8 +498,22 @@ var ExpoLogger = class {
|
|
|
449
498
|
}
|
|
450
499
|
};
|
|
451
500
|
|
|
501
|
+
// src/providers/embedded/phantom-app.ts
|
|
502
|
+
var ReactNativePhantomAppProvider = class {
|
|
503
|
+
isAvailable() {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
authenticate(_options) {
|
|
507
|
+
return Promise.reject(
|
|
508
|
+
new Error(
|
|
509
|
+
"Phantom app authentication is not available in React Native. Please use other authentication methods like Google, Apple, or JWT."
|
|
510
|
+
)
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
452
515
|
// src/PhantomProvider.tsx
|
|
453
|
-
var
|
|
516
|
+
var import_react_native3 = require("react-native");
|
|
454
517
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
455
518
|
var PhantomContext = (0, import_react.createContext)(void 0);
|
|
456
519
|
function PhantomProvider({ children, config, debugConfig }) {
|
|
@@ -459,48 +522,65 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
459
522
|
const [connectError, setConnectError] = (0, import_react.useState)(null);
|
|
460
523
|
const [addresses, setAddresses] = (0, import_react.useState)([]);
|
|
461
524
|
const [walletId, setWalletId] = (0, import_react.useState)(null);
|
|
462
|
-
const [
|
|
525
|
+
const [user, setUser] = (0, import_react.useState)(null);
|
|
463
526
|
const memoizedConfig = (0, import_react.useMemo)(() => {
|
|
464
527
|
const redirectUrl = config.authOptions?.redirectUrl || `${config.scheme}://phantom-auth-callback`;
|
|
465
528
|
return {
|
|
466
529
|
...config,
|
|
530
|
+
apiBaseUrl: config.apiBaseUrl || import_constants2.DEFAULT_WALLET_API_URL,
|
|
531
|
+
embeddedWalletType: config.embeddedWalletType || import_constants2.DEFAULT_EMBEDDED_WALLET_TYPE,
|
|
467
532
|
authOptions: {
|
|
468
533
|
...config.authOptions || {},
|
|
469
|
-
redirectUrl
|
|
534
|
+
redirectUrl,
|
|
535
|
+
authUrl: config.authOptions?.authUrl || import_constants2.DEFAULT_AUTH_URL
|
|
470
536
|
}
|
|
471
537
|
};
|
|
472
538
|
}, [config]);
|
|
473
|
-
(0, import_react.
|
|
539
|
+
const sdk = (0, import_react.useMemo)(() => {
|
|
474
540
|
const storage = new ExpoSecureStorage();
|
|
475
541
|
const authProvider = new ExpoAuthProvider();
|
|
476
542
|
const urlParamsAccessor = new ExpoURLParamsAccessor();
|
|
477
543
|
const logger = new ExpoLogger(debugConfig?.enabled || false);
|
|
478
544
|
const stamper = new ReactNativeStamper({
|
|
479
|
-
keyPrefix: `phantom-rn-${memoizedConfig.
|
|
480
|
-
|
|
545
|
+
keyPrefix: `phantom-rn-${memoizedConfig.appId}`,
|
|
546
|
+
appId: memoizedConfig.appId
|
|
481
547
|
});
|
|
548
|
+
const platformName = `${import_react_native3.Platform.OS}-${import_react_native3.Platform.Version}`;
|
|
482
549
|
const platform = {
|
|
483
550
|
storage,
|
|
484
551
|
authProvider,
|
|
485
552
|
urlParamsAccessor,
|
|
486
553
|
stamper,
|
|
487
|
-
|
|
554
|
+
phantomAppProvider: new ReactNativePhantomAppProvider(),
|
|
555
|
+
name: platformName,
|
|
556
|
+
analyticsHeaders: {
|
|
557
|
+
[import_constants2.ANALYTICS_HEADERS.SDK_TYPE]: "react-native",
|
|
558
|
+
[import_constants2.ANALYTICS_HEADERS.PLATFORM]: import_react_native3.Platform.OS,
|
|
559
|
+
[import_constants2.ANALYTICS_HEADERS.PLATFORM_VERSION]: `${import_react_native3.Platform.Version}`,
|
|
560
|
+
[import_constants2.ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
561
|
+
[import_constants2.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
562
|
+
[import_constants2.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.21"
|
|
563
|
+
// Replaced at build time
|
|
564
|
+
}
|
|
488
565
|
};
|
|
489
|
-
|
|
566
|
+
return new import_embedded_provider_core.EmbeddedProvider(memoizedConfig, platform, logger);
|
|
567
|
+
}, [memoizedConfig, debugConfig, config.appId, config.embeddedWalletType]);
|
|
568
|
+
(0, import_react.useEffect)(() => {
|
|
490
569
|
const handleConnectStart = () => {
|
|
491
570
|
setIsConnecting(true);
|
|
492
571
|
setConnectError(null);
|
|
493
572
|
};
|
|
494
|
-
const handleConnect = async () => {
|
|
573
|
+
const handleConnect = async (data) => {
|
|
495
574
|
try {
|
|
496
575
|
setIsConnected(true);
|
|
497
576
|
setIsConnecting(false);
|
|
498
|
-
|
|
577
|
+
setUser(data);
|
|
578
|
+
const addrs = await sdk.getAddresses();
|
|
499
579
|
setAddresses(addrs);
|
|
500
580
|
} catch (err) {
|
|
501
581
|
console.error("Error connecting:", err);
|
|
502
582
|
try {
|
|
503
|
-
await
|
|
583
|
+
await sdk.disconnect();
|
|
504
584
|
} catch (err2) {
|
|
505
585
|
console.error("Error disconnecting:", err2);
|
|
506
586
|
}
|
|
@@ -509,6 +589,7 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
509
589
|
const handleConnectError = (errorData) => {
|
|
510
590
|
setIsConnecting(false);
|
|
511
591
|
setConnectError(new Error(errorData.error || "Connection failed"));
|
|
592
|
+
setAddresses([]);
|
|
512
593
|
};
|
|
513
594
|
const handleDisconnect = () => {
|
|
514
595
|
setIsConnected(false);
|
|
@@ -516,22 +597,20 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
516
597
|
setConnectError(null);
|
|
517
598
|
setAddresses([]);
|
|
518
599
|
setWalletId(null);
|
|
600
|
+
setUser(null);
|
|
519
601
|
};
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
setSdk(sdkInstance);
|
|
602
|
+
sdk.on("connect_start", handleConnectStart);
|
|
603
|
+
sdk.on("connect", handleConnect);
|
|
604
|
+
sdk.on("connect_error", handleConnectError);
|
|
605
|
+
sdk.on("disconnect", handleDisconnect);
|
|
525
606
|
return () => {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
607
|
+
sdk.off("connect_start", handleConnectStart);
|
|
608
|
+
sdk.off("connect", handleConnect);
|
|
609
|
+
sdk.off("connect_error", handleConnectError);
|
|
610
|
+
sdk.off("disconnect", handleDisconnect);
|
|
530
611
|
};
|
|
531
|
-
}, [
|
|
612
|
+
}, [sdk]);
|
|
532
613
|
(0, import_react.useEffect)(() => {
|
|
533
|
-
if (!sdk)
|
|
534
|
-
return;
|
|
535
614
|
if (config.autoConnect !== false) {
|
|
536
615
|
sdk.autoConnect().catch(() => {
|
|
537
616
|
});
|
|
@@ -545,9 +624,10 @@ function PhantomProvider({ children, config, debugConfig }) {
|
|
|
545
624
|
connectError,
|
|
546
625
|
addresses,
|
|
547
626
|
walletId,
|
|
548
|
-
setWalletId
|
|
627
|
+
setWalletId,
|
|
628
|
+
user
|
|
549
629
|
}),
|
|
550
|
-
[sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId]
|
|
630
|
+
[sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId, user]
|
|
551
631
|
);
|
|
552
632
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhantomContext.Provider, { value, children });
|
|
553
633
|
}
|
|
@@ -564,12 +644,12 @@ var import_react2 = require("react");
|
|
|
564
644
|
function useConnect() {
|
|
565
645
|
const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
|
|
566
646
|
const connect = (0, import_react2.useCallback)(
|
|
567
|
-
async (
|
|
647
|
+
async (options) => {
|
|
568
648
|
if (!sdk) {
|
|
569
649
|
throw new Error("SDK not initialized");
|
|
570
650
|
}
|
|
571
651
|
try {
|
|
572
|
-
const result = await sdk.connect();
|
|
652
|
+
const result = await sdk.connect(options);
|
|
573
653
|
if (result.status === "completed" && result.walletId) {
|
|
574
654
|
setWalletId(result.walletId);
|
|
575
655
|
}
|
|
@@ -628,190 +708,30 @@ function useAccounts() {
|
|
|
628
708
|
}
|
|
629
709
|
|
|
630
710
|
// src/hooks/useSolana.ts
|
|
631
|
-
var import_react4 = require("react");
|
|
632
711
|
function useSolana() {
|
|
633
712
|
const { sdk, isConnected } = usePhantom();
|
|
634
|
-
const getSolanaChain = (0, import_react4.useCallback)(() => {
|
|
635
|
-
if (!sdk)
|
|
636
|
-
throw new Error("Phantom SDK not initialized.");
|
|
637
|
-
if (!sdk.isConnected())
|
|
638
|
-
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
639
|
-
return sdk.solana;
|
|
640
|
-
}, [sdk]);
|
|
641
|
-
const solanaChain = (0, import_react4.useMemo)(() => {
|
|
642
|
-
if (!sdk || !isConnected)
|
|
643
|
-
return null;
|
|
644
|
-
try {
|
|
645
|
-
return sdk.solana;
|
|
646
|
-
} catch {
|
|
647
|
-
return null;
|
|
648
|
-
}
|
|
649
|
-
}, [sdk, isConnected]);
|
|
650
|
-
const signMessage = (0, import_react4.useCallback)(
|
|
651
|
-
async (message) => {
|
|
652
|
-
const chain = getSolanaChain();
|
|
653
|
-
return await chain.signMessage(message);
|
|
654
|
-
},
|
|
655
|
-
[getSolanaChain]
|
|
656
|
-
);
|
|
657
|
-
const signTransaction = (0, import_react4.useCallback)(
|
|
658
|
-
async (transaction) => {
|
|
659
|
-
const chain = getSolanaChain();
|
|
660
|
-
return await chain.signTransaction(transaction);
|
|
661
|
-
},
|
|
662
|
-
[getSolanaChain]
|
|
663
|
-
);
|
|
664
|
-
const signAndSendTransaction = (0, import_react4.useCallback)(
|
|
665
|
-
async (transaction) => {
|
|
666
|
-
const chain = getSolanaChain();
|
|
667
|
-
return await chain.signAndSendTransaction(transaction);
|
|
668
|
-
},
|
|
669
|
-
[getSolanaChain]
|
|
670
|
-
);
|
|
671
|
-
const connect = (0, import_react4.useCallback)(
|
|
672
|
-
async (options) => {
|
|
673
|
-
const chain = getSolanaChain();
|
|
674
|
-
return await chain.connect(options);
|
|
675
|
-
},
|
|
676
|
-
[getSolanaChain]
|
|
677
|
-
);
|
|
678
|
-
const disconnect = (0, import_react4.useCallback)(async () => {
|
|
679
|
-
const chain = getSolanaChain();
|
|
680
|
-
return await chain.disconnect();
|
|
681
|
-
}, [getSolanaChain]);
|
|
682
|
-
const switchNetwork = (0, import_react4.useCallback)(
|
|
683
|
-
async (network) => {
|
|
684
|
-
const chain = getSolanaChain();
|
|
685
|
-
return await chain.switchNetwork?.(network);
|
|
686
|
-
},
|
|
687
|
-
[getSolanaChain]
|
|
688
|
-
);
|
|
689
|
-
const getPublicKey = (0, import_react4.useCallback)(async () => {
|
|
690
|
-
if (!sdk || !sdk.isConnected())
|
|
691
|
-
return null;
|
|
692
|
-
return await sdk.solana.getPublicKey();
|
|
693
|
-
}, [sdk]);
|
|
694
713
|
return {
|
|
695
|
-
// Chain instance for
|
|
696
|
-
solana:
|
|
697
|
-
// Convenient methods
|
|
698
|
-
signMessage,
|
|
699
|
-
signTransaction,
|
|
700
|
-
signAndSendTransaction,
|
|
701
|
-
connect,
|
|
702
|
-
disconnect,
|
|
703
|
-
switchNetwork,
|
|
704
|
-
getPublicKey,
|
|
714
|
+
// Chain instance with connection enforcement for signing methods
|
|
715
|
+
solana: sdk.solana,
|
|
705
716
|
// State
|
|
706
|
-
isAvailable: !!
|
|
707
|
-
isConnected: solanaChain?.isConnected() ?? false
|
|
717
|
+
isAvailable: !!isConnected
|
|
708
718
|
};
|
|
709
719
|
}
|
|
710
720
|
|
|
711
721
|
// src/hooks/useEthereum.ts
|
|
712
|
-
var import_react5 = require("react");
|
|
713
722
|
function useEthereum() {
|
|
714
723
|
const { sdk, isConnected } = usePhantom();
|
|
715
|
-
const getEthereumChain = (0, import_react5.useCallback)(() => {
|
|
716
|
-
if (!sdk)
|
|
717
|
-
throw new Error("Phantom SDK not initialized.");
|
|
718
|
-
if (!sdk.isConnected())
|
|
719
|
-
throw new Error("Phantom SDK not connected. Call connect() first.");
|
|
720
|
-
return sdk.ethereum;
|
|
721
|
-
}, [sdk]);
|
|
722
|
-
const ethereumChain = (0, import_react5.useMemo)(() => {
|
|
723
|
-
if (!sdk || !isConnected)
|
|
724
|
-
return null;
|
|
725
|
-
try {
|
|
726
|
-
return sdk.ethereum;
|
|
727
|
-
} catch {
|
|
728
|
-
return null;
|
|
729
|
-
}
|
|
730
|
-
}, [sdk, isConnected]);
|
|
731
|
-
const request = (0, import_react5.useCallback)(
|
|
732
|
-
async (args) => {
|
|
733
|
-
const chain = getEthereumChain();
|
|
734
|
-
return await chain.request(args);
|
|
735
|
-
},
|
|
736
|
-
[getEthereumChain]
|
|
737
|
-
);
|
|
738
|
-
const signPersonalMessage = (0, import_react5.useCallback)(
|
|
739
|
-
async (message, address) => {
|
|
740
|
-
const chain = getEthereumChain();
|
|
741
|
-
return await chain.signPersonalMessage(message, address);
|
|
742
|
-
},
|
|
743
|
-
[getEthereumChain]
|
|
744
|
-
);
|
|
745
|
-
const signTransaction = (0, import_react5.useCallback)(
|
|
746
|
-
async (transaction) => {
|
|
747
|
-
const chain = getEthereumChain();
|
|
748
|
-
return await chain.signTransaction(transaction);
|
|
749
|
-
},
|
|
750
|
-
[getEthereumChain]
|
|
751
|
-
);
|
|
752
|
-
const sendTransaction = (0, import_react5.useCallback)(
|
|
753
|
-
async (transaction) => {
|
|
754
|
-
const chain = getEthereumChain();
|
|
755
|
-
return await chain.sendTransaction(transaction);
|
|
756
|
-
},
|
|
757
|
-
[getEthereumChain]
|
|
758
|
-
);
|
|
759
|
-
const switchChain = (0, import_react5.useCallback)(
|
|
760
|
-
async (chainId) => {
|
|
761
|
-
const chain = getEthereumChain();
|
|
762
|
-
return await chain.switchChain(chainId);
|
|
763
|
-
},
|
|
764
|
-
[getEthereumChain]
|
|
765
|
-
);
|
|
766
|
-
const getChainId = (0, import_react5.useCallback)(async () => {
|
|
767
|
-
const chain = getEthereumChain();
|
|
768
|
-
return await chain.getChainId();
|
|
769
|
-
}, [getEthereumChain]);
|
|
770
|
-
const getAccounts = (0, import_react5.useCallback)(async () => {
|
|
771
|
-
const chain = getEthereumChain();
|
|
772
|
-
return await chain.getAccounts();
|
|
773
|
-
}, [getEthereumChain]);
|
|
774
|
-
const signMessage = (0, import_react5.useCallback)(
|
|
775
|
-
async (message) => {
|
|
776
|
-
const accounts = await getAccounts();
|
|
777
|
-
return await request({
|
|
778
|
-
method: "eth_sign",
|
|
779
|
-
params: [accounts[0], message]
|
|
780
|
-
});
|
|
781
|
-
},
|
|
782
|
-
[request, getAccounts]
|
|
783
|
-
);
|
|
784
|
-
const signTypedData = (0, import_react5.useCallback)(
|
|
785
|
-
async (typedData) => {
|
|
786
|
-
const chain = getEthereumChain();
|
|
787
|
-
const accounts = await getAccounts();
|
|
788
|
-
return await chain.signTypedData(typedData, accounts[0]);
|
|
789
|
-
},
|
|
790
|
-
[getEthereumChain, getAccounts]
|
|
791
|
-
);
|
|
792
724
|
return {
|
|
793
|
-
// Chain instance for
|
|
794
|
-
ethereum:
|
|
795
|
-
// Standard EIP-1193 interface
|
|
796
|
-
request,
|
|
797
|
-
// Convenient methods
|
|
798
|
-
signPersonalMessage,
|
|
799
|
-
signMessage,
|
|
800
|
-
signTransaction,
|
|
801
|
-
signTypedData,
|
|
802
|
-
sendTransaction,
|
|
803
|
-
switchChain,
|
|
804
|
-
getChainId,
|
|
805
|
-
getAccounts,
|
|
725
|
+
// Chain instance with connection enforcement for signing methods
|
|
726
|
+
ethereum: sdk.ethereum,
|
|
806
727
|
// State
|
|
807
|
-
isAvailable: !!
|
|
808
|
-
isConnected: ethereumChain?.isConnected() ?? false
|
|
728
|
+
isAvailable: !!isConnected
|
|
809
729
|
};
|
|
810
730
|
}
|
|
811
731
|
|
|
812
732
|
// src/index.ts
|
|
813
733
|
var import_client = require("@phantom/client");
|
|
814
|
-
var
|
|
734
|
+
var import_constants3 = require("@phantom/constants");
|
|
815
735
|
// Annotate the CommonJS export names for ESM import in node:
|
|
816
736
|
0 && (module.exports = {
|
|
817
737
|
AddressType,
|