mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-27 07:01:14 +00:00
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:
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user