@@ -3,6 +3,7 @@ import { NetworkSymbol, getNetwork } from '@suite-common/wallet-config';
33import { FeeInfo , FeeLevelLabel } from '@suite-common/wallet-types' ;
44import { isDecimalsValid } from '@suite-common/wallet-utils' ;
55import type { UseFormReturn } from '@suite-native/forms' ;
6+ import { Translate } from '@suite-native/intl' ;
67import { BigNumber } from '@trezor/utils' ;
78
89import { getFeeDecimals } from './utils' ;
@@ -11,14 +12,12 @@ export type FeesFormContext = {
1112 symbol ?: NetworkSymbol ;
1213 networkFeeInfo ?: FeeInfo ;
1314 minimalFeeLimit ?: string ;
15+ translate ?: Translate ;
1416} ;
1517
1618const FeeLevelLabels : Array < FeeLevelLabel > = [ 'economy' , 'low' , 'normal' , 'high' , 'custom' ] ;
1719
18- const createFeeDecimalsTest = (
19- value : string | undefined ,
20- { options : { context } } : yup . TestContext < FeesFormContext > ,
21- ) => {
20+ const validateFeeDecimalLength = ( value : string | undefined , context : FeesFormContext ) => {
2221 if ( ! value ) return true ;
2322
2423 const { networkFeeInfo, symbol } = context ! ;
@@ -36,96 +35,189 @@ const createFeeDecimalsTest = (
3635 return isDecimalsValid ( value , maxDecimals ) ;
3736} ;
3837
39- const createFeeValidation = ( ) =>
40- yup
38+ export const feesFormValidationSchema = yup . object ( {
39+ feeLevel : yup . string ( ) . oneOf ( FeeLevelLabels ) . required ( 'Fee level is required' ) ,
40+ customFeePerUnit : yup
4141 . string ( )
42- . test ( 'too-many-decimals' , 'Too many decimals.' , createFeeDecimalsTest )
43- . test (
44- 'fee-too-low' ,
45- 'Fee is too low.' ,
46- ( value , { options : { context } } : yup . TestContext < FeesFormContext > ) => {
47- if ( ! value ) return true ;
48- const { networkFeeInfo } = context ! ;
42+ . test ( 'too-many-decimals' , 'Too many decimals.' , function ( value ) {
43+ const { translate, ...context } = this . options . context as FeesFormContext ;
44+ if ( ! validateFeeDecimalLength ( value , context ) ) {
45+ return this . createError ( {
46+ message : translate ! (
47+ 'transactionManagement.fees.custom.bottomSheet.errors.decimals' ,
48+ ) ,
49+ } ) ;
50+ }
51+
52+ return true ;
53+ } )
54+ . test ( 'fee-too-low' , 'Fee is too low.' , function ( value ) {
55+ if ( ! value ) return true ;
56+ const { networkFeeInfo, translate } = this . options . context as FeesFormContext ;
57+
58+ if ( ! networkFeeInfo ) return false ;
59+ const { minFee } = networkFeeInfo ;
60+
61+ if ( Number ( value ) < minFee ) {
62+ return this . createError ( {
63+ message : translate ! (
64+ 'transactionManagement.fees.custom.bottomSheet.errors.feePerUnit.low' ,
65+ ) ,
66+ } ) ;
67+ }
68+
69+ return true ;
70+ } )
71+ . test ( 'fee-too-high' , 'Fee is too high.' , function ( value ) {
72+ const { networkFeeInfo, translate } = this . options . context as FeesFormContext ;
73+
74+ if ( ! value || ! networkFeeInfo ) return false ;
75+
76+ const feeBig = new BigNumber ( value ) ;
77+ const { maxFee } = networkFeeInfo ;
78+
79+ if ( feeBig . gt ( maxFee ) ) {
80+ return this . createError ( {
81+ message : translate ! (
82+ 'transactionManagement.fees.custom.bottomSheet.errors.feePerUnit.high' ,
83+ ) ,
84+ } ) ;
85+ }
86+
87+ return true ;
88+ } )
89+ . required ( ) ,
90+ customFeeLimit : yup . string ( ) . test (
91+ 'fee-limit-too-low' ,
92+ 'Value is too low.' ,
4993
50- if ( ! networkFeeInfo ) return false ;
51- const { minFee } = networkFeeInfo ;
94+ function ( value ) {
95+ const { symbol , minimalFeeLimit , translate } = this . options . context as FeesFormContext ;
5296
53- return Number ( value ) >= minFee ;
54- } ,
55- )
56- . test (
57- 'fee-too-high' ,
58- 'Fee is too high.' ,
59- ( value , { options : { context } } : yup . TestContext < FeesFormContext > ) => {
60- if ( ! value ) return true ;
97+ if ( ! symbol ) return true ;
6198
62- const { networkFeeInfo } = context ! ;
99+ const { networkType } = getNetwork ( symbol ) ;
63100
64- if ( ! value || ! networkFeeInfo ) return false ;
101+ // Fee limit is used only for Ethereum, pass this validation for other networks.
102+ if ( networkType !== 'ethereum' ) return true ;
65103
66- const feeBig = new BigNumber ( value ) ;
67- const { maxFee } = networkFeeInfo ;
104+ if ( ! value || ! minimalFeeLimit ) return false ;
68105
69- return feeBig . lte ( maxFee ) ;
70- } ,
71- ) ;
106+ const feeBig = new BigNumber ( value ) ;
72107
73- export const feesFormValidationSchema = yup . object ( {
74- feeLevel : yup . string ( ) . oneOf ( FeeLevelLabels ) . required ( 'Fee level is required' ) ,
75- customFeePerUnit : createFeeValidation ( ) . required ( ) ,
76- customFeeLimit : yup
108+ if ( feeBig . isLessThan ( minimalFeeLimit ) ) {
109+ return this . createError ( {
110+ message : translate ! (
111+ 'transactionManagement.fees.custom.bottomSheet.errors.feeLimit.low' ,
112+ ) ,
113+ } ) ;
114+ }
115+
116+ return true ;
117+ } ,
118+ ) ,
119+ // EIP1559 only validations
120+ customMaxFeePerGas : yup
77121 . string ( )
122+ . test ( 'too-many-decimals' , 'Too many decimals.' , function ( value ) {
123+ const { translate, ...context } = this . options . context as FeesFormContext ;
124+ if ( ! validateFeeDecimalLength ( value , context ) ) {
125+ return this . createError ( {
126+ message : translate ! (
127+ 'transactionManagement.fees.custom.bottomSheet.errors.decimals' ,
128+ ) ,
129+ } ) ;
130+ }
131+
132+ return true ;
133+ } )
134+ . test ( 'max-fee-per-gas-range' , 'Max fee per gas is out of range.' , function ( value ) {
135+ const { translate, networkFeeInfo } = this . options . context as FeesFormContext ;
136+ if ( ! value || ! networkFeeInfo ) return false ;
137+
138+ const { maxFee, minFee } = networkFeeInfo ;
139+
140+ if ( Number ( value ) > Number ( maxFee ) || Number ( value ) < Number ( minFee ) ) {
141+ return this . createError ( {
142+ message : translate ! (
143+ 'transactionManagement.fees.custom.bottomSheet.errors.maxFeePerGas.outOfRange' ,
144+ {
145+ minFee,
146+ maxFee,
147+ } ,
148+ ) ,
149+ } ) ;
150+ }
151+
152+ return true ;
153+ } )
78154 . test (
79- 'fee-limit-too-low' ,
80- 'Value is too low.' ,
81- ( value , { options : { context } } : yup . TestContext < FeesFormContext > ) => {
82- const { symbol, minimalFeeLimit } = context ! ;
83- if ( ! symbol ) return true ;
155+ 'custom-max-fee-per-gas-higher-than-priority' ,
156+ 'Max fee must be higher than priority fee.' ,
157+ function ( value ) {
158+ if ( ! value ) return true ;
84159
85- const { networkType } = getNetwork ( symbol ) ;
160+ const { customMaxPriorityFeePerGas } = this . parent ;
86161
87- // Fee limit is used only for Ethereum, pass this validation for other networks.
88- if ( networkType !== 'ethereum' ) return true ;
162+ if ( ! customMaxPriorityFeePerGas ) return true ;
89163
90- if ( ! value || ! minimalFeeLimit ) return false ;
164+ const { translate } = this . options . context as FeesFormContext ;
91165
92- const feeBig = new BigNumber ( value ) ;
166+ if ( Number ( value ) < Number ( customMaxPriorityFeePerGas ) ) {
167+ return this . createError ( {
168+ message : translate ! (
169+ 'transactionManagement.fees.custom.bottomSheet.errors.maxFeePerGas.lessThanPriority' ,
170+ ) ,
171+ } ) ;
172+ }
93173
94- return feeBig . gte ( minimalFeeLimit ) ;
174+ return true ;
95175 } ,
96176 ) ,
97- // EIP1559 only validations
98- customMaxFeePerGas : createFeeValidation ( ) . test (
99- 'custom-max-fee-per-gas-higher-than-priority' ,
100- 'Max fee must be higher than or equal to priority fee.' ,
101- function ( value ) {
102- if ( ! value ) return true ;
103-
104- const { customMaxPriorityFeePerGas } = this . parent ;
105-
106- if ( ! customMaxPriorityFeePerGas ) return true ;
107-
108- return Number ( value ) > Number ( customMaxPriorityFeePerGas ) ;
109- } ,
110- ) ,
111177 customMaxPriorityFeePerGas : yup
112178 . string ( )
113- . test ( 'too-many-decimals' , 'Too many decimals.' , createFeeDecimalsTest )
179+ . test ( 'too-many-decimals' , 'Too many decimals.' , function ( value ) {
180+ const { translate, ...context } = this . options . context as FeesFormContext ;
181+ if ( ! validateFeeDecimalLength ( value , context ) ) {
182+ return this . createError ( {
183+ message : translate ! (
184+ 'transactionManagement.fees.custom.bottomSheet.errors.decimals' ,
185+ ) ,
186+ } ) ;
187+ }
188+
189+ return true ;
190+ } )
114191 . test (
115192 'custom-priority-fee-per-gas' ,
116193 'Priority fee higher than max fee or below minimum.' ,
117194 function ( value ) {
118195 if ( ! value ) return true ;
119- const { networkFeeInfo } = this . options . context ! ;
196+ const { networkFeeInfo, translate } = this . options . context as FeesFormContext ;
120197
121198 if ( ! networkFeeInfo ) return false ;
122199 const { minPriorityFee } = networkFeeInfo ;
123200
124- if ( Number ( value ) < minPriorityFee ) return false ;
201+ if ( Number ( value ) < minPriorityFee ) {
202+ return this . createError ( {
203+ message : translate ! (
204+ 'transactionManagement.fees.custom.bottomSheet.errors.maxPriorityFee.min' ,
205+ { minPriorityFee } ,
206+ ) ,
207+ } ) ;
208+ }
125209
126210 const { customMaxFeePerGas } = this . parent ;
127211
128- return ! ( customMaxFeePerGas && Number ( value ) > Number ( customMaxFeePerGas ) ) ;
212+ if ( customMaxFeePerGas && Number ( value ) > Number ( customMaxFeePerGas ) ) {
213+ return this . createError ( {
214+ message : translate ! (
215+ 'transactionManagement.fees.custom.bottomSheet.errors.maxPriorityFee.higherThanMaxFee' ,
216+ ) ,
217+ } ) ;
218+ }
219+
220+ return true ;
129221 } ,
130222 ) ,
131223} ) ;
0 commit comments