refactor(amm): remove the dead Network/context machinery

The liquidity token surface moved app-side (resolveTokens + custom tokens),
leaving the whole newPositionContext path dormant. Delete it end to end and
point the swap methods at the same lean program-id helper everything else uses.
This commit is contained in:
r4bbit
2026-08-13 16:17:58 +02:00
parent 10b52ea2f6
commit cbb75c38fd
17 changed files with 88 additions and 923 deletions
+2 -98
View File
@@ -9,14 +9,8 @@ QtObject {
readonly property bool walletStateReady: root.backend !== null
&& root.backend.walletStateReady === true
readonly property var newPositionContext: root.walletStateReady
&& root.backend.newPositionContext
? root.backend.newPositionContext
: root.loadingContext()
readonly property var viewState: ({
"quote": root.newPositionQuote,
"contextLoading": root.contextLoading || !root.walletStateReady
|| root.newPositionContext.status === "loading",
"quoteLoading": root.quoteLoading,
"quoteStale": root.quoteStale,
"submitting": root.submitting,
@@ -24,29 +18,22 @@ QtObject {
// Create-vs-add routing signal, from the resolvePool read: true = add (pool exists),
// false = create, undefined = not resolved yet (a new pair, still resolving).
"poolExists": root.poolExists,
"errorCode": root.flowErrorCode || root.contextErrorCode
|| root.quoteErrorCode
"errorCode": root.flowErrorCode || root.quoteErrorCode
})
property var newPositionQuote: ({})
// Whether the selected pair's pool exists (from resolvePool); drives create-vs-add.
// undefined until the first resolve for the current pair lands.
property var poolExists: undefined
property var resolvedTokenIds: []
property int contextSerial: 0
property int quoteSerial: 0
property bool contextLoading: false
property bool quoteLoading: false
property bool quoteStale: true
property bool submitting: false
property string transactionId: ""
property string flowErrorCode: ""
property string contextErrorCode: ""
property string quoteErrorCode: ""
property var pendingQuoteRequest: ({ "ok": false, "request": ({}) })
signal tokenResolutionFinished(bool finalResponse)
signal tokenResolutionFailed(string code)
signal quoteRefreshRequested(bool immediate)
signal submitSucceeded
signal submitFailed
@@ -59,14 +46,7 @@ QtObject {
onTriggered: root.requestQuoteNow(root.quoteSerial)
}
onNewPositionContextChanged: root.invalidateQuote()
onWalletStateReadyChanged: {
++root.contextSerial
if (!root.walletStateReady)
root.contextLoading = false
root.invalidateQuote()
}
onWalletStateReadyChanged: root.invalidateQuote()
onActiveChanged: {
if (!root.active)
@@ -77,72 +57,6 @@ QtObject {
})
}
function contextHints(refreshWalletAccounts) {
const request = root.pendingQuoteRequest.request || {}
const recent = []
if (request.tokenAId)
recent.push(request.tokenAId)
if (request.tokenBId && request.tokenBId !== request.tokenAId)
recent.push(request.tokenBId)
return {
"recentTokenIds": recent,
"resolvedTokenIds": root.resolvedTokenIds,
"refreshWalletAccounts": refreshWalletAccounts === true
}
}
function refreshContext(refreshWalletAccounts, completed) {
const serial = ++root.contextSerial
root.contextLoading = true
if (!root.walletStateReady || root.runtime === null) {
root.contextLoading = false
return
}
root.runtime.watch(root.backend.refreshNewPositionContext(
root.contextHints(refreshWalletAccounts)),
function() {
root.finishContextRefresh(serial, completed)
},
function(error) {
root.failContextRefresh(serial)
})
}
function finishContextRefresh(serial, completed) {
if (serial !== root.contextSerial)
return
root.contextLoading = false
root.contextErrorCode = ""
Qt.callLater(function() {
if (serial !== root.contextSerial)
return
root.tokenResolutionFinished(true)
if (completed)
completed()
})
}
function failContextRefresh(serial) {
if (serial !== root.contextSerial)
return
root.contextLoading = false
root.contextErrorCode = "backend_error"
root.tokenResolutionFailed("backend_error")
}
function resolveToken(tokenId) {
const value = String(tokenId || "").trim()
if (value.length === 0)
return
if (root.resolvedTokenIds.indexOf(value) < 0) {
const next = root.resolvedTokenIds.slice(0)
next.push(value)
root.resolvedTokenIds = next
}
root.refreshContext(false)
}
function scheduleQuote(immediate, quoteRequest) {
++root.quoteSerial
root.pendingQuoteRequest = quoteRequest
@@ -361,7 +275,6 @@ QtObject {
root.submitting = false
root.transactionId = String(result.transactionId)
root.flowErrorCode = ""
root.contextErrorCode = ""
root.quoteErrorCode = ""
root.invalidateQuote()
root.submitSucceeded()
@@ -414,7 +327,6 @@ QtObject {
root.submitting = false
root.transactionId = String(result.transactionId)
root.flowErrorCode = ""
root.contextErrorCode = ""
root.quoteErrorCode = ""
root.invalidateQuote()
root.submitSucceeded()
@@ -443,7 +355,6 @@ QtObject {
root.invalidateQuote()
root.transactionId = ""
root.flowErrorCode = ""
root.contextErrorCode = ""
root.quoteErrorCode = ""
}
@@ -463,13 +374,6 @@ QtObject {
root.quoteStale = true
}
function loadingContext() {
return {
"status": "loading",
"tokens": []
}
}
function quoteError(code) {
return {
"status": "error",
+1 -49
View File
@@ -71,22 +71,9 @@ namespace {
}
return out;
}
// The new-position context placeholder published before the module
// connection is up (matches the module's "loading" contextState).
QVariantMap loadingContext()
{
return QVariantMap {
{ QStringLiteral("status"), QStringLiteral("loading") },
{ QStringLiteral("networkId"), QStringLiteral("lez") },
{ QStringLiteral("networkFingerprint"), QString() },
{ QStringLiteral("tokens"), QVariantList() },
{ QStringLiteral("feeTiers"), QVariantList() },
{ QStringLiteral("warnings"), QVariantList() },
};
}
}
AmmUiBackend::AmmUiBackend(LogosAPI* logosAPI, QObject* parent)
: AmmUiBackendSimpleSource(parent),
m_logosAPI(logosAPI ? logosAPI : new LogosAPI("amm_ui", this)),
@@ -148,7 +135,6 @@ void AmmUiBackend::disconnectWallet()
{
m_walletController->disconnect();
setWalletStateReady(true);
refreshNewPositionContext(QVariantMap());
}
QString AmmUiBackend::createAccountPublic()
@@ -176,28 +162,6 @@ QString AmmUiBackend::getBalance(QString accountIdHex, bool isPublic)
return m_walletController->balance(accountIdHex, isPublic);
}
QVariantMap AmmUiBackend::refreshNewPositionContext(QVariantMap request)
{
const bool refreshWalletAccounts =
request.take(QStringLiteral("refreshWalletAccounts")).toBool();
if (request.contains(QStringLiteral("recentTokenIds"))
|| request.contains(QStringLiteral("resolvedTokenIds"))) {
m_newPositionHints = request;
}
else {
request = m_newPositionHints;
}
if (!walletStateReady()) {
const QVariantMap context = loadingContext();
setNewPositionContext(context);
return context;
}
const QVariantMap context = m_logos->amm_module.newPositionContext(
request, isWalletOpen(), refreshWalletAccounts);
setNewPositionContext(context);
return context;
}
void AmmUiBackend::syncWalletState()
{
const WalletUiState& state = m_walletController->state();
@@ -211,18 +175,6 @@ void AmmUiBackend::syncWalletState()
setCurrentBlockHeight(state.currentBlockHeight);
setSequencerAddr(state.sequencerAddress);
setSequencerReachable(state.sequencerReachable);
publishNetworkContext();
}
void AmmUiBackend::publishNetworkContext()
{
if (!walletStateReady()) {
setNewPositionContext(loadingContext());
return;
}
setNewPositionContext(m_logos->amm_module.newPositionContext(
m_newPositionHints, isWalletOpen(), false));
}
QVariantMap AmmUiBackend::resolvePool(QString defAHex, QString defBHex)
+1 -10
View File
@@ -46,7 +46,6 @@ public slots:
void refreshAccounts() override;
void refreshBalances() override;
QString getBalance(QString accountIdHex, bool isPublic) override;
QVariantMap refreshNewPositionContext(QVariantMap request) override;
// Return the new wallet's BIP39 mnemonic (empty string on failure) so the
// UI can force a one-time seed-phrase backup step.
QString createNewDefault(QString password) override;
@@ -101,24 +100,16 @@ private:
QStringList loadCustomTokenIds() const;
bool saveCustomTokenIds(const QStringList& ids) const;
QString customTokenStorePath() const;
// Publishes the new-position context PROP: a local "loading" placeholder
// until wallet state (and thus the module connection) is ready, then the
// module's newPositionContext for the current hints.
void publishNetworkContext();
LogosAPI* m_logosAPI;
// Handle for the amm_module core module (resolvePool / swapExactInput /
// tokenList / new-position). The module wraps the amm_ffi brain and
// tokenList / resolveTokens). The module wraps the amm_ffi brain and
// reaches the shared wallet through its own logos_execution_zone dependency;
// this backend keeps a thin LogosModules over the same LogosAPI as the
// wallet provider so both resolve that one shared wallet instance.
std::unique_ptr<LogosModules> m_logos;
std::unique_ptr<LogosWalletProvider> m_wallet;
std::unique_ptr<WalletController> m_walletController;
// Sticky new-position hints (recent/resolved token ids) so a bare
// republish (wallet-state change) keeps the user's last selection.
QVariantMap m_newPositionHints;
};
#endif // AMM_UI_BACKEND_H
-7
View File
@@ -26,13 +26,6 @@ class AmmUiBackend
SLOT(void refreshBalances())
SLOT(QString getBalance(QString accountIdHex, bool isPublic))
// New Position backend surface. QML calls these through logos.watch(...).
// The QVariant payloads are stable maps/lists so the UI never assembles AMM
// transactions or duplicates quote state.
PROP(QVariantMap newPositionContext READONLY)
// Return the published context so the QML refresh watcher always settles.
SLOT(QVariantMap refreshNewPositionContext(QVariantMap request))
// Wallet lifecycle. createNewDefault() is the happy path: it creates a
// fresh wallet at the canonical walletHome with no path picking. createNew()
// keeps explicit paths for an "advanced" flow. Both return the new wallet's
+5 -116
View File
@@ -11,21 +11,12 @@ TestCase {
name: "LiquidityPage"
Component {
id: backendComponent
id: pageComponent
QtObject {
property bool walletStateReady: false
property int contextRefreshCalls: 0
property var newPositionContext: ({
"status": "ready",
"tokens": [],
"feeTiers": []
})
function refreshNewPositionContext(request) {
++contextRefreshCalls
return newPositionContext
}
Pages.LiquidityPage {
visible: false
width: 800
height: 600
}
}
@@ -54,106 +45,4 @@ TestCase {
verify(form.width > 0)
verify(form.width <= page.width - 32)
}
Component {
id: runtimeComponent
QtObject {
function watch(value, succeeded, failed) {
if (value === undefined)
return
succeeded(value)
}
}
}
Component {
id: pageComponent
Pages.LiquidityPage {
visible: false
width: 800
height: 600
}
}
function test_contextWaitsForWalletState() {
var backend = createTemporaryObject(backendComponent, testCase)
var page = createTemporaryObject(pageComponent, testCase, {
"backend": backend
})
verify(backend)
verify(page)
compare(page.flow.newPositionContext.status, "loading")
backend.walletStateReady = true
tryCompare(page.flow.newPositionContext, "status", "ready")
}
function test_contextRefreshControlsWalletScan() {
var backend = createTemporaryObject(backendComponent, testCase, {
"walletStateReady": true
})
var page = createTemporaryObject(pageComponent, testCase, {
"backend": backend
})
verify(backend)
verify(page)
compare(page.flow.contextHints(false).refreshWalletAccounts, false)
compare(page.flow.contextHints(true).refreshWalletAccounts, true)
}
function test_refreshPositionCompletesAndReenablesTokenSelection() {
var backend = createTemporaryObject(backendComponent, testCase, {
"walletStateReady": true
})
var runtime = createTemporaryObject(runtimeComponent, testCase)
var page = createTemporaryObject(pageComponent, testCase, {
"backend": backend,
"runtime": runtime
})
verify(backend)
verify(runtime)
verify(page)
var refreshButton = findChild(page, "refreshPositionButton")
var tokenAInput = findChild(page, "tokenAAmountInput")
verify(refreshButton)
verify(tokenAInput)
refreshButton.clicked()
tryCompare(backend, "contextRefreshCalls", 1)
tryCompare(page.flow, "contextLoading", false)
compare(refreshButton.enabled, true)
compare(tokenAInput.tokenSelectionEnabled, true)
}
function test_staleContextCompletionCannotFinishNewerRefresh() {
var backend = createTemporaryObject(backendComponent, testCase, {
"walletStateReady": true
})
var page = createTemporaryObject(pageComponent, testCase, {
"backend": backend
})
verify(backend)
verify(page)
page.flow.contextSerial = 2
page.flow.contextLoading = true
page.flow.contextErrorCode = "newer_request_pending"
page.flow.finishContextRefresh(1, null)
page.flow.failContextRefresh(1)
compare(page.flow.contextLoading, true)
compare(page.flow.contextErrorCode, "newer_request_pending")
page.flow.finishContextRefresh(2, null)
compare(page.flow.contextLoading, false)
compare(page.flow.contextErrorCode, "")
}
}