From 85adf6c24f84aaa2e4a44bef658cb83ca2b0a441 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Wed, 4 Oct 2023 15:28:16 +0100 Subject: [PATCH 1/3] fix exchange rate bugs - Return early for dcr-ltc market as Binance does not support it yet. - Fix the bug that caused weird estimated rates. - Improve the estimated rates display. - Fix comment formatting and typos. Signed-off-by: Philemon Ukane --- libwallet/ext/service.go | 6 ++ libwallet/instantswap.go | 34 ++++++++-- ui/page/exchange/create_order_page.go | 81 +++++++++++++---------- ui/page/exchange/order_scheduler_modal.go | 39 ++++++----- ui/values/dimensions.go | 3 +- ui/values/localizable/en.go | 5 +- ui/values/strings.go | 1 - 7 files changed, 108 insertions(+), 61 deletions(-) diff --git a/libwallet/ext/service.go b/libwallet/ext/service.go index c91d0d3a9..b61c65783 100644 --- a/libwallet/ext/service.go +++ b/libwallet/ext/service.go @@ -317,6 +317,12 @@ func (s *Service) GetXpub(xPub string) (xPubBalAndTxs *XpubBalAndTxs, err error) func (s *Service) GetTicker(exchange string, market string) (ticker *Ticker, err error) { switch exchange { case Binance: + // Return early for dcr-ltc markets ad binance does not support this + // atm. + if strings.EqualFold(market, "ltc-dcr") { + return &Ticker{}, nil + } + symbArr := strings.Split(market, "-") if len(symbArr) != 2 { return ticker, errors.New("invalid symbol format") diff --git a/libwallet/instantswap.go b/libwallet/instantswap.go index b5dee2b2f..712efc11a 100644 --- a/libwallet/instantswap.go +++ b/libwallet/instantswap.go @@ -3,6 +3,7 @@ package libwallet import ( "context" "math" + "strings" "time" "decred.org/dcrwallet/v3/errors" @@ -87,9 +88,11 @@ func (mgr *AssetsManager) StartScheduler(ctx context.Context, params instantswap return errors.E(op, "source wallet balance is less than or equals the set balance to maintain") // stop scheduling if the source wallet balance is less than or equals the set balance to maintain } + fromCur := params.Order.FromCurrency + toCur := params.Order.ToCurrency rateRequestParams := api.ExchangeRateRequest{ - From: params.Order.FromCurrency, - To: params.Order.ToCurrency, + From: fromCur, + To: toCur, Amount: DefaultRateRequestAmount, // amount needs to be greater than 0 to get the exchange rate } log.Info("Order Scheduler: getting exchange rate info") @@ -103,17 +106,22 @@ func (mgr *AssetsManager) StartScheduler(ctx context.Context, params instantswap params.MaxDeviationRate = DefaultMarketDeviation // default 5% } - market := params.Order.FromCurrency + "-" + params.Order.ToCurrency - ticker, err := mgr.ExternalService.GetTicker(ext.Binance, market) + ticker, err := mgr.ExternalService.GetTicker(ext.Binance, MarketName(fromCur, toCur)) if err != nil { log.Error("unable to get market rate from binance") return errors.E(op, err) } - exchangeServerRate := 1 / res.ExchangeRate + exchangeServerRate := res.EstimatedAmount // estimated receivable value for libwallet.DefaultRateRequestAmount (1) binanceRate := ticker.LastTradePrice - log.Info(params.Order.ExchangeServer.Server+" rate: ", exchangeServerRate) - log.Info(ext.Binance+" rate: ", binanceRate) + /// Binance always returns ticker.LastTradePrice in's the quote asset + // unit e.g DCR-BTC, LTC-BTC. We will also do this when and if USDT is supported. + if strings.EqualFold(fromCur, "btc") { + binanceRate = 1 / ticker.LastTradePrice + } + + log.Info(params.Order.ExchangeServer.Server+" rate: 1 %s ~= %f %s", fromCur, exchangeServerRate, toCur) + log.Info(ext.Binance+" rate: 1 %s ~= %f %s", fromCur, binanceRate, toCur) // check if the server rate deviates from the market rate by ± 5% // exit if true @@ -300,3 +308,15 @@ func (mgr *AssetsManager) IsOrderSchedulerRunning() bool { func (mgr *AssetsManager) GetShedulerRuntime() string { return time.Since(mgr.InstantSwap.SchedulerStartTime).Round(time.Second).String() } + +// MarketName is a convenience function that returns a proper market name for +// the from and to currencies used when fetching ticker data from binance. +func MarketName(fromCur, toCur string) string { + dcrToLtc := strings.EqualFold(fromCur, "dcr") && strings.EqualFold(toCur, "ltc") + btcToOthersExceptUsdt := strings.EqualFold(fromCur, "btc") && !strings.EqualFold(toCur, "usdt") + if dcrToLtc || btcToOthersExceptUsdt { + return toCur + "-" + fromCur // e.g DCR/BTC, LTC/BTC and not BTC/LTC or BTC/DCR + } + + return fromCur + "-" + toCur +} diff --git a/ui/page/exchange/create_order_page.go b/ui/page/exchange/create_order_page.go index 2fd456918..fc90f5ae8 100644 --- a/ui/page/exchange/create_order_page.go +++ b/ui/page/exchange/create_order_page.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "strconv" + "strings" "gioui.org/font" "gioui.org/layout" @@ -296,7 +297,7 @@ func (pg *CreateOrderPage) HandleUserInteractions() { switch evt.(type) { case widget.ChangeEvent: if pg.inputsNotEmpty(pg.fromAmountEditor.Edit.Editor) { - f, err := strconv.ParseFloat(pg.fromAmountEditor.Edit.Editor.Text(), 32) + fromAmt, err := strconv.ParseFloat(pg.fromAmountEditor.Edit.Editor.Text(), 32) if err != nil { // empty usd input pg.toAmountEditor.Edit.Editor.SetText("") @@ -307,7 +308,7 @@ func (pg *CreateOrderPage) HandleUserInteractions() { } pg.amountErrorText = "" if pg.exchangeRate != -1 { - value := f / pg.exchangeRate + value := fromAmt * pg.exchangeRate v := strconv.FormatFloat(value, 'f', 8, 64) pg.amountErrorText = "" pg.fromAmountEditor.Edit.LineColor = pg.Theme.Color.Gray2 @@ -396,7 +397,7 @@ func (pg *CreateOrderPage) HandleUserInteractions() { func (pg *CreateOrderPage) updateAmount() { if pg.inputsNotEmpty(pg.fromAmountEditor.Edit.Editor) { - f, err := strconv.ParseFloat(pg.fromAmountEditor.Edit.Editor.Text(), 32) + fromAmt, err := strconv.ParseFloat(pg.fromAmountEditor.Edit.Editor.Text(), 32) if err != nil { pg.toAmountEditor.Edit.Editor.SetText("") pg.amountErrorText = values.String(values.StrInvalidAmount) @@ -406,7 +407,7 @@ func (pg *CreateOrderPage) updateAmount() { } pg.amountErrorText = "" if pg.exchangeRate != -1 { - value := f / pg.exchangeRate + value := fromAmt * pg.exchangeRate v := strconv.FormatFloat(value, 'f', 8, 64) pg.amountErrorText = "" pg.fromAmountEditor.Edit.LineColor = pg.Theme.Color.Gray2 @@ -559,9 +560,9 @@ func (pg *CreateOrderPage) isExchangeAPIAllowed() bool { return isAllowed } -// isMultipleAssetTypeWalletAvailable checks if multiple asset types are available -// for exchange funtionality to run smoothly. Otherwise exchange functionality is -// disable till different asset type wallets are created. +// isMultipleAssetTypeWalletAvailable checks if multiple asset types are +// available for exchange functionality to run smoothly. Otherwise exchange +// functionality is disable till different asset type wallets are created. func (pg *CreateOrderPage) isMultipleAssetTypeWalletAvailable() bool { pg.errMsg = values.String(values.StrMinimumAssetType) allWallets := len(pg.WL.AssetsManager.AllWallets()) @@ -625,7 +626,7 @@ func (pg *CreateOrderPage) Layout(gtx C) D { overlay = layout.Stacked(func(gtx C) D { return components.DisablePageWithOverlay(pg.Load, nil, gtxCopy, msg, navBtn) }) - // Disable main page from recieving events + // Disable main page from receiving events. gtx = gtx.Disabled() } return layout.Stack{}.Layout(gtx, layout.Expanded(pg.layout), overlay) @@ -638,9 +639,10 @@ func (pg *CreateOrderPage) Layout(gtx C) D { Direction: layout.Center, }.Layout2(gtx, func(gtx C) D { return cryptomaterial.LinearLayout{ - Width: gtx.Dp(values.MarginPadding550), + Width: gtx.Dp(values.MarginPadding600), Height: cryptomaterial.MatchParent, Alignment: layout.Middle, + Padding: layout.Inset{Top: values.MarginPadding20}, }.Layout2(gtx, func(gtx C) D { return sp.Layout(pg.ParentWindow(), gtx) }) @@ -848,17 +850,25 @@ func (pg *CreateOrderPage) layout(gtx C) D { return pg.materialLoader.Layout(gtx) } - if pg.exchangeRate != -1 { + fromCur := strings.ToUpper(pg.fromCurrency.String()) + toCur := strings.ToUpper(pg.toCurrency.String()) + missingAsset := fromCur == "" || toCur == "" + if pg.exchangeRate > 0 && !missingAsset { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(func(gtx C) D { - exchangeRate := values.StringF(values.StrServerRate, pg.exchangeSelector.SelectedExchange().Name, pg.exchangeRate) + serverName := pg.exchangeSelector.SelectedExchange().Name + exchangeRate := values.StringF(values.StrServerRate, serverName, fromCur, pg.exchangeRate, toCur) txt := pg.Theme.Label(values.TextSize14, exchangeRate) txt.Font.Weight = font.SemiBold txt.Color = pg.Theme.Color.Gray1 return txt.Layout(gtx) }), layout.Rigid(func(gtx C) D { - binanceRate := values.StringF(values.StrBinanceRate, pg.binanceRate) + if pg.binanceRate == -1 { + return D{} + } + + binanceRate := values.StringF(values.StrBinanceRate, fromCur, pg.binanceRate, toCur) txt := pg.Theme.Label(values.TextSize14, binanceRate) txt.Font.Weight = font.SemiBold txt.Color = pg.Theme.Color.Gray1 @@ -1050,10 +1060,14 @@ func (pg *CreateOrderPage) updateExchangeRate() { } func (pg *CreateOrderPage) getExchangeRateInfo() error { + pg.exchangeRate = -1 + pg.binanceRate = -1 pg.fetchingRate = true + fromCur := pg.fromCurrency.String() + toCur := pg.toCurrency.String() params := api.ExchangeRateRequest{ - From: pg.fromCurrency.String(), - To: pg.toCurrency.String(), + From: fromCur, + To: toCur, Amount: libwallet.DefaultRateRequestAmount, // amount needs to be greater than 0 to get the exchange rate } res, err := pg.WL.AssetsManager.InstantSwap.GetExchangeRateInfo(pg.exchange, params) @@ -1064,24 +1078,22 @@ func (pg *CreateOrderPage) getExchangeRateInfo() error { return err } - var binanceRate float64 - ticker, err := pg.WL.AssetsManager.ExternalService.GetTicker(ext.Binance, values.String(values.StrDcrBtcPair)) + ticker, err := pg.WL.AssetsManager.ExternalService.GetTicker(ext.Binance, libwallet.MarketName(fromCur, toCur)) if err != nil { log.Error(err) } - if ticker != nil { - switch pg.fromCurrency { - case libutils.DCRWalletAsset: - binanceRate = 1 / ticker.LastTradePrice - case libutils.BTCWalletAsset: - binanceRate = ticker.LastTradePrice + if ticker != nil && ticker.LastTradePrice > 0 { + pg.binanceRate = ticker.LastTradePrice + /// Binance always returns ticker.LastTradePrice in's the quote asset + // unit e.g DCR-BTC, LTC-BTC. We will also do this when and if USDT is supported. + if pg.fromCurrency == libutils.BTCWalletAsset { + pg.binanceRate = 1 / ticker.LastTradePrice } } + pg.exchangeRate = res.EstimatedAmount // estimated receivable value for libwallet.DefaultRateRequestAmount (1) pg.min = res.Min pg.max = res.Max - pg.exchangeRate = res.ExchangeRate - pg.binanceRate = binanceRate pg.exchangeRateInfo = fmt.Sprintf(values.String(values.StrMinMax), pg.min, pg.max) pg.updateAmount() @@ -1092,8 +1104,8 @@ func (pg *CreateOrderPage) getExchangeRateInfo() error { return nil } -// loadOrderConfig loads the existing exchange configuration or creates a -// new one if none existed before. +// loadOrderConfig loads the existing exchange configuration or creates a new +// one if none existed before. func (pg *CreateOrderPage) loadOrderConfig() { sourceAccount, destinationAccount := int32(-1), int32(-1) var sourceWallet, destinationWallet *load.WalletMapping @@ -1118,13 +1130,13 @@ func (pg *CreateOrderPage) loadOrderConfig() { sourceAccount = exchangeConfig.SourceAccountNumber destinationAccount = exchangeConfig.DestinationAccountNumber } else { - // New exchange configuration will be generated using the set asset types - // since none existed before. - // It two distinct asset type wallet don't exist execution does get here. - wals := pg.WL.AssetsManager.AllWallets() - pg.fromCurrency = wals[0].GetAssetType() + // New exchange configuration will be generated using the set asset + // types since none existed before. It two distinct asset type wallet + // don't exist execution does get here. + wallets := pg.WL.AssetsManager.AllWallets() + pg.fromCurrency = wallets[0].GetAssetType() - for _, w := range wals { + for _, w := range wallets { if w.GetAssetType() != pg.fromCurrency { pg.toCurrency = w.GetAssetType() break @@ -1212,7 +1224,8 @@ func (pg *CreateOrderPage) loadOrderConfig() { pg.toAmountEditor.AssetTypeSelector.SetSelectedAssetType(pg.toCurrency) } -// updateExchangeConfig Updates the newly created or modified exchange configuration. +// updateExchangeConfig Updates the newly created or modified exchange +// configuration. func (pg *CreateOrderPage) updateExchangeConfig() { configInfo := sharedW.ExchangeConfig{ SourceAsset: pg.fromCurrency, @@ -1233,7 +1246,7 @@ func (pg *CreateOrderPage) listenForSyncNotifications() { pg.OrderNotificationListener = listeners.NewOrderNotificationListener() err := pg.WL.AssetsManager.InstantSwap.AddNotificationListener(pg.OrderNotificationListener, CreateOrderPageID) if err != nil { - log.Errorf("Error adding instanswap notification listener: %v", err) + log.Errorf("Error adding instantswap notification listener: %v", err) return } diff --git a/ui/page/exchange/order_scheduler_modal.go b/ui/page/exchange/order_scheduler_modal.go index 5ea43fa93..60e24ab83 100644 --- a/ui/page/exchange/order_scheduler_modal.go +++ b/ui/page/exchange/order_scheduler_modal.go @@ -65,6 +65,8 @@ func newOrderSchedulerModalModal(l *load.Load, data *orderData) *orderSchedulerM frequencySelector: NewFrequencySelector(l), orderData: data, copyRedirect: l.Theme.NewClickable(false), + binanceRate: -1, + exchangeRate: -1, } osm.cancelBtn = l.Theme.OutlineButton(values.String(values.StrCancel)) @@ -270,17 +272,21 @@ func (osm *orderSchedulerModal) Layout(gtx layout.Context) D { return osm.materialLoader.Layout(gtx) } - if osm.exchangeSelector.SelectedExchange() != nil && osm.exchangeRate != -1 { + fromCur := osm.fromCurrency.String() + toCur := osm.toCurrency.String() + missingAsset := fromCur == "" || toCur == "" + if osm.exchangeSelector.SelectedExchange() != nil && osm.exchangeRate != -1 && !missingAsset { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(func(gtx C) D { - exchangeRate := values.StringF(values.StrServerRate, osm.exchangeSelector.SelectedExchange().Name, osm.exchangeRate) + exName := osm.exchangeSelector.SelectedExchange().Name + exchangeRate := values.StringF(values.StrServerRate, exName, fromCur, osm.exchangeRate, toCur) txt := osm.Theme.Label(values.TextSize14, exchangeRate) txt.Font.Weight = font.SemiBold txt.Color = osm.Theme.Color.Gray1 return txt.Layout(gtx) }), layout.Rigid(func(gtx C) D { - binanceRate := values.StringF(values.StrBinanceRate, osm.binanceRate) + binanceRate := values.StringF(values.StrBinanceRate, fromCur, osm.binanceRate, toCur) txt := osm.Theme.Label(values.TextSize14, binanceRate) txt.Font.Weight = font.SemiBold txt.Color = osm.Theme.Color.Gray1 @@ -473,11 +479,15 @@ func (osm *orderSchedulerModal) startOrderScheduler() { } func (osm *orderSchedulerModal) getExchangeRateInfo() error { + osm.binanceRate = -1 + osm.exchangeRate = -1 osm.fetchingRate = true osm.rateError = false + fromCur := osm.fromCurrency.String() + toCur := osm.toCurrency.String() params := api.ExchangeRateRequest{ - From: osm.fromCurrency.String(), - To: osm.toCurrency.String(), + From: fromCur, + To: toCur, Amount: libwallet.DefaultRateRequestAmount, // amount needs to be greater than 0 to get the exchange rate } res, err := osm.WL.AssetsManager.InstantSwap.GetExchangeRateInfo(osm.exchange, params) @@ -487,24 +497,23 @@ func (osm *orderSchedulerModal) getExchangeRateInfo() error { return err } - ticker, err := osm.WL.AssetsManager.ExternalService.GetTicker(ext.Binance, values.String(values.StrDcrBtcPair)) + ticker, err := osm.WL.AssetsManager.ExternalService.GetTicker(ext.Binance, libwallet.MarketName(fromCur, toCur)) if err != nil { osm.rateError = true osm.fetchingRate = false return err } - var binanceRate float64 - switch osm.fromCurrency { - case utils.DCRWalletAsset: - binanceRate = ticker.LastTradePrice - case utils.BTCWalletAsset: - binanceRate = 1 / ticker.LastTradePrice + if ticker != nil && ticker.LastTradePrice > 0 { + osm.binanceRate = ticker.LastTradePrice + /// Binance always returns ticker.LastTradePrice in's the quote asset + // unit e.g DCR-BTC, LTC-BTC. We will also do this when and if USDT is supported. + if osm.fromCurrency == utils.BTCWalletAsset { + osm.binanceRate = 1 / ticker.LastTradePrice + } } - osm.exchangeRate = 1 / res.ExchangeRate - osm.binanceRate = binanceRate - + osm.exchangeRate = res.EstimatedAmount // estimated receivable value for libwallet.DefaultRateRequestAmount (1) osm.fetchingRate = false osm.rateError = false diff --git a/ui/values/dimensions.go b/ui/values/dimensions.go index 0ac38db10..9af7fc42c 100644 --- a/ui/values/dimensions.go +++ b/ui/values/dimensions.go @@ -86,8 +86,9 @@ var ( MarginPadding377 = unit.Dp(377) MarginPadding390 = unit.Dp(390) MarginPadding450 = unit.Dp(450) - MarginPadding550 = unit.Dp(550) MarginPadding500 = unit.Dp(500) + MarginPadding550 = unit.Dp(550) + MarginPadding600 = unit.Dp(600) TextSize10 = unit.Sp(10) TextSize12 = unit.Sp(12) diff --git a/ui/values/localizable/en.go b/ui/values/localizable/en.go index 1193dc9cb..c438e5035 100644 --- a/ui/values/localizable/en.go +++ b/ui/values/localizable/en.go @@ -67,7 +67,7 @@ const EN = ` "bestBlockAge" = "Best block age" "bestBlocks" = "Best block" "bestBlockTimestamp" = "Best block timestamp" -"binanceRate" = "Binance rate: %f" +"binanceRate" = "Binance rate: 1 %s ~= %f %s" "blockHeaderFetched" = "Block header fetched" "blockHeaderFetchedCount" = "%d of %d" "blocksLeft" = "%d blocks left" @@ -157,7 +157,6 @@ const EN = ` "daysAgo" = "%d days ago" "daysToMiss" = "Days to miss" "daysToVote" = "Days to vote" -"dcrBtcPair" = "dcr-btc" "dcrCaps" = "DCR" "dcrDex" = "DCRDEX" "dcrReceived" = "You have received %s DCR" @@ -524,7 +523,7 @@ const EN = ` "sendWarning" = "Your DCR will be sent after this step." "sent" = "Sent" "server" = "Server" -"serverRate" = "%s rate: %f" +"serverRate" = "%s rate: 1 %s ~= %f %s" "setchoice" = "Set Choice" "setGapLimit" = "Set Gap Limit" "setGapLimitInfo" = "%v In some rare circumstances, address may not be discovered with the default gap limit of 20. It's recommended to only use this functionality after trying other options. And be aware that raising the gap limit above 100 will lead to excessive loading times to complete this request. %v" diff --git a/ui/values/strings.go b/ui/values/strings.go index a86d67a0c..1f241271b 100644 --- a/ui/values/strings.go +++ b/ui/values/strings.go @@ -267,7 +267,6 @@ const ( StrDaysAgo = "daysAgo" StrDaysToMiss = "daysToMiss" StrDaysToVote = "daysToVote" - StrDcrBtcPair = "dcrBtcPair" StrDCRCaps = "dcrCaps" StrDcrDex = "dcrDex" StrDcrReceived = "dcrReceived" From f9d5e3f8876a1816adafe067a7e0a673051503b3 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Wed, 4 Oct 2023 19:46:31 +0100 Subject: [PATCH 2/3] dreacot review changes Signed-off-by: Philemon Ukane --- libwallet/ext/service.go | 2 +- libwallet/instantswap.go | 7 +++++-- ui/page/exchange/create_order_page.go | 2 +- ui/page/exchange/order_scheduler_modal.go | 6 +++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libwallet/ext/service.go b/libwallet/ext/service.go index b61c65783..439b45274 100644 --- a/libwallet/ext/service.go +++ b/libwallet/ext/service.go @@ -317,7 +317,7 @@ func (s *Service) GetXpub(xPub string) (xPubBalAndTxs *XpubBalAndTxs, err error) func (s *Service) GetTicker(exchange string, market string) (ticker *Ticker, err error) { switch exchange { case Binance: - // Return early for dcr-ltc markets ad binance does not support this + // Return early for dcr-ltc markets as binance does not support this // atm. if strings.EqualFold(market, "ltc-dcr") { return &Ticker{}, nil diff --git a/libwallet/instantswap.go b/libwallet/instantswap.go index 712efc11a..fcad405c4 100644 --- a/libwallet/instantswap.go +++ b/libwallet/instantswap.go @@ -14,6 +14,7 @@ import ( "github.com/crypto-power/cryptopower/libwallet/ext" "github.com/crypto-power/cryptopower/libwallet/instantswap" "github.com/crypto-power/cryptopower/libwallet/utils" + "github.com/crypto-power/cryptopower/ui/values" "github.com/crypto-power/instantswap/blockexplorer" _ "github.com/crypto-power/instantswap/blockexplorer/btcexplorer" //nolint:revive _ "github.com/crypto-power/instantswap/blockexplorer/dcrexplorer" @@ -120,8 +121,10 @@ func (mgr *AssetsManager) StartScheduler(ctx context.Context, params instantswap binanceRate = 1 / ticker.LastTradePrice } - log.Info(params.Order.ExchangeServer.Server+" rate: 1 %s ~= %f %s", fromCur, exchangeServerRate, toCur) - log.Info(ext.Binance+" rate: 1 %s ~= %f %s", fromCur, binanceRate, toCur) + serverRateStr := values.StringF(values.StrServerRate, params.Order.ExchangeServer.Server, fromCur, exchangeServerRate, toCur) + log.Info(serverRateStr) + binanceRateStr := values.StringF(values.StrBinanceRate, fromCur, binanceRate, toCur) + log.Info(binanceRateStr) // check if the server rate deviates from the market rate by ± 5% // exit if true diff --git a/ui/page/exchange/create_order_page.go b/ui/page/exchange/create_order_page.go index fc90f5ae8..2ba978fa0 100644 --- a/ui/page/exchange/create_order_page.go +++ b/ui/page/exchange/create_order_page.go @@ -864,7 +864,7 @@ func (pg *CreateOrderPage) layout(gtx C) D { return txt.Layout(gtx) }), layout.Rigid(func(gtx C) D { - if pg.binanceRate == -1 { + if pg.binanceRate <= 0 { return D{} } diff --git a/ui/page/exchange/order_scheduler_modal.go b/ui/page/exchange/order_scheduler_modal.go index 60e24ab83..67fc0ff81 100644 --- a/ui/page/exchange/order_scheduler_modal.go +++ b/ui/page/exchange/order_scheduler_modal.go @@ -275,7 +275,7 @@ func (osm *orderSchedulerModal) Layout(gtx layout.Context) D { fromCur := osm.fromCurrency.String() toCur := osm.toCurrency.String() missingAsset := fromCur == "" || toCur == "" - if osm.exchangeSelector.SelectedExchange() != nil && osm.exchangeRate != -1 && !missingAsset { + if osm.exchangeSelector.SelectedExchange() != nil && osm.exchangeRate > 0 && !missingAsset { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(func(gtx C) D { exName := osm.exchangeSelector.SelectedExchange().Name @@ -286,6 +286,10 @@ func (osm *orderSchedulerModal) Layout(gtx layout.Context) D { return txt.Layout(gtx) }), layout.Rigid(func(gtx C) D { + if osm.binanceRate <= 0 { + return D{} + } + binanceRate := values.StringF(values.StrBinanceRate, fromCur, osm.binanceRate, toCur) txt := osm.Theme.Label(values.TextSize14, binanceRate) txt.Font.Weight = font.SemiBold From 2c1bd8e76e184cb5a2e817db888413741005df89 Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Wed, 4 Oct 2023 20:00:43 +0100 Subject: [PATCH 3/3] go fmt Signed-off-by: Philemon Ukane --- ui/page/exchange/order_scheduler_modal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/page/exchange/order_scheduler_modal.go b/ui/page/exchange/order_scheduler_modal.go index 67fc0ff81..5ea93892f 100644 --- a/ui/page/exchange/order_scheduler_modal.go +++ b/ui/page/exchange/order_scheduler_modal.go @@ -289,7 +289,7 @@ func (osm *orderSchedulerModal) Layout(gtx layout.Context) D { if osm.binanceRate <= 0 { return D{} } - + binanceRate := values.StringF(values.StrBinanceRate, fromCur, osm.binanceRate, toCur) txt := osm.Theme.Label(values.TextSize14, binanceRate) txt.Font.Weight = font.SemiBold