feat(wallet): humanize shared wallet experience

Consolidate wallet account decoding and portfolio handling around the shared Rust IDL decoder. Simplify AMM wallet integration, remove obsolete caches and network plumbing, and cover account selection and live flows.
This commit is contained in:
Ricardo Guilherme Schmidt
2026-08-21 17:38:45 -03:00
parent 62d133e909
commit 8c3e6fccfe
64 changed files with 6268 additions and 27501 deletions
@@ -5,53 +5,127 @@ import QtQuick.Layouts
ItemDelegate {
id: root
required property int index
required property string name
required property string alias
required property string address
required property string balance
required property bool isPublic
required property string displayAddress
required property string kind
required property string section
required property string programName
required property string accountType
required property string decodedData
required property string visibility
required property bool canBePrimary
required property bool isPrimary
signal copyRequested(string text)
signal makePrimaryRequested(string address)
signal renameRequested(string address, string alias)
leftPadding: 12
rightPadding: 8
topPadding: 10
bottomPadding: 10
enabled: root.section !== "hidden"
Accessible.name: root.isPrimary
? qsTr("%1, primary account").arg(root.name)
: root.name
Accessible.name: qsTr("%1, balance %2").arg(root.name).arg(root.balance || "0")
function kindLabel() {
if (root.kind === "user")
return qsTr("User")
if (root.kind === "private")
return qsTr("Account")
if (root.accountType.length > 0)
return root.accountType
return root.kind === "unknown" ? qsTr("Unknown") : qsTr("Program")
}
background: Rectangle {
color: root.highlighted || root.hovered ? "#27272a" : "#18181b"
radius: 6
border.width: root.activeFocus ? 1 : 0
border.color: "#f26a21"
color: root.isPrimary || root.hovered ? "#27272a" : "#18181b"
radius: 8
border.width: root.activeFocus || root.isPrimary ? 1 : 0
border.color: root.isPrimary ? "#f59e0b" : "#52525b"
}
contentItem: ColumnLayout {
spacing: 6
spacing: 7
RowLayout {
Layout.fillWidth: true
spacing: 8
spacing: 7
Label {
Layout.fillWidth: true
text: root.name
color: "#f4f4f5"
color: "#fafafa"
font.bold: true
elide: Text.ElideRight
}
Label {
visible: root.isPrimary
text: qsTr("Primary")
color: "#fbbf24"
font.pixelSize: 11
font.bold: true
}
Label {
text: root.isPublic ? qsTr("Public") : qsTr("Private")
text: root.kindLabel()
color: "#a1a1aa"
font.pixelSize: 11
}
Item { Layout.fillWidth: true }
Label {
text: root.visibility === "private" ? qsTr("Private") : qsTr("Public")
color: root.visibility === "private" ? "#c4b5fd" : "#93c5fd"
font.pixelSize: 11
}
}
Label {
objectName: "walletProgramName"
visible: root.section === "advanced" && root.programName.length > 0
Layout.fillWidth: true
text: qsTr("Program: %1").arg(root.programName)
color: "#a1a1aa"
font.pixelSize: 11
elide: Text.ElideRight
}
ColumnLayout {
visible: root.section === "advanced" && root.decodedData.length > 0
Layout.fillWidth: true
spacing: 4
Label {
text: root.balance.length > 0 ? root.balance : "-"
color: "#f4f4f5"
font.bold: true
objectName: "walletDecodedDataLabel"
text: qsTr("Decoded data")
color: "#a1a1aa"
font.pixelSize: 11
}
Rectangle {
objectName: "walletDecodedDataBox"
Layout.fillWidth: true
implicitHeight: decodedDataText.implicitHeight + 16
color: "#18181b"
radius: 6
border.width: 1
border.color: "#3f3f46"
Text {
id: decodedDataText
objectName: "walletDecodedData"
anchors.fill: parent
anchors.margins: 8
text: root.decodedData
color: "#d4d4d8"
font.family: "monospace"
font.pixelSize: 10
textFormat: Text.PlainText
wrapMode: Text.WrapAnywhere
}
}
}
@@ -61,17 +135,45 @@ ItemDelegate {
Label {
Layout.fillWidth: true
text: root.address
color: "#a1a1aa"
text: root.displayAddress
color: "#71717a"
font.family: "monospace"
font.pixelSize: 11
elide: Text.ElideMiddle
}
CopyButton {
visible: root.address.length > 0
onCopyRequested: root.copyRequested(root.address)
visible: root.displayAddress.length > 0
copyText: root.displayAddress
copyLabel: qsTr("Copy address")
}
}
RowLayout {
Layout.fillWidth: true
spacing: 6
Button {
objectName: "walletRenameButton"
text: qsTr("Rename")
flat: true
onClicked: root.renameRequested(root.address, root.alias)
}
Item { Layout.fillWidth: true }
Button {
objectName: "walletMakePrimaryButton"
visible: root.canBePrimary && !root.isPrimary
text: qsTr("Make primary")
flat: true
onClicked: root.makePrimaryRequested(root.address)
}
}
}
onClicked: {
if (root.canBePrimary && !root.isPrimary)
root.makePrimaryRequested(root.address)
}
}
+20 -1
View File
@@ -5,9 +5,11 @@ WalletIconButton {
signal copyRequested
property string copyText: ""
property string copyLabel: qsTr("Copy")
property bool copied: false
accessibleName: root.copied ? qsTr("Copied") : qsTr("Copy")
accessibleName: root.copied ? qsTr("Copied") : root.copyLabel
iconSource: root.copied
? Qt.resolvedUrl("icons/checkmark.svg")
: Qt.resolvedUrl("icons/copy.svg")
@@ -18,7 +20,24 @@ WalletIconButton {
onTriggered: root.copied = false
}
TextEdit {
id: clipboardProxy
visible: false
}
function copyToClipboard() {
if (root.copyText.length === 0)
return
clipboardProxy.text = root.copyText
clipboardProxy.selectAll()
clipboardProxy.copy()
clipboardProxy.deselect()
clipboardProxy.text = ""
}
onClicked: {
root.copyToClipboard()
root.copyRequested()
root.copied = true
resetTimer.restart()
@@ -16,9 +16,13 @@ Popup {
x: parent ? Math.max(0, Math.round((parent.width - width) / 2)) : 0
y: parent ? Math.max(0, Math.round((parent.height - height) / 2)) : 0
padding: 20
focus: true
closePolicy: root.busy ? Popup.NoAutoClose : Popup.CloseOnEscape | Popup.CloseOnPressOutside
onOpened: privateSwitch.checked = false
onOpened: {
privateSwitch.checked = false
Qt.callLater(function() { privateSwitch.forceActiveFocus() })
}
background: Rectangle {
color: "#18181b"
@@ -20,6 +20,7 @@ Popup {
x: parent ? Math.max(0, Math.round((parent.width - width) / 2)) : 0
y: parent ? Math.max(0, Math.round((parent.height - height) / 2)) : 0
padding: 20
focus: true
closePolicy: root.busy || root.mnemonic.length > 0
? Popup.NoAutoClose
: Popup.CloseOnEscape | Popup.CloseOnPressOutside
@@ -15,8 +15,11 @@ Popup {
x: parent ? Math.max(0, Math.round((parent.width - width) / 2)) : 0
y: parent ? Math.max(0, Math.round((parent.height - height) / 2)) : 0
padding: 20
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
onOpened: Qt.callLater(function() { closeButton.forceActiveFocus() })
background: Rectangle {
color: "#18181b"
border.color: "#3f3f46"
@@ -44,6 +47,8 @@ Popup {
}
Button {
id: closeButton
Layout.alignment: Qt.AlignRight
text: qsTr("Close")
onClicked: root.close()