fix(apps/amm): ensure changing endpoint works

This commit is contained in:
r4bbit 2026-06-26 13:00:02 +02:00
parent fe4c7a96da
commit 70a5a2e136
No known key found for this signature in database
GPG Key ID: E95F1E9447DC91A9
4 changed files with 120 additions and 19 deletions

View File

@ -45,7 +45,7 @@ Item {
height: show ? 32 : 0
visible: height > 0
clip: true
color: Theme.palette.warning
color: Theme.palette.error
Behavior on height { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
@ -56,7 +56,7 @@ Item {
elide: Text.ElideMiddle
font.pixelSize: 12
font.weight: Font.Medium
color: Theme.palette.background
color: Theme.palette.text
text: qsTr("Unable to connect to network")
}
}

View File

@ -428,14 +428,29 @@ Item {
Layout.fillWidth: true
height: 40
text: qsTr("Save")
onClicked: {
// The new endpoint only goes live after an app restart (the
// module can't re-open an already-open wallet), so confirm
// the user understands that before persisting.
onClicked: restartDialog.open()
}
// Persist the change; the running wallet keeps the old endpoint
// until the user restarts (we can't reliably quit this host).
RestartRequiredDialog {
id: restartDialog
title: qsTr("Restart to apply")
confirmLabel: qsTr("Save")
message: qsTr("Changing the network endpoint only takes effect after restarting the app. "
+ "Save now, then quit and reopen the app to apply it.")
onConfirmed: {
if (!root.backend) return
seqStatus.text = ""
logos.watch(root.backend.changeSequencerAddr(seqField.text),
function(ok) {
seqStatus.ok = ok
seqStatus.text = ok ? qsTr("Network updated.")
: qsTr("Failed to update network.")
seqStatus.text = ok
? qsTr("Saved — quit and reopen the app to apply.")
: qsTr("Invalid network URL.")
},
function(error) {
seqStatus.ok = false

View File

@ -0,0 +1,73 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Logos.Theme
import Logos.Controls
// Modal shown before applying a setting that only takes effect after a restart.
// The caller handles `confirmed` (persist the change, then close the app).
Popup {
id: root
property string title: qsTr("Restart required")
property string message: ""
property string confirmLabel: qsTr("Save & close")
signal confirmed()
modal: true
dim: true
padding: Theme.spacing.large
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
// Center on the full-window overlay rather than the small control this is
// declared inside.
parent: Overlay.overlay
anchors.centerIn: parent
width: 360
background: Rectangle {
color: Theme.palette.backgroundSecondary
radius: Theme.spacing.radiusXlarge
border.color: Theme.palette.backgroundElevated
}
contentItem: ColumnLayout {
width: root.availableWidth
spacing: Theme.spacing.large
LogosText {
text: root.title
font.pixelSize: Theme.typography.titleText
font.weight: Theme.typography.weightBold
color: Theme.palette.text
}
LogosText {
Layout.fillWidth: true
text: root.message
wrapMode: Text.WordWrap
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.textSecondary
}
RowLayout {
Layout.topMargin: Theme.spacing.medium
Layout.fillWidth: true
spacing: Theme.spacing.medium
LogosButton {
text: qsTr("Cancel")
Layout.fillWidth: true
onClicked: root.close()
}
LogosButton {
text: root.confirmLabel
Layout.fillWidth: true
onClicked: {
root.confirmed()
root.close()
}
}
}
}
}

View File

@ -354,12 +354,28 @@ void AmmUiBackend::persistStoragePath(const QString& path)
bool AmmUiBackend::changeSequencerAddr(QString url)
{
const QString trimmed = url.trimmed();
if (trimmed.isEmpty()) {
QString normalized = url.trimmed();
if (normalized.isEmpty()) {
qWarning() << "AmmUiBackend: refusing to set empty sequencer_addr";
return false;
}
// The wallet config parses sequencer_addr as a strict URL — a missing
// scheme makes the whole config fail to deserialize (and would leave the
// wallet unopenable). Default to http:// so users can type just host:port,
// then validate before writing anything.
if (!normalized.contains(QStringLiteral("://")))
normalized.prepend(QStringLiteral("http://"));
const QUrl parsed(normalized, QUrl::StrictMode);
if (!parsed.isValid() || parsed.host().isEmpty()
|| (parsed.scheme() != QStringLiteral("http")
&& parsed.scheme() != QStringLiteral("https"))) {
qWarning() << "AmmUiBackend: invalid sequencer URL" << url;
return false;
}
normalized = parsed.toString();
const QString cfg = configPath().isEmpty() ? defaultConfigPath() : configPath();
// Preserve the other config fields (poll timeouts, retries) — only swap the
@ -370,7 +386,7 @@ bool AmmUiBackend::changeSequencerAddr(QString url)
obj = QJsonDocument::fromJson(in.readAll()).object();
in.close();
}
obj.insert(QStringLiteral("sequencer_addr"), trimmed);
obj.insert(QStringLiteral("sequencer_addr"), normalized);
QFile out(cfg);
if (!out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
@ -380,17 +396,14 @@ bool AmmUiBackend::changeSequencerAddr(QString url)
out.write(QJsonDocument(obj).toJson(QJsonDocument::Indented));
out.close();
// Re-open so the live wallet uses the new endpoint right away.
if (isWalletOpen()) {
const QString stg = storagePath().isEmpty() ? defaultStoragePath() : storagePath();
const int err = m_logos->logos_execution_zone.open(cfg, stg);
if (err != WALLET_FFI_SUCCESS) {
qWarning() << "AmmUiBackend: reopen after sequencer change failed, code" << err;
return false;
}
refreshSequencerAddr();
refreshAccounts();
}
// Config is now the source of truth — reflect the change in the UI.
if (sequencerAddr() != normalized)
setSequencerAddr(normalized);
checkReachability();
// The module can't re-open an already-open wallet, so the new endpoint only
// takes effect on the next launch. The UI confirms a restart before calling
// this and closes the app afterwards.
return true;
}