mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-28 01:52:56 +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 { deepLinkParser } from '../../utils/deepLinkParser';
|
||||||
import RootNavigation from '../../navigation/rootNavigation';
|
import RootNavigation from '../../navigation/rootNavigation';
|
||||||
import getWindowDimensions from '../../utils/getWindowDimensions';
|
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 { handleHiveUriOperation, resolveTransaction } from '../../providers/hive/dhive';
|
||||||
import bugsnagInstance from '../../config/bugsnag';
|
import bugsnagInstance from '../../config/bugsnag';
|
||||||
import { get, isArray } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import showLoginAlert from '../../utils/showLoginAlert';
|
import showLoginAlert from '../../utils/showLoginAlert';
|
||||||
import authType from '../../constants/authType';
|
import authType from '../../constants/authType';
|
||||||
import { delay } from '../../utils/editor';
|
import { delay } from '../../utils/editor';
|
||||||
@ -162,66 +162,64 @@ export const QRModal = ({}: QRModalProps) => {
|
|||||||
authoritiesMap.set('owner', currentAccount?.local?.ownerKey ? true : false);
|
authoritiesMap.set('owner', currentAccount?.local?.ownerKey ? true : false);
|
||||||
authoritiesMap.set('memo', currentAccount?.local?.memoKey ? true : false);
|
authoritiesMap.set('memo', currentAccount?.local?.memoKey ? true : false);
|
||||||
|
|
||||||
const parsedHiveUriValidation = validateParsedHiveUri(parsed, authoritiesMap);
|
getFormattedTx(parsed.tx, authoritiesMap)
|
||||||
if (parsedHiveUriValidation.error) {
|
.then(async (formattedTx) => {
|
||||||
// show alert to user if parsed uri contains invalid operation data
|
// resolve the decoded tx and params to a signable tx
|
||||||
Alert.alert(
|
const tx = await resolveTransaction(formattedTx.tx, parsed.params, currentAccount.name);
|
||||||
intl.formatMessage(
|
const ops = get(tx, 'operations', []);
|
||||||
{ id: parsedHiveUriValidation.key1 },
|
const op = ops[0];
|
||||||
{ 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];
|
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
showActionModal({
|
showActionModal({
|
||||||
title: intl.formatMessage({
|
title: intl.formatMessage({
|
||||||
id: 'qr.confirmTransaction',
|
id: 'qr.confirmTransaction',
|
||||||
}),
|
|
||||||
bodyContent: _renderActionModalBody(op, parsedHiveUriValidation.opName),
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: intl.formatMessage({
|
|
||||||
id: 'qr.cancel',
|
|
||||||
}),
|
}),
|
||||||
onPress: () => {},
|
bodyContent: _renderActionModalBody(op, formattedTx.opName),
|
||||||
style: 'cancel',
|
buttons: [
|
||||||
},
|
{
|
||||||
{
|
text: intl.formatMessage({
|
||||||
text: intl.formatMessage({
|
id: 'qr.cancel',
|
||||||
id: 'qr.approve',
|
}),
|
||||||
}),
|
onPress: () => {},
|
||||||
onPress: () => {
|
style: 'cancel',
|
||||||
handleHiveUriOperation(currentAccount, pinCode, tx)
|
},
|
||||||
.then(() => {
|
{
|
||||||
dispatch(toastNotification(intl.formatMessage({ id: 'alert.successful' })));
|
text: intl.formatMessage({
|
||||||
})
|
id: 'qr.approve',
|
||||||
.catch((err) => {
|
}),
|
||||||
bugsnagInstance.notify(err);
|
onPress: () => {
|
||||||
if (err) {
|
handleHiveUriOperation(currentAccount, pinCode, tx)
|
||||||
dispatch(toastNotification(intl.formatMessage({ id: err })));
|
.then(() => {
|
||||||
} else {
|
dispatch(toastNotification(intl.formatMessage({ id: 'alert.successful' })));
|
||||||
dispatch(
|
})
|
||||||
toastNotification(intl.formatMessage({ id: 'qr.transaction_failed' })),
|
.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) => {
|
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
|
* Validates tx from 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
|
* Accepts tx object of 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
|
* 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>) => {
|
export const getFormattedTx = (tx: any, authoritiesMap: Map<string, boolean>) => {
|
||||||
let validateObj = {
|
let opName;
|
||||||
error: false,
|
let errorObj = {
|
||||||
key1: '',
|
errorKey1: '',
|
||||||
key2: '',
|
errorKey2: '',
|
||||||
opName: '',
|
authorityKeyType: '',
|
||||||
keyType: '',
|
|
||||||
tx: parsedUri.tx,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ops = get(parsedUri.tx, 'operations', []);
|
const ops = get(tx, 'operations', []);
|
||||||
const isValidOp = _checkOpsArray(ops);
|
const isValidOp = _checkOpsArray(ops);
|
||||||
if (!isValidOp) {
|
if (!isValidOp) {
|
||||||
validateObj.error = true;
|
errorObj.errorKey1 = 'qr.multi_array_ops_alert';
|
||||||
validateObj.key1 = 'qr.multi_array_ops_alert';
|
errorObj.errorKey2 = 'qr.multi_array_ops_aler_desct';
|
||||||
validateObj.key2 = 'qr.multi_array_ops_aler_desct';
|
return Promise.reject(errorObj);
|
||||||
return validateObj;
|
|
||||||
}
|
}
|
||||||
const op = ops[0]; // single operation
|
const op = ops[0]; // single operation
|
||||||
const operationName = op[0]; // operation name
|
const operationName = op[0]; // operation name
|
||||||
let operationObj = op[1]; // operation object
|
let operationObj = op[1]; // operation object
|
||||||
|
|
||||||
if (!operationName) {
|
if (!operationName) {
|
||||||
validateObj.error = true;
|
errorObj.errorKey1 = 'qr.invalid_op';
|
||||||
validateObj.key1 = 'qr.invalid_op';
|
errorObj.errorKey2 = 'qr.invalid_op_desc';
|
||||||
validateObj.key2 = 'qr.invalid_op_desc';
|
return Promise.reject(errorObj);
|
||||||
return validateObj;
|
|
||||||
}
|
}
|
||||||
const opProps = getOperationProps(operationName); // get operation props from operations.json file i-e signer field and operation name
|
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) {
|
if (!opProps) {
|
||||||
validateObj.error = true;
|
errorObj.errorKey1 = 'qr.invalid_op';
|
||||||
validateObj.key1 = 'qr.invalid_op';
|
errorObj.errorKey2 = 'qr.invalid_op_desc';
|
||||||
validateObj.key2 = 'qr.invalid_op_desc';
|
return Promise.reject(errorObj);
|
||||||
return validateObj;
|
|
||||||
}
|
}
|
||||||
if (authoritiesMap && !authoritiesMap.get(opProps.opAuthority)) {
|
if (authoritiesMap && !authoritiesMap.get(opProps.opAuthority)) {
|
||||||
validateObj.error = true;
|
errorObj.errorKey1 = 'qr.invalid_key';
|
||||||
validateObj.key1 = 'qr.invalid_key';
|
errorObj.errorKey2 = 'qr.invalid_key_desc';
|
||||||
validateObj.key2 = 'qr.invalid_key_desc';
|
return Promise.reject(errorObj);
|
||||||
return validateObj;
|
|
||||||
}
|
}
|
||||||
// if amount field present in operation, validate and check for proper formatting and format to 3 decimal places
|
// if amount field present in operation, validate and check for proper formatting and format to 3 decimal places
|
||||||
if (operationObj.hasOwnProperty('amount')) {
|
if (operationObj.hasOwnProperty('amount')) {
|
||||||
const amount = _formatAmount(operationObj.amount);
|
const amount = _formatAmount(operationObj.amount);
|
||||||
operationObj.amount = amount;
|
operationObj.amount = amount;
|
||||||
if (!amount) {
|
if (!amount) {
|
||||||
validateObj.error = true;
|
errorObj.errorKey1 = 'qr.invalid_amount';
|
||||||
validateObj.key1 = 'qr.invalid_amount';
|
errorObj.errorKey2 = 'qr.invalid_amount_desc';
|
||||||
validateObj.key2 = 'qr.invalid_amount_desc';
|
return Promise.reject(errorObj);
|
||||||
return validateObj;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const opSignerValue = get(op[1], opProps.signerField, '');
|
const opSignerValue = get(op[1], opProps.signerField, '');
|
||||||
// if signer field contains empty value, fill it with __signer
|
// if signer field contains empty value, fill it with __signer
|
||||||
if (!opSignerValue) {
|
if (!opSignerValue) {
|
||||||
operationObj[opProps.signerField] = '__signer';
|
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 = '';
|
opName = opProps.opName;
|
||||||
validateObj.key2 = '';
|
tx = {
|
||||||
validateObj.opName = opProps.opName;
|
...tx,
|
||||||
validateObj.tx = {
|
|
||||||
...validateObj.tx,
|
|
||||||
operations: [[operationName, operationObj]],
|
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