refactored the tx validator method

This commit is contained in:
Sadaqat Ali 2023-09-27 15:06:41 +05:00
parent 5e45fdeb69
commit e8aafe22cc
2 changed files with 89 additions and 108 deletions

View File

@ -16,10 +16,10 @@ import {
import { deepLinkParser } from '../../utils/deepLinkParser';
import RootNavigation from '../../navigation/rootNavigation';
import getWindowDimensions from '../../utils/getWindowDimensions';
import { isHiveUri, validateParsedHiveUri } from '../../utils/hive-uri';
import { isHiveUri, getFormattedTx } from '../../utils/hive-uri';
import { handleHiveUriOperation, resolveTransaction } from '../../providers/hive/dhive';
import bugsnagInstance from '../../config/bugsnag';
import { get, isArray } from 'lodash';
import { get } from 'lodash';
import showLoginAlert from '../../utils/showLoginAlert';
import authType from '../../constants/authType';
import { delay } from '../../utils/editor';
@ -162,66 +162,64 @@ export const QRModal = ({}: QRModalProps) => {
authoritiesMap.set('owner', currentAccount?.local?.ownerKey ? true : false);
authoritiesMap.set('memo', currentAccount?.local?.memoKey ? true : false);
const parsedHiveUriValidation = validateParsedHiveUri(parsed, authoritiesMap);
if (parsedHiveUriValidation.error) {
// show alert to user if parsed uri contains invalid operation data
Alert.alert(
intl.formatMessage(
{ id: parsedHiveUriValidation.key1 },
{ key: parsedHiveUriValidation.keyType },
),
intl.formatMessage(
{
id: parsedHiveUriValidation.key2,
},
{ key: parsedHiveUriValidation.keyType },
),
);
return;
}
// resolve the decoded tx and params to a signable tx
const tx = await resolveTransaction(parsed.tx, parsed.params, currentAccount.name);
const ops = get(tx, 'operations', []);
const op = ops[0];
getFormattedTx(parsed.tx, authoritiesMap)
.then(async (formattedTx) => {
// resolve the decoded tx and params to a signable tx
const tx = await resolveTransaction(formattedTx.tx, parsed.params, currentAccount.name);
const ops = get(tx, 'operations', []);
const op = ops[0];
dispatch(
showActionModal({
title: intl.formatMessage({
id: 'qr.confirmTransaction',
}),
bodyContent: _renderActionModalBody(op, parsedHiveUriValidation.opName),
buttons: [
{
text: intl.formatMessage({
id: 'qr.cancel',
dispatch(
showActionModal({
title: intl.formatMessage({
id: 'qr.confirmTransaction',
}),
onPress: () => {},
style: 'cancel',
},
{
text: intl.formatMessage({
id: 'qr.approve',
}),
onPress: () => {
handleHiveUriOperation(currentAccount, pinCode, tx)
.then(() => {
dispatch(toastNotification(intl.formatMessage({ id: 'alert.successful' })));
})
.catch((err) => {
bugsnagInstance.notify(err);
if (err) {
dispatch(toastNotification(intl.formatMessage({ id: err })));
} else {
dispatch(
toastNotification(intl.formatMessage({ id: 'qr.transaction_failed' })),
);
}
});
bodyContent: _renderActionModalBody(op, formattedTx.opName),
buttons: [
{
text: intl.formatMessage({
id: 'qr.cancel',
}),
onPress: () => {},
style: 'cancel',
},
{
text: intl.formatMessage({
id: 'qr.approve',
}),
onPress: () => {
handleHiveUriOperation(currentAccount, pinCode, tx)
.then(() => {
dispatch(toastNotification(intl.formatMessage({ id: 'alert.successful' })));
})
.catch((err) => {
bugsnagInstance.notify(err);
if (err) {
dispatch(toastNotification(intl.formatMessage({ id: err })));
} else {
dispatch(
toastNotification(intl.formatMessage({ id: 'qr.transaction_failed' })),
);
}
});
},
},
],
}),
);
})
.catch((errObj) => {
Alert.alert(
intl.formatMessage({ id: errObj.errorKey1 }, { key: errObj.authorityKeyType }),
intl.formatMessage(
{
id: errObj.errorKey2,
},
},
],
}),
);
{ key: errObj.authorityKeyType },
),
);
return;
});
};
const _handleDeepLink = async (url) => {

View File

@ -61,86 +61,69 @@ const _formatAmount = (amount: string) => {
};
/**
* Validates parsed data from hive-uri, checks if operation length is not greater than one and __signer is present in operation
* Accepts parsed uri from decode method of hive-uri
* Returns an object with error status, keys for showing errors, and operation name parsed from operations.json
* Validates tx from parsed data from hive-uri, checks if operation length is not greater than one and __signer is present in operation
* Accepts tx object of parsed uri from decode method of hive-uri
* Returns promise with keys for showing errors, and operation name parsed from operations.json and in case of success returns formatted tx
*
* */
export const validateParsedHiveUri = (parsedUri: any, authoritiesMap: Map<string, boolean>) => {
let validateObj = {
error: false,
key1: '',
key2: '',
opName: '',
keyType: '',
tx: parsedUri.tx,
export const getFormattedTx = (tx: any, authoritiesMap: Map<string, boolean>) => {
let opName;
let errorObj = {
errorKey1: '',
errorKey2: '',
authorityKeyType: '',
};
const ops = get(parsedUri.tx, 'operations', []);
const ops = get(tx, 'operations', []);
const isValidOp = _checkOpsArray(ops);
if (!isValidOp) {
validateObj.error = true;
validateObj.key1 = 'qr.multi_array_ops_alert';
validateObj.key2 = 'qr.multi_array_ops_aler_desct';
return validateObj;
errorObj.errorKey1 = 'qr.multi_array_ops_alert';
errorObj.errorKey2 = 'qr.multi_array_ops_aler_desct';
return Promise.reject(errorObj);
}
const op = ops[0]; // single operation
const operationName = op[0]; // operation name
let operationObj = op[1]; // operation object
if (!operationName) {
validateObj.error = true;
validateObj.key1 = 'qr.invalid_op';
validateObj.key2 = 'qr.invalid_op_desc';
return validateObj;
errorObj.errorKey1 = 'qr.invalid_op';
errorObj.errorKey2 = 'qr.invalid_op_desc';
return Promise.reject(errorObj);
}
const opProps = getOperationProps(operationName); // get operation props from operations.json file i-e signer field and operation name
validateObj.keyType = opProps?.opAuthority || ''; // set key type to validate object
errorObj.authorityKeyType = opProps?.opAuthority || ''; // set key type to validate object
if (!opProps) {
validateObj.error = true;
validateObj.key1 = 'qr.invalid_op';
validateObj.key2 = 'qr.invalid_op_desc';
return validateObj;
errorObj.errorKey1 = 'qr.invalid_op';
errorObj.errorKey2 = 'qr.invalid_op_desc';
return Promise.reject(errorObj);
}
if (authoritiesMap && !authoritiesMap.get(opProps.opAuthority)) {
validateObj.error = true;
validateObj.key1 = 'qr.invalid_key';
validateObj.key2 = 'qr.invalid_key_desc';
return validateObj;
errorObj.errorKey1 = 'qr.invalid_key';
errorObj.errorKey2 = 'qr.invalid_key_desc';
return Promise.reject(errorObj);
}
// if amount field present in operation, validate and check for proper formatting and format to 3 decimal places
if (operationObj.hasOwnProperty('amount')) {
const amount = _formatAmount(operationObj.amount);
operationObj.amount = amount;
if (!amount) {
validateObj.error = true;
validateObj.key1 = 'qr.invalid_amount';
validateObj.key2 = 'qr.invalid_amount_desc';
return validateObj;
errorObj.errorKey1 = 'qr.invalid_amount';
errorObj.errorKey2 = 'qr.invalid_amount_desc';
return Promise.reject(errorObj);
}
}
const opSignerValue = get(op[1], opProps.signerField, '');
// if signer field contains empty value, fill it with __signer
if (!opSignerValue) {
operationObj[opProps.signerField] = '__signer';
validateObj.error = false;
validateObj.key1 = '';
validateObj.key2 = '';
validateObj.opName = opProps.opName;
validateObj.tx = {
...validateObj.tx,
operations: [[operationName, operationObj]],
};
return validateObj;
}
validateObj.error = false;
validateObj.key1 = '';
validateObj.key2 = '';
validateObj.opName = opProps.opName;
validateObj.tx = {
...validateObj.tx,
opName = opProps.opName;
tx = {
...tx,
operations: [[operationName, operationObj]],
};
return validateObj;
// resolve with formatted tx and opName
return Promise.resolve({ tx: tx, opName: opName });
};