@dubsdotapp/expo 0.2.48 → 0.2.50
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 +49 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/managed-wallet.tsx +28 -4
- package/src/wallet/phantom-deeplink/crypto.ts +29 -0
package/package.json
CHANGED
package/src/managed-wallet.tsx
CHANGED
|
@@ -11,6 +11,29 @@ import { STORAGE_KEYS } from './storage';
|
|
|
11
11
|
|
|
12
12
|
const TAG = '[Dubs:ManagedWallet]';
|
|
13
13
|
|
|
14
|
+
/** Auto-detect redirect URI on iOS using the app's scheme from expo-linking. */
|
|
15
|
+
function getDefaultRedirectUri(): string | undefined {
|
|
16
|
+
if (Platform.OS !== 'ios') return undefined;
|
|
17
|
+
try {
|
|
18
|
+
const expoLinking = require('expo-linking');
|
|
19
|
+
if (expoLinking.createURL) {
|
|
20
|
+
const uri = expoLinking.createURL('phantom-callback');
|
|
21
|
+
console.log(TAG, 'Auto-detected redirect URI via expo-linking:', uri);
|
|
22
|
+
return uri;
|
|
23
|
+
}
|
|
24
|
+
} catch {}
|
|
25
|
+
try {
|
|
26
|
+
const Constants = require('expo-constants').default;
|
|
27
|
+
const scheme = Constants.expoConfig?.scheme;
|
|
28
|
+
if (scheme) {
|
|
29
|
+
const uri = `${scheme}://phantom-callback`;
|
|
30
|
+
console.log(TAG, 'Auto-detected redirect URI via expo-constants:', uri);
|
|
31
|
+
return uri;
|
|
32
|
+
}
|
|
33
|
+
} catch {}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
14
37
|
// ── Module-level Phantom adapter singleton ──
|
|
15
38
|
// Persists across React remounts (e.g. when the app backgrounds to open Phantom).
|
|
16
39
|
// This prevents the Linking listener from being torn down mid-flow.
|
|
@@ -95,11 +118,12 @@ export function ManagedWalletProvider({
|
|
|
95
118
|
const [error, setError] = useState<string | null>(null);
|
|
96
119
|
|
|
97
120
|
// Determine which adapter to use:
|
|
98
|
-
// - Android
|
|
121
|
+
// - Android → MWA (Phantom + other wallets support Mobile Wallet Adapter natively)
|
|
99
122
|
// - iOS → Phantom deeplinks (MWA not available on iOS)
|
|
100
|
-
const
|
|
123
|
+
const resolvedRedirectUri = redirectUri || getDefaultRedirectUri();
|
|
124
|
+
const usePhantom = Platform.OS === 'ios' && !!resolvedRedirectUri;
|
|
101
125
|
|
|
102
|
-
console.log(TAG, `Platform: ${Platform.OS}, redirectUri: ${
|
|
126
|
+
console.log(TAG, `Platform: ${Platform.OS}, redirectUri: ${resolvedRedirectUri ?? 'none'} (explicit: ${!!redirectUri}), usePhantom: ${usePhantom}`);
|
|
103
127
|
|
|
104
128
|
const adapterRef = useRef<WalletAdapter | null>(null);
|
|
105
129
|
const transactRef = useRef<any>(null);
|
|
@@ -108,7 +132,7 @@ export function ManagedWalletProvider({
|
|
|
108
132
|
if (!adapterRef.current) {
|
|
109
133
|
if (usePhantom) {
|
|
110
134
|
adapterRef.current = getOrCreatePhantomAdapter({
|
|
111
|
-
redirectUri:
|
|
135
|
+
redirectUri: resolvedRedirectUri!,
|
|
112
136
|
appUrl,
|
|
113
137
|
cluster,
|
|
114
138
|
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;
|