mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-24 00:46:27 +03:00
refactored the tx validator method
This commit is contained in:
parent
5e45fdeb69
commit
e8aafe22cc
@ -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) => {
|
||||
|
@ -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 });
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user