44 NodeTier ,
55} from 'types/generated/auctioneerrpc/auctioneer_pb' ;
66import { LeaseDuration } from 'types/state' ;
7+ import debounce from 'lodash/debounce' ;
78import { annualPercentRate , toBasisPoints , toPercent } from 'util/bigmath' ;
89import { BLOCKS_PER_DAY } from 'util/constants' ;
910import { prefixTranslation } from 'util/translate' ;
@@ -31,6 +32,11 @@ export default class OrderFormView {
3132 /** toggle to show or hide the additional options */
3233 addlOptionsVisible = false ;
3334
35+ /** quoted fees */
36+ executionFee = 0 ;
37+ worstChainFee = 0 ;
38+ quoteLoading = false ;
39+
3440 constructor ( store : Store ) {
3541 makeAutoObservable ( this , { } , { deep : false , autoBind : true } ) ;
3642
@@ -184,22 +190,27 @@ export default class OrderFormView {
184190
185191 setAmount ( amount : number ) {
186192 this . amount = amount ;
193+ this . fetchQuote ( ) ;
187194 }
188195
189196 setPremium ( premium : number ) {
190197 this . premium = premium ;
198+ this . fetchQuote ( ) ;
191199 }
192200
193201 setDuration ( duration : LeaseDuration ) {
194202 this . duration = duration ;
203+ this . fetchQuote ( ) ;
195204 }
196205
197206 setMinChanSize ( minChanSize : number ) {
198207 this . minChanSize = minChanSize ;
208+ this . fetchQuote ( ) ;
199209 }
200210
201211 setMaxBatchFeeRate ( feeRate : number ) {
202212 this . maxBatchFeeRate = feeRate ;
213+ this . fetchQuote ( ) ;
203214 }
204215
205216 setMinNodeTier ( minNodeTier : Tier ) {
@@ -220,6 +231,7 @@ export default class OrderFormView {
220231 const suggested = this . amount * prevPctRate ;
221232 // round to the nearest 10 to offset lose of precision in calculating percentages
222233 this . premium = Math . round ( suggested / 10 ) * 10 ;
234+ this . fetchQuote ( ) ;
223235 } catch ( error ) {
224236 this . _store . appView . handleError ( error , 'Unable to suggest premium' ) ;
225237 }
@@ -229,6 +241,51 @@ export default class OrderFormView {
229241 this . addlOptionsVisible = ! this . addlOptionsVisible ;
230242 }
231243
244+ /** requests a quote for an order to obtain accurate fees */
245+ async quoteOrder ( ) {
246+ const minUnitsMatch = Math . floor ( this . minChanSize / ONE_UNIT ) ;
247+ const satsPerKWeight = this . _store . api . pool . satsPerVByteToKWeight (
248+ this . maxBatchFeeRate ,
249+ ) ;
250+
251+ const {
252+ totalExecutionFeeSat,
253+ worstCaseChainFeeSat,
254+ } = await this . _store . orderStore . quoteOrder (
255+ this . amount ,
256+ this . perBlockFixedRate ,
257+ this . derivedDuration ,
258+ minUnitsMatch ,
259+ satsPerKWeight ,
260+ ) ;
261+
262+ runInAction ( ( ) => {
263+ this . executionFee = totalExecutionFeeSat ;
264+ this . worstChainFee = worstCaseChainFeeSat ;
265+ this . quoteLoading = false ;
266+ } ) ;
267+ }
268+
269+ /** quote order at most once every second when using this func */
270+ quoteOrderThrottled = debounce ( this . quoteOrder , 1000 ) ;
271+
272+ /**
273+ * sets the quoteLoading flag before while waiting for the throttled quote
274+ * request to complete
275+ */
276+ fetchQuote ( ) {
277+ if ( ! this . isValid ) {
278+ runInAction ( ( ) => {
279+ this . executionFee = 0 ;
280+ this . worstChainFee = 0 ;
281+ this . quoteLoading = false ;
282+ } ) ;
283+ return ;
284+ }
285+ this . quoteLoading = true ;
286+ this . quoteOrderThrottled ( ) ;
287+ }
288+
232289 /** submits the order to the API and resets the form values if successful */
233290 async placeOrder ( ) {
234291 const minUnitsMatch = Math . floor ( this . minChanSize / ONE_UNIT ) ;
@@ -249,6 +306,8 @@ export default class OrderFormView {
249306 this . amount = 0 ;
250307 this . premium = 0 ;
251308 this . duration = 0 ;
309+ this . executionFee = 0 ;
310+ this . worstChainFee = 0 ;
252311 // persist the additional options so they can be used for future orders
253312 this . _store . settingsStore . setOrderSettings (
254313 this . minChanSize ,
0 commit comments