Skip to content

Commit

Permalink
rename quantity to amount on dex order form and use core.PreOrder for…
Browse files Browse the repository at this point in the history
… estimates

Signed-off-by: Philemon Ukane <[email protected]>
  • Loading branch information
ukane-philemon committed Oct 19, 2024
1 parent 1aafc71 commit ffb6890
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 43 deletions.
1 change: 1 addition & 0 deletions libwallet/dex_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ type DEXClient interface {
WalletIDForAsset(assetID uint32) (*int, error)
MaxBuy(host string, base, quote uint32, rate uint64) (*core.MaxOrderEstimate, error)
MaxSell(host string, base, quote uint32) (*core.MaxOrderEstimate, error)
PreOrder(form *core.TradeForm) (*core.OrderEstimate, error)
Cancel(oid dex.Bytes) error
}
105 changes: 66 additions & 39 deletions ui/page/dcrdex/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ type DEXMarketPage struct {
toggleBuyAndSellBtn *cryptomaterial.SegmentedControl
orderTypesDropdown *cryptomaterial.DropDown

priceEditor cryptomaterial.Editor
lotsEditor cryptomaterial.Editor
totalEditor cryptomaterial.Editor
quantityEditor cryptomaterial.Editor
lotsInfoBtn *cryptomaterial.Clickable
priceEditor cryptomaterial.Editor
lotsEditor cryptomaterial.Editor
totalEditor cryptomaterial.Editor
amountEditor cryptomaterial.Editor
lotsInfoBtn *cryptomaterial.Clickable

maxBuyOrSellStr string
orderFeeEstimateStr string
Expand Down Expand Up @@ -156,7 +156,7 @@ func NewDEXMarketPage(l *load.Load, selectServer string) *DEXMarketPage {
lotsEditor: newTextEditor(l.Theme, values.String(values.StrLots), "", false),
lotsInfoBtn: th.NewClickable(false),
totalEditor: newTextEditor(th, values.String(values.StrTotal), "", false),
quantityEditor: newTextEditor(th, values.String(values.StrQuantity), "", false),
amountEditor: newTextEditor(th, values.String(values.StrAmount), "", false),
maxBuyOrSellStr: "---",
orderFeeEstimateStr: "------",
loginBtn: th.Button(values.String(values.StrLogin)),
Expand All @@ -180,9 +180,9 @@ func NewDEXMarketPage(l *load.Load, selectServer string) *DEXMarketPage {

pg.orderTypesDropdown.CollapsedLayoutTextDirection = layout.E

pg.priceEditor.IsTitleLabel, pg.lotsEditor.IsTitleLabel, pg.totalEditor.IsTitleLabel, pg.quantityEditor.IsTitleLabel = false, false, false, false
pg.priceEditor.IsTitleLabel, pg.lotsEditor.IsTitleLabel, pg.totalEditor.IsTitleLabel, pg.amountEditor.IsTitleLabel = false, false, false, false

pg.quantityEditor.Editor.ReadOnly = true
pg.amountEditor.Editor.ReadOnly = true
pg.totalEditor.Editor.ReadOnly = true

pg.seeFullOrderBookBtn.HighlightColor, pg.seeFullOrderBookBtn.Background = color.NRGBA{}, color.NRGBA{}
Expand Down Expand Up @@ -415,7 +415,7 @@ func (pg *DEXMarketPage) fetchOrderBook() {
// Update order form editors.
pg.priceEditor.ExtraText = pg.selectedMarketOrderBook.quoteSymbol + " / " + pg.selectedMarketOrderBook.baseSymbol
pg.totalEditor.ExtraText = pg.selectedMarketOrderBook.quoteSymbol
pg.quantityEditor.ExtraText = pg.selectedMarketOrderBook.baseSymbol
pg.amountEditor.ExtraText = pg.selectedMarketOrderBook.baseSymbol

pg.showLoader = true
go func() {
Expand Down Expand Up @@ -869,9 +869,9 @@ func (pg *DEXMarketPage) orderForm(gtx C) D {
layout.Rigid(func(gtx C) D {
return orderFormRow(gtx, vertical, []layout.FlexChild{
layout.Rigid(func(gtx C) D {
return layout.Inset{Bottom: dp5}.Layout(gtx, pg.semiBoldLabelText(fmt.Sprintf("%s (%s)", values.String(values.StrQuantity), lotsSubText)).Layout)
return layout.Inset{Bottom: dp5}.Layout(gtx, pg.semiBoldLabelText(fmt.Sprintf("%s (%s)", values.String(values.StrAmount), lotsSubText)).Layout)
}),
layout.Rigid(pg.quantityEditor.Layout),
layout.Rigid(pg.amountEditor.Layout),
})
}),
layout.Rigid(func(gtx C) D {
Expand Down Expand Up @@ -970,20 +970,18 @@ func (pg *DEXMarketPage) missingMarketWallet() libutils.AssetType {
return ""
}

func (pg *DEXMarketPage) estimateOrderFee() {
func (pg *DEXMarketPage) setMaxBuyAndMaxSell() {
pg.maxBuyOrSellStr = "---"
pg.orderFeeEstimateStr = values.String(values.StrNotAvailable)
host, base, quote := pg.serverSelector.Selected(), pg.selectedMarketOrderBook.base, pg.selectedMarketOrderBook.quote

dexc := pg.AssetsManager.DexClient()

mkt := pg.selectedMarketInfo()
price := pg.orderPrice(mkt)
if price <= 0 && !pg.isSellOrder() {
return
}

host, base, quote := pg.serverSelector.Selected(), pg.selectedMarketOrderBook.base, pg.selectedMarketOrderBook.quote

dexc := pg.AssetsManager.DexClient()

var est *core.MaxOrderEstimate
var err error
if pg.isSellOrder() {
Expand All @@ -995,18 +993,9 @@ func (pg *DEXMarketPage) estimateOrderFee() {
return
}

swapFee := conventionalAmt(est.Swap.MaxFees)
redeemFee := conventionalAmt(est.Redeem.RealisticBestCase)
baseSym := convertAssetIDToAssetType(base)
quoteSym := convertAssetIDToAssetType(quote)
maxBuyOrSellAssetSym := baseSym
// Swap fees are denominated in the outgoing asset's unit, while Redeem fees
// are denominated in the incoming asset's unit.
if pg.isSellOrder() { // Outgoing is base asset
pg.orderFeeEstimateStr = values.StringF(values.StrSwapAndRedeemFee, fmt.Sprintf("%f %s", swapFee, baseSym), fmt.Sprintf("%f %s", redeemFee, quoteSym))
} else { // Outgoing is quote asset
maxBuyOrSellAssetSym = quoteSym
pg.orderFeeEstimateStr = values.StringF(values.StrSwapAndRedeemFee, fmt.Sprintf("%f %s", swapFee, quoteSym), fmt.Sprintf("%f %s", redeemFee, baseSym))
maxBuyOrSellAssetSym := convertAssetIDToAssetType(base)
if !pg.isSellOrder() {
maxBuyOrSellAssetSym = convertAssetIDToAssetType(quote)
}

/* TODO: Check reputation value i.e parcel limit - used parcel. If estimated
Expand All @@ -1019,6 +1008,43 @@ func (pg *DEXMarketPage) estimateOrderFee() {
)
}

func (pg *DEXMarketPage) estimateOrderFee() {
pg.orderFeeEstimateStr = values.String(values.StrNotAvailable)

mkt := pg.selectedMarketInfo()
price := pg.orderPrice(mkt)
if price <= 0 && !pg.isSellOrder() {
return
}

dexc := pg.AssetsManager.DexClient()

form := pg.validatedOrderFormInfo()
if form == nil {
return
}

// Use fee estimate from pre-order.
orderEst, err := dexc.PreOrder(form)
if err != nil || orderEst.Swap == nil || orderEst.Swap.Estimate == nil || orderEst.Redeem == nil || orderEst.Redeem.Estimate == nil {
return
}

s := orderEst.Swap.Estimate
r := orderEst.Redeem.Estimate
swapFee := conventionalAmt(s.MaxFees)
redeemFee := conventionalAmt(r.RealisticBestCase)
baseSym := convertAssetIDToAssetType(pg.selectedMarketOrderBook.base)
quoteSym := convertAssetIDToAssetType(pg.selectedMarketOrderBook.quote)
// Swap fees are denominated in the outgoing asset's unit, while Redeem fees
// are denominated in the incoming asset's unit.
if pg.isSellOrder() { // Outgoing is base asset
pg.orderFeeEstimateStr = values.StringF(values.StrSwapAndRedeemFee, fmt.Sprintf("%f %s", swapFee, baseSym), fmt.Sprintf("%f %s", redeemFee, quoteSym))
} else { // Outgoing is quote asset
pg.orderFeeEstimateStr = values.StringF(values.StrSwapAndRedeemFee, fmt.Sprintf("%f %s", swapFee, quoteSym), fmt.Sprintf("%f %s", redeemFee, baseSym))
}
}

func trimZeros(s string) string {
return strings.TrimSuffix(strings.TrimRight(s, "0"), ".")
}
Expand Down Expand Up @@ -1371,8 +1397,9 @@ func (pg *DEXMarketPage) refreshOrderForm() {
pg.lotsEditor.UpdateFocus(true)
pg.lotsEditor.Editor.SetText("")
pg.totalEditor.Editor.SetText("")
pg.quantityEditor.Editor.SetText("")
pg.amountEditor.Editor.SetText("")
pg.refreshPriceField()
pg.orderFeeEstimateStr = values.String(values.StrNotAvailable)

if !isSell { // Buy
pg.createOrderBtn.Text = values.String(values.StrBuy)
Expand All @@ -1395,10 +1422,9 @@ func (pg *DEXMarketPage) orderFormEditorSubtext() (totalSubText, lotsSubText str
}

func (pg *DEXMarketPage) handleEditorEvents(gtx C) {
var toggleBuyAndSellBtnChanged bool
if pg.toggleBuyAndSellBtn.Changed() {
toggleBuyAndSellBtnChanged = true
pg.refreshOrderForm()
pg.setMaxBuyAndMaxSell()
}

if pg.orderTypesDropdown.Changed(gtx) {
Expand Down Expand Up @@ -1445,7 +1471,7 @@ func (pg *DEXMarketPage) handleEditorEvents(gtx C) {
}
}

if (reEstimateFee || toggleBuyAndSellBtnChanged) && !pg.showLoader {
if reEstimateFee && !pg.showLoader {
pg.showLoader = true
go func() {
pg.estimateOrderFee()
Expand Down Expand Up @@ -1504,6 +1530,7 @@ func (pg *DEXMarketPage) HandleUserInteractions(gtx C) {
if pg.marketSelector.Changed(gtx) {
pg.fetchOrderBook()
pg.refreshOrderForm()
pg.setMaxBuyAndMaxSell()
}

if pg.orderHistoryBtn.Clicked(gtx) {
Expand Down Expand Up @@ -1895,30 +1922,30 @@ func (pg *DEXMarketPage) calculateOrderAmount(mkt *core.Market) bool {
if orderPrice == 0 {
pg.lotsEditor.Editor.SetText("")
pg.totalEditor.Editor.SetText("")
pg.quantityEditor.Editor.SetText("")
pg.amountEditor.Editor.SetText("")
return false
}

// Use only lots editor to calculate.
lotsStr := pg.lotsEditor.Editor.Text()
if lotsStr == "" {
pg.totalEditor.Editor.SetText("")
pg.quantityEditor.Editor.SetText("")
pg.amountEditor.Editor.SetText("")
return false
}

lots, err := strconv.ParseFloat(lotsStr, 64)
if err != nil || lots <= 0 || float64(int64(lots)) != lots {
pg.lotsEditor.SetError(values.String(values.StrInvalidLot))
pg.totalEditor.Editor.SetText("")
pg.quantityEditor.Editor.SetText("")
pg.amountEditor.Editor.SetText("")
return false
}

quantity := lots * mkt.MsgRateToConventional(mkt.LotSize)
amtText := trimmedConventionalAmtString(quantity * orderPrice)
amount := lots * mkt.MsgRateToConventional(mkt.LotSize)
amtText := trimmedConventionalAmtString(amount * orderPrice)
pg.totalEditor.Editor.SetText(amtText)
pg.quantityEditor.Editor.SetText(fmt.Sprint(trimmedConventionalAmtString(quantity)))
pg.amountEditor.Editor.SetText(fmt.Sprint(trimmedConventionalAmtString(amount)))

return true
}
Expand Down
5 changes: 2 additions & 3 deletions ui/values/localizable/en.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,6 @@ const EN = `
"to" = "To"
"token" = "Token: %s"
"total" = "Total"
"quantity" = "Quantity"
"totalAmount" = "Total Amount"
"totalBalance" = "Total Balance"
"totalCost" = "Total cost"
Expand Down Expand Up @@ -851,15 +850,15 @@ const EN = `
"24hHigh" = "24h High"
"lots" = "Lots"
"lotSizeFmt" = "1 Lot = %v"
"lotsExplanation" = "The Lot size is the minimum amount you can buy or sell in one trade. Lot sizes are chosen to minimize the on chain fees to below ~1% of each trade value. If you want to buy or sell 10 (or any number) lots, total order quantity will be -> (number of lots * lots size) denominated in the base currency."
"lotsExplanation" = "The Lot size is the minimum amount you can buy or sell in one trade. Lot sizes are chosen to minimize the on chain fees to below ~1% of each trade value. If you want to buy or sell 10 (or any number) lots, total order amount will be -> (number of lots * lots size) denominated in the base currency."
"invalidPrice" = "Invalid price"
"invalidLot" = "Invalid lot: Lot must be a valid non-decimal number"
"minMaxLot" = "Min Lots: %d, Max Lots: %d"
"buy" = "Buy"
"sell" = "Sell"
"immediate" = "Immediate"
"immediateOrder" = "Immediate Order"
"immediateExplanation" = "If the order doesn't fully match during the next match cycle, any unmatched quantity will not be booked or matched again. Taker-only order."
"immediateExplanation" = "If the order doesn't fully match during the next match cycle, any unmatched quantity/amount will not be booked or matched again. Taker-only order."
"limit" = "Limit"
"estimatedFee" = "Est. Fee: "
"epoch" = "Epoch"
Expand Down
1 change: 0 additions & 1 deletion ui/values/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,6 @@ const (
StrTo = "to"
StrToken = "token"
StrTotal = "total"
StrQuantity = "quantity"
StrTotalAmount = "totalAmount"
StrTotalBalance = "totalBalance"
StrTotalCost = "totalCost"
Expand Down

0 comments on commit ffb6890

Please sign in to comment.