Skip to content

Commit 1773ad0

Browse files
committed
feat(suite-native): add eip1559 standard fee options
1 parent efd52c4 commit 1773ad0

File tree

18 files changed

+80
-72
lines changed

18 files changed

+80
-72
lines changed

suite-common/wallet-core/src/fees/feesReducer.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createReducer } from '@reduxjs/toolkit';
22

33
import { createWeakMapSelector } from '@suite-common/redux-utils';
4-
import { formatDuration } from '@suite-common/suite-utils';
4+
import { formatDurationStrict } from '@suite-common/suite-utils';
55
import { NetworkSymbol, getNetworkType } from '@suite-common/wallet-config';
66
import { FeeInfo, FeeLevelLabel, FeesState, FeesStatus } from '@suite-common/wallet-types';
77
import { getConvertedOrDefaultFeeInfo } from '@suite-common/wallet-utils';
@@ -96,11 +96,19 @@ export const selectNetworkFeeLevel = createMemoizedSelector(
9696
);
9797

9898
export const selectConvertedNetworkFeeLevelTimeEstimate = createMemoizedSelector(
99-
[selectConvertedNetworkFeeInfo, selectNetworkFeeLevel],
100-
(networkFeeInfo, feeLevel): string | null => {
99+
[
100+
selectConvertedNetworkFeeInfo,
101+
selectNetworkFeeLevel,
102+
(_state: FeesRootState, symbol?: NetworkSymbol) => symbol,
103+
],
104+
(networkFeeInfo, feeLevel, symbol): string | null => {
101105
if (!feeLevel || !networkFeeInfo) return null;
102106

103-
return formatDuration(networkFeeInfo.blockTime * feeLevel.blocks * 60);
107+
const networkType = symbol ? getNetworkType(symbol) : null;
108+
109+
const multiplier = networkType === 'bitcoin' ? 60 : 1;
110+
111+
return formatDurationStrict(networkFeeInfo.blockTime * feeLevel.blocks * multiplier);
104112
},
105113
);
106114

suite-native/module-send/src/components/SendFeesForm.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
55
import { useNavigation } from '@react-navigation/native';
66

77
import { SendRootState, selectSendFormDraftByKey } from '@suite-common/wallet-core';
8-
import { AccountKey, TokenAddress } from '@suite-common/wallet-types';
8+
import { AccountKey, FeeLevelLabel, TokenAddress } from '@suite-common/wallet-types';
99
import { VStack } from '@suite-native/atoms';
1010
import { Form } from '@suite-native/forms';
1111
import {
@@ -21,7 +21,6 @@ import {
2121
FeesContent,
2222
FeesFooter,
2323
NativeSendRootState,
24-
NativeSupportedFeeLevel,
2524
useFeesManagement,
2625
} from '@suite-native/transaction-management';
2726

@@ -69,7 +68,7 @@ export const SendFeesForm = ({ accountKey, tokenContract }: SendFormProps) => {
6968
accountKey,
7069
tokenContract,
7170
updateThunk: updateSelectedFeeLevelThunk,
72-
selectedFee: formDraft?.selectedFee as NativeSupportedFeeLevel,
71+
selectedFee: formDraft?.selectedFee as FeeLevelLabel,
7372
selectedFeePerUnit: formDraft?.feePerUnit,
7473
selectedSetMaxOutputId: formDraft?.setMaxOutputId,
7574
});

suite-native/module-trading/src/components/fees/TradingFeesForm.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
55
import { RouteProp, useRoute } from '@react-navigation/native';
66

77
import { FormDraftRootState, selectDeepCopyOfFormDraft } from '@suite-common/wallet-core';
8-
import { AccountKey, FormDraftKeyPrefix, TokenAddress } from '@suite-common/wallet-types';
8+
import {
9+
AccountKey,
10+
FeeLevelLabel,
11+
FormDraftKeyPrefix,
12+
TokenAddress,
13+
} from '@suite-common/wallet-types';
914
import { getFormDraftKey } from '@suite-common/wallet-utils';
1015
import { VStack } from '@suite-native/atoms';
1116
import { Form } from '@suite-native/forms';
1217
import { TradingStackParamList, TradingStackRoutes } from '@suite-native/navigation';
13-
import {
14-
FeesContent,
15-
FeesFooter,
16-
NativeSupportedFeeLevel,
17-
useFeesManagement,
18-
} from '@suite-native/transaction-management';
18+
import { FeesContent, FeesFooter, useFeesManagement } from '@suite-native/transaction-management';
1919

2020
import { updateTradingSelectedFeeLevelThunk } from '../../thunks';
2121

@@ -51,7 +51,7 @@ export const TradingFeesForm = ({ accountKey, tokenContract }: TradingFeesFormPr
5151
accountKey,
5252
tokenContract,
5353
updateThunk: updateTradingSelectedFeeLevelThunk,
54-
selectedFee: formDraft?.selectedFee as NativeSupportedFeeLevel,
54+
selectedFee: formDraft?.selectedFee as FeeLevelLabel,
5555
selectedFeePerUnit: formDraft?.feePerUnit,
5656
selectedSetMaxOutputId: formDraft?.setMaxOutputId,
5757
formDraftKey,

suite-native/module-trading/src/hooks/general/useTradingTransaction.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ import {
3030
selectSendSerializedTx,
3131
updateFeeInfoThunk,
3232
} from '@suite-common/wallet-core';
33-
import { TokenAddress } from '@suite-common/wallet-types';
33+
import { FeeLevelLabel, TokenAddress } from '@suite-common/wallet-types';
3434
import { TokensRootState, selectAccountTokenDecimals } from '@suite-native/tokens';
3535
import { TradingRootState, getFormDraftKeyByTradeType } from '@suite-native/trading-state';
3636
import {
37-
NativeSupportedFeeLevel,
3837
selectFeeLevels,
3938
useFeesFetching,
4039
usePrecomposedTransactionError,
@@ -50,7 +49,7 @@ export type TradingTransactionSignAndSendProps = {
5049
};
5150

5251
export type TradingTransactionComposeProps = {
53-
selectedFeeLevel?: NativeSupportedFeeLevel;
52+
selectedFeeLevel?: FeeLevelLabel;
5453
feePerUnit?: string;
5554
feeLimit?: string;
5655
};
@@ -129,7 +128,7 @@ export const useTradingTransaction = ({
129128

130129
const feeLevels = useSelector(selectFeeLevels);
131130

132-
const selectedLevel = feeLevels[(selectedFee as NativeSupportedFeeLevel) ?? 'normal'];
131+
const selectedLevel = feeLevels[(selectedFee as FeeLevelLabel) ?? 'normal'];
133132
const feeError = selectedLevel?.type === 'error' ? selectedLevel.error : null;
134133

135134
const txnErrorString = usePrecomposedTransactionError({
@@ -202,7 +201,7 @@ export const useTradingTransaction = ({
202201
}
203202

204203
await composeRequest({
205-
selectedFeeLevel: selectedFee as NativeSupportedFeeLevel,
204+
selectedFeeLevel: selectedFee as FeeLevelLabel,
206205
feePerUnit: feePerUnitDraft,
207206
feeLimit: feeLimitDraft,
208207
});
@@ -311,7 +310,7 @@ export const useTradingTransaction = ({
311310
useEffect(() => {
312311
if (selectedFee && networkFeeInfo) {
313312
composeRequest({
314-
selectedFeeLevel: selectedFee as NativeSupportedFeeLevel,
313+
selectedFeeLevel: selectedFee as FeeLevelLabel,
315314
feePerUnit: feePerUnitDraft,
316315
feeLimit: feeLimitDraft,
317316
});

suite-native/module-trading/src/thunks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ import {
2727
import {
2828
Account,
2929
FeeInfo,
30+
FeeLevelLabel,
3031
PrecomposedTransactionFinal,
3132
isFinalPrecomposedTransaction,
3233
} from '@suite-common/wallet-types';
3334
import { tryGetAccountIdentity } from '@suite-common/wallet-utils';
3435
import { requestPrioritizedDeviceAccess } from '@suite-native/device-mutex';
3536
import { getFormDraftKeyByTradeType } from '@suite-native/trading-state';
3637
import {
37-
NativeSupportedFeeLevel,
3838
UpdateSelectedFeeLevelThunkParams,
3939
addTransactionLabelingThunk,
4040
transactionManagementActions,
@@ -117,7 +117,7 @@ export const composeTradingTransactionThunk = createThunk(
117117
account: Account;
118118
network: Network;
119119
feeInfo: FeeInfo | null;
120-
selectedFeeLevel?: NativeSupportedFeeLevel;
120+
selectedFeeLevel?: FeeLevelLabel;
121121
feeLimit?: string;
122122
feePerUnit?: string;
123123
isSlip24Active?: boolean;

suite-native/transaction-management/src/__tests__/selectors.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GeneralPrecomposedLevels } from '@suite-common/wallet-types';
1+
import { FeeLevelLabel, GeneralPrecomposedLevels } from '@suite-common/wallet-types';
22

33
import {
44
selectCustomFeeLevel,
@@ -7,7 +7,6 @@ import {
77
selectIsTransactionAlreadySigned,
88
} from '../selectors';
99
import { NativeSendRootState } from '../sendFormSlice';
10-
import { NativeSupportedFeeLevel } from '../types';
1110

1211
const createMockState = (
1312
overrides: Partial<NativeSendRootState['wallet']['send']> = {},
@@ -134,10 +133,7 @@ describe('transaction-management selectors', () => {
134133

135134
it('should return 0 when fee level does not exist', () => {
136135
const state = createMockState();
137-
const result = selectFeeLevelTransactionBytes(
138-
state,
139-
'normal' as NativeSupportedFeeLevel,
140-
);
136+
const result = selectFeeLevelTransactionBytes(state, 'normal' as FeeLevelLabel);
141137

142138
expect(result).toBe(0);
143139
});

suite-native/transaction-management/src/components/fees/CustomFee/CustomFee.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
22
import Animated, { FadeInLeft, FadeOutLeft } from 'react-native-reanimated';
33

44
import { type NetworkSymbol, getNetworkType } from '@suite-common/wallet-config';
5-
import { AccountKey, FormState } from '@suite-common/wallet-types';
5+
import { AccountKey, FeeLevelLabel, FormState } from '@suite-common/wallet-types';
66
import { Box, Button, useBottomSheetModal } from '@suite-native/atoms';
77
import { useFormContext } from '@suite-native/forms';
88
import { Icon } from '@suite-native/icons';
@@ -12,7 +12,6 @@ import { CustomFeeBottomSheet } from './CustomFeeBottomSheet';
1212
import { CustomFeeCard } from './CustomFeeCard';
1313
import { FeesFormValues } from '../../../feesFormSchema';
1414
import { useCustomFee } from '../../../hooks/fees/useCustomFee';
15-
import { NativeSupportedFeeLevel } from '../../../types/fees';
1615

1716
type CustomFeeProps = {
1817
accountKey: AccountKey;
@@ -45,7 +44,7 @@ const CustomFeeContentWrapper = ({ accountKey, formDraft, onCustomFeeSet }: Cust
4544
const { bottomSheetRef, openModal, closeModal } = useBottomSheetModal();
4645

4746
const [previousSelectedFeeLevelLabel, setPreviousSelectedFeeLevelLabel] =
48-
useState<NativeSupportedFeeLevel>('normal');
47+
useState<FeeLevelLabel>('normal');
4948
const { watch, setValue, getValues } = useFormContext<FeesFormValues>();
5049

5150
const isCustomFeeSelected = watch('feeLevel') === 'custom';

suite-native/transaction-management/src/components/fees/FeeOptionList/FeeOption.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import Animated, {
88
} from 'react-native-reanimated';
99
import { useSelector } from 'react-redux';
1010

11-
import { type NetworkSymbol, type NetworkType, getNetworkType } from '@suite-common/wallet-config';
11+
import {
12+
type NetworkSymbol,
13+
type NetworkType,
14+
getNetworkType,
15+
hasNetworkSettlementLayer,
16+
} from '@suite-common/wallet-config';
1217
import {
1318
FeesRootState,
1419
selectConvertedNetworkFeeLevelFeePerUnit,
@@ -19,7 +24,7 @@ import {
1924
GeneralPrecomposedTransactionFinal,
2025
isFinalPrecomposedTransaction,
2126
} from '@suite-common/wallet-types';
22-
import { getFeeUnits } from '@suite-common/wallet-utils';
27+
import { getFeeUnits, isEip1559 } from '@suite-common/wallet-utils';
2328
import { Box, HStack, Radio, Text, VStack } from '@suite-native/atoms';
2429
import { CryptoAmountFormatter, CryptoToFiatAmountFormatter } from '@suite-native/formatters';
2530
import { EmptyAmountSkeleton } from '@suite-native/formatters/src/components/EmptyAmountSkeleton';
@@ -42,6 +47,7 @@ export type FeeOptionProps = {
4247
};
4348

4449
const feeLabelsMap = {
50+
low: 'transactionManagement.fees.levels.low',
4551
economy: 'transactionManagement.fees.levels.low',
4652
normal: 'transactionManagement.fees.levels.normal',
4753
high: 'transactionManagement.fees.levels.high',
@@ -64,16 +70,25 @@ const getFeePerUnit = ({
6470
feeLevel,
6571
transactionBytes,
6672
backendFeePerUnit = '0',
73+
symbol,
6774
}: {
6875
networkType: NetworkType;
6976
feeLevel: GeneralPrecomposedTransaction;
7077
transactionBytes: number;
7178
backendFeePerUnit: string;
79+
symbol: NetworkSymbol;
7280
}): string => {
7381
if (!isFinalPrecomposedTransaction(feeLevel)) {
7482
return backendFeePerUnit;
7583
}
7684

85+
if (networkType === 'ethereum') {
86+
const decimals = hasNetworkSettlementLayer(symbol) ? 4 : 2;
87+
const value = Number(isEip1559(feeLevel) ? feeLevel.maxFeePerGas : feeLevel.feePerByte);
88+
89+
return value.toFixed(decimals);
90+
}
91+
7792
if (networkType === 'bitcoin') {
7893
const feePerVb = Number(feeLevel.fee) / transactionBytes;
7994

@@ -142,6 +157,7 @@ export const FeeOption = ({
142157
feeLevel,
143158
transactionBytes,
144159
backendFeePerUnit: backendFeePerUnit ?? '0',
160+
symbol,
145161
});
146162

147163
const formattedFeePerUnit = `${feePerUnit} ${feeUnits}`;

suite-native/transaction-management/src/components/fees/FeeOptionList/FeeOptionsList.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Animated, { FadeInLeft, FadeOutLeft } from 'react-native-reanimated';
22

33
import { D, pipe } from '@mobily/ts-belt';
44

5-
import { type NetworkSymbol } from '@suite-common/wallet-config';
5+
import { type NetworkSymbol, getNetworkType } from '@suite-common/wallet-config';
66
import { GeneralPrecomposedLevels } from '@suite-common/wallet-types';
77
import { VStack } from '@suite-native/atoms';
88

@@ -35,9 +35,11 @@ export const FeeOptionsList = ({
3535
isLoading,
3636
onSelectedFeeLevel,
3737
}: FeeOptionsListProps) => {
38+
const isBtcNetworkType = getNetworkType(symbol) === 'bitcoin';
39+
3840
const predefinedFeeLevels = pipe(
3941
feeLevels,
40-
D.filterWithKey(key => key !== 'custom' && key !== 'low'),
42+
D.filterWithKey(key => key !== 'custom' && (isBtcNetworkType ? key !== 'low' : true)),
4143
);
4244

4345
const transactionBytes = getTransactionBytes(predefinedFeeLevels);

suite-native/transaction-management/src/components/fees/FeesContent.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { NetworkSymbol } from '@suite-common/wallet-config';
2-
import { AccountKey, FormState } from '@suite-common/wallet-types';
2+
import { AccountKey, FeeLevelLabel, FormState } from '@suite-common/wallet-types';
33
import { Text, VStack } from '@suite-native/atoms';
44
import { Translation } from '@suite-native/intl';
55

66
import { CustomFee } from './CustomFee/CustomFee';
77
import { FeeOptionsList, FeeOptionsListProps } from './FeeOptionList/FeeOptionsList';
8-
import { NativeSupportedFeeLevel } from '../../types/fees';
98

109
type FeesContentProps = {
11-
selectedFeeLevel: NativeSupportedFeeLevel;
10+
selectedFeeLevel: FeeLevelLabel;
1211
feeLevels: FeeOptionsListProps['feeLevels'];
1312
symbol: NetworkSymbol;
1413
accountKey: AccountKey;

0 commit comments

Comments
 (0)