@phantom/react-native-sdk 1.0.0-beta.21 → 1.0.0-beta.24

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/dist/index.mjs CHANGED
@@ -1,7 +1,414 @@
1
1
  // src/PhantomProvider.tsx
2
- import { createContext, useContext, useState, useEffect, useMemo } from "react";
2
+ import { useState as useState5, useEffect as useEffect2, useMemo as useMemo2 } 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
+ import {
5
+ ANALYTICS_HEADERS,
6
+ DEFAULT_WALLET_API_URL,
7
+ DEFAULT_EMBEDDED_WALLET_TYPE,
8
+ DEFAULT_AUTH_URL as DEFAULT_AUTH_URL2
9
+ } from "@phantom/constants";
10
+ import { ThemeProvider, darkTheme } from "@phantom/wallet-sdk-ui";
11
+
12
+ // src/ModalProvider.tsx
13
+ import { useState as useState4, useCallback as useCallback4, useMemo } from "react";
14
+
15
+ // src/ModalContext.ts
16
+ import { createContext, useContext } from "react";
17
+ var ModalContext = createContext(void 0);
18
+ function useModal() {
19
+ const context = useContext(ModalContext);
20
+ if (!context) {
21
+ throw new Error("useModal must be used within a ModalProvider");
22
+ }
23
+ return {
24
+ open: context.openModal,
25
+ close: context.closeModal,
26
+ isOpened: context.isModalOpen
27
+ };
28
+ }
29
+
30
+ // src/components/Modal.tsx
31
+ import { Modal as RNModal, View, StyleSheet, SafeAreaView } from "react-native";
32
+ import { useTheme } from "@phantom/wallet-sdk-ui";
33
+ import { jsx, jsxs } from "react/jsx-runtime";
34
+ function Modal({ isVisible, onClose, children }) {
35
+ const theme = useTheme();
36
+ const styles = StyleSheet.create({
37
+ bottomSheet: {
38
+ backgroundColor: theme.background,
39
+ borderTopLeftRadius: 32,
40
+ borderTopRightRadius: 32,
41
+ bottom: 0,
42
+ left: 0,
43
+ paddingBottom: 20,
44
+ position: "absolute",
45
+ right: 0
46
+ },
47
+ handle: {
48
+ alignSelf: "center",
49
+ backgroundColor: theme.secondary,
50
+ borderRadius: 2.5,
51
+ height: 5,
52
+ marginTop: 12,
53
+ opacity: 0.3,
54
+ width: 40
55
+ }
56
+ });
57
+ return /* @__PURE__ */ jsx(RNModal, { visible: isVisible, transparent: true, animationType: "slide", onRequestClose: onClose, children: /* @__PURE__ */ jsxs(SafeAreaView, { style: styles.bottomSheet, children: [
58
+ /* @__PURE__ */ jsx(View, { style: styles.handle }),
59
+ children
60
+ ] }) });
61
+ }
62
+
63
+ // src/PhantomContext.tsx
64
+ import { createContext as createContext2, useContext as useContext2 } from "react";
65
+ var PhantomContext = createContext2(void 0);
66
+ function usePhantom() {
67
+ const context = useContext2(PhantomContext);
68
+ if (context === void 0) {
69
+ throw new Error("usePhantom must be used within a PhantomProvider");
70
+ }
71
+ return context;
72
+ }
73
+
74
+ // src/components/ConnectModalContent.tsx
75
+ import { useState, useCallback as useCallback2 } from "react";
76
+ import { View as View2, Image, StyleSheet as StyleSheet2, ActivityIndicator } from "react-native";
77
+ import { Button, Icon, Text, useTheme as useTheme2, hexToRgba, ModalHeader } from "@phantom/wallet-sdk-ui";
78
+
79
+ // src/hooks/useConnect.ts
80
+ import { useCallback } from "react";
81
+ function useConnect() {
82
+ const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
83
+ const connect = useCallback(
84
+ async (options) => {
85
+ if (!sdk) {
86
+ throw new Error("SDK not initialized");
87
+ }
88
+ try {
89
+ const result = await sdk.connect(options);
90
+ if (result.status === "completed" && result.walletId) {
91
+ setWalletId(result.walletId);
92
+ }
93
+ return result;
94
+ } catch (err) {
95
+ const error = err;
96
+ throw error;
97
+ }
98
+ },
99
+ [sdk, setWalletId]
100
+ );
101
+ return {
102
+ connect,
103
+ isConnecting,
104
+ error: connectError
105
+ };
106
+ }
107
+
108
+ // src/components/ConnectModalContent.tsx
109
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
110
+ function ConnectModalContent({ appIcon, onClose }) {
111
+ const theme = useTheme2();
112
+ const { isConnecting: contextIsConnecting, allowedProviders } = usePhantom();
113
+ const { connect } = useConnect();
114
+ const [isConnecting, setIsConnecting] = useState(false);
115
+ const [error, setError] = useState(null);
116
+ const [providerType, setProviderType] = useState(null);
117
+ const isLoading = contextIsConnecting || isConnecting;
118
+ const errorBackgroundColor = hexToRgba(theme.error, 0.1);
119
+ const errorBorderColor = hexToRgba(theme.error, 0.3);
120
+ const errorTextColor = theme.error;
121
+ const connectWithAuthProvider = useCallback2(
122
+ async (provider) => {
123
+ try {
124
+ setIsConnecting(true);
125
+ setError(null);
126
+ setProviderType(provider);
127
+ await connect({ provider });
128
+ onClose();
129
+ } catch (err) {
130
+ const error2 = err instanceof Error ? err : new Error(String(err));
131
+ setError(error2);
132
+ } finally {
133
+ setIsConnecting(false);
134
+ setProviderType(null);
135
+ }
136
+ },
137
+ [connect, onClose]
138
+ );
139
+ const styles = StyleSheet2.create({
140
+ appIcon: {
141
+ borderRadius: 28,
142
+ height: 56,
143
+ marginBottom: 12,
144
+ width: 56
145
+ },
146
+ buttonContainer: {
147
+ alignItems: "center",
148
+ flexDirection: "column",
149
+ gap: 12,
150
+ paddingHorizontal: 32,
151
+ width: "100%"
152
+ },
153
+ buttonContent: {
154
+ alignItems: "center",
155
+ flexDirection: "row",
156
+ justifyContent: "space-between",
157
+ width: "100%"
158
+ },
159
+ buttonContentLeft: {
160
+ alignItems: "center",
161
+ flexDirection: "row",
162
+ gap: 8
163
+ },
164
+ container: {
165
+ alignItems: "center",
166
+ flexDirection: "column",
167
+ gap: 12,
168
+ paddingBottom: 24,
169
+ width: "100%"
170
+ },
171
+ errorContainer: {
172
+ backgroundColor: errorBackgroundColor,
173
+ borderColor: errorBorderColor,
174
+ borderRadius: parseInt(theme.borderRadius),
175
+ borderWidth: 1,
176
+ padding: 12,
177
+ width: "100%"
178
+ },
179
+ errorText: {
180
+ color: errorTextColor,
181
+ fontSize: 14
182
+ },
183
+ footer: {
184
+ alignItems: "center",
185
+ borderColor: theme.aux,
186
+ borderTopWidth: 1,
187
+ flexDirection: "row",
188
+ gap: 4,
189
+ justifyContent: "center",
190
+ marginTop: 24,
191
+ padding: 16,
192
+ width: "100%"
193
+ },
194
+ loadingContainer: {
195
+ alignItems: "center",
196
+ flexDirection: "column",
197
+ gap: 12,
198
+ justifyContent: "center",
199
+ padding: 24
200
+ }
201
+ });
202
+ return /* @__PURE__ */ jsxs2(View2, { style: styles.container, children: [
203
+ /* @__PURE__ */ jsx2(ModalHeader, { title: "Login or Sign Up", onClose }),
204
+ appIcon && /* @__PURE__ */ jsx2(Image, { testID: "app-icon", source: { uri: appIcon }, style: styles.appIcon }),
205
+ isLoading ? /* @__PURE__ */ jsxs2(View2, { style: styles.loadingContainer, children: [
206
+ /* @__PURE__ */ jsx2(ActivityIndicator, { testID: "activity-indicator", size: "large", color: theme.brand }),
207
+ /* @__PURE__ */ jsx2(Text, { variant: "label", color: theme.secondary, children: "Loading..." })
208
+ ] }) : /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContainer, children: [
209
+ error && /* @__PURE__ */ jsx2(View2, { style: styles.errorContainer, children: /* @__PURE__ */ jsx2(Text, { style: styles.errorText, children: error.message }) }),
210
+ allowedProviders.includes("google") && /* @__PURE__ */ jsx2(
211
+ Button,
212
+ {
213
+ onClick: () => connectWithAuthProvider("google"),
214
+ disabled: isConnecting,
215
+ isLoading: isConnecting && providerType === "google",
216
+ fullWidth: true,
217
+ children: /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContent, children: [
218
+ /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContentLeft, children: [
219
+ /* @__PURE__ */ jsx2(Icon, { type: "google", size: 20, color: theme.text }),
220
+ /* @__PURE__ */ jsx2(Text, { variant: "captionBold", children: "Continue with Google" })
221
+ ] }),
222
+ /* @__PURE__ */ jsx2(Icon, { type: "chevron-right", size: 16, color: theme.secondary })
223
+ ] })
224
+ }
225
+ ),
226
+ allowedProviders.includes("apple") && /* @__PURE__ */ jsx2(
227
+ Button,
228
+ {
229
+ onClick: () => connectWithAuthProvider("apple"),
230
+ disabled: isConnecting,
231
+ isLoading: isConnecting && providerType === "apple",
232
+ fullWidth: true,
233
+ children: /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContent, children: [
234
+ /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContentLeft, children: [
235
+ /* @__PURE__ */ jsx2(Icon, { type: "apple", size: 20, color: theme.text }),
236
+ /* @__PURE__ */ jsx2(Text, { variant: "captionBold", children: "Continue with Apple" })
237
+ ] }),
238
+ /* @__PURE__ */ jsx2(Icon, { type: "chevron-right", size: 16, color: theme.secondary })
239
+ ] })
240
+ }
241
+ ),
242
+ allowedProviders.includes("x") && /* @__PURE__ */ jsx2(
243
+ Button,
244
+ {
245
+ onClick: () => connectWithAuthProvider("x"),
246
+ disabled: isConnecting,
247
+ isLoading: isConnecting && providerType === "x",
248
+ fullWidth: true,
249
+ children: /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContent, children: [
250
+ /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContentLeft, children: [
251
+ /* @__PURE__ */ jsx2(Icon, { type: "x", size: 20, color: theme.text }),
252
+ /* @__PURE__ */ jsx2(Text, { variant: "captionBold", children: "Continue with X" })
253
+ ] }),
254
+ /* @__PURE__ */ jsx2(Icon, { type: "chevron-right", size: 16, color: theme.secondary })
255
+ ] })
256
+ }
257
+ ),
258
+ allowedProviders.includes("tiktok") && /* @__PURE__ */ jsx2(
259
+ Button,
260
+ {
261
+ onClick: () => connectWithAuthProvider("tiktok"),
262
+ disabled: isConnecting,
263
+ isLoading: isConnecting && providerType === "tiktok",
264
+ fullWidth: true,
265
+ children: /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContent, children: [
266
+ /* @__PURE__ */ jsxs2(View2, { style: styles.buttonContentLeft, children: [
267
+ /* @__PURE__ */ jsx2(Icon, { type: "tiktok", size: 20, color: theme.text }),
268
+ /* @__PURE__ */ jsx2(Text, { variant: "captionBold", children: "Continue with TikTok" })
269
+ ] }),
270
+ /* @__PURE__ */ jsx2(Icon, { type: "chevron-right", size: 16, color: theme.secondary })
271
+ ] })
272
+ }
273
+ )
274
+ ] }),
275
+ /* @__PURE__ */ jsxs2(View2, { style: styles.footer, children: [
276
+ /* @__PURE__ */ jsx2(Text, { variant: "label", color: theme.secondary, children: "Powered by" }),
277
+ /* @__PURE__ */ jsx2(Icon, { type: "phantom", size: 16, color: theme.secondary }),
278
+ /* @__PURE__ */ jsx2(Text, { variant: "label", color: theme.secondary, children: "Phantom" })
279
+ ] })
280
+ ] });
281
+ }
282
+
283
+ // src/components/ConnectedModalContent.tsx
284
+ import { useState as useState3, useEffect } from "react";
285
+ import { View as View3, StyleSheet as StyleSheet3 } from "react-native";
286
+ import { Button as Button2, Text as Text2, useTheme as useTheme3, hexToRgba as hexToRgba2, ModalHeader as ModalHeader2 } from "@phantom/wallet-sdk-ui";
287
+
288
+ // src/hooks/useDisconnect.ts
289
+ import { useState as useState2, useCallback as useCallback3 } from "react";
290
+ function useDisconnect() {
291
+ const { sdk } = usePhantom();
292
+ const [isDisconnecting, setIsDisconnecting] = useState2(false);
293
+ const [error, setError] = useState2(null);
294
+ const disconnect = useCallback3(async () => {
295
+ if (!sdk) {
296
+ throw new Error("SDK not initialized");
297
+ }
298
+ setIsDisconnecting(true);
299
+ setError(null);
300
+ try {
301
+ await sdk.disconnect();
302
+ } catch (err) {
303
+ const error2 = err;
304
+ setError(error2);
305
+ throw error2;
306
+ } finally {
307
+ setIsDisconnecting(false);
308
+ }
309
+ }, [sdk]);
310
+ return {
311
+ disconnect,
312
+ isDisconnecting,
313
+ error
314
+ };
315
+ }
316
+
317
+ // src/components/ConnectedModalContent.tsx
318
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
319
+ function ConnectedModalContent({ onClose }) {
320
+ const theme = useTheme3();
321
+ const { addresses } = usePhantom();
322
+ const { disconnect } = useDisconnect();
323
+ const [isDisconnecting, setIsDisconnecting] = useState3(false);
324
+ const [disconnectError, setDisconnectError] = useState3(null);
325
+ const errorBackgroundColor = hexToRgba2(theme.error, 0.1);
326
+ const errorBorderColor = hexToRgba2(theme.error, 0.3);
327
+ useEffect(() => {
328
+ setDisconnectError(null);
329
+ }, []);
330
+ const handleDisconnect = async () => {
331
+ try {
332
+ setIsDisconnecting(true);
333
+ setDisconnectError(null);
334
+ await disconnect();
335
+ onClose();
336
+ } catch (err) {
337
+ const error = err instanceof Error ? err : new Error(String(err));
338
+ setDisconnectError(error);
339
+ } finally {
340
+ setIsDisconnecting(false);
341
+ }
342
+ };
343
+ const styles = StyleSheet3.create({
344
+ accountItem: {
345
+ flexDirection: "column",
346
+ gap: 8,
347
+ width: "100%"
348
+ },
349
+ accountList: {
350
+ flexDirection: "column",
351
+ gap: 16,
352
+ width: "100%"
353
+ },
354
+ accountTypeText: {
355
+ textTransform: "uppercase"
356
+ },
357
+ addressText: {
358
+ fontFamily: "monospace"
359
+ },
360
+ container: {
361
+ alignItems: "center",
362
+ flexDirection: "column",
363
+ gap: 24,
364
+ paddingBottom: 24,
365
+ paddingHorizontal: 32,
366
+ width: "100%"
367
+ },
368
+ errorContainer: {
369
+ backgroundColor: errorBackgroundColor,
370
+ borderColor: errorBorderColor,
371
+ borderRadius: theme.borderRadius,
372
+ borderWidth: 1,
373
+ padding: 12,
374
+ width: "100%"
375
+ }
376
+ });
377
+ return /* @__PURE__ */ jsxs3(View3, { style: styles.container, children: [
378
+ /* @__PURE__ */ jsx3(ModalHeader2, { title: "Wallet", onClose }),
379
+ addresses && addresses.length > 0 && /* @__PURE__ */ jsx3(View3, { style: styles.accountList, children: addresses.map((account, index) => /* @__PURE__ */ jsxs3(View3, { style: styles.accountItem, children: [
380
+ /* @__PURE__ */ jsx3(Text2, { variant: "label", color: theme.secondary, style: styles.accountTypeText, children: account.addressType }),
381
+ /* @__PURE__ */ jsx3(Text2, { variant: "caption", style: styles.addressText, children: account.address })
382
+ ] }, index)) }),
383
+ disconnectError && /* @__PURE__ */ jsx3(View3, { style: styles.errorContainer, children: /* @__PURE__ */ jsx3(Text2, { variant: "caption", color: theme.error, children: "Failed to disconnect" }) }),
384
+ /* @__PURE__ */ jsx3(Button2, { onClick: handleDisconnect, disabled: isDisconnecting, isLoading: isDisconnecting, fullWidth: true, children: /* @__PURE__ */ jsx3(Text2, { variant: "captionBold", children: isDisconnecting ? "Disconnecting..." : "Disconnect" }) })
385
+ ] });
386
+ }
387
+
388
+ // src/ModalProvider.tsx
389
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
390
+ function ModalProvider({ children, appIcon, appName }) {
391
+ const { isConnected } = usePhantom();
392
+ const [isModalOpen, setIsModalOpen] = useState4(false);
393
+ const openModal = useCallback4(() => {
394
+ setIsModalOpen(true);
395
+ }, []);
396
+ const closeModal = useCallback4(() => {
397
+ setIsModalOpen(false);
398
+ }, []);
399
+ const modalContextValue = useMemo(
400
+ () => ({
401
+ isModalOpen,
402
+ openModal,
403
+ closeModal
404
+ }),
405
+ [isModalOpen, openModal, closeModal]
406
+ );
407
+ return /* @__PURE__ */ jsxs4(ModalContext.Provider, { value: modalContextValue, children: [
408
+ children,
409
+ /* @__PURE__ */ jsx4(Modal, { isVisible: isModalOpen, onClose: closeModal, appIcon, appName, isMobile: true, children: isConnected ? /* @__PURE__ */ jsx4(ConnectedModalContent, { onClose: closeModal }) : /* @__PURE__ */ jsx4(ConnectModalContent, { appIcon, appName, onClose: closeModal }) })
410
+ ] });
411
+ }
5
412
 
