fix(amm): guard resolvePool against stale callbacks; clarify deadline-ms and program-binary docs

This commit is contained in:
Andrea Franz 2026-07-23 14:14:55 +02:00 committed by r4bbit
parent fe41baf210
commit cf92e5d111
3 changed files with 31 additions and 8 deletions

View File

@ -88,9 +88,25 @@ Rectangle {
if (!root.backend || !root.sellToken || !root.buyToken)
return
// Capture the pair this request is for. resolvePool callbacks can arrive
// out of order: if the user switches tokens while an earlier resolve is
// still in flight, its (stale) callback must NOT overwrite the current
// pair's pool state that would corrupt the preview and the submitted
// min_out. A stale callback also leaves poolLoading alone, since the
// newer in-flight request owns it.
var reqSell = root.sellToken.definitionId
var reqBuy = root.buyToken.definitionId
function isStale() {
return !root.sellToken || !root.buyToken
|| root.sellToken.definitionId !== reqSell
|| root.buyToken.definitionId !== reqBuy
}
root.poolLoading = true
logos.watch(root.backend.resolvePool(root.sellToken.definitionId, root.buyToken.definitionId),
logos.watch(root.backend.resolvePool(reqSell, reqBuy),
function (pool) {
if (isStale())
return
root.poolLoading = false
root.poolResolved = true
root.poolExists = !!(pool && pool.exists)
@ -103,6 +119,8 @@ Rectangle {
root.poolError = (pool && pool.error && pool.error !== "no_pool") ? pool.error : ""
},
function (error) {
if (isStale())
return
console.warn("resolvePool error:", error)
root.poolLoading = false
root.poolResolved = true

View File

@ -62,11 +62,14 @@ namespace {
// canonical wallet (~/.lee/wallet) used by the wallet UI and other apps.
const char WALLET_HOME_ENV[] = "LEE_WALLET_HOME_DIR";
// Absolute path to the deployed AMM program's compiled ELF (amm.bin). The
// app can't safely embed/derive this itself: the wallet module's bundled
// AMM program may differ from whatever is actually deployed on the target
// sequencer, and the program's ELF bytes are what determine its program id
// (and therefore every PDA derived from it). See apps/amm/README.md.
// Absolute path to the deployed AMM program's RISC Zero program binary
// (amm.bin — the `ProgramBinary` `.bin` from the docker guest build, decoded
// on the Rust side via `ProgramBinary::decode`; NOT a raw ELF — pointing at
// the raw guest ELF yields a different/failed program id). The app can't
// safely embed/derive this itself: the wallet module's bundled AMM program
// may differ from whatever is actually deployed on the target sequencer, and
// the binary's bytes are what determine its program id (and therefore every
// PDA derived from it). See apps/amm/README.md.
const char AMM_PROGRAM_BIN_ENV[] = "AMM_PROGRAM_BIN";
// Absolute path to the JSON token-list config consumed by tokenList()

View File

@ -53,8 +53,10 @@ class AmmUiBackend
SLOT(QVariantMap resolvePool(QString defAHex, QString defBHex))
// Submits a real on-chain SwapExactInput transaction against the pool for
// (defAHex, defBHex). amountInDecimal/minOutDecimal are decimal-string
// u128 amounts in base units; deadlineDecimal is a decimal-string u64
// unix timestamp. Returns the tx hash, or an empty string on failure
// u128 amounts in base units; deadlineDecimal is a decimal-string u64 unix
// timestamp in MILLISECONDS (matches amm_core's SwapExactInput deadline —
// passing seconds would expire the swap immediately once deadline handling
// is enforced). Returns the tx hash, or an empty string on failure
// (no pool, unreadable AMM_PROGRAM_BIN, bad inputs, or a failed tx).
SLOT(QString swapExactInput(QString defAHex, QString defBHex, QString userInputHoldingHex, QString userOutputHoldingHex, QString amountInDecimal, QString minOutDecimal, QString deadlineDecimal))
// Reads the token list config at TOKENS_CONFIG (absolute path, JSON array