@oobit/react-native-sdk 1.0.3 → 1.0.5

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.d.ts CHANGED
@@ -4,8 +4,12 @@
4
4
  */
5
5
  export { WidgetSDK } from './WidgetSDK';
6
6
  export type { WidgetSDKRef } from './WidgetSDK';
7
- export type { WidgetSDKConfig, WidgetEnvironment, DepositToken, WidgetMessageType, BaseWidgetMessage, WidgetMessage, WidgetReadyMessage, OpenWalletMessage, CardCreatedMessage, WidgetErrorMessage, WidgetCloseMessage, TransactionRequestedMessage, NativeMessageType, NativeMessage, NativeBackPressedMessage, NativeNavigateBackMessage, NativePlatformInfoMessage, NativeWalletOpenedMessage, } from './types';
7
+ export type { WidgetSDKConfig, WidgetEnvironment, DepositToken, WidgetMessageType, BaseWidgetMessage, WidgetMessage, WidgetReadyMessage, OpenWalletMessage, CardCreatedMessage, WidgetErrorMessage, WidgetCloseMessage, TransactionRequestedMessage, RequestCardDetailsSessionMessage, NativeMessageType, NativeMessage, NativeBackPressedMessage, NativeNavigateBackMessage, NativePlatformInfoMessage, NativeWalletOpenedMessage, NativeCardDetailsSessionMessage, NativeBiometricFailedMessage, } from './types';
8
8
  export { WALLET_URLS, MessageTypes } from './types';
9
9
  export { WIDGET_URLS, getWidgetUrl } from './config';
10
10
  export { openNativeWallet, isWalletAvailable } from './walletUtils';
11
+ export { authenticateWithBiometrics, isBiometricAvailable, getBiometryTypeLabel, BiometryTypes, } from './biometricUtils';
12
+ export type { BiometricResult, BiometricAvailability } from './biometricUtils';
13
+ export { generateSessionCredentials, generateRandomHexKey, hexToBase64, } from './cryptoUtils';
14
+ export type { SessionCredentials } from './cryptoUtils';
11
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAEV,eAAe,EACf,iBAAiB,EACjB,YAAY,EAGZ,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,EAG3B,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAEV,eAAe,EACf,iBAAiB,EACjB,YAAY,EAGZ,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,EAC3B,gCAAgC,EAGhC,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Export all public components, types, and utilities
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.isWalletAvailable = exports.openNativeWallet = exports.getWidgetUrl = exports.WIDGET_URLS = exports.MessageTypes = exports.WALLET_URLS = exports.WidgetSDK = void 0;
7
+ exports.hexToBase64 = exports.generateRandomHexKey = exports.generateSessionCredentials = exports.BiometryTypes = exports.getBiometryTypeLabel = exports.isBiometricAvailable = exports.authenticateWithBiometrics = exports.isWalletAvailable = exports.openNativeWallet = exports.getWidgetUrl = exports.WIDGET_URLS = exports.MessageTypes = exports.WALLET_URLS = exports.WidgetSDK = void 0;
8
8
  var WidgetSDK_1 = require("./WidgetSDK");
9
9
  Object.defineProperty(exports, "WidgetSDK", { enumerable: true, get: function () { return WidgetSDK_1.WidgetSDK; } });
10
10
  // Export constants
