Skip to content

Commit

Permalink
[FIX] Swaps approval transaction (#4263)
Browse files Browse the repository at this point in the history
  • Loading branch information
gantunesr authored Jul 8, 2022
1 parent 79a5293 commit 3b6268b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React, { useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, TouchableOpacity, TextInput } from 'react-native';
import React, { useCallback, useEffect, useState } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
TextInput,
} from 'react-native';
import { fontStyles } from '../../../../styles/common';
import Text from '../../../Base/Text';
import StyledButton from '../../StyledButton';
import { strings } from '../../../../../locales/i18n';
import { isNumber } from '../../../../util/number';
import ConnectHeader from '../../ConnectHeader';
import Device from '../../../../util/device';
import ErrorMessage from '../../../Views/SendFlow/ErrorMessage';
import { useAppThemeFromContext, mockTheme } from '../../../../util/theme';
import formatNumber from '../../../../util/formatNumber';
import { INTEGER_OR_FLOAT_REGEX } from '../../../../util/number';

const createStyles = (colors) =>
const createStyles = (colors: any) =>
StyleSheet.create({
wrapper: {
paddingHorizontal: 24,
Expand Down Expand Up @@ -99,6 +103,20 @@ const createStyles = (colors) =>
},
});

interface IEditPermissionProps {
host: string;
minimumSpendLimit: string;
spendLimitUnlimitedSelected: boolean;
tokenSymbol: string;
spendLimitCustomValue: string;
originalApproveAmount: string;
onSetApprovalAmount: () => void;
onSpendLimitCustomValueChange: (approvalCustomValue: string) => void;
onPressSpendLimitUnlimitedSelected: () => void;
onPressSpendLimitCustomSelected: () => void;
toggleEditPermission: () => void;
}

