@expensify/react-native-wallet 0.1.40 → 0.2.0
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/README.md +60 -8
- package/android/src/main/java/com/expensify/wallet/Utils.kt +6 -1
- package/android/src/main/java/com/expensify/wallet/WalletModule.kt +273 -50
- package/android/src/main/java/com/expensify/wallet/model/CardData.kt +3 -1
- package/android/src/paper/java/com/expensify/wallet/NativeWalletSpec.java +8 -0
- package/ios/RNWallet.mm +30 -0
- package/ios/WalletManager.swift +57 -17
- package/lib/commonjs/NativeWallet.js.map +1 -1
- package/lib/commonjs/index.js +46 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeWallet.js.map +1 -1
- package/lib/module/index.js +46 -4
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeWallet.d.ts +18 -2
- package/lib/typescript/src/NativeWallet.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +13 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeWallet.ts +21 -1
- package/src/index.tsx +68 -4
package/src/index.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
/* eslint-disable @lwc/lwc/no-async-await */
|
|
2
3
|
import {NativeEventEmitter, Platform} from 'react-native';
|
|
3
4
|
import type {EmitterSubscription} from 'react-native';
|
|
@@ -11,8 +12,10 @@ import type {
|
|
|
11
12
|
IOSEncryptPayload,
|
|
12
13
|
AndroidWalletData,
|
|
13
14
|
onCardActivatedPayload,
|
|
15
|
+
onPaymentCredentialsRequestPayload,
|
|
14
16
|
IOSAddPaymentPassData,
|
|
15
17
|
TokenInfo,
|
|
18
|
+
AndroidPaymentCredentialsResponse,
|
|
16
19
|
} from './NativeWallet';
|
|
17
20
|
import {getCardState, getTokenizationStatus} from './utils';
|
|
18
21
|
import AddToWalletButton from './AddToWalletButton';
|
|
@@ -22,6 +25,25 @@ function getModuleLinkingRejection() {
|
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
let eventEmitter: NativeEventEmitter | undefined;
|
|
28
|
+
let paymentCredentialsHandler: ((data: onPaymentCredentialsRequestPayload) => Promise<AndroidPaymentCredentialsResponse>) | null = null;
|
|
29
|
+
|
|
30
|
+
if (Platform.OS === 'android' && Wallet) {
|
|
31
|
+
eventEmitter ??= new NativeEventEmitter(Wallet);
|
|
32
|
+
eventEmitter.addListener('onPaymentCredentialsRequest', async (data: onPaymentCredentialsRequestPayload) => {
|
|
33
|
+
if (!paymentCredentialsHandler) {
|
|
34
|
+
console.warn(`[${PACKAGE_NAME}] Received payment credentials request but no handler is set`);
|
|
35
|
+
await Wallet?.AndroidRejectPaymentCredentials(data.requestId, 'No payment credentials handler is set').catch(() => undefined);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const responseData = await paymentCredentialsHandler(data);
|
|
40
|
+
await Wallet?.AndroidProvidePaymentCredentials(data.requestId, responseData);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`[${PACKAGE_NAME}] Error handling payment credentials request:`, error);
|
|
43
|
+
await Wallet?.AndroidRejectPaymentCredentials(data.requestId, error instanceof Error ? error.message : String(error)).catch(() => undefined);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
25
47
|
|
|
26
48
|
function addListener(event: string, callback: (data: onCardActivatedPayload) => void): EmitterSubscription {
|
|
27
49
|
if (!Wallet) {
|
|
@@ -84,7 +106,30 @@ async function getCardStatusByIdentifier(identifier: string, tsp: string): Promi
|
|
|
84
106
|
return getCardState(tokenState);
|
|
85
107
|
}
|
|
86
108
|
|
|
87
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Checks whether the card can still be added to a Google Wallet target: the phone or a paired wearable.
|
|
111
|
+
* Use it to decide whether to show the "Add to Google Wallet" button when wearables are supported.
|
|
112
|
+
* @param last4Digits - The last 4 digits of the card number (FPAN, not the token)
|
|
113
|
+
* @param network - The card network, e.g. `VISA`, `MASTERCARD`
|
|
114
|
+
* @param issuerName - The issuer name used for matching, as in the token metadata (not the card display name)
|
|
115
|
+
* @returns `true` if at least one target can still receive the card
|
|
116
|
+
*/
|
|
117
|
+
async function hasEligibleTokenizationTarget(last4Digits: string, network: string, issuerName: string): Promise<boolean> {
|
|
118
|
+
if (Platform.OS === 'ios') {
|
|
119
|
+
throw new Error('hasEligibleTokenizationTarget is not available on iOS');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!Wallet) {
|
|
123
|
+
return getModuleLinkingRejection();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return Wallet.hasEligibleTokenizationTarget(last4Digits, network.toUpperCase(), issuerName);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function addCardToGoogleWallet(
|
|
130
|
+
cardData: AndroidCardData,
|
|
131
|
+
handlePaymentCredentialsGeneration: (data: onPaymentCredentialsRequestPayload) => Promise<AndroidPaymentCredentialsResponse>,
|
|
132
|
+
): Promise<TokenizationStatus> {
|
|
88
133
|
if (Platform.OS === 'ios') {
|
|
89
134
|
throw new Error('addCardToGoogleWallet is not available on iOS');
|
|
90
135
|
}
|
|
@@ -96,8 +141,14 @@ async function addCardToGoogleWallet(cardData: AndroidCardData): Promise<Tokeniz
|
|
|
96
141
|
if (!isWalletInitialized) {
|
|
97
142
|
throw new Error('Wallet could not be initialized');
|
|
98
143
|
}
|
|
99
|
-
|
|
100
|
-
|
|
144
|
+
|
|
145
|
+
paymentCredentialsHandler = handlePaymentCredentialsGeneration;
|
|
146
|
+
try {
|
|
147
|
+
const tokenizationStatus = await Wallet.addCardToGoogleWallet(cardData);
|
|
148
|
+
return getTokenizationStatus(tokenizationStatus);
|
|
149
|
+
} finally {
|
|
150
|
+
paymentCredentialsHandler = null;
|
|
151
|
+
}
|
|
101
152
|
}
|
|
102
153
|
|
|
103
154
|
async function resumeAddCardToGoogleWallet(cardData: AndroidResumeCardData): Promise<TokenizationStatus> {
|
|
@@ -164,13 +215,26 @@ async function addCardToAppleWallet(
|
|
|
164
215
|
return getTokenizationStatus(status);
|
|
165
216
|
}
|
|
166
217
|
|
|
167
|
-
export type {
|
|
218
|
+
export type {
|
|
219
|
+
AndroidCardData,
|
|
220
|
+
AndroidWalletData,
|
|
221
|
+
CardStatus,
|
|
222
|
+
IOSEncryptPayload,
|
|
223
|
+
IOSCardData,
|
|
224
|
+
IOSAddPaymentPassData,
|
|
225
|
+
onCardActivatedPayload,
|
|
226
|
+
onPaymentCredentialsRequestPayload,
|
|
227
|
+
TokenizationStatus,
|
|
228
|
+
TokenInfo,
|
|
229
|
+
AndroidPaymentCredentialsResponse,
|
|
230
|
+
};
|
|
168
231
|
export {
|
|
169
232
|
AddToWalletButton,
|
|
170
233
|
checkWalletAvailability,
|
|
171
234
|
getSecureWalletInfo,
|
|
172
235
|
getCardStatusBySuffix,
|
|
173
236
|
getCardStatusByIdentifier,
|
|
237
|
+
hasEligibleTokenizationTarget,
|
|
174
238
|
addCardToGoogleWallet,
|
|
175
239
|
resumeAddCardToGoogleWallet,
|
|
176
240
|
listTokens,
|