@@ -18,4 +18,15 @@ Object.defineProperty(exports, "getWidgetUrl", { enumerable: true, get: function
18
18
  var walletUtils_1 = require("./walletUtils");
19
19
  Object.defineProperty(exports, "openNativeWallet", { enumerable: true, get: function () { return walletUtils_1.openNativeWallet; } });
20
20
  Object.defineProperty(exports, "isWalletAvailable", { enumerable: true, get: function () { return walletUtils_1.isWalletAvailable; } });
21
+ // Export biometric utilities
22
+ var biometricUtils_1 = require("./biometricUtils");
23
+ Object.defineProperty(exports, "authenticateWithBiometrics", { enumerable: true, get: function () { return biometricUtils_1.authenticateWithBiometrics; } });
24
+ Object.defineProperty(exports, "isBiometricAvailable", { enumerable: true, get: function () { return biometricUtils_1.isBiometricAvailable; } });
25
+ Object.defineProperty(exports, "getBiometryTypeLabel", { enumerable: true, get: function () { return biometricUtils_1.getBiometryTypeLabel; } });
26
+ Object.defineProperty(exports, "BiometryTypes", { enumerable: true, get: function () { return biometricUtils_1.BiometryTypes; } });
27
+ // Export crypto utilities (for advanced usage)
28
+ var cryptoUtils_1 = require("./cryptoUtils");
29
+ Object.defineProperty(exports, "generateSessionCredentials", { enumerable: true, get: function () { return cryptoUtils_1.generateSessionCredentials; } });
30
+ Object.defineProperty(exports, "generateRandomHexKey", { enumerable: true, get: function () { return cryptoUtils_1.generateRandomHexKey; } });
31
+ Object.defineProperty(exports, "hexToBase64", { enumerable: true, get: function () { return cryptoUtils_1.hexToBase64; } });
21
32
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AA8BlB,mBAAmB;AACnB,iCAAoD;AAA3C,oGAAA,WAAW,OAAA;AAAE,qGAAA,YAAY,OAAA;AAClC,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAElC,0BAA0B;AAC1B,6CAAoE;AAA3D,+GAAA,gBAAgB,OAAA;AAAE,gHAAA,iBAAiB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAiClB,mBAAmB;AACnB,iCAAoD;AAA3C,oGAAA,WAAW,OAAA;AAAE,qGAAA,YAAY,OAAA;AAClC,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAElC,0BAA0B;AAC1B,6CAAoE;AAA3D,+GAAA,gBAAgB,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAE5C,6BAA6B;AAC7B,mDAK0B;AAJxB,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AACpB,+GAAA,aAAa,OAAA;AAIf,+CAA+C;AAC/C,6CAIuB;AAHrB,yHAAA,0BAA0B,OAAA;AAC1B,mHAAA,oBAAoB,OAAA;AACpB,0GAAA,WAAW,OAAA"}
package/dist/types.d.ts CHANGED
@@ -12,67 +12,81 @@ export interface DepositToken {
12
12
  iconUrl: string | null;
13
13
  networkName: string;
14
14
  }
15
- export type WidgetMessageType = 'widget:ready' | 'widget:open-wallet' | 'widget:card-created' | 'widget:error' | 'widget:close' | 'widget:transaction-requested' | 'widget:token-expired';
15
+ export type WidgetMessageType = "widget:ready" | "widget:open-wallet" | "widget:card-created" | "widget:error" | "widget:close" | "widget:transaction-requested" | "widget:token-expired" | "widget:request-card-details-session";
16
16
  /**
17
17
  * Native Message Types
18
18
  * Messages sent from the native app to the web widget
19
19
  */
20
- export type NativeMessageType = 'native:platform-info' | 'native:wallet-opened' | 'native:back-pressed' | 'native:navigate-back';
20
+ export type NativeMessageType = "native:platform-info" | "native:wallet-opened" | "native:back-pressed" | "native:navigate-back" | "native:card-details-session" | "native:biometric-failed";
21
21
  export interface NativeBackPressedMessage {
22
- type: 'native:back-pressed';
22
+ type: "native:back-pressed";
23
23
  timestamp: number;
24
24
  }
25
25
  export interface NativeNavigateBackMessage {
26
- type: 'native:navigate-back';
26
+ type: "native:navigate-back";
27
27
  timestamp: number;
28
28
  }
29
29
  export interface NativePlatformInfoMessage {
30
- type: 'native:platform-info';
30
+ type: "native:platform-info";
31
31
  payload: {
32
32
  platform: string;
33
33
  walletAvailable: boolean;
34
34
  };
35
35
  }
36
36
  export interface NativeWalletOpenedMessage {
37
- type: 'native:wallet-opened';
37
+ type: "native:wallet-opened";
38
38
  payload: {
39
39
  success: boolean;
40
40
  };
41
41
  }
42
- export type NativeMessage = NativeBackPressedMessage | NativeNavigateBackMessage | NativePlatformInfoMessage | NativeWalletOpenedMessage;
42
+ export interface NativeCardDetailsSessionMessage {
43
+ type: "native:card-details-session";
44
+ payload: {
45
+ sessionId: string;
46
+ secretKey: string;
47
+ };
48
+ }
49
+ export interface NativeBiometricFailedMessage {
50
+ type: "native:biometric-failed";
51
+ payload: {
52
+ reason: "cancelled" | "failed" | "not_available" | "not_enrolled";
53
+ message?: string;
54
+ };
55
+ }
56
+ export type NativeMessage = NativeBackPressedMessage | NativeNavigateBackMessage | NativePlatformInfoMessage | NativeWalletOpenedMessage | NativeCardDetailsSessionMessage | NativeBiometricFailedMessage;
43
57
  export interface BaseWidgetMessage {
44
58
  type: WidgetMessageType;
45
59
  timestamp: number;
46
60
  }
47
61
  export interface WidgetReadyMessage extends BaseWidgetMessage {
48
- type: 'widget:ready';
62
+ type: "widget:ready";
49
63
  }
50
64
  export interface OpenWalletMessage extends BaseWidgetMessage {
51
- type: 'widget:open-wallet';
65
+ type: "widget:open-wallet";
52
66
  payload: {
53
- platform: 'ios' | 'android';
67
+ platform: "ios" | "android";
54
68
  };
55
69
  }
56
70
  export interface CardCreatedMessage extends BaseWidgetMessage {
57
- type: 'widget:card-created';
71
+ type: "widget:card-created";
58
72
  payload: {
59
73
  cardId: string;
60
- cardType: 'virtual' | 'physical';
74
+ cardType: "virtual" | "physical";
61
75
  last4: string;
62
76
  };
63
77
  }
64
78
  export interface WidgetErrorMessage extends BaseWidgetMessage {
65
- type: 'widget:error';
79
+ type: "widget:error";
66
80
  payload: {
67
81
  code: string;
68
82
  message: string;
69
83
  };
70
84
  }
71
85
  export interface WidgetCloseMessage extends BaseWidgetMessage {
72
- type: 'widget:close';
86
+ type: "widget:close";
73
87
  }
74
88
  export interface TransactionRequestedMessage extends BaseWidgetMessage {
75
- type: 'widget:transaction-requested';
89
+ type: "widget:transaction-requested";
76
90
  payload: {
77
91
  token: DepositToken;
78
92
  cryptoAmount: string;
@@ -81,18 +95,24 @@ export interface TransactionRequestedMessage extends BaseWidgetMessage {
81
95
  };
82
96
  }
83
97
  export interface TokenExpiredMessage extends BaseWidgetMessage {
84
- type: 'widget:token-expired';
98
+ type: "widget:token-expired";
85
99
  payload?: {
86
100
  reason?: string;
87
101
  };
88
102
  }
89
- export type WidgetMessage = WidgetReadyMessage | OpenWalletMessage | CardCreatedMessage | WidgetErrorMessage | WidgetCloseMessage | TransactionRequestedMessage | TokenExpiredMessage;
103
+ export interface RequestCardDetailsSessionMessage extends BaseWidgetMessage {
104
+ type: "widget:request-card-details-session";
105
+ payload: {
106
+ publicKey: string;
107
+ };
108
+ }
109
+ export type WidgetMessage = WidgetReadyMessage | OpenWalletMessage | CardCreatedMessage | WidgetErrorMessage | WidgetCloseMessage | TransactionRequestedMessage | TokenExpiredMessage | RequestCardDetailsSessionMessage;
90
110
  /**
91
111
  * Widget environment configuration
92
112
  * - 'development': Uses development/staging widget URL
93
113
  * - 'production': Uses production widget URL
94
114
  */
95
- export type WidgetEnvironment = 'development' | 'production';
115
+ export type WidgetEnvironment = "development" | "production";
96
116
  /**
97
117
  * SDK Configuration
98
118
  */
@@ -140,9 +160,12 @@ export declare const MessageTypes: {
140
160
  readonly CLOSE: "widget:close";
141
161
  readonly TRANSACTION_REQUESTED: "widget:transaction-requested";
142
162
  readonly TOKEN_EXPIRED: "widget:token-expired";
163
+ readonly REQUEST_CARD_DETAILS_SESSION: "widget:request-card-details-session";
143
164
  readonly PLATFORM_INFO: "native:platform-info";
144
165
  readonly WALLET_OPENED: "native:wallet-opened";
145
166
  readonly BACK_PRESSED: "native:back-pressed";
146
167
  readonly NAVIGATE_BACK: "native:navigate-back";
168
+ readonly CARD_DETAILS_SESSION: "native:card-details-session";
169
+ readonly BIOMETRIC_FAILED: "native:biometric-failed";
147
170
  };
148
171
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -10,12 +10,12 @@ exports.MessageTypes = exports.WALLET_URLS = void 0;
10
10
  */
11
11
  exports.WALLET_URLS = {
12
12
  ios: {
13
- passkit: 'shoebox://', // Apple Wallet deep link
14
- fallback: 'https://wallet.apple.com',
13
+ passkit: "shoebox://", // Apple Wallet deep link
14
+ fallback: "https://wallet.apple.com",
15
15
  },
16
16
  android: {
17
- googlePay: 'https://pay.google.com/gp/w/home/wallet',
18
- fallback: 'https://wallet.google.com',
17
+ googlePay: "https://pay.google.com/gp/w/home/wallet",
18
+ fallback: "https://wallet.google.com",
19
19
  },
20
20
  };
21
21
  /**
@@ -27,17 +27,20 @@ exports.WALLET_URLS = {
27
27
  */
28
28
  exports.MessageTypes = {
29
29
  // Widget → Native
30
- READY: 'widget:ready',
31
- OPEN_WALLET: 'widget:open-wallet',
32
- CARD_CREATED: 'widget:card-created',
33
- ERROR: 'widget:error',
34
- CLOSE: 'widget:close',
35
- TRANSACTION_REQUESTED: 'widget:transaction-requested',
36
- TOKEN_EXPIRED: 'widget:token-expired',
30
+ READY: "widget:ready",
31
+ OPEN_WALLET: "widget:open-wallet",
32
+ CARD_CREATED: "widget:card-created",
33
+ ERROR: "widget:error",
34
+ CLOSE: "widget:close",
35
+ TRANSACTION_REQUESTED: "widget:transaction-requested",
36
+ TOKEN_EXPIRED: "widget:token-expired",
37
+ REQUEST_CARD_DETAILS_SESSION: "widget:request-card-details-session",
37
38
  // Native → Widget
38
- PLATFORM_INFO: 'native:platform-info',
39
- WALLET_OPENED: 'native:wallet-opened',
40
- BACK_PRESSED: 'native:back-pressed',
41
- NAVIGATE_BACK: 'native:navigate-back',
39
+ PLATFORM_INFO: "native:platform-info",
40
+ WALLET_OPENED: "native:wallet-opened",
41
+ BACK_PRESSED: "native:back-pressed",
42
+ NAVIGATE_BACK: "native:navigate-back",
43
+ CARD_DETAILS_SESSION: "native:card-details-session",
44
+ BIOMETRIC_FAILED: "native:biometric-failed",
42
45
  };
43
46
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAyJH;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,GAAG,EAAE;QACH,OAAO,EAAE,YAAY,EAAE,yBAAyB;QAChD,QAAQ,EAAE,0BAA0B;KACrC;IACD,OAAO,EAAE;QACP,SAAS,EAAE,yCAAyC;QACpD,QAAQ,EAAE,2BAA2B;KACtC;CACO,CAAC;AAEX;;;;;;GAMG;AACU,QAAA,YAAY,GAAG;IAC1B,kBAAkB;IAClB,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,oBAAoB;IACjC,YAAY,EAAE,qBAAqB;IACnC,KAAK,EAAE,cAAc;IACrB,KAAK,EAAE,cAAc;IACrB,qBAAqB,EAAE,8BAA8B;IACrD,aAAa,EAAE,sBAAsB;IACrC,kBAAkB;IAClB,aAAa,EAAE,sBAAsB;IACrC,aAAa,EAAE,sBAAsB;IACrC,YAAY,EAAE,qBAAqB;IACnC,aAAa,EAAE,sBAAsB;CAC7B,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA2LH;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,GAAG,EAAE;QACH,OAAO,EAAE,YAAY,EAAE,yBAAyB;QAChD,QAAQ,EAAE,0BAA0B;KACrC;IACD,OAAO,EAAE;QACP,SAAS,EAAE,yCAAyC;QACpD,QAAQ,EAAE,2BAA2B;KACtC;CACO,CAAC;AAEX;;;;;;GAMG;AACU,QAAA,YAAY,GAAG;IAC1B,kBAAkB;IAClB,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,oBAAoB;IACjC,YAAY,EAAE,qBAAqB;IACnC,KAAK,EAAE,cAAc;IACrB,KAAK,EAAE,cAAc;IACrB,qBAAqB,EAAE,8BAA8B;IACrD,aAAa,EAAE,sBAAsB;IACrC,4BAA4B,EAAE,qCAAqC;IACnE,kBAAkB;IAClB,aAAa,EAAE,sBAAsB;IACrC,aAAa,EAAE,sBAAsB;IACrC,YAAY,EAAE,qBAAqB;IACnC,aAAa,EAAE,sBAAsB;IACrC,oBAAoB,EAAE,6BAA6B;IACnD,gBAAgB,EAAE,yBAAyB;CACnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oobit/react-native-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "React Native SDK for integrating Oobit crypto payments into wallet apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -39,15 +39,13 @@
39
39
  "url": "git+https://github.com/oobit-tech/react-native-SDK.git"
40
40
  },
41
41
  "peerDependencies": {
42
+ "expo-intent-launcher": ">=6.0.0",
42
43
  "expo-linking": ">=6.0.0",
43
44
  "react": ">=18.0.0",
44
45
  "react-native": ">=0.70.0",
45
- "react-native-webview": ">=13.0.0"
46
- },
47
- "peerDependenciesMeta": {
48
- "expo-intent-launcher": {
49
- "optional": true
50
- }
46
+ "react-native-webview": ">=13.0.0",
47
+ "react-native-biometrics": ">=3.0.0",
48
+ "react-native-quick-crypto": ">=0.7.0"
51
49
  },
52
50
  "devDependencies": {
53
51
  "@types/react": "~19.1.0",
@@ -58,6 +56,8 @@
58
56
  "expo-linking": "~8.0.8",
59
57
  "react": "19.1.0",
60
58
  "react-native": "0.81.5",
59
+ "react-native-biometrics": "^3.0.1",
60
+ "react-native-quick-crypto": "^0.7.9",
61
61
  "react-native-webview": "13.15.0",
62
62
  "typescript": "~5.9.2"
63
63
  },
package/src/WidgetSDK.tsx CHANGED
@@ -11,10 +11,24 @@ import React, {
11
11
  useRef,
12
12
  useState,
13
13
  } from "react";
14
- import { ActivityIndicator, BackHandler, Linking, Platform, StyleSheet, View } from "react-native";
14
+ import {
15
+ ActivityIndicator,
16
+ BackHandler,
17
+ Linking,
18
+ Platform,
19
+ StyleSheet,
20
+ View,
21
+ } from "react-native";
15
22
  import { WebView, WebViewMessageEvent } from "react-native-webview";
23
+ import { authenticateWithBiometrics } from "./biometricUtils";
16
24
  import { getWidgetUrl } from "./config";
17
- import { WidgetMessage, WidgetSDKConfig } from "./types";
25
+ import { generateSessionCredentials } from "./cryptoUtils";
26
+ import {
27
+ NativeBiometricFailedMessage,
28
+ NativeCardDetailsSessionMessage,
29
+ WidgetMessage,
30
+ WidgetSDKConfig,
31
+ } from "./types";
18
32
  import { isWalletAvailable, openNativeWallet } from "./walletUtils";
19
33
 
20
34
  export interface WidgetSDKRef {
@@ -117,6 +131,10 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
117
131
  onError?.("TOKEN_EXPIRED", "Access token has expired");
118
132
  break;
119
133
 
134
+ case "widget:request-card-details-session":
135
+ handleCardDetailsRequest(message);
136
+ break;
137
+
120
138
  default:
121
139
  console.warn("[WidgetSDK] Unknown message type:", message);
122
140
  }
@@ -178,7 +196,8 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
178
196
  const handleTransactionRequested = (message: WidgetMessage) => {
179
197
  if (message.type !== "widget:transaction-requested") return;
180
198
 
181
- const { token, cryptoAmount, depositAddress, depositAddressTag } = message.payload;
199
+ const { token, cryptoAmount, depositAddress, depositAddressTag } =
200
+ message.payload;
182
201
  console.log("[WidgetSDK] Transaction requested:", {
183
202
  token,
184
203
  cryptoAmount,
@@ -186,7 +205,89 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
186
205
  depositAddressTag,
187
206
  });
188
207
 
189
- onTransactionRequested?.(token, cryptoAmount, depositAddress, depositAddressTag);
208
+ onTransactionRequested?.(
209
+ token,
210
+ cryptoAmount,
211
+ depositAddress,
212
+ depositAddressTag
213
+ );
214
+ };
215
+
216
+ /**
217
+ * Handle card details session request from widget
218
+ * 1. Show biometric prompt for user authentication
219
+ * 2. Generate cryptographically linked sessionId + secretKey pair
220
+ * 3. Send credentials back to widget for API call and decryption
221
+ */
222
+ const handleCardDetailsRequest = async (message: WidgetMessage) => {
223
+ if (message.type !== "widget:request-card-details-session") return;
224
+
225
+ const { publicKey } = message.payload;
226
+ console.log(
227
+ "[WidgetSDK] Card details requested, initiating biometric auth..."
228
+ );
229
+
230
+ // Step 1: Authenticate with biometrics
231
+ const biometricResult = await authenticateWithBiometrics(
232
+ "Authenticate to view card details"
233
+ );
234
+
235
+ if (!biometricResult.success) {
236
+ console.log(
237
+ "[WidgetSDK] Biometric auth failed:",
238
+ biometricResult.error
239
+ );
240
+
241
+ const failedMessage: NativeBiometricFailedMessage = {
242
+ type: "native:biometric-failed",
243
+ payload: {
244
+ reason: biometricResult.error?.reason || "failed",
245
+ message: biometricResult.error?.message,
246
+ },
247
+ };
248
+
249
+ sendMessageToWidget(failedMessage);
250
+ return;
251
+ }
252
+
253
+ // Step 2: Generate session credentials
254
+ try {
255
+ console.log(
256
+ "[WidgetSDK] Biometric auth successful, generating session credentials..."
257
+ );
258
+
259
+ const { secretKeyHex, sessionId } = await generateSessionCredentials(
260
+ publicKey
261
+ );
262
+
263
+ console.log("[WidgetSDK] Session credentials generated successfully");
264
+
265
+ // Step 3: Send credentials to widget
266
+ const sessionMessage: NativeCardDetailsSessionMessage = {
267
+ type: "native:card-details-session",
268
+ payload: {
269
+ sessionId,
270
+ secretKey: secretKeyHex,
271
+ },
272
+ };
273
+
274
+ sendMessageToWidget(sessionMessage);
275
+ } catch (error) {
276
+ console.error(
277
+ "[WidgetSDK] Failed to generate session credentials:",
278
+ error
279
+ );
280
+
281
+ const failedMessage: NativeBiometricFailedMessage = {
282
+ type: "native:biometric-failed",
283
+ payload: {
284
+ reason: "failed",
285
+ message: "Failed to generate secure session",
286
+ },
287
+ };
288
+
289
+ sendMessageToWidget(failedMessage);
290
+ }
190
291
  };
191
292
 
192
293
  /**
@@ -286,8 +387,8 @@ const styles = StyleSheet.create({
286
387
  },
287
388
  loadingOverlay: {
288
389
  ...StyleSheet.absoluteFillObject,
289
- backgroundColor: 'rgba(255, 255, 255, 0.9)',
290
- justifyContent: 'center',
291
- alignItems: 'center',
390
+ backgroundColor: "rgba(255, 255, 255, 0.9)",
391
+ justifyContent: "center",
392
+ alignItems: "center",
292
393
  },
293
394
  });
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Biometric Authentication Utilities
3
+ *
4
+ * Provides cross-platform biometric authentication for card details access.
5
+ * Supports Face ID, Touch ID, and Android biometrics.
6
+ *
7
+ * @requires react-native-biometrics - npm install react-native-biometrics
8
+ */
9
+
10
+ import ReactNativeBiometrics, { BiometryTypes, type BiometryType } from 'react-native-biometrics';
11
+
12
+ /**
13
+ * Result of a biometric authentication attempt
14
+ */
15
+ export interface BiometricResult {
16
+ /** Whether authentication was successful */
17
+ success: boolean;
18
+ /** Error details if authentication failed */
19
+ error?: {
20
+ reason: 'cancelled' | 'failed' | 'not_available' | 'not_enrolled';
21
+ message?: string;
22
+ };
23
+ }
24
+
25
+ /**
26
+ * Information about biometric capabilities on the device
27
+ */
28
+ export interface BiometricAvailability {
29
+ /** Whether any biometric authentication is available */
30
+ available: boolean;
31
+ /** The type of biometry available (FaceID, TouchID, Biometrics, or null) */
32
+ biometryType: BiometryType | null;
33
+ }
34
+
35
+ // Singleton instance of ReactNativeBiometrics
36
+ const rnBiometrics = new ReactNativeBiometrics({
37
+ allowDeviceCredentials: false, // Only allow biometric, not PIN/password fallback
38
+ });
39
+
40
+ /**
41
+ * Checks if biometric authentication is available on the device
42
+ *
43
+ * @returns Object containing availability status and biometry type
44
+ */
45
+ export async function isBiometricAvailable(): Promise<BiometricAvailability> {
46
+ try {
47
+ const { available, biometryType } = await rnBiometrics.isSensorAvailable();
48
+
49
+ return {
50
+ available,
51
+ biometryType: biometryType || null,
52
+ };
53
+ } catch (error) {
54
+ console.error('[BiometricUtils] Error checking biometric availability:', error);
55
+ return {
56
+ available: false,
57
+ biometryType: null,
58
+ };
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Prompts the user for biometric authentication
64
+ *
65
+ * This function should be called before generating session credentials
66
+ * for viewing card details. It ensures proper user verification before
67
+ * accessing sensitive payment card information.
68
+ *
69
+ * @param promptMessage - Message to display in the biometric prompt
70
+ * @returns Result indicating success or failure with reason
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const result = await authenticateWithBiometrics('Authenticate to view card details');
75
+ * if (result.success) {
76
+ * // Proceed with generating session credentials
77
+ * } else {
78
+ * // Handle failure based on result.error.reason
79
+ * }
80
+ * ```
81
+ */
82
+ export async function authenticateWithBiometrics(
83
+ promptMessage: string = 'Authenticate to view card details'
84
+ ): Promise<BiometricResult> {
85
+ try {
86
+ // First check if biometrics are available
87
+ const { available, biometryType } = await rnBiometrics.isSensorAvailable();
88
+
89
+ if (!available) {
90
+ console.log('[BiometricUtils] Biometrics not available on device');
91
+ return {
92
+ success: false,
93
+ error: {
94
+ reason: 'not_available',
95
+ message: 'Biometric authentication is not available on this device',
96
+ },
97
+ };
98
+ }
99
+
100
+ // Check if biometrics are enrolled
101
+ const { keysExist } = await rnBiometrics.biometricKeysExist();
102
+
103
+ // Note: Even without keys, simplePrompt should work for basic authentication
104
+ // The keysExist check is more for cryptographic operations
105
+
106
+ console.log(
107
+ `[BiometricUtils] Attempting biometric auth. Type: ${biometryType}, Keys exist: ${keysExist}`
108
+ );
109
+
110
+ // Perform the biometric authentication
111
+ const { success, error } = await rnBiometrics.simplePrompt({
112
+ promptMessage,
113
+ cancelButtonText: 'Cancel',
114
+ });
115
+
116
+ if (success) {
117
+ console.log('[BiometricUtils] Biometric authentication successful');
118
+ return { success: true };
119
+ }
120
+
121
+ // Handle various failure reasons
122
+ console.log('[BiometricUtils] Biometric authentication failed:', error);
123
+
124
+ // Parse the error message to determine the reason
125
+ const errorMessage = error || 'Authentication failed';
126
+ let reason: NonNullable<BiometricResult['error']>['reason'] = 'failed';
127
+
128
+ if (
129
+ errorMessage.toLowerCase().includes('cancel') ||
130
+ errorMessage.toLowerCase().includes('user cancel')
131
+ ) {
132
+ reason = 'cancelled';
133
+ } else if (
134
+ errorMessage.toLowerCase().includes('not enrolled') ||
135
+ errorMessage.toLowerCase().includes('no fingerprint') ||
136
+ errorMessage.toLowerCase().includes('no face')
137
+ ) {
138
+ reason = 'not_enrolled';
139
+ } else if (
140
+ errorMessage.toLowerCase().includes('not available') ||
141
+ errorMessage.toLowerCase().includes('not supported')
142
+ ) {
143
+ reason = 'not_available';
144
+ }
145
+
146
+ return {
147
+ success: false,
148
+ error: {
149
+ reason,
150
+ message: errorMessage,
151
+ },
152
+ };
153
+ } catch (error) {
154
+ console.error('[BiometricUtils] Biometric authentication error:', error);
155
+
156
+ const errorMessage =
157
+ error instanceof Error ? error.message : 'Unknown error occurred';
158
+
159
+ return {
160
+ success: false,
161
+ error: {
162
+ reason: 'failed',
163
+ message: errorMessage,
164
+ },
165
+ };
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Gets a user-friendly description of the biometric type
171
+ *
172
+ * @param biometryType - The biometry type from the device
173
+ * @returns Human-readable string for the biometry type
174
+ */
175
+ export function getBiometryTypeLabel(biometryType: BiometryType | null): string {
176
+ switch (biometryType) {
177
+ case BiometryTypes.FaceID:
178
+ return 'Face ID';
179
+ case BiometryTypes.TouchID:
180
+ return 'Touch ID';
181
+ case BiometryTypes.Biometrics:
182
+ return 'Biometrics';
183
+ default:
184
+ return 'Biometric Authentication';
185
+ }
186
+ }
187
+
188
+ // Re-export BiometryTypes for convenience
189
+ export { BiometryTypes };