function EditPermission({
host,
minimumSpendLimit,
Expand All @@ -111,21 +129,25 @@ function EditPermission({
onPressSpendLimitUnlimitedSelected,
onPressSpendLimitCustomSelected,
toggleEditPermission,
}) {
}: IEditPermissionProps) {
const [initialState] = useState({
spendLimitUnlimitedSelected,
spendLimitCustomValue,
});
const [disableBtn, setDisableBtn] = useState(false);
const [displayErrorMsg, setDisplayErrorMsg] = useState(false);
const { colors, themeAppearance } = useAppThemeFromContext() || mockTheme;
const styles = createStyles(colors);

const displayErrorMessage = useMemo(
() =>
(!spendLimitUnlimitedSelected &&
!INTEGER_OR_FLOAT_REGEX.test(spendLimitCustomValue)) ||
Number(minimumSpendLimit) > spendLimitCustomValue,
[spendLimitUnlimitedSelected, spendLimitCustomValue, minimumSpendLimit],
);
useEffect(() => {
setDisplayErrorMsg(
Number(minimumSpendLimit) > Number(spendLimitCustomValue),
);
}, [minimumSpendLimit, spendLimitCustomValue, spendLimitUnlimitedSelected]);

useEffect(() => {
setDisableBtn(!isNumber(spendLimitCustomValue) || displayErrorMsg);
}, [spendLimitCustomValue, displayErrorMsg]);

const onSetApprovalAmount = useCallback(() => {
if (!spendLimitUnlimitedSelected && !spendLimitCustomValue) {
Expand All @@ -141,13 +163,12 @@ function EditPermission({
]);

const onBackPress = useCallback(() => {
const { spendLimitUnlimitedSelected, spendLimitCustomValue } = initialState;
if (spendLimitUnlimitedSelected) {
if (initialState.spendLimitUnlimitedSelected) {
onPressSpendLimitUnlimitedSelected();
} else {
onPressSpendLimitCustomSelected();
}
onSpendLimitCustomValueChange(spendLimitCustomValue);
onSpendLimitCustomValueChange(initialState.spendLimitCustomValue);
toggleEditPermission();
}, [
initialState,
Expand Down Expand Up @@ -249,7 +270,7 @@ function EditPermission({
returnKeyType={'done'}
keyboardAppearance={themeAppearance}
/>
{displayErrorMessage && (
{displayErrorMsg && (
<View style={styles.errorMessageWrapper}>
<ErrorMessage
errorMessage={strings(
Expand All @@ -265,7 +286,7 @@ function EditPermission({
</View>
</View>
<StyledButton
disabled={displayErrorMessage}
disabled={disableBtn}
type="confirm"
onPress={onSetApprovalAmount}
>
Expand All @@ -275,18 +296,4 @@ function EditPermission({
);
}

EditPermission.propTypes = {
host: PropTypes.string.isRequired,
minimumSpendLimit: PropTypes.string,
spendLimitUnlimitedSelected: PropTypes.bool.isRequired,
tokenSymbol: PropTypes.string.isRequired,
spendLimitCustomValue: PropTypes.string.isRequired,
originalApproveAmount: PropTypes.string.isRequired,
onPressSpendLimitUnlimitedSelected: PropTypes.func.isRequired,
onPressSpendLimitCustomSelected: PropTypes.func.isRequired,
onSpendLimitCustomValueChange: PropTypes.func.isRequired,
onSetApprovalAmount: PropTypes.func.isRequired,
toggleEditPermission: PropTypes.func.isRequired,
};

export default EditPermission;
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ function ApprovalTransactionEditionModal({
chainId,
}) {
/* Approval transaction if any */
const [customApprovalTransaction, setCustomApprovalTransaction] =
useState(approvalTransaction);
const [approvalTransactionAmount, setApprovalTransactionAmount] =
useState('');
const [approvalCustomValue, setApprovalCustomValue] =
Expand All @@ -49,10 +51,12 @@ function ApprovalTransactionEditionModal({
(approvalCustomValue) => setApprovalCustomValue(approvalCustomValue),
[],
);

const onPressSpendLimitUnlimitedSelected = useCallback(
() => setSpendLimitUnlimitedSelected(true),
[],
);

const onPressSpendLimitCustomSelected = useCallback(
() => setSpendLimitUnlimitedSelected(false),
[],
Expand All @@ -66,8 +70,9 @@ function ApprovalTransactionEditionModal({
: approvalCustomValue,
sourceToken.decimals,
swapsUtils.getSwapsContractAddress(chainId),
approvalTransaction,
customApprovalTransaction,
);
setCustomApprovalTransaction(newApprovalTransaction);
setApprovalTransaction(newApprovalTransaction);
onCancelEditQuoteTransactions();
} catch (err) {
Expand All @@ -78,27 +83,32 @@ function ApprovalTransactionEditionModal({
spendLimitUnlimitedSelected,
approvalTransactionAmount,
approvalCustomValue,
approvalTransaction,
customApprovalTransaction,
sourceToken,
chainId,
onCancelEditQuoteTransactions,
]);

useEffect(() => {
setApprovalTransaction(originalApprovalTransaction);
if (originalApprovalTransaction) {
const newApprovalTx = spendLimitUnlimitedSelected
? originalApprovalTransaction
: customApprovalTransaction;
setApprovalTransaction(newApprovalTx);
if (newApprovalTx) {
const approvalTransactionAmount = decodeApproveData(
originalApprovalTransaction.data,
newApprovalTx.data,
).encodedAmount;
const amountDec = hexToBN(approvalTransactionAmount).toString(10);
setApprovalTransactionAmount(
fromTokenMinimalUnitString(amountDec, sourceToken.decimals),
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
originalApprovalTransaction,
sourceToken.decimals,
setApprovalTransaction,
spendLimitUnlimitedSelected,
customApprovalTransaction,
]);

return (
Expand All @@ -120,7 +130,7 @@ function ApprovalTransactionEditionModal({
<KeyboardAwareScrollView
contentContainerStyle={styles.keyboardAwareWrapper}
>
{Boolean(approvalTransaction) && (
{Boolean(customApprovalTransaction) && (
<EditPermission
host={'Swaps'}
minimumSpendLimit={minimumSpendLimit}
Expand Down
10 changes: 10 additions & 0 deletions app/util/number/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,16 @@ export function toBN(value) {
return new BN(value);
}

/**
* Determines if a string is a valid number
*
* @param {*} str - Number string
* @returns {boolean} - True if the string is a valid number
*/
export function isNumber(str) {
return /^(\d+(\.\d+)?)$/.test(str);
}

/**
* Converts some unit to wei
*
Expand Down
26 changes: 26 additions & 0 deletions app/util/number/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
toHexadecimal,
safeNumberToBN,
fastSplit,
isNumber,
} from '.';

describe('Number utils :: BNToHex', () => {
Expand Down Expand Up @@ -489,3 +490,28 @@ describe('Number utils :: fastSplit', () => {
expect(fastSplit('test string', ' ')).toEqual('test');
});
});

describe('Number utils :: isNumber', () => {
it('should be a valid number ', () => {
expect(isNumber('1650.7')).toBe(true);
expect(isNumber('1000')).toBe(true);
expect(isNumber('0.0001')).toBe(true);
expect(isNumber('0001')).toBe(true);
expect(isNumber('1')).toBe(true);
});

it('should not be a valid number ', () => {
expect(isNumber('..7')).toBe(false);
expect(isNumber('1..1')).toBe(false);
expect(isNumber('0..')).toBe(false);
expect(isNumber('a.0001')).toBe(false);
expect(isNumber('00a01')).toBe(false);
expect(isNumber('1,.')).toBe(false);
expect(isNumber('1,')).toBe(false);
expect(isNumber('.')).toBe(false);
expect(isNumber('a¡1')).toBe(false);
expect(isNumber('.01')).toBe(false);
expect(isNumber(undefined)).toBe(false);
expect(isNumber(null)).toBe(false);
});
});

0 comments on commit 3b6268b

Please sign in to comment.