react-native-unit-components
Version:
Unit React Native components
108 lines (106 loc) • 4.15 kB
JavaScript
import { useEffect, useState, useRef } from 'react';
import { UNWalletCode, UNWalletName } from '../../../types/shared/wallet.types';
import { UnitComponentsSDK } from '../../../unitComponentsSdkManager/UnitComponentsSdkManager';
import { getMobileWalletPayload } from '../../../networking/requests/UNWalletPayloadRequest';
import { useSelector, useDispatch } from 'react-redux';
import { selectWallet, setSignedNonce } from '../../../slices/pushProvisioningSlice';
import { useLaunchInitialize } from './useLaunchInitialize';
import { UNVPErrorType } from '../types';
import { promiseRejectToUNVPErrorType } from '../helpers';
import { UNComponentsErrorCodes } from '../../../types/shared/error.types';
import { isUNComponentsError } from '../../../types/internal/errorHelpers';
export const useCardWallet = cardId => {
const [currentUNWallet, setCurrentUNWallet] = useState();
const {
signedNonce
} = useSelector(selectWallet);
const {
initializePushProvisioning
} = useLaunchInitialize();
const dispatch = useDispatch();
const isRecoveringSignedNonceRef = useRef(false);
const customerToken = useSelector(state => state.configuration.customerToken);
const shouldRecoverVPSDKForError = errorType => {
const recoveringTypes = [UNVPErrorType.PayloadDecryptionFailed, UNVPErrorType.SessionExpired, UNVPErrorType.InvalidNonce];
return recoveringTypes.includes(errorType);
};
useEffect(() => {
const getEncryptedPayload = async () => {
const env = UnitComponentsSDK.getEnv();
if (!env || !customerToken) return;
// In case we use flow
if (!signedNonce) {
await initializePushProvisioning();
return;
}
const encryptedPayload = await getMobileWalletPayload(customerToken, cardId, env, signedNonce);
return encryptedPayload;
};
const getCardWalletData = async () => {
const currentProvisioningModule = UnitComponentsSDK.getPushProvisionModule();
if (!currentProvisioningModule) return;
try {
const encryptedPayload = await getEncryptedPayload();
if (!encryptedPayload) return;
const walletsResponse = await currentProvisioningModule.launchGetWallets(JSON.stringify({
encPayload: encryptedPayload
}));
const unWallet = parseWalletsResponse(walletsResponse);
if (!unWallet) return;
setCurrentUNWallet(unWallet);
return;
} catch (error) {
console.error('Coudln\'t get card wallet data:', error);
if (isRecoveringSignedNonceRef.current) return;
isRecoveringSignedNonceRef.current = true;
// handle unit network api errors
if (isUNComponentsError(error)) {
const errors = error.errors;
// errors will return in an array but hold only a single error element
if (errors[0]?.code === UNComponentsErrorCodes.INVALID_NONCE) {
dispatch(setSignedNonce(null));
}
return;
}
// handle VDE SDK errors
const errorType = promiseRejectToUNVPErrorType(error);
if (!errorType) return;
if (shouldRecoverVPSDKForError(errorType)) {
dispatch(setSignedNonce(null));
return;
}
}
};
getCardWalletData();
}, [signedNonce, cardId, customerToken]);
return {
currentUNWallet
};
};
const parseWalletsResponse = walletsResponse => {
try {
const parsedWalletsResponse = JSON.parse(walletsResponse);
const wallets = parsedWalletsResponse.wallets;
if (!wallets) return null;
if (wallets[0].code === UNWalletCode.Apple) {
return {
name: UNWalletName.Apple,
code: UNWalletCode.Apple,
status: wallets[0].status
};
} else {
const googleWallet = wallets.filter(wallet => {
return wallet.name === UNWalletName.Google;
});
if (!googleWallet) return null;
return {
name: UNWalletName.Google,
code: UNWalletCode.Google,
status: googleWallet[0].status
};
}
} catch (error) {
throw new Error('Error parsing wallet response');
}
};
//# sourceMappingURL=useCardWallet.js.map