Skip to content

Commit

Permalink
fix: add low fee caps
Browse files Browse the repository at this point in the history
  • Loading branch information
fbwoolf committed Mar 24, 2022
1 parent b844fbe commit 7196a88
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 40 deletions.
4 changes: 3 additions & 1 deletion config/wallet-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"okcoin": { "name": "okcoin", "enabled": true }
},
"feeEstimations": {
"maxValues": [500000, 750000, 2000000],
"maxValuesEnabled": false,
"maxValues": [500000, 750000, 2000000]
"minValues": [2500, 3000, 3500],
"minValuesEnabled": true
}
}
14 changes: 14 additions & 0 deletions config/wallet-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@
"type": "number",
"description": "Fee estimation max value"
}
},
"minValuesEnabled": {
"type": "boolean",
"description": "Whether or not the minimum values are enabled"
},
"minValues": {
"type": "array",
"description": "Low, middle and high min values for fee estimations",
"minItems": 3,
"maxItems": 3,
"items": {
"type": "number",
"description": "Fee estimation min value"
}
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/app/common/transactions/use-fee-estimations-capped-values.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
useConfigFeeEstimationsMaxEnabled,
useConfigFeeEstimationsMaxValues,
useConfigFeeEstimationsMinEnabled,
useConfigFeeEstimationsMinValues,
} from '@app/query/hiro-config/hiro-config.query';

const defaultFeeEstimationsMaxValues = [500000, 750000, 2000000];
const defaultFeeEstimationsMinValues = [2500, 3000, 3500];

export function useFeeEstimationsMaxValues() {
// Get it first from the config
const configFeeEstimationsMaxEnabled = useConfigFeeEstimationsMaxEnabled();
const configFeeEstimationsMaxValues = useConfigFeeEstimationsMaxValues();
// Only when the remote config file explicitly sets the maxValuesEnabled as false, we return no max cap for fees
if (configFeeEstimationsMaxEnabled === false) return;
return configFeeEstimationsMaxValues || defaultFeeEstimationsMaxValues;
}

export function useFeeEstimationsMinValues() {
// Get it first from the config
const configFeeEstimationsMinEnabled = useConfigFeeEstimationsMinEnabled();
const configFeeEstimationsMinValues = useConfigFeeEstimationsMinValues();
// Only when the remote config file explicitly sets the minValuesEnabled as false, we return no min cap for fees
if (configFeeEstimationsMinEnabled === false) return;
return configFeeEstimationsMinValues || defaultFeeEstimationsMinValues;
}
15 changes: 0 additions & 15 deletions src/app/common/transactions/use-fee-estimations-max-values.ts

This file was deleted.

