mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-30 18:53:11 +00:00
fix(amm-ui): require explicit liquidity inputs
Keep wallet assets as token choices without automatically selecting a pair. Keep pool-probe amounts internal so active-pool quotes do not populate the form before user input.
This commit is contained in:
parent
01829a280c
commit
aafe5e900b
@ -109,13 +109,13 @@ AmmActionCard {
|
|||||||
implicitHeight: content.implicitHeight + root.contentPadding * 2
|
implicitHeight: content.implicitHeight + root.contentPadding * 2
|
||||||
implicitWidth: 480
|
implicitWidth: 480
|
||||||
|
|
||||||
Component.onCompleted: Qt.callLater(root.ensurePair)
|
Component.onCompleted: Qt.callLater(root.reconcileSelection)
|
||||||
onNewPositionContextChanged: Qt.callLater(root.applyContextChange)
|
onNewPositionContextChanged: Qt.callLater(root.applyContextChange)
|
||||||
function applyContextChange() {
|
function applyContextChange() {
|
||||||
if (root.resolvingToken)
|
if (root.resolvingToken)
|
||||||
root.finishTokenResolution()
|
root.finishTokenResolution()
|
||||||
else
|
else
|
||||||
root.ensurePair()
|
root.reconcileSelection()
|
||||||
}
|
}
|
||||||
onQuotePayloadChanged: {
|
onQuotePayloadChanged: {
|
||||||
if (root.quoteStale)
|
if (root.quoteStale)
|
||||||
@ -786,26 +786,23 @@ AmmActionCard {
|
|||||||
root.tokenResolutionErrorSide = side
|
root.tokenResolutionErrorSide = side
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensurePair() {
|
function reconcileSelection() {
|
||||||
var status = String(root.newPositionContext.status || "")
|
var status = String(root.newPositionContext.status || "")
|
||||||
if (status !== "ready" && status !== "no_wallet")
|
if (status !== "ready" && status !== "no_wallet")
|
||||||
return
|
return
|
||||||
var previousA = root.selectedTokenAId
|
var previousA = root.selectedTokenAId
|
||||||
var previousB = root.selectedTokenBId
|
var previousB = root.selectedTokenBId
|
||||||
var selectable = root.selectableTokenIds()
|
var selectable = root.selectableTokenIds()
|
||||||
if (selectable.length === 0) {
|
if (root.selectedTokenAId.length > 0
|
||||||
|
&& selectable.indexOf(root.selectedTokenAId) < 0) {
|
||||||
root.selectedTokenAId = ""
|
root.selectedTokenAId = ""
|
||||||
|
}
|
||||||
|
if (root.selectedTokenBId.length > 0
|
||||||
|
&& selectable.indexOf(root.selectedTokenBId) < 0) {
|
||||||
root.selectedTokenBId = ""
|
root.selectedTokenBId = ""
|
||||||
if (previousA.length > 0 || previousB.length > 0)
|
|
||||||
root.resetPairDraft()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (selectable.indexOf(root.selectedTokenAId) < 0)
|
|
||||||
root.selectedTokenAId = selectable[0]
|
|
||||||
if (selectable.indexOf(root.selectedTokenBId) < 0
|
|
||||||
|| root.selectedTokenBId === root.selectedTokenAId) {
|
|
||||||
root.selectedTokenBId = selectable.length > 1 ? selectable[1] : ""
|
|
||||||
}
|
}
|
||||||
|
if (root.selectedTokenBId === root.selectedTokenAId)
|
||||||
|
root.selectedTokenBId = ""
|
||||||
if (root.selectedTokenAId !== previousA || root.selectedTokenBId !== previousB)
|
if (root.selectedTokenAId !== previousA || root.selectedTokenBId !== previousB)
|
||||||
root.resetPairDraft()
|
root.resetPairDraft()
|
||||||
else if (root.hasPair)
|
else if (root.hasPair)
|
||||||
@ -987,14 +984,7 @@ AmmActionCard {
|
|||||||
return { "ok": false, "errors": errors, "request": ({}) }
|
return { "ok": false, "errors": errors, "request": ({}) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var canonicalAId = root.displayIsCanonical ? root.selectedTokenAId : root.selectedTokenBId
|
var request = root.pairRequest()
|
||||||
var canonicalBId = root.displayIsCanonical ? root.selectedTokenBId : root.selectedTokenAId
|
|
||||||
var request = {
|
|
||||||
"schema": "new-position.v1",
|
|
||||||
"tokenAId": canonicalAId,
|
|
||||||
"tokenBId": canonicalBId,
|
|
||||||
"feeBps": root.selectedFeeBps
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.activePool) {
|
if (root.activePool) {
|
||||||
var parsedA = AmountMath.parseHuman(root.amountA, root.decimalsA)
|
var parsedA = AmountMath.parseHuman(root.amountA, root.decimalsA)
|
||||||
@ -1085,6 +1075,17 @@ AmmActionCard {
|
|||||||
return { "ok": errors.length === 0, "errors": errors, "request": request }
|
return { "ok": errors.length === 0, "errors": errors, "request": request }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pairRequest() {
|
||||||
|
return {
|
||||||
|
"schema": "new-position.v1",
|
||||||
|
"tokenAId": root.displayIsCanonical
|
||||||
|
? root.selectedTokenAId : root.selectedTokenBId,
|
||||||
|
"tokenBId": root.displayIsCanonical
|
||||||
|
? root.selectedTokenBId : root.selectedTokenAId,
|
||||||
|
"feeBps": root.selectedFeeBps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function requestQuote(immediate) {
|
function requestQuote(immediate) {
|
||||||
if (root.activePool && root.amountA.length === 0 && root.amountB.length === 0) {
|
if (root.activePool && root.amountA.length === 0 && root.amountB.length === 0) {
|
||||||
root.localErrors = []
|
root.localErrors = []
|
||||||
@ -1327,24 +1328,18 @@ AmmActionCard {
|
|||||||
return
|
return
|
||||||
if (root.poolFeeBps > 0 && root.selectedFeeBps !== root.poolFeeBps) {
|
if (root.poolFeeBps > 0 && root.selectedFeeBps !== root.poolFeeBps) {
|
||||||
root.selectedFeeBps = root.poolFeeBps
|
root.selectedFeeBps = root.poolFeeBps
|
||||||
if (root.amountA.length === 0 && root.amountB.length === 0) {
|
root.localErrors = []
|
||||||
root.amountA = AmountMath.formatRaw(
|
root.quoteRequested(true, {
|
||||||
root.probeRaw(root.tokenA, root.decimalsA), root.decimalsA)
|
"ok": true,
|
||||||
root.amountB = AmountMath.formatRaw(
|
"errors": [],
|
||||||
root.probeRaw(root.tokenB, root.decimalsB), root.decimalsB)
|
"request": root.poolProbeRequest(root.pairRequest())
|
||||||
}
|
})
|
||||||
root.requestQuote(true)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.quotePayload.status !== "ok")
|
if (root.quotePayload.status !== "ok")
|
||||||
return
|
return
|
||||||
|
|
||||||
if (root.activePool && root.amountA.length === 0 && root.amountB.length === 0) {
|
|
||||||
root.amountA = AmountMath.formatRaw(root.displayRaw("maxAmountARaw", "maxAmountBRaw", "A"), root.decimalsA)
|
|
||||||
root.amountB = AmountMath.formatRaw(root.displayRaw("maxAmountARaw", "maxAmountBRaw", "B"), root.decimalsB)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.missingPool) {
|
if (root.missingPool) {
|
||||||
var rawA = root.displayRaw("actualAmountARaw", "actualAmountBRaw", "A")
|
var rawA = root.displayRaw("actualAmountARaw", "actualAmountBRaw", "A")
|
||||||
var rawB = root.displayRaw("actualAmountARaw", "actualAmountBRaw", "B")
|
var rawB = root.displayRaw("actualAmountARaw", "actualAmountBRaw", "B")
|
||||||
|
|||||||
@ -91,17 +91,33 @@ TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createForm() {
|
function createEmptyForm(context) {
|
||||||
var form = createTemporaryObject(formComponent, testCase, {
|
var form = createTemporaryObject(formComponent, testCase, {
|
||||||
"flowState": flowState(({}))
|
"flowState": flowState(({})),
|
||||||
|
"newPositionContext": context || readyContext()
|
||||||
})
|
})
|
||||||
verify(form)
|
verify(form)
|
||||||
wait(0)
|
wait(0)
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
|
||||||
|
function createForm(context) {
|
||||||
|
var form = createEmptyForm(context)
|
||||||
|
form.selectToken("A", tokenLow)
|
||||||
|
form.selectToken("B", tokenHigh)
|
||||||
compare(form.selectedTokenAId, tokenLow)
|
compare(form.selectedTokenAId, tokenLow)
|
||||||
compare(form.selectedTokenBId, tokenHigh)
|
compare(form.selectedTokenBId, tokenHigh)
|
||||||
return form
|
return form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_walletTokensDoNotPrefillPosition() {
|
||||||
|
var form = createEmptyForm()
|
||||||
|
compare(form.selectedTokenAId, "")
|
||||||
|
compare(form.selectedTokenBId, "")
|
||||||
|
compare(form.amountA, "")
|
||||||
|
compare(form.amountB, "")
|
||||||
|
}
|
||||||
|
|
||||||
function test_displayOrderMapsToCanonicalRequestAfterSwap() {
|
function test_displayOrderMapsToCanonicalRequestAfterSwap() {
|
||||||
var form = createForm()
|
var form = createForm()
|
||||||
var built = form.buildQuoteRequest()
|
var built = form.buildQuoteRequest()
|
||||||
@ -159,12 +175,7 @@ TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_missingPoolAcceptsLargeDirectAmountsFromEitherSide() {
|
function test_missingPoolAcceptsLargeDirectAmountsFromEitherSide() {
|
||||||
var form = createTemporaryObject(formComponent, testCase, {
|
var form = createForm(rawAmountsContext())
|
||||||
"flowState": flowState(({})),
|
|
||||||
"newPositionContext": rawAmountsContext()
|
|
||||||
})
|
|
||||||
verify(form)
|
|
||||||
wait(0)
|
|
||||||
form.priceAmountA = "15"
|
form.priceAmountA = "15"
|
||||||
form.priceAmountB = "10"
|
form.priceAmountB = "10"
|
||||||
form.flowState = flowState({
|
form.flowState = flowState({
|
||||||
@ -199,12 +210,7 @@ TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_missingPoolRoundsPairedRawAmounts() {
|
function test_missingPoolRoundsPairedRawAmounts() {
|
||||||
var form = createTemporaryObject(formComponent, testCase, {
|
var form = createForm(rawAmountsContext())
|
||||||
"flowState": flowState(({})),
|
|
||||||
"newPositionContext": rawAmountsContext()
|
|
||||||
})
|
|
||||||
verify(form)
|
|
||||||
wait(0)
|
|
||||||
form.priceAmountA = "15"
|
form.priceAmountA = "15"
|
||||||
form.priceAmountB = "10"
|
form.priceAmountB = "10"
|
||||||
form.flowState = flowState({
|
form.flowState = flowState({
|
||||||
@ -415,14 +421,14 @@ TestCase {
|
|||||||
var form = createForm()
|
var form = createForm()
|
||||||
form.flowState = flowState(quote)
|
form.flowState = flowState(quote)
|
||||||
wait(0)
|
wait(0)
|
||||||
compare(form.amountA, "20")
|
compare(form.amountA, "")
|
||||||
compare(form.amountB, "4")
|
compare(form.amountB, "")
|
||||||
|
|
||||||
quoteRequestedSpy.target = form
|
quoteRequestedSpy.target = form
|
||||||
quoteRequestedSpy.clear()
|
quoteRequestedSpy.clear()
|
||||||
form.editActiveAmount("A", "5")
|
form.editActiveAmount("A", "5")
|
||||||
compare(form.amountA, "5")
|
compare(form.amountA, "5")
|
||||||
compare(form.amountB, "4")
|
compare(form.amountB, "")
|
||||||
compare(quoteRequestedSpy.count, 0)
|
compare(quoteRequestedSpy.count, 0)
|
||||||
|
|
||||||
form.finishActiveAmount("A", "5")
|
form.finishActiveAmount("A", "5")
|
||||||
@ -509,6 +515,8 @@ TestCase {
|
|||||||
wait(0)
|
wait(0)
|
||||||
|
|
||||||
compare(form.selectedFeeBps, 5)
|
compare(form.selectedFeeBps, 5)
|
||||||
|
compare(form.amountA, "")
|
||||||
|
compare(form.amountB, "")
|
||||||
compare(quoteRequestedSpy.count, 1)
|
compare(quoteRequestedSpy.count, 1)
|
||||||
verify(quoteRequestedSpy.signalArguments[0][1].ok)
|
verify(quoteRequestedSpy.signalArguments[0][1].ok)
|
||||||
compare(quoteRequestedSpy.signalArguments[0][1].request.maxAmountARaw, "5000000000")
|
compare(quoteRequestedSpy.signalArguments[0][1].request.maxAmountARaw, "5000000000")
|
||||||
@ -582,8 +590,8 @@ TestCase {
|
|||||||
}
|
}
|
||||||
wait(0)
|
wait(0)
|
||||||
|
|
||||||
compare(form.selectedTokenAId, tokenHigh)
|
compare(form.selectedTokenAId, "")
|
||||||
compare(form.selectedTokenBId, tokenThird)
|
compare(form.selectedTokenBId, tokenHigh)
|
||||||
compare(form.amountA, "")
|
compare(form.amountA, "")
|
||||||
compare(form.amountB, "")
|
compare(form.amountB, "")
|
||||||
compare(form.minimumAmountARaw, "")
|
compare(form.minimumAmountARaw, "")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user