6
413
  // src/providers/embedded/storage.ts
7
414
  import * as SecureStore from "expo-secure-store";
@@ -109,7 +516,7 @@ var ExpoAuthProvider = class {
109
516
  // OAuth session management - defaults to allow refresh unless explicitly clearing after logout
110
517
  clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
111
518
  allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
112
- sdk_version: "1.0.0-beta.21",
519
+ sdk_version: "1.0.0-beta.24",
113
520
  sdk_type: "react-native",
114
521
  platform: Platform.OS
115
522
  });
@@ -141,7 +548,6 @@ var ExpoAuthProvider = class {
141
548
  const url = new URL(result.url);
142
549
  const walletId = url.searchParams.get("wallet_id");
143
550
  const organizationId = url.searchParams.get("organization_id");
144
- const provider2 = url.searchParams.get("provider");
145
551
  const accountDerivationIndex = url.searchParams.get("selected_account_index");
146
552
  const expiresInMs = url.searchParams.get("expires_in_ms");
147
553
  const authUserId = url.searchParams.get("auth_user_id");
@@ -155,7 +561,7 @@ var ExpoAuthProvider = class {
155
561
  console.log("[ExpoAuthProvider] Auth redirect parameters", {
156
562
  walletId,
157
563
  organizationId,
158
- provider: provider2,
564
+ provider,
159
565
  accountDerivationIndex,
160
566
  expiresInMs,
161
567
  authUserId
@@ -163,7 +569,7 @@ var ExpoAuthProvider = class {
163
569
  return {
164
570
  walletId,
165
571
  organizationId,
166
- provider: provider2 || void 0,
572
+ provider: provider || void 0,
167
573
  accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
168
574
  expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
169
575
  authUserId: authUserId || void 0
@@ -470,16 +876,15 @@ var ReactNativePhantomAppProvider = class {
470
876
 
471
877
  // src/PhantomProvider.tsx
472
878
  import { Platform as Platform2 } from "react-native";
473
- import { jsx } from "react/jsx-runtime";
474
- var PhantomContext = createContext(void 0);
475
- function PhantomProvider({ children, config, debugConfig }) {
476
- const [isConnected, setIsConnected] = useState(false);
477
- const [isConnecting, setIsConnecting] = useState(false);
478
- const [connectError, setConnectError] = useState(null);
479
- const [addresses, setAddresses] = useState([]);
480
- const [walletId, setWalletId] = useState(null);
481
- const [user, setUser] = useState(null);
482
- const memoizedConfig = useMemo(() => {
879
+ import { jsx as jsx5 } from "react/jsx-runtime";
880
+ function PhantomProvider({ children, config, debugConfig, theme, appIcon, appName }) {
881
+ const [isConnected, setIsConnected] = useState5(false);
882
+ const [isConnecting, setIsConnecting] = useState5(false);
883
+ const [connectError, setConnectError] = useState5(null);
884
+ const [addresses, setAddresses] = useState5([]);
885
+ const [walletId, setWalletId] = useState5(null);
886
+ const [user, setUser] = useState5(null);
887
+ const memoizedConfig = useMemo2(() => {
483
888
  const redirectUrl = config.authOptions?.redirectUrl || `${config.scheme}://phantom-auth-callback`;
484
889
  return {
485
890
  ...config,
@@ -492,7 +897,7 @@ function PhantomProvider({ children, config, debugConfig }) {
492
897
  }
493
898
  };
494
899
  }, [config]);
495
- const sdk = useMemo(() => {
900
+ const sdk = useMemo2(() => {
496
901
  const storage = new ExpoSecureStorage();
497
902
  const authProvider = new ExpoAuthProvider();
498
903
  const urlParamsAccessor = new ExpoURLParamsAccessor();
@@ -515,13 +920,13 @@ function PhantomProvider({ children, config, debugConfig }) {
515
920
  [ANALYTICS_HEADERS.PLATFORM_VERSION]: `${Platform2.Version}`,
516
921
  [ANALYTICS_HEADERS.APP_ID]: config.appId,
517
922
  [ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
518
- [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.21"
923
+ [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.24"
519
924
  // Replaced at build time
520
925
  }
521
926
  };
522
927
  return new EmbeddedProvider(memoizedConfig, platform, logger);
523
928
  }, [memoizedConfig, debugConfig, config.appId, config.embeddedWalletType]);
524
- useEffect(() => {
929
+ useEffect2(() => {
525
930
  const handleConnectStart = () => {
526
931
  setIsConnecting(true);
527
932
  setConnectError(null);
@@ -566,13 +971,11 @@ function PhantomProvider({ children, config, debugConfig }) {
566
971
  sdk.off("disconnect", handleDisconnect);
567
972
  };
568
973
  }, [sdk]);
569
- useEffect(() => {
570
- if (config.autoConnect !== false) {
571
- sdk.autoConnect().catch(() => {
572
- });
573
- }
574
- }, [sdk, config.autoConnect]);
575
- const value = useMemo(
974
+ useEffect2(() => {
975
+ sdk.autoConnect().catch(() => {
976
+ });
977
+ }, [sdk]);
978
+ const value = useMemo2(
576
979
  () => ({
577
980
  sdk,
578
981
  isConnected,
@@ -581,76 +984,13 @@ function PhantomProvider({ children, config, debugConfig }) {
581
984
  addresses,
582
985
  walletId,
583
986
  setWalletId,
584
- user
987
+ user,
988
+ allowedProviders: config.providers
585
989
  }),
586
- [sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId, user]
990
+ [sdk, isConnected, isConnecting, connectError, addresses, walletId, setWalletId, user, config.providers]
587
991
  );
588
- return /* @__PURE__ */ jsx(PhantomContext.Provider, { value, children });
589
- }
590
- function usePhantom() {
591
- const context = useContext(PhantomContext);
592
- if (context === void 0) {
593
- throw new Error("usePhantom must be used within a PhantomProvider");
594
- }
595
- return context;
596
- }
597
-
598
- // src/hooks/useConnect.ts
599
- import { useCallback } from "react";
600
- function useConnect() {
601
- const { sdk, isConnecting, connectError, setWalletId } = usePhantom();
602
- const connect = useCallback(
603
- async (options) => {
604
- if (!sdk) {
605
- throw new Error("SDK not initialized");
606
- }
607
- try {
608
- const result = await sdk.connect(options);
609
- if (result.status === "completed" && result.walletId) {
610
- setWalletId(result.walletId);
611
- }
612
- return result;
613
- } catch (err) {
614
- const error = err;
615
- throw error;
616
- }
617
- },
618
- [sdk, setWalletId]
619
- );
620
- return {
621
- connect,
622
- isConnecting,
623
- error: connectError
624
- };
625
- }
626
-
627
- // src/hooks/useDisconnect.ts
628
- import { useState as useState2, useCallback as useCallback2 } from "react";
629
- function useDisconnect() {
630
- const { sdk } = usePhantom();
631
- const [isDisconnecting, setIsDisconnecting] = useState2(false);
632
- const [error, setError] = useState2(null);
633
- const disconnect = useCallback2(async () => {
634
- if (!sdk) {
635
- throw new Error("SDK not initialized");
636
- }
637
- setIsDisconnecting(true);
638
- setError(null);
639
- try {
640
- await sdk.disconnect();
641
- } catch (err) {
642
- const error2 = err;
643
- setError(error2);
644
- throw error2;
645
- } finally {
646
- setIsDisconnecting(false);
647
- }
648
- }, [sdk]);
649
- return {
650
- disconnect,
651
- isDisconnecting,
652
- error
653
- };
992
+ const resolvedTheme = theme || darkTheme;
993
+ return /* @__PURE__ */ jsx5(ThemeProvider, { theme: resolvedTheme, children: /* @__PURE__ */ jsx5(PhantomContext.Provider, { value, children: /* @__PURE__ */ jsx5(ModalProvider, { appIcon, appName, children }) }) });
654
994
  }
655
995
 
656
996
  // src/hooks/useAccounts.ts
@@ -688,14 +1028,18 @@ function useEthereum() {
688
1028
  // src/index.ts
689
1029
  import { AddressType } from "@phantom/client";
690
1030
  import { NetworkId } from "@phantom/constants";
1031
+ import { darkTheme as darkTheme2, lightTheme } from "@phantom/wallet-sdk-ui";
691
1032
  export {
692
1033
  AddressType,
693
1034
  NetworkId,
694
1035
  PhantomProvider,
1036
+ darkTheme2 as darkTheme,
1037
+ lightTheme,
695
1038
  useAccounts,
696
1039
  useConnect,
697
1040
  useDisconnect,
698
1041
  useEthereum,
1042
+ useModal,
699
1043
  usePhantom,
700
1044
  useSolana
701
1045
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/react-native-sdk",
3
- "version": "1.0.0-beta.21",
3
+ "version": "1.0.0-beta.24",
4
4
  "description": "Phantom Wallet SDK for React Native and Expo applications",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -41,18 +41,19 @@
41
41
  "author": "Phantom",
42
42
  "repository": {
43
43
  "type": "git",
44
- "url": "https://github.com/phantom/wallet-sdk.git",
44
+ "url": "https://github.com/phantom/phantom-connect-sdk",
45
45
  "directory": "packages/react-native-sdk"
46
46
  },
47
47
  "dependencies": {
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",
48
+ "@phantom/api-key-stamper": "^1.0.0-beta.12",
49
+ "@phantom/base64url": "^1.0.0-beta.12",
50
+ "@phantom/chain-interfaces": "^1.0.0-beta.12",
51
+ "@phantom/client": "^1.0.0-beta.24",
52
+ "@phantom/constants": "^1.0.0-beta.12",
53
+ "@phantom/crypto": "^1.0.0-beta.12",
54
+ "@phantom/embedded-provider-core": "^1.0.0-beta.24",
55
+ "@phantom/sdk-types": "^1.0.0-beta.12",
56
+ "@phantom/wallet-sdk-ui": "^1.0.0-beta.3",
56
57
  "@types/bs58": "^5.0.0",
57
58
  "bs58": "^6.0.0",
58
59
  "buffer": "^6.0.3"
@@ -64,9 +65,12 @@
64
65
  "expo-web-browser": ">=12.0.0",
65
66
  "react": ">=19.0.0",
66
67
  "react-native": ">=0.79.0",
67
- "react-native-get-random-values": ">=1.8.0"
68
+ "react-native-get-random-values": ">=1.8.0",
69
+ "react-native-svg": ">=15.0.0"
68
70
  },
69
71
  "devDependencies": {
72
+ "@testing-library/jest-native": "^5.4.3",
73
+ "@testing-library/react-native": "14.0.0-alpha.1",
70
74
  "@types/jest": "^29.5.14",
71
75
  "@types/react": "~19.0.10",
72
76
  "@types/react-native": "^0.72.0",
@@ -81,12 +85,13 @@
81
85
  "jest": "^29.7.0",
82
86
  "jest-environment-jsdom": "^29.7.0",
83
87
  "prettier": "^3.5.2",
84
- "react": "19.1.1",
88
+ "react": "19.0.0",
85
89
  "react-native": "0.79.5",
86
90
  "rimraf": "^6.0.1",
87
91
  "ts-jest": "^29",
88
92
  "tsup": "^6.7.0",
89
- "typescript": "^5.8.3"
93
+ "typescript": "^5.8.3",
94
+ "universal-test-renderer": "0.6.0"
90
95
  },
91
96
  "publishConfig": {
92
97
  "directory": "_release/package"