Files
lez-programs/apps/amm/qml/components/swap/SwapSummary.qml
r4bbit d9876d08ca feat(apps/amm): drive the exact-output swap preview from swapExactOutQuote
Wire the Buy direction of the swap card to the module's server-side
swapExactOutQuote, mirroring the exact-input path. AmmUiBackend gains a
swapExactOutQuote(tokenIn, tokenOut, amountOutDecimal, slippageBps) slot
returning { requiredInRaw, maxInRaw, priceImpactBps } (read-only).

Editing the Buy amount now debounces a swapExactOutQuote call and sources the
required input (shown in the Sell field), the price impact, and the slippage
ceiling from it — the exact figures come straight from the quote's raw integer
strings, so the preview matches execution and no reserve orientation happens
client-side. A retyped amount invalidates the quote up front.

SwapSummary's last row is generalised from a hardcoded "Min received" to a
direction-aware bound (boundLabel/boundText): "Min received" (min out) for
exact input, "Maximum sent" (max in) for exact output. SwapConfirmationSummary
is updated for the renamed property.

The Buy field remains preview-only — canSubmit is still sell-only, pending the
exact-output submit wiring. The now-orphaned DummySwapState pricing helpers are
left for a follow-up cleanup.
2026-08-06 23:15:02 +02:00

150 lines
4.1 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.15
Item {
id: root
property var theme
property string swapModeText: ""
property string feeText: ""
property string priceImpactText: ""
property real priceImpactPercent: 0
property string slippageText: ""
// The slippage-bound row adapts to direction: "Min received" (exact input) or
// "Maximum sent" (exact output).
property string boundLabel: qsTr("Min received")
property string boundText: ""
readonly property color priceImpactColor: {
if (root.priceImpactPercent > 5) return "#F08A76";
if (root.priceImpactPercent > 1) return "#F2B366";
return root.theme.colors.textPrimary;
}
implicitHeight: column.implicitHeight
ColumnLayout {
id: column
anchors.fill: parent
spacing: 8
Item {
implicitHeight: 18
visible: root.swapModeText.length > 0
Layout.fillWidth: true
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textSecondary
font.pixelSize: 12
text: qsTr("Type of swap")
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textPrimary
font.bold: true
font.pixelSize: 12
text: root.swapModeText
}
}
Item {
implicitHeight: 18
Layout.fillWidth: true
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textSecondary
font.pixelSize: 12
text: qsTr("Fee")
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textPrimary
font.bold: true
font.pixelSize: 12
text: root.feeText
}
}
Item {
implicitHeight: 18
Layout.fillWidth: true
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textSecondary
font.pixelSize: 12
text: qsTr("Price impact")
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
color: root.priceImpactColor
font.bold: true
font.pixelSize: 12
text: root.priceImpactText
}
}
Item {
implicitHeight: 18
visible: root.slippageText.length > 0
Layout.fillWidth: true
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textSecondary
font.pixelSize: 12
text: qsTr("Slippage tolerance")
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textPrimary
font.bold: true
font.pixelSize: 12
text: root.slippageText
}
}
Item {
implicitHeight: 18
Layout.fillWidth: true
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textSecondary
font.pixelSize: 12
text: root.boundLabel
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
color: root.theme.colors.textPrimary
font.bold: true
font.pixelSize: 12
text: root.boundText
}
}
}
}