17 changes: 11 additions & 6 deletions src/app/pages/send-tokens/components/send-form-inner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ import {
import { SendFormMemoWarning } from './memo-warning';
import {
getDefaultSimulatedFeeEstimations,
getFeeEstimationsWithMaxValues,
getFeeEstimationsWithCappedValues,
} from '@shared/transactions/fee-estimations';
import { useFeeEstimationsMaxValues } from '@app/common/transactions/use-fee-estimations-max-values';
import {
useFeeEstimationsMaxValues,
useFeeEstimationsMinValues,
} from '@app/common/transactions/use-fee-estimations-capped-values';

interface SendFormInnerProps {
assetError: string | undefined;
Expand All @@ -52,6 +55,7 @@ export function SendFormInner(props: SendFormInnerProps) {

const [, setFeeEstimations] = useFeeEstimationsState();
const feeEstimationsMaxValues = useFeeEstimationsMaxValues();
const feeEstimationsMinValues = useFeeEstimationsMinValues();
const { selectedAsset } = useSelectedAsset();
const assets = useTransferableAssets();
const analytics = useAnalytics();
Expand All @@ -69,13 +73,14 @@ export function SendFormInner(props: SendFormInnerProps) {
void analytics.track('use_fee_estimation_default_simulated');
}
if (feeEstimationsResp.estimations && feeEstimationsResp.estimations.length) {
const feeEstimationsWithMaxValues = getFeeEstimationsWithMaxValues(
const feeEstimationsWithCappedValues = getFeeEstimationsWithCappedValues(
feeEstimationsResp.estimations,
feeEstimationsMaxValues
feeEstimationsMaxValues,
feeEstimationsMinValues
);
setFeeEstimations(feeEstimationsWithMaxValues);
setFeeEstimations(feeEstimationsWithCappedValues);
void analytics.track('use_fee_estimation', {
maxValues: feeEstimationsWithMaxValues,
cappedValues: feeEstimationsWithCappedValues,
estimations: feeEstimationsResp.estimations,
});
}
Expand Down
17 changes: 11 additions & 6 deletions src/app/pages/transaction-request/components/fee-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ import { useFeeEstimationsState } from '@app/store/transactions/fees.hooks';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import {
getDefaultSimulatedFeeEstimations,
getFeeEstimationsWithMaxValues,
getFeeEstimationsWithCappedValues,
} from '@shared/transactions/fee-estimations';
import { useFeeEstimationsMaxValues } from '@app/common/transactions/use-fee-estimations-max-values';
import {
useFeeEstimationsMaxValues,
useFeeEstimationsMinValues,
} from '@app/common/transactions/use-fee-estimations-capped-values';

export function FeeForm(): JSX.Element | null {
const analytics = useAnalytics();
Expand All @@ -34,6 +37,7 @@ export function FeeForm(): JSX.Element | null {

const [, setFeeEstimations] = useFeeEstimationsState();
const feeEstimationsMaxValues = useFeeEstimationsMaxValues();
const feeEstimationsMinValues = useFeeEstimationsMinValues();

useEffect(() => {
if (feeEstimationsResp) {
Expand All @@ -45,13 +49,14 @@ export function FeeForm(): JSX.Element | null {
void analytics.track('use_fee_estimation_default_simulated');
}
if (feeEstimationsResp.estimations && feeEstimationsResp.estimations.length) {
const feeEstimationsWithMaxValues = getFeeEstimationsWithMaxValues(
const feeEstimationsWithCappedValues = getFeeEstimationsWithCappedValues(
feeEstimationsResp.estimations,
feeEstimationsMaxValues
feeEstimationsMaxValues,
feeEstimationsMinValues
);
setFeeEstimations(feeEstimationsWithMaxValues);
setFeeEstimations(feeEstimationsWithCappedValues);
void analytics.track('use_fee_estimation', {
maxValues: feeEstimationsWithMaxValues,
cappedValues: feeEstimationsWithCappedValues,
estimations: feeEstimationsResp.estimations,
});
}
Expand Down
34 changes: 25 additions & 9 deletions src/app/query/hiro-config/hiro-config.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ interface ActiveFiatProviderType {
}

interface FeeEstimationsConfig {
maxValuesEnabled?: boolean;
maxValues?: number[];
maxValuesEnabled?: boolean;
minValues?: number[];
minValuesEnabled?: boolean;
}

interface HiroConfig {
messages: any;
activeFiatProviders?: Record<string, ActiveFiatProviderType>;
feeEstimations?: FeeEstimationsConfig;
feeEstimationsMinMax?: FeeEstimationsConfig;
}

const GITHUB_PRIMARY_BRANCH = 'main';
Expand Down Expand Up @@ -69,16 +71,30 @@ export function useHasFiatProviders() {
);
}

export function useConfigFeeEstimationsEnabled() {
export function useConfigFeeEstimationsMaxEnabled() {
const config = useRemoteHiroConfig();
if (isUndefined(config) || isUndefined(config?.feeEstimations)) return;
return config.feeEstimations.maxValuesEnabled;
if (isUndefined(config) || isUndefined(config?.feeEstimationsMinMax)) return;
return config.feeEstimationsMinMax.maxValuesEnabled;
}

export function useConfigFeeEstimationsMaxValues() {
const config = useRemoteHiroConfig();
if (typeof config?.feeEstimations === 'undefined') return;
if (!config.feeEstimations.maxValues) return;
if (!Array.isArray(config.feeEstimations.maxValues)) return;
return config.feeEstimations.maxValues;
if (typeof config?.feeEstimationsMinMax === 'undefined') return;
if (!config.feeEstimationsMinMax.maxValues) return;
if (!Array.isArray(config.feeEstimationsMinMax.maxValues)) return;
return config.feeEstimationsMinMax.maxValues;
}

export function useConfigFeeEstimationsMinEnabled() {
const config = useRemoteHiroConfig();
if (isUndefined(config) || isUndefined(config?.feeEstimationsMinMax)) return;
return config.feeEstimationsMinMax.minValuesEnabled;
}

export function useConfigFeeEstimationsMinValues() {
const config = useRemoteHiroConfig();
if (typeof config?.feeEstimationsMinMax === 'undefined') return;
if (!config.feeEstimationsMinMax.minValues) return;
if (!Array.isArray(config.feeEstimationsMinMax.minValues)) return;
return config.feeEstimationsMinMax.minValues;
}
13 changes: 10 additions & 3 deletions src/shared/transactions/fee-estimations.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { BigNumber } from 'bignumber.js';

import { DEFAULT_FEE_RATE } from '@shared/constants';
import { FeeEstimation } from '@shared/models/fees-types';
import { BigNumber } from 'bignumber.js';

export function getFeeEstimationsWithMaxValues(
export function getFeeEstimationsWithCappedValues(
feeEstimations: FeeEstimation[],
feeEstimationsMaxValues: number[] | undefined
feeEstimationsMaxValues: number[] | undefined,
feeEstimationsMinValues: number[] | undefined
) {
return feeEstimations.map((feeEstimation, index) => {
if (
feeEstimationsMaxValues &&
new BigNumber(feeEstimation.fee).isGreaterThan(feeEstimationsMaxValues[index])
) {
return { fee: feeEstimationsMaxValues[index], fee_rate: 0 };
} else if (
feeEstimationsMinValues &&
new BigNumber(feeEstimation.fee).isLessThan(feeEstimationsMinValues[index])
) {
return { fee: feeEstimationsMinValues[index], fee_rate: 0 };
} else {
return feeEstimation;
}
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/send-tokens/send-tokens.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UserAreaSelectors } from '@tests/integration/user-area.selectors';
import { SendPage } from '../../page-objects/send-form.page';
import { WalletPage } from '../../page-objects/wallet.page';
import { BrowserDriver, createTestSelector, setupBrowser } from '../utils';
import { SettingsSelectors } from '../settings.selectors';

jest.setTimeout(120_000);
jest.retryTimes(process.env.CI ? 2 : 0);
Expand Down Expand Up @@ -42,6 +43,9 @@ describe(`Send tokens flow`, () => {

describe('Set max button', () => {
it('does not set a fee below zero, when the account balance is 0 STX', async () => {
await walletPage.clickSettingsButton();
await walletPage.page.click(createTestSelector(SettingsSelectors.SwitchAccount));
await walletPage.page.click(createTestSelector('switch-account-item-1'));
await sendForm.clickSendMaxBtn();
const amount = await sendForm.getAmountFieldValue();
expect(amount).toEqual('');
Expand Down

0 comments on commit 7196a88

Please sign in to comment.