@dubsdotapp/expo 0.2.47 → 0.2.49
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.js +25 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/managed-wallet.tsx +5 -49
- package/src/wallet/phantom-deeplink/crypto.ts +29 -0
package/package.json
CHANGED
package/src/managed-wallet.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
3
|
import { MwaWalletAdapter } from './wallet/mwa-adapter';
|
|
4
4
|
import { PhantomDeeplinkAdapter } from './wallet/phantom-deeplink';
|
|
5
5
|
import type { PhantomSession } from './wallet/phantom-deeplink';
|
|
@@ -11,42 +11,6 @@ import { STORAGE_KEYS } from './storage';
|
|
|
11
11
|
|
|
12
12
|
const TAG = '[Dubs:ManagedWallet]';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Auto-detect the app's redirect URI for Phantom deeplinks on iOS.
|
|
16
|
-
* Uses expo-linking (available in all Expo apps) to construct a URI
|
|
17
|
-
* from the app's scheme defined in app.json.
|
|
18
|
-
*/
|
|
19
|
-
function getDefaultRedirectUri(): string | undefined {
|
|
20
|
-
if (Platform.OS !== 'ios') return undefined;
|
|
21
|
-
try {
|
|
22
|
-
// expo-linking re-exports Linking with createURL that uses the app scheme
|
|
23
|
-
const expoLinking = require('expo-linking');
|
|
24
|
-
if (expoLinking.createURL) {
|
|
25
|
-
const uri = expoLinking.createURL('phantom-callback');
|
|
26
|
-
console.log(TAG, 'Auto-detected redirect URI via expo-linking:', uri);
|
|
27
|
-
return uri;
|
|
28
|
-
}
|
|
29
|
-
} catch (e) {
|
|
30
|
-
console.log(TAG, 'expo-linking createURL failed:', e instanceof Error ? e.message : e);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Fallback: construct from Constants if available
|
|
34
|
-
try {
|
|
35
|
-
const Constants = require('expo-constants').default;
|
|
36
|
-
const scheme = Constants.expoConfig?.scheme;
|
|
37
|
-
if (scheme) {
|
|
38
|
-
const uri = `${scheme}://phantom-callback`;
|
|
39
|
-
console.log(TAG, 'Auto-detected redirect URI via expo-constants:', uri);
|
|
40
|
-
return uri;
|
|
41
|
-
}
|
|
42
|
-
} catch (e) {
|
|
43
|
-
console.log(TAG, 'expo-constants fallback failed:', e instanceof Error ? e.message : e);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(TAG, 'Could not auto-detect redirect URI on iOS — pass redirectUri to DubsProvider');
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
14
|
// ── Module-level Phantom adapter singleton ──
|
|
51
15
|
// Persists across React remounts (e.g. when the app backgrounds to open Phantom).
|
|
52
16
|
// This prevents the Linking listener from being torn down mid-flow.
|
|
@@ -131,13 +95,11 @@ export function ManagedWalletProvider({
|
|
|
131
95
|
const [error, setError] = useState<string | null>(null);
|
|
132
96
|
|
|
133
97
|
// Determine which adapter to use:
|
|
134
|
-
// - Android → MWA (Phantom + other wallets support Mobile Wallet Adapter natively)
|
|
98
|
+
// - Android (all devices) → MWA (Phantom + other wallets support Mobile Wallet Adapter natively)
|
|
135
99
|
// - iOS → Phantom deeplinks (MWA not available on iOS)
|
|
136
|
-
const usePhantom = Platform.OS === 'ios';
|
|
137
|
-
// Auto-detect redirect URI on iOS if not explicitly provided
|
|
138
|
-
const resolvedRedirectUri = usePhantom ? (redirectUri || getDefaultRedirectUri()) : undefined;
|
|
100
|
+
const usePhantom = Platform.OS === 'ios' && !!redirectUri;
|
|
139
101
|
|
|
140
|
-
console.log(TAG, `Platform: ${Platform.OS}, redirectUri: ${
|
|
102
|
+
console.log(TAG, `Platform: ${Platform.OS}, redirectUri: ${redirectUri ? 'provided' : 'not set'}, usePhantom: ${usePhantom}`);
|
|
141
103
|
|
|
142
104
|
const adapterRef = useRef<WalletAdapter | null>(null);
|
|
143
105
|
const transactRef = useRef<any>(null);
|
|
@@ -145,14 +107,8 @@ export function ManagedWalletProvider({
|
|
|
145
107
|
// Lazily create adapter — Phantom uses a module-level singleton to survive remounts
|
|
146
108
|
if (!adapterRef.current) {
|
|
147
109
|
if (usePhantom) {
|
|
148
|
-
if (!resolvedRedirectUri) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
'@dubsdotapp/expo: Could not auto-detect redirect URI on iOS. ' +
|
|
151
|
-
'Either set a "scheme" in your app.json or pass redirectUri to <DubsProvider>.',
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
110
|
adapterRef.current = getOrCreatePhantomAdapter({
|
|
155
|
-
redirectUri:
|
|
111
|
+
redirectUri: redirectUri!,
|
|
156
112
|
appUrl,
|
|
157
113
|
cluster,
|
|
158
114
|
storage,
|
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
import nacl from 'tweetnacl';
|
|
2
2
|
import bs58 from 'bs58';
|
|
3
3
|
|
|
4
|
+
// tweetnacl checks self.crypto.getRandomValues at import time.
|
|
5
|
+
// In some React Native environments this isn't set up yet.
|
|
6
|
+
// Ensure PRNG is configured before any crypto operations.
|
|
7
|
+
try {
|
|
8
|
+
nacl.randomBytes(1);
|
|
9
|
+
} catch {
|
|
10
|
+
// Try globalThis.crypto (available in Hermes / RN 0.76+)
|
|
11
|
+
const g = typeof globalThis !== 'undefined' ? globalThis : (typeof self !== 'undefined' ? self : undefined);
|
|
12
|
+
if (g?.crypto?.getRandomValues) {
|
|
13
|
+
nacl.setPRNG((x: Uint8Array, n: number) => {
|
|
14
|
+
const v = new Uint8Array(n);
|
|
15
|
+
g.crypto.getRandomValues(v);
|
|
16
|
+
for (let i = 0; i < n; i++) x[i] = v[i];
|
|
17
|
+
});
|
|
18
|
+
} else {
|
|
19
|
+
// Try expo-crypto as fallback
|
|
20
|
+
try {
|
|
21
|
+
const { getRandomValues } = require('expo-crypto');
|
|
22
|
+
nacl.setPRNG((x: Uint8Array, n: number) => {
|
|
23
|
+
const v = new Uint8Array(n);
|
|
24
|
+
getRandomValues(v);
|
|
25
|
+
for (let i = 0; i < n; i++) x[i] = v[i];
|
|
26
|
+
});
|
|
27
|
+
} catch {
|
|
28
|
+
// PRNG will throw when used — unavoidable without a crypto source
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
4
33
|
export interface KeyPair {
|
|
5
34
|
publicKey: Uint8Array;
|
|
6
35
|
secretKey: Uint8Array;
|