mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-26 14:41:12 +00:00
fix(liquidity): move quote details to confirmation
This commit is contained in:
@@ -4,6 +4,8 @@ import QtQuick
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Logos.Controls
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
@@ -75,8 +77,9 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationDeposit"
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("Deposit")
|
||||
label: root.snapshot.depositLabel || qsTr("Deposit")
|
||||
value: qsTr("%1 + %2")
|
||||
.arg(root.snapshot.depositAText || "-")
|
||||
.arg(root.snapshot.depositBText || "-")
|
||||
@@ -84,11 +87,107 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationInitialPrice"
|
||||
Layout.fillWidth: true
|
||||
visible: root.isMissingPool() && String(root.snapshot.initialPriceText || "").length > 0
|
||||
label: qsTr("Initial price")
|
||||
value: root.snapshot.initialPriceText || "-"
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationInversePrice"
|
||||
Layout.fillWidth: true
|
||||
visible: root.isMissingPool() && String(root.snapshot.inverseInitialPriceText || "").length > 0
|
||||
label: qsTr("Inverse price")
|
||||
value: root.snapshot.inverseInitialPriceText || "-"
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationDepositMultiplier"
|
||||
Layout.fillWidth: true
|
||||
visible: root.isMissingPool() && String(root.snapshot.depositMultiplierText || "").length > 0
|
||||
label: qsTr("Deposit multiplier")
|
||||
value: root.snapshot.depositMultiplierText || "-"
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationDepositScale"
|
||||
Layout.fillWidth: true
|
||||
visible: root.isMissingPool() && String(root.snapshot.depositScaleText || "").length > 0
|
||||
label: qsTr("Deposit scale")
|
||||
value: root.snapshot.depositScaleText || "-"
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationExpectedLp"
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("Expected LP")
|
||||
value: root.snapshot.expectedLpText || "-"
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationLpGuard"
|
||||
Layout.fillWidth: true
|
||||
label: root.snapshot.lpGuardLabel || qsTr("Minimum LP")
|
||||
value: root.snapshot.lpGuardText || "-"
|
||||
}
|
||||
|
||||
SummaryRow {
|
||||
objectName: "confirmationPool"
|
||||
Layout.fillWidth: true
|
||||
visible: String(root.snapshot.poolId || "").length > 0
|
||||
label: qsTr("Pool")
|
||||
value: String(root.snapshot.poolId || "")
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
|
||||
LogosButton {
|
||||
id: accountPlanButton
|
||||
|
||||
objectName: "confirmationAccountPlan"
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
visible: root.accountPlan().length > 0
|
||||
text: qsTr("Account plan (%1)").arg(root.accountPlan().length)
|
||||
property bool expanded: false
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
radius: 6
|
||||
onClicked: expanded = !expanded
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
visible: accountPlanButton.visible && accountPlanButton.expanded
|
||||
|
||||
Repeater {
|
||||
model: root.accountPlan()
|
||||
|
||||
SummaryRow {
|
||||
required property var modelData
|
||||
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("%1. %2 · %3")
|
||||
.arg(Number(modelData.order || 0) + 1)
|
||||
.arg(String(modelData.role || "-"))
|
||||
.arg(String(modelData.action || "-"))
|
||||
value: modelData.accountId ? String(modelData.accountId)
|
||||
: qsTr("Assigned by wallet")
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isMissingPool() {
|
||||
return root.snapshot.poolStatus === "missing_pool"
|
||||
}
|
||||
|
||||
function accountPlan() {
|
||||
return root.snapshot.accountPreview || []
|
||||
}
|
||||
|
||||
function destinationRows() {
|
||||
var rows = []
|
||||
var options = root.snapshot.lpHoldingOptions || []
|
||||
|
||||
@@ -548,96 +548,6 @@ AmmActionCard {
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 9
|
||||
visible: root.quotePayload.status === "ok"
|
||||
&& root.quoteMatchesPair()
|
||||
&& !root.quoteStale
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 1
|
||||
color: root.theme.colors.divider
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
label: root.activePool ? qsTr("Expected spend") : qsTr("Opening deposit")
|
||||
value: root.depositSummary()
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
visible: root.missingPool
|
||||
label: qsTr("Initial price")
|
||||
value: root.initialPriceText(false)
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
visible: root.missingPool
|
||||
label: qsTr("Inverse price")
|
||||
value: root.initialPriceText(true)
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
visible: root.missingPool
|
||||
label: qsTr("Deposit multiplier")
|
||||
value: root.depositMultiplierValue()
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
visible: root.missingPool
|
||||
label: qsTr("Deposit scale")
|
||||
value: root.depositBasisPointsText()
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
label: qsTr("Expected LP")
|
||||
value: root.rawLpText(root.quotePayload.expectedLpRaw)
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
label: root.activePool ? qsTr("Minimum LP") : qsTr("Locked LP")
|
||||
value: root.rawLpText(root.activePool
|
||||
? root.quotePayload.minimumLpRaw
|
||||
: root.quotePayload.lockedLpRaw)
|
||||
}
|
||||
|
||||
LabelValueRow {
|
||||
label: qsTr("Pool")
|
||||
value: String(root.quotePayload.poolId || "")
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
|
||||
LogosButton {
|
||||
id: accountPlanButton
|
||||
text: qsTr("Account plan (%1)").arg(root.accountPreview().length)
|
||||
enabled: root.accountPreview().length > 0
|
||||
property bool checked: false
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
radius: 6
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
onClicked: checked = !checked
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
visible: accountPlanButton.checked
|
||||
|
||||
Repeater {
|
||||
model: root.accountPreview()
|
||||
|
||||
LabelValueRow {
|
||||
required property var modelData
|
||||
label: qsTr("%1. %2 · %3").arg(modelData.order + 1).arg(modelData.role).arg(modelData.action)
|
||||
value: modelData.accountId ? modelData.accountId : qsTr("Assigned by wallet")
|
||||
valueWrapAnywhere: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: warningTextItem.implicitHeight + 20
|
||||
@@ -683,32 +593,6 @@ AmmActionCard {
|
||||
}
|
||||
}
|
||||
|
||||
component LabelValueRow: RowLayout {
|
||||
required property string label
|
||||
required property string value
|
||||
property bool valueWrapAnywhere: false
|
||||
Layout.fillWidth: true
|
||||
spacing: 12
|
||||
|
||||
Text {
|
||||
text: parent.label
|
||||
color: root.theme.colors.textSecondary
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Text {
|
||||
text: parent.value
|
||||
color: root.theme.colors.textPrimary
|
||||
font.pixelSize: 12
|
||||
font.weight: Font.Medium
|
||||
horizontalAlignment: Text.AlignRight
|
||||
wrapMode: parent.valueWrapAnywhere ? Text.WrapAnywhere : Text.Wrap
|
||||
Layout.maximumWidth: root.compact ? 190 : 280
|
||||
}
|
||||
}
|
||||
|
||||
component PriceRatioAdjustment: RowLayout {
|
||||
id: ratioAdjustment
|
||||
|
||||
@@ -1531,20 +1415,21 @@ AmmActionCard {
|
||||
}
|
||||
|
||||
function quoteAmount(canonicalAField, canonicalBField, side) {
|
||||
return root.quoteAmountFromQuote(root.quotePayload,
|
||||
canonicalAField,
|
||||
canonicalBField,
|
||||
side)
|
||||
}
|
||||
|
||||
function quoteAmountFromQuote(quote, canonicalAField, canonicalBField, side) {
|
||||
var token = side === "A" ? root.tokenA : root.tokenB
|
||||
var decimals = side === "A" ? root.decimalsA : root.decimalsB
|
||||
var raw = root.displayRaw(canonicalAField, canonicalBField, side)
|
||||
var raw = root.displayQuoteRaw(quote, canonicalAField, canonicalBField, side)
|
||||
return raw.length > 0
|
||||
? qsTr("%1 %2").arg(AmountMath.formatRaw(raw, decimals)).arg(root.shortTokenName(token))
|
||||
: "—"
|
||||
}
|
||||
|
||||
function depositSummary() {
|
||||
var amountA = root.quoteAmount("actualAmountARaw", "actualAmountBRaw", "A")
|
||||
var amountB = root.quoteAmount("actualAmountARaw", "actualAmountBRaw", "B")
|
||||
return amountA + " + " + amountB
|
||||
}
|
||||
|
||||
function initialPriceText(inverse) {
|
||||
var price = inverse ? root.inverseInitialPrice : root.initialPrice
|
||||
if (price.length === 0)
|
||||
@@ -1603,19 +1488,59 @@ AmmActionCard {
|
||||
return warnings.length > 0 ? root.issueText(warnings[0].code) : ""
|
||||
}
|
||||
|
||||
function confirmationDetails(quote) {
|
||||
var sourceQuote = quote || ({})
|
||||
var status = String(sourceQuote.poolStatus || root.poolStatus || "")
|
||||
var isActivePool = status === "active_pool"
|
||||
var accountPlan = sourceQuote.accountPreview || []
|
||||
return {
|
||||
"poolStatus": status,
|
||||
"depositLabel": isActivePool ? qsTr("Expected spend") : qsTr("Opening deposit"),
|
||||
"depositAText": root.quoteAmountFromQuote(sourceQuote,
|
||||
"actualAmountARaw",
|
||||
"actualAmountBRaw",
|
||||
"A"),
|
||||
"depositBText": root.quoteAmountFromQuote(sourceQuote,
|
||||
"actualAmountARaw",
|
||||
"actualAmountBRaw",
|
||||
"B"),
|
||||
"initialPriceText": isActivePool ? "" : root.initialPriceText(false),
|
||||
"inverseInitialPriceText": isActivePool ? "" : root.initialPriceText(true),
|
||||
"depositMultiplierText": isActivePool ? "" : root.depositMultiplierValue(),
|
||||
"depositScaleText": isActivePool ? "" : root.depositBasisPointsText(),
|
||||
"expectedLpText": root.rawLpText(sourceQuote.expectedLpRaw),
|
||||
"lpGuardLabel": isActivePool ? qsTr("Minimum LP") : qsTr("Locked LP"),
|
||||
"lpGuardText": root.rawLpText(isActivePool
|
||||
? sourceQuote.minimumLpRaw
|
||||
: sourceQuote.lockedLpRaw),
|
||||
"poolId": String(sourceQuote.poolId || ""),
|
||||
"accountPreview": accountPlan
|
||||
}
|
||||
}
|
||||
|
||||
function refreshConfirmationSnapshot(snapshot) {
|
||||
var refreshed = {}
|
||||
for (var field in snapshot)
|
||||
refreshed[field] = snapshot[field]
|
||||
var sourceQuote = refreshed.quote || root.quotePayload
|
||||
refreshed.quote = sourceQuote
|
||||
var details = root.confirmationDetails(sourceQuote)
|
||||
for (var detail in details)
|
||||
refreshed[detail] = details[detail]
|
||||
return refreshed
|
||||
}
|
||||
|
||||
function submissionSnapshot() {
|
||||
var built = root.buildQuoteRequest()
|
||||
var poolProbe = root.poolProbeRequest(built.request)
|
||||
poolProbe.poolId = String(root.quotePayload.poolId || "")
|
||||
return {
|
||||
return root.refreshConfirmationSnapshot({
|
||||
"request": built.request,
|
||||
"poolProbeRequest": poolProbe,
|
||||
"quote": root.quotePayload,
|
||||
"quoteHash": String(root.quotePayload.quoteHash || ""),
|
||||
"pairText": qsTr("%1 / %2").arg(root.shortTokenName(root.tokenA)).arg(root.shortTokenName(root.tokenB)),
|
||||
"feeText": root.feeLabel(root.selectedFeeBps),
|
||||
"depositAText": root.quoteAmount("actualAmountARaw", "actualAmountBRaw", "A"),
|
||||
"depositBText": root.quoteAmount("actualAmountARaw", "actualAmountBRaw", "B"),
|
||||
"expectedLpText": root.rawLpText(root.quotePayload.expectedLpRaw),
|
||||
"instruction": String(root.quotePayload.instruction || ""),
|
||||
"lpHoldingOptions": root.quotePayload.lpHoldingOptions || [],
|
||||
"selectedLpHoldingId": String(root.quotePayload.selectedLpHoldingId || ""),
|
||||
@@ -1623,7 +1548,7 @@ AmmActionCard {
|
||||
&& root.quotePayload.lpDestinationRequired !== true,
|
||||
"lpDestinationRequired": root.quotePayload.lpDestinationRequired === true,
|
||||
"quoteReady": root.quotePayload.canSubmit === true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onlyLpDestinationBlocks() {
|
||||
|
||||
@@ -253,7 +253,7 @@ Item {
|
||||
}
|
||||
|
||||
function onConfirmationQuoteReady(snapshot) {
|
||||
confirmationDialog.updateSnapshot(snapshot)
|
||||
confirmationDialog.updateSnapshot(form.refreshConfirmationSnapshot(snapshot))
|
||||
}
|
||||
|
||||
function onSubmitSucceeded() {
|
||||
|
||||
@@ -291,6 +291,7 @@ QtObject {
|
||||
var refreshed = {}
|
||||
for (var field in snapshot)
|
||||
refreshed[field] = snapshot[field]
|
||||
refreshed.quote = quote
|
||||
refreshed.quoteHash = String(quote.quoteHash || "")
|
||||
refreshed.expectedLpText = String(quote.expectedLpRaw || "") + " raw LP"
|
||||
refreshed.instruction = String(quote.instruction || "")
|
||||
|
||||
@@ -79,4 +79,62 @@ TestCase {
|
||||
verify(picker)
|
||||
compare(picker.background.color, summary.theme.colors.panelBg)
|
||||
}
|
||||
|
||||
function test_confirmationShowsQuoteDetails() {
|
||||
var summary = createTemporaryObject(summaryComponent, testCase, {
|
||||
"snapshot": {
|
||||
"instruction": "NewDefinition",
|
||||
"poolStatus": "missing_pool",
|
||||
"depositLabel": "Opening deposit",
|
||||
"depositAText": "2 Low",
|
||||
"depositBText": "3 High",
|
||||
"initialPriceText": "1 Low = 1.5 High",
|
||||
"inverseInitialPriceText": "1 High = 0.66 Low",
|
||||
"depositMultiplierText": "2x minimum",
|
||||
"depositScaleText": "20000 basis points",
|
||||
"expectedLpText": "10 raw LP",
|
||||
"lpGuardLabel": "Locked LP",
|
||||
"lpGuardText": "2 raw LP",
|
||||
"poolId": "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE",
|
||||
"accountPreview": [{
|
||||
"order": 0,
|
||||
"role": "LP holding",
|
||||
"action": "create",
|
||||
"accountId": "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE"
|
||||
}]
|
||||
}
|
||||
})
|
||||
verify(summary)
|
||||
|
||||
var deposit = findChild(summary, "confirmationDeposit")
|
||||
var initialPrice = findChild(summary, "confirmationInitialPrice")
|
||||
var inversePrice = findChild(summary, "confirmationInversePrice")
|
||||
var multiplier = findChild(summary, "confirmationDepositMultiplier")
|
||||
var scale = findChild(summary, "confirmationDepositScale")
|
||||
var expectedLp = findChild(summary, "confirmationExpectedLp")
|
||||
var lpGuard = findChild(summary, "confirmationLpGuard")
|
||||
var pool = findChild(summary, "confirmationPool")
|
||||
var accountPlan = findChild(summary, "confirmationAccountPlan")
|
||||
|
||||
verify(deposit)
|
||||
verify(initialPrice)
|
||||
verify(inversePrice)
|
||||
verify(multiplier)
|
||||
verify(scale)
|
||||
verify(expectedLp)
|
||||
verify(lpGuard)
|
||||
verify(pool)
|
||||
verify(accountPlan)
|
||||
compare(deposit.label, "Opening deposit")
|
||||
compare(deposit.value, "2 Low + 3 High")
|
||||
compare(initialPrice.value, "1 Low = 1.5 High")
|
||||
compare(inversePrice.value, "1 High = 0.66 Low")
|
||||
compare(multiplier.value, "2x minimum")
|
||||
compare(scale.value, "20000 basis points")
|
||||
compare(expectedLp.value, "10 raw LP")
|
||||
compare(lpGuard.label, "Locked LP")
|
||||
compare(lpGuard.value, "2 raw LP")
|
||||
compare(pool.value, "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE")
|
||||
compare(accountPlan.text, "Account plan (1)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,14 @@ TestCase {
|
||||
"request": ({ "schema": "new-position.v2" }),
|
||||
"quoteHash": "sha256:stale",
|
||||
"expectedLpText": "10 raw LP",
|
||||
"instruction": "AddLiquidity"
|
||||
"instruction": "AddLiquidity",
|
||||
"poolId": "11111111111111111111111111111111",
|
||||
"accountPreview": [{
|
||||
"order": 0,
|
||||
"role": "LP holding",
|
||||
"action": "create",
|
||||
"accountId": "11111111111111111111111111111111"
|
||||
}]
|
||||
})
|
||||
tryCompare(dialog, "opened", true)
|
||||
|
||||
@@ -307,6 +314,13 @@ TestCase {
|
||||
"quoteHash": "sha256:fresh",
|
||||
"expectedLpRaw": "20",
|
||||
"instruction": "AddLiquidity",
|
||||
"poolId": "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE",
|
||||
"accountPreview": [{
|
||||
"order": 0,
|
||||
"role": "LP holding",
|
||||
"action": "reuse",
|
||||
"accountId": "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE"
|
||||
}],
|
||||
"lpHoldingOptions": [],
|
||||
"selectedLpHoldingId": "",
|
||||
"requiresFreshLp": true,
|
||||
@@ -319,6 +333,9 @@ TestCase {
|
||||
tryCompare(dialog, "opened", true)
|
||||
compare(dialog.snapshot.quoteHash, "sha256:fresh")
|
||||
compare(dialog.snapshot.expectedLpText, "20 raw LP")
|
||||
compare(dialog.snapshot.poolId, "1thX6LZfHDZZKUs92febYZhYRcXddmzfzF2NvTkPNE")
|
||||
compare(dialog.snapshot.accountPreview.length, 1)
|
||||
compare(dialog.snapshot.accountPreview[0].action, "reuse")
|
||||
compare(dialog.snapshot.quoteReady, true)
|
||||
compare(page.flow.flowErrorCode, "")
|
||||
}
|
||||
|
||||
@@ -657,13 +657,26 @@ TestCase {
|
||||
"quoteHash": "sha256:expected",
|
||||
"actualAmountARaw": "2000000",
|
||||
"actualAmountBRaw": "3",
|
||||
"expectedLpRaw": "10"
|
||||
"expectedLpRaw": "10",
|
||||
"lockedLpRaw": "2",
|
||||
"accountPreview": [{
|
||||
"order": 0,
|
||||
"role": "LP holding",
|
||||
"action": "create",
|
||||
"accountId": submittedTransactionId
|
||||
}]
|
||||
})
|
||||
wait(0)
|
||||
|
||||
var snapshot = form.submissionSnapshot()
|
||||
compare(snapshot.poolProbeRequest.poolId, submittedTransactionId)
|
||||
verify(snapshot.request.poolId === undefined)
|
||||
compare(snapshot.depositLabel, "Opening deposit")
|
||||
compare(snapshot.lpGuardLabel, "Locked LP")
|
||||
compare(snapshot.lpGuardText, "2 raw LP")
|
||||
compare(snapshot.poolId, submittedTransactionId)
|
||||
compare(snapshot.accountPreview.length, 1)
|
||||
compare(snapshot.accountPreview[0].accountId, submittedTransactionId)
|
||||
}
|
||||
|
||||
function test_staleQuoteErrorsDoNotMarkCurrentDraft() {
|
||||
|
||||
Reference in New Issue
Block a user