From c078574d5e37489d483f7cc206fa2a5507da3267 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Tue, 8 Oct 2024 11:17:39 +0100 Subject: [PATCH] use core.Trade to place trades instead of core.TradeAsync (#679) Other fixes in this commit include: - Refresh order form after market change. - Refresh order price after market change. --- libwallet/dex_interface.go | 4 ++++ ui/page/dcrdex/market.go | 45 ++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/libwallet/dex_interface.go b/libwallet/dex_interface.go index 70010fb04..8761739b4 100644 --- a/libwallet/dex_interface.go +++ b/libwallet/dex_interface.go @@ -31,6 +31,10 @@ type DEXClient interface { SyncBook(dex string, base, quote uint32) (*orderbook.OrderBook, core.BookFeed, error) Orders(filter *core.OrderFilter) ([]*core.Order, error) ActiveOrders() (map[string][]*core.Order, map[string][]*core.InFlightOrder, error) + Trade(pw []byte, form *core.TradeForm) (*core.Order, error) + // TradeAsync is like Trade but a temporary order is returned before order + // server validation. This helps handle some issues related to UI/UX where + // server response might take a fairly long time (15 - 20s). Unused. TradeAsync(pw []byte, form *core.TradeForm) (*core.InFlightOrder, error) WalletState(assetID uint32) *core.WalletState WalletSettings(assetID uint32) (map[string]string, error) diff --git a/ui/page/dcrdex/market.go b/ui/page/dcrdex/market.go index b322128b1..1ef03c204 100644 --- a/ui/page/dcrdex/market.go +++ b/ui/page/dcrdex/market.go @@ -195,7 +195,7 @@ func NewDEXMarketPage(l *load.Load, selectServer string) *DEXMarketPage { pg.immediateOrderCheckbox.Font.Weight = font.SemiBold - pg.setBuyOrSell() + pg.refreshOrderForm() return pg } @@ -256,6 +256,10 @@ func (pg *DEXMarketPage) OnNavigatedTo() { if n.Topic() == core.TopicAsyncOrderFailure { pg.notifyError(n.Details()) } + // TODO: Handle Inflight Orders if we eventually use + // core.TradeAsync. We are expected to update mkt.Inflight + // order list to remove or add an inflight order based on + // the order topic. pg.refreshOrders() pg.ParentWindow().Reload() case core.NoteTypeBalance, core.NoteTypeSpots: @@ -400,6 +404,7 @@ func (pg *DEXMarketPage) fetchOrderBook() { quote: quoteAssetID, baseSymbol: base, quoteSymbol: quote, + marketID: pg.formatSelectedMarketAsDEXMarketName(), } pg.closeAndResetOrderbookListener() @@ -419,7 +424,6 @@ func (pg *DEXMarketPage) fetchOrderBook() { // Fetch order book and only update if we're still on the same market. book, feed, err := pg.AssetsManager.DexClient().SyncBook(pg.serverSelector.Selected(), baseAssetID, quoteAssetID) if err == nil && pg.selectedMarketOrderBook.base == baseAssetID && pg.selectedMarketOrderBook.quote == quoteAssetID { - pg.selectedMarketOrderBook.marketID = pg.formatSelectedMarketAsDEXMarketName() pg.selectedMarketOrderBook.feed = feed pg.selectedMarketOrderBook.book = book pg.closeOrderBookListener = feed.Close @@ -1361,7 +1365,7 @@ func (pg *DEXMarketPage) orderColumn(header bool, txt string, columnWidth unit.D }) } -func (pg *DEXMarketPage) setBuyOrSell() { +func (pg *DEXMarketPage) refreshOrderForm() { isSell := pg.isSellOrder() pg.lotsOrAmountEditor.Editor.ReadOnly = !isSell pg.lotsOrAmountEditor.UpdateFocus(!pg.lotsOrAmountEditor.Editor.ReadOnly) @@ -1369,6 +1373,7 @@ func (pg *DEXMarketPage) setBuyOrSell() { pg.totalEditor.UpdateFocus(!pg.totalEditor.Editor.ReadOnly) pg.lotsOrAmountEditor.Editor.SetText("") pg.totalEditor.Editor.SetText("") + pg.refreshPriceField() if !isSell { // Buy pg.createOrderBtn.Text = values.String(values.StrBuy) @@ -1394,23 +1399,16 @@ func (pg *DEXMarketPage) handleEditorEvents(gtx C) { var toggleBuyAndSellBtnChanged bool if pg.toggleBuyAndSellBtn.Changed() { toggleBuyAndSellBtnChanged = true - pg.setBuyOrSell() + pg.refreshOrderForm() } - isMktOrder := pg.isMarketOrder() - mkt := pg.selectedMarketInfo() if pg.orderTypesDropdown.Changed(gtx) { - isMktOrder = pg.isMarketOrder() - pg.priceEditor.Editor.ReadOnly = isMktOrder - if isMktOrder { - pg.priceEditor.Editor.SetText(values.String(values.StrMarket)) - } else if price := pg.orderPrice(mkt); price > 0 { - pg.priceEditor.Editor.SetText(trimmedAmtString(price)) - } else { - pg.priceEditor.Editor.SetText("") - } + pg.refreshPriceField() } + isMktOrder := pg.isMarketOrder() + mkt := pg.selectedMarketInfo() + var reEstimateFee bool for pg.priceEditor.Changed() { pg.priceEditor.SetError("") @@ -1481,6 +1479,20 @@ func (pg *DEXMarketPage) handleEditorEvents(gtx C) { } } +func (pg *DEXMarketPage) refreshPriceField() { + mkt := pg.selectedMarketInfo() + isMktOrder := pg.isMarketOrder() + pg.priceEditor.Editor.ReadOnly = isMktOrder + if isMktOrder { + pg.priceEditor.Editor.SetText(values.String(values.StrMarket)) + } else if mkt != nil && mkt.SpotPrice != nil { + price := mkt.MsgRateToConventional(mkt.SpotPrice.Rate) + pg.priceEditor.Editor.SetText(trimmedAmtString(price)) + } else { + pg.priceEditor.Editor.SetText("") + } +} + // HandleUserInteractions is called just before Layout() to determine if any // user interaction recently occurred on the page and may be used to update the // page's UI components shortly before they are displayed. @@ -1516,6 +1528,7 @@ func (pg *DEXMarketPage) HandleUserInteractions(gtx C) { if pg.marketSelector.Changed(gtx) { pg.fetchOrderBook() + pg.refreshOrderForm() } if pg.orderHistoryBtn.Clicked(gtx) { @@ -1604,7 +1617,7 @@ func (pg *DEXMarketPage) HandleUserInteractions(gtx C) { return false } - _, err = dexc.TradeAsync([]byte(password), orderForm) + _, err = dexc.Trade([]byte(password), orderForm) return err == nil })