@oobit/react-native-sdk 1.1.0 → 2.0.1
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/WidgetSDK.d.ts.map +1 -1
- package/dist/WidgetSDK.js +12 -56
- package/dist/WidgetSDK.js.map +1 -1
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -7
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -18
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -36
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/WidgetSDK.tsx +12 -68
- package/src/config.ts +21 -10
- package/src/index.ts +1 -42
- package/src/types.ts +3 -38
- package/dist/biometricUtils.d.ts +0 -66
- package/dist/biometricUtils.d.ts.map +0 -1
- package/dist/biometricUtils.js +0 -183
- package/dist/biometricUtils.js.map +0 -1
- package/dist/cryptoUtils.d.ts +0 -64
- package/dist/cryptoUtils.d.ts.map +0 -1
- package/dist/cryptoUtils.js +0 -123
- package/dist/cryptoUtils.js.map +0 -1
- package/src/cryptoUtils.ts +0 -131
package/src/WidgetSDK.tsx
CHANGED
|
@@ -37,27 +37,12 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
37
37
|
{
|
|
38
38
|
accessToken,
|
|
39
39
|
userWalletAddress,
|
|
40
|
-
environment,
|
|
41
|
-
onReady,
|
|
42
40
|
onError,
|
|
43
41
|
onClose,
|
|
44
42
|
onTransactionRequested,
|
|
45
|
-
onLoadingChange,
|
|
46
|
-
debug = false,
|
|
47
|
-
loadingIndicatorColor = "#007AFF",
|
|
48
43
|
},
|
|
49
44
|
ref
|
|
50
45
|
) => {
|
|
51
|
-
// Debug logger - only logs when debug is enabled
|
|
52
|
-
const log = debug
|
|
53
|
-
? (...args: unknown[]) => console.log("[WidgetSDK]", ...args)
|
|
54
|
-
: () => {};
|
|
55
|
-
const logError = debug
|
|
56
|
-
? (...args: unknown[]) => console.error("[WidgetSDK]", ...args)
|
|
57
|
-
: () => {};
|
|
58
|
-
const logWarn = debug
|
|
59
|
-
? (...args: unknown[]) => console.warn("[WidgetSDK]", ...args)
|
|
60
|
-
: () => {};
|
|
61
46
|
const webViewRef = useRef<WebView>(null);
|
|
62
47
|
const [walletAvailable, setWalletAvailable] = useState(false);
|
|
63
48
|
const [isLoading, setIsLoading] = useState(true);
|
|
@@ -95,18 +80,12 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
95
80
|
});
|
|
96
81
|
},
|
|
97
82
|
reload: () => {
|
|
98
|
-
log("Reloading widget");
|
|
99
83
|
setIsLoading(true);
|
|
100
84
|
hasLoadedOnce.current = false;
|
|
101
85
|
webViewRef.current?.reload();
|
|
102
86
|
},
|
|
103
87
|
}));
|
|
104
88
|
|
|
105
|
-
// Notify parent of loading state changes
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
onLoadingChange?.(isLoading);
|
|
108
|
-
}, [isLoading, onLoadingChange]);
|
|
109
|
-
|
|
110
89
|
const checkWalletAvailability = async () => {
|
|
111
90
|
const available = await isWalletAvailable();
|
|
112
91
|
setWalletAvailable(available);
|
|
@@ -119,8 +98,6 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
119
98
|
try {
|
|
120
99
|
const message: WidgetMessage = JSON.parse(event.nativeEvent.data);
|
|
121
100
|
|
|
122
|
-
log("Received message:", message.type);
|
|
123
|
-
|
|
124
101
|
switch (message.type) {
|
|
125
102
|
case "widget:ready":
|
|
126
103
|
handleReady();
|
|
@@ -135,7 +112,7 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
135
112
|
break;
|
|
136
113
|
|
|
137
114
|
case "widget:close":
|
|
138
|
-
|
|
115
|
+
onClose?.();
|
|
139
116
|
break;
|
|
140
117
|
|
|
141
118
|
case "widget:transaction-requested":
|
|
@@ -143,27 +120,19 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
143
120
|
break;
|
|
144
121
|
|
|
145
122
|
case "widget:token-expired":
|
|
146
|
-
logError("Access token expired");
|
|
147
123
|
onError?.("TOKEN_EXPIRED", "Access token has expired");
|
|
148
124
|
break;
|
|
149
125
|
|
|
150
126
|
case "widget:copy-to-clipboard":
|
|
151
127
|
handleCopyToClipboard(message as CopyToClipboardMessage);
|
|
152
128
|
break;
|
|
153
|
-
|
|
154
|
-
default:
|
|
155
|
-
logWarn("Unknown message type:", message);
|
|
156
129
|
}
|
|
157
|
-
} catch
|
|
158
|
-
logError("Failed to parse message:", error);
|
|
130
|
+
} catch {
|
|
159
131
|
onError?.("PARSE_ERROR", "Failed to parse widget message");
|
|
160
132
|
}
|
|
161
133
|
};
|
|
162
134
|
|
|
163
135
|
const handleReady = () => {
|
|
164
|
-
log("Widget ready");
|
|
165
|
-
onReady?.();
|
|
166
|
-
|
|
167
136
|
// Send platform info to widget
|
|
168
137
|
sendMessageToWidget({
|
|
169
138
|
type: "native:platform-info",
|
|
@@ -175,8 +144,6 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
175
144
|
};
|
|
176
145
|
|
|
177
146
|
const handleOpenWallet = async () => {
|
|
178
|
-
log("Opening native wallet...");
|
|
179
|
-
|
|
180
147
|
const success = await openNativeWallet();
|
|
181
148
|
|
|
182
149
|
// Notify widget of result
|
|
@@ -190,28 +157,16 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
190
157
|
if (message.type !== "widget:error") return;
|
|
191
158
|
|
|
192
159
|
const { code, message: errorMessage } = message.payload;
|
|
193
|
-
logError("Widget error:", code, errorMessage);
|
|
194
|
-
|
|
195
160
|
onError?.(code, errorMessage);
|
|
196
161
|
};
|
|
197
162
|
|
|
198
|
-
const handleClose = () => {
|
|
199
|
-
log("Widget closed");
|
|
200
|
-
onClose?.();
|
|
201
|
-
};
|
|
202
|
-
|
|
203
163
|
const handleTransactionRequested = (message: WidgetMessage) => {
|
|
204
164
|
if (message.type !== "widget:transaction-requested") return;
|
|
205
165
|
|
|
206
166
|
const { token, cryptoAmount, depositAddress, depositAddressTag } =
|
|
207
167
|
message.payload;
|
|
208
|
-
log("Transaction requested:", {
|
|
209
|
-
token: token.symbol,
|
|
210
|
-
cryptoAmount,
|
|
211
|
-
depositAddress,
|
|
212
|
-
});
|
|
213
168
|
|
|
214
|
-
onTransactionRequested
|
|
169
|
+
onTransactionRequested(
|
|
215
170
|
token,
|
|
216
171
|
cryptoAmount,
|
|
217
172
|
depositAddress,
|
|
@@ -221,12 +176,9 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
221
176
|
|
|
222
177
|
/**
|
|
223
178
|
* Handle clipboard copy request from widget
|
|
224
|
-
* Copies text to device clipboard and sends result back to widget
|
|
225
179
|
*/
|
|
226
180
|
const handleCopyToClipboard = async (message: CopyToClipboardMessage) => {
|
|
227
181
|
const { text, label } = message.payload;
|
|
228
|
-
// Log only the label, never the actual text content (security)
|
|
229
|
-
log("Copy to clipboard requested:", label || "unlabeled");
|
|
230
182
|
|
|
231
183
|
try {
|
|
232
184
|
await Clipboard.setStringAsync(text);
|
|
@@ -234,8 +186,7 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
234
186
|
type: "native:clipboard-result",
|
|
235
187
|
payload: { success: true, label },
|
|
236
188
|
});
|
|
237
|
-
} catch
|
|
238
|
-
logError("Clipboard copy failed:", error);
|
|
189
|
+
} catch {
|
|
239
190
|
sendMessageToWidget({
|
|
240
191
|
type: "native:clipboard-result",
|
|
241
192
|
payload: {
|
|
@@ -250,7 +201,7 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
250
201
|
/**
|
|
251
202
|
* Send message to the web widget
|
|
252
203
|
*/
|
|
253
|
-
const sendMessageToWidget = (message:
|
|
204
|
+
const sendMessageToWidget = (message: unknown) => {
|
|
254
205
|
const js = `
|
|
255
206
|
window.postMessage(${JSON.stringify(message)}, '*');
|
|
256
207
|
true;
|
|
@@ -263,17 +214,15 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
263
214
|
* Build the widget URL with query parameters
|
|
264
215
|
*/
|
|
265
216
|
const finalWidgetUrl = useMemo(() => {
|
|
266
|
-
const baseUrl = getWidgetUrl(
|
|
217
|
+
const baseUrl = getWidgetUrl(accessToken);
|
|
267
218
|
const params = new URLSearchParams({
|
|
268
219
|
token: accessToken,
|
|
269
220
|
platform: Platform.OS,
|
|
270
221
|
userWalletAddress: userWalletAddress,
|
|
271
222
|
});
|
|
272
223
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return url;
|
|
276
|
-
}, [accessToken, userWalletAddress, environment]);
|
|
224
|
+
return `${baseUrl}?${params.toString()}`;
|
|
225
|
+
}, [accessToken, userWalletAddress]);
|
|
277
226
|
|
|
278
227
|
return (
|
|
279
228
|
<View style={styles.container}>
|
|
@@ -288,13 +237,11 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
288
237
|
setIsLoading(false);
|
|
289
238
|
}
|
|
290
239
|
}}
|
|
291
|
-
onError={(
|
|
292
|
-
const { nativeEvent } = syntheticEvent;
|
|
293
|
-
logError("WebView error:", nativeEvent);
|
|
240
|
+
onError={() => {
|
|
294
241
|
setIsLoading(false);
|
|
295
242
|
onError?.("WEBVIEW_ERROR", "Failed to load widget");
|
|
296
243
|
}}
|
|
297
|
-
//
|
|
244
|
+
// Allow external URLs to open in native apps
|
|
298
245
|
onShouldStartLoadWithRequest={(request) => {
|
|
299
246
|
const { url } = request;
|
|
300
247
|
|
|
@@ -305,10 +252,7 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
305
252
|
url.includes("wallet.google.com") ||
|
|
306
253
|
url.includes("wallet.apple.com")
|
|
307
254
|
) {
|
|
308
|
-
|
|
309
|
-
Linking.openURL(url).catch((err) => {
|
|
310
|
-
logError("Failed to open URL:", err);
|
|
311
|
-
});
|
|
255
|
+
Linking.openURL(url).catch(() => {});
|
|
312
256
|
return false; // Don't load in WebView
|
|
313
257
|
}
|
|
314
258
|
|
|
@@ -327,7 +271,7 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
327
271
|
/>
|
|
328
272
|
{isLoading && (
|
|
329
273
|
<View style={styles.loadingOverlay}>
|
|
330
|
-
<ActivityIndicator size="large" color=
|
|
274
|
+
<ActivityIndicator size="large" color="#007AFF" />
|
|
331
275
|
</View>
|
|
332
276
|
)}
|
|
333
277
|
</View>
|
package/src/config.ts
CHANGED
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Widget SDK Configuration
|
|
3
|
-
* Environment
|
|
3
|
+
* Environment detection based on access token prefix
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Token prefixes that determine the environment
|
|
8
|
+
*/
|
|
9
|
+
const TOKEN_PREFIX = {
|
|
10
|
+
SANDBOX: "sbx_",
|
|
11
|
+
PRODUCTION: "prod_",
|
|
12
|
+
} as const;
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
15
|
* Widget URLs by environment
|
|
10
16
|
*/
|
|
11
17
|
export const WIDGET_URLS = {
|
|
12
|
-
|
|
18
|
+
sandbox: "https://oobit-widget-dev.web.app",
|
|
13
19
|
production: "https://oobit-widget.web.app",
|
|
14
20
|
} as const;
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
|
-
* Get the widget URL
|
|
18
|
-
* @param
|
|
19
|
-
* @returns The widget URL for the
|
|
23
|
+
* Get the widget URL based on the access token prefix
|
|
24
|
+
* @param accessToken - The access token (prefixed with sbx_ or prod_)
|
|
25
|
+
* @returns The widget URL for the corresponding environment
|
|
20
26
|
*/
|
|
21
|
-
export function getWidgetUrl(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
export function getWidgetUrl(accessToken: string): string {
|
|
28
|
+
if (accessToken.startsWith(TOKEN_PREFIX.SANDBOX)) {
|
|
29
|
+
return WIDGET_URLS.sandbox;
|
|
30
|
+
}
|
|
31
|
+
if (accessToken.startsWith(TOKEN_PREFIX.PRODUCTION)) {
|
|
32
|
+
return WIDGET_URLS.production;
|
|
33
|
+
}
|
|
34
|
+
// Default to production for backwards compatibility
|
|
35
|
+
return WIDGET_URLS.production;
|
|
25
36
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,53 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Widget SDK - Public API
|
|
3
|
-
* Export all public components, types, and utilities
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
export { WidgetSDK } from "./WidgetSDK";
|
|
7
6
|
export type { WidgetSDKRef } from "./WidgetSDK";
|
|
8
7
|
|
|
9
|
-
// Export all message types for clients to use
|
|
10
8
|
export type {
|
|
11
|
-
BaseWidgetMessage,
|
|
12
|
-
CopyToClipboardMessage,
|
|
13
9
|
DepositToken,
|
|
14
|
-
NativeBackPressedMessage,
|
|
15
|
-
NativeBiometricFailedMessage,
|
|
16
|
-
NativeCardDetailsSessionMessage,
|
|
17
|
-
NativeMessage,
|
|
18
|
-
// Native → Widget message types
|
|
19
|
-
NativeMessageType,
|
|
20
|
-
NativeNavigateBackMessage,
|
|
21
|
-
NativePlatformInfoMessage,
|
|
22
|
-
NativeWalletOpenedMessage,
|
|
23
|
-
OpenWalletMessage,
|
|
24
|
-
RequestCardDetailsSessionMessage,
|
|
25
|
-
TokenExpiredMessage,
|
|
26
|
-
TransactionRequestedMessage,
|
|
27
|
-
WidgetCloseMessage,
|
|
28
|
-
WidgetEnvironment,
|
|
29
|
-
WidgetErrorMessage,
|
|
30
|
-
WidgetMessage,
|
|
31
|
-
// Widget → Native message types
|
|
32
|
-
WidgetMessageType,
|
|
33
|
-
WidgetReadyMessage,
|
|
34
|
-
// Configuration
|
|
35
|
-
WidgetSDKConfig,
|
|
36
|
-
// Error codes
|
|
37
10
|
SDKErrorCode,
|
|
11
|
+
WidgetSDKConfig,
|
|
38
12
|
} from "./types";
|
|
39
|
-
|
|
40
|
-
// Export constants
|
|
41
|
-
export { getWidgetUrl, WIDGET_URLS } from "./config";
|
|
42
|
-
export { MessageTypes, WALLET_URLS } from "./types";
|
|
43
|
-
|
|
44
|
-
// Export wallet utilities
|
|
45
|
-
export { isWalletAvailable, openNativeWallet } from "./walletUtils";
|
|
46
|
-
|
|
47
|
-
// Export crypto utilities (for advanced usage)
|
|
48
|
-
export {
|
|
49
|
-
generateRandomHexKey,
|
|
50
|
-
generateSessionCredentials,
|
|
51
|
-
hexToBase64,
|
|
52
|
-
} from "./cryptoUtils";
|
|
53
|
-
export type { SessionCredentials } from "./cryptoUtils";
|
package/src/types.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
export interface DepositToken {
|
|
11
11
|
symbol: string;
|
|
12
12
|
name: string;
|
|
13
|
-
iconUrl: string | null;
|
|
14
13
|
networkName: string;
|
|
14
|
+
chainId: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export type WidgetMessageType =
|
|
@@ -166,13 +166,6 @@ export type WidgetMessage =
|
|
|
166
166
|
| RequestCardDetailsSessionMessage
|
|
167
167
|
| CopyToClipboardMessage;
|
|
168
168
|
|
|
169
|
-
/**
|
|
170
|
-
* Widget environment configuration
|
|
171
|
-
* - 'development': Uses development/staging widget URL
|
|
172
|
-
* - 'production': Uses production widget URL
|
|
173
|
-
*/
|
|
174
|
-
export type WidgetEnvironment = "development" | "production";
|
|
175
|
-
|
|
176
169
|
/**
|
|
177
170
|
* Known SDK error codes
|
|
178
171
|
* - TOKEN_EXPIRED: The access token has expired
|
|
@@ -185,23 +178,10 @@ export type SDKErrorCode = "TOKEN_EXPIRED" | "PARSE_ERROR" | "WEBVIEW_ERROR";
|
|
|
185
178
|
* SDK Configuration
|
|
186
179
|
*/
|
|
187
180
|
export interface WidgetSDKConfig {
|
|
188
|
-
accessToken: string; // Required: Access token from backend
|
|
181
|
+
accessToken: string; // Required: Access token from backend (prefixed with sbx_ or prod_)
|
|
189
182
|
userWalletAddress: string; // Required: User's external wallet address for crypto deposits
|
|
190
|
-
/**
|
|
191
|
-
* Widget environment to use.
|
|
192
|
-
* - 'development': Uses https://oobit-widget-dev.web.app
|
|
193
|
-
* - 'production': Uses https://widget.oobit.com
|
|
194
|
-
* @default 'production'
|
|
195
|
-
*/
|
|
196
|
-
environment?: WidgetEnvironment;
|
|
197
|
-
/**
|
|
198
|
-
* Called when the widget is ready and loaded
|
|
199
|
-
*/
|
|
200
|
-
onReady?: () => void;
|
|
201
183
|
/**
|
|
202
184
|
* Called when an error occurs
|
|
203
|
-
* @param code - Error code (SDKErrorCode or custom widget error code)
|
|
204
|
-
* @param message - Human-readable error message
|
|
205
185
|
*/
|
|
206
186
|
onError?: (code: SDKErrorCode | string, message: string) => void;
|
|
207
187
|
/**
|
|
@@ -211,27 +191,12 @@ export interface WidgetSDKConfig {
|
|
|
211
191
|
/**
|
|
212
192
|
* Called when a crypto transaction is requested
|
|
213
193
|
*/
|
|
214
|
-
onTransactionRequested
|
|
194
|
+
onTransactionRequested: (
|
|
215
195
|
token: DepositToken,
|
|
216
196
|
cryptoAmount: string,
|
|
217
197
|
depositAddress: string,
|
|
218
198
|
depositAddressTag: string | null
|
|
219
199
|
) => void;
|
|
220
|
-
/**
|
|
221
|
-
* Called when the loading state changes
|
|
222
|
-
* @param isLoading - Whether the widget is currently loading
|
|
223
|
-
*/
|
|
224
|
-
onLoadingChange?: (isLoading: boolean) => void;
|
|
225
|
-
/**
|
|
226
|
-
* Enable debug logging to console
|
|
227
|
-
* @default false
|
|
228
|
-
*/
|
|
229
|
-
debug?: boolean;
|
|
230
|
-
/**
|
|
231
|
-
* Custom color for the loading indicator
|
|
232
|
-
* @default "#007AFF"
|
|
233
|
-
*/
|
|
234
|
-
loadingIndicatorColor?: string;
|
|
235
200
|
}
|
|
236
201
|
|
|
237
202
|
/**
|
package/dist/biometricUtils.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Biometric Authentication Utilities
|
|
3
|
-
*
|
|
4
|
-
* Provides cross-platform biometric authentication for card details access.
|
|
5
|
-
* Uses expo-local-authentication which works in Expo Go without native modules.
|
|
6
|
-
*
|
|
7
|
-
* @requires expo-local-authentication - included in Expo SDK
|
|
8
|
-
*/
|
|
9
|
-
import * as LocalAuthentication from 'expo-local-authentication';
|
|
10
|
-
/**
|
|
11
|
-
* Result of a biometric authentication attempt
|
|
12
|
-
*/
|
|
13
|
-
export interface BiometricResult {
|
|
14
|
-
/** Whether authentication was successful */
|
|
15
|
-
success: boolean;
|
|
16
|
-
/** Error details if authentication failed */
|
|
17
|
-
error?: {
|
|
18
|
-
reason: 'cancelled' | 'failed' | 'not_available' | 'not_enrolled';
|
|
19
|
-
message?: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Information about biometric capabilities on the device
|
|
24
|
-
*/
|
|
25
|
-
export interface BiometricAvailability {
|
|
26
|
-
/** Whether any biometric authentication is available */
|
|
27
|
-
available: boolean;
|
|
28
|
-
/** The types of biometry available */
|
|
29
|
-
biometryTypes: LocalAuthentication.AuthenticationType[];
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Checks if biometric authentication is available on the device
|
|
33
|
-
*
|
|
34
|
-
* @returns Object containing availability status and biometry types
|
|
35
|
-
*/
|
|
36
|
-
export declare function isBiometricAvailable(): Promise<BiometricAvailability>;
|
|
37
|
-
/**
|
|
38
|
-
* Prompts the user for biometric authentication
|
|
39
|
-
*
|
|
40
|
-
* This function should be called before generating session credentials
|
|
41
|
-
* for viewing card details. It ensures proper user verification before
|
|
42
|
-
* accessing sensitive payment card information.
|
|
43
|
-
*
|
|
44
|
-
* @param promptMessage - Message to display in the biometric prompt
|
|
45
|
-
* @returns Result indicating success or failure with reason
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```typescript
|
|
49
|
-
* const result = await authenticateWithBiometrics('Authenticate to view card details');
|
|
50
|
-
* if (result.success) {
|
|
51
|
-
* // Proceed with generating session credentials
|
|
52
|
-
* } else {
|
|
53
|
-
* // Handle failure based on result.error.reason
|
|
54
|
-
* }
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
export declare function authenticateWithBiometrics(promptMessage?: string): Promise<BiometricResult>;
|
|
58
|
-
/**
|
|
59
|
-
* Gets a user-friendly description of the biometric type
|
|
60
|
-
*
|
|
61
|
-
* @param biometryType - The biometry type from the device
|
|
62
|
-
* @returns Human-readable string for the biometry type
|
|
63
|
-
*/
|
|
64
|
-
export declare function getBiometryTypeLabel(biometryType: LocalAuthentication.AuthenticationType): string;
|
|
65
|
-
export { AuthenticationType } from 'expo-local-authentication';
|
|
66
|
-
//# sourceMappingURL=biometricUtils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"biometricUtils.d.ts","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,eAAe,GAAG,cAAc,CAAC;QAClE,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,aAAa,EAAE,mBAAmB,CAAC,kBAAkB,EAAE,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAiB3E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,0BAA0B,CAC9C,aAAa,GAAE,MAA4C,GAC1D,OAAO,CAAC,eAAe,CAAC,CA8E1B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,mBAAmB,CAAC,kBAAkB,GACnD,MAAM,CAWR;AAGD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/biometricUtils.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Biometric Authentication Utilities
|
|
4
|
-
*
|
|
5
|
-
* Provides cross-platform biometric authentication for card details access.
|
|
6
|
-
* Uses expo-local-authentication which works in Expo Go without native modules.
|
|
7
|
-
*
|
|
8
|
-
* @requires expo-local-authentication - included in Expo SDK
|
|
9
|
-
*/
|
|
10
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
-
}
|
|
16
|
-
Object.defineProperty(o, k2, desc);
|
|
17
|
-
}) : (function(o, m, k, k2) {
|
|
18
|
-
if (k2 === undefined) k2 = k;
|
|
19
|
-
o[k2] = m[k];
|
|
20
|
-
}));
|
|
21
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
-
}) : function(o, v) {
|
|
24
|
-
o["default"] = v;
|
|
25
|
-
});
|
|
26
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
-
var ownKeys = function(o) {
|
|
28
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
-
var ar = [];
|
|
30
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
-
return ar;
|
|
32
|
-
};
|
|
33
|
-
return ownKeys(o);
|
|
34
|
-
};
|
|
35
|
-
return function (mod) {
|
|
36
|
-
if (mod && mod.__esModule) return mod;
|
|
37
|
-
var result = {};
|
|
38
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
-
__setModuleDefault(result, mod);
|
|
40
|
-
return result;
|
|
41
|
-
};
|
|
42
|
-
})();
|
|
43
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.AuthenticationType = void 0;
|
|
45
|
-
exports.isBiometricAvailable = isBiometricAvailable;
|
|
46
|
-
exports.authenticateWithBiometrics = authenticateWithBiometrics;
|
|
47
|
-
exports.getBiometryTypeLabel = getBiometryTypeLabel;
|
|
48
|
-
const LocalAuthentication = __importStar(require("expo-local-authentication"));
|
|
49
|
-
/**
|
|
50
|
-
* Checks if biometric authentication is available on the device
|
|
51
|
-
*
|
|
52
|
-
* @returns Object containing availability status and biometry types
|
|
53
|
-
*/
|
|
54
|
-
async function isBiometricAvailable() {
|
|
55
|
-
try {
|
|
56
|
-
const hasHardware = await LocalAuthentication.hasHardwareAsync();
|
|
57
|
-
const isEnrolled = await LocalAuthentication.isEnrolledAsync();
|
|
58
|
-
const supportedTypes = await LocalAuthentication.supportedAuthenticationTypesAsync();
|
|
59
|
-
return {
|
|
60
|
-
available: hasHardware && isEnrolled,
|
|
61
|
-
biometryTypes: supportedTypes,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.error('[BiometricUtils] Error checking biometric availability:', error);
|
|
66
|
-
return {
|
|
67
|
-
available: false,
|
|
68
|
-
biometryTypes: [],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Prompts the user for biometric authentication
|
|
74
|
-
*
|
|
75
|
-
* This function should be called before generating session credentials
|
|
76
|
-
* for viewing card details. It ensures proper user verification before
|
|
77
|
-
* accessing sensitive payment card information.
|
|
78
|
-
*
|
|
79
|
-
* @param promptMessage - Message to display in the biometric prompt
|
|
80
|
-
* @returns Result indicating success or failure with reason
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```typescript
|
|
84
|
-
* const result = await authenticateWithBiometrics('Authenticate to view card details');
|
|
85
|
-
* if (result.success) {
|
|
86
|
-
* // Proceed with generating session credentials
|
|
87
|
-
* } else {
|
|
88
|
-
* // Handle failure based on result.error.reason
|
|
89
|
-
* }
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
async function authenticateWithBiometrics(promptMessage = 'Authenticate to view card details') {
|
|
93
|
-
try {
|
|
94
|
-
// First check if biometrics are available
|
|
95
|
-
const hasHardware = await LocalAuthentication.hasHardwareAsync();
|
|
96
|
-
if (!hasHardware) {
|
|
97
|
-
console.log('[BiometricUtils] Biometrics not available on device');
|
|
98
|
-
return {
|
|
99
|
-
success: false,
|
|
100
|
-
error: {
|
|
101
|
-
reason: 'not_available',
|
|
102
|
-
message: 'Biometric authentication is not available on this device',
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
// Check if biometrics are enrolled
|
|
107
|
-
const isEnrolled = await LocalAuthentication.isEnrolledAsync();
|
|
108
|
-
if (!isEnrolled) {
|
|
109
|
-
console.log('[BiometricUtils] No biometrics enrolled');
|
|
110
|
-
return {
|
|
111
|
-
success: false,
|
|
112
|
-
error: {
|
|
113
|
-
reason: 'not_enrolled',
|
|
114
|
-
message: 'No biometric authentication is set up on this device',
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
console.log('[BiometricUtils] Attempting biometric authentication...');
|
|
119
|
-
// Perform the biometric authentication
|
|
120
|
-
const result = await LocalAuthentication.authenticateAsync({
|
|
121
|
-
promptMessage,
|
|
122
|
-
cancelLabel: 'Cancel',
|
|
123
|
-
disableDeviceFallback: false, // Allow PIN/password fallback
|
|
124
|
-
fallbackLabel: 'Use Passcode',
|
|
125
|
-
});
|
|
126
|
-
if (result.success) {
|
|
127
|
-
console.log('[BiometricUtils] Biometric authentication successful');
|
|
128
|
-
return { success: true };
|
|
129
|
-
}
|
|
130
|
-
// Handle various failure reasons
|
|
131
|
-
console.log('[BiometricUtils] Biometric authentication failed:', result.error);
|
|
132
|
-
let reason = 'failed';
|
|
133
|
-
if (result.error === 'user_cancel' || result.error === 'system_cancel') {
|
|
134
|
-
reason = 'cancelled';
|
|
135
|
-
}
|
|
136
|
-
else if (result.error === 'not_enrolled') {
|
|
137
|
-
reason = 'not_enrolled';
|
|
138
|
-
}
|
|
139
|
-
else if (result.error === 'not_available') {
|
|
140
|
-
reason = 'not_available';
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
success: false,
|
|
144
|
-
error: {
|
|
145
|
-
reason,
|
|
146
|
-
message: result.warning || 'Authentication failed',
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
console.error('[BiometricUtils] Biometric authentication error:', error);
|
|
152
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
153
|
-
return {
|
|
154
|
-
success: false,
|
|
155
|
-
error: {
|
|
156
|
-
reason: 'failed',
|
|
157
|
-
message: errorMessage,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Gets a user-friendly description of the biometric type
|
|
164
|
-
*
|
|
165
|
-
* @param biometryType - The biometry type from the device
|
|
166
|
-
* @returns Human-readable string for the biometry type
|
|
167
|
-
*/
|
|
168
|
-
function getBiometryTypeLabel(biometryType) {
|
|
169
|
-
switch (biometryType) {
|
|
170
|
-
case LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION:
|
|
171
|
-
return 'Face ID';
|
|
172
|
-
case LocalAuthentication.AuthenticationType.FINGERPRINT:
|
|
173
|
-
return 'Touch ID';
|
|
174
|
-
case LocalAuthentication.AuthenticationType.IRIS:
|
|
175
|
-
return 'Iris';
|
|
176
|
-
default:
|
|
177
|
-
return 'Biometric Authentication';
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// Re-export AuthenticationType for convenience
|
|
181
|
-
var expo_local_authentication_1 = require("expo-local-authentication");
|
|
182
|
-
Object.defineProperty(exports, "AuthenticationType", { enumerable: true, get: function () { return expo_local_authentication_1.AuthenticationType; } });
|
|
183
|
-
//# sourceMappingURL=biometricUtils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"biometricUtils.js","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":"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"}
|