mirror of
https://github.com/logos-blockchain/logos-blockchain-ui.git
synced 2026-07-09 09:19:26 +00:00
Make deposit work
This commit is contained in:
parent
4ab800bf4a
commit
9a8f8875b1
@ -17,6 +17,8 @@
|
||||
#include <QUrl>
|
||||
#include <QVariant>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
const QString BlockchainBackend::BLOCKCHAIN_MODULE_NAME =
|
||||
QStringLiteral("liblogos_blockchain_module");
|
||||
|
||||
@ -57,6 +59,44 @@ static QString toDisplayMessage(const LogosResult& result)
|
||||
return result.success ? result.value.toString() : toErrorMessage(result);
|
||||
}
|
||||
|
||||
// Decode a base58 (Bitcoin alphabet) string to raw bytes. On an invalid
|
||||
// character *ok is set to false and an empty array is returned.
|
||||
static QByteArray decodeBase58(const QString& input, bool* ok)
|
||||
{
|
||||
static const QByteArray kAlphabet =
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
const QByteArray s = input.trimmed().toLatin1();
|
||||
QByteArray bytes; // little-endian while building, reversed at the end
|
||||
bytes.append('\0');
|
||||
|
||||
for (const char c : s) {
|
||||
const int value = kAlphabet.indexOf(c);
|
||||
if (value < 0) {
|
||||
if (ok) *ok = false;
|
||||
return {};
|
||||
}
|
||||
int carry = value;
|
||||
for (int j = 0; j < bytes.size(); ++j) {
|
||||
carry += static_cast<unsigned char>(bytes[j]) * 58;
|
||||
bytes[j] = static_cast<char>(carry & 0xff);
|
||||
carry >>= 8;
|
||||
}
|
||||
while (carry > 0) {
|
||||
bytes.append(static_cast<char>(carry & 0xff));
|
||||
carry >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Each leading '1' maps to a leading zero byte.
|
||||
for (int i = 0; i < s.size() && s[i] == '1'; ++i)
|
||||
bytes.append('\0');
|
||||
|
||||
std::reverse(bytes.begin(), bytes.end());
|
||||
if (ok) *ok = true;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
BlockchainBackend::BlockchainBackend(LogosAPI* logosAPI, QObject* parent)
|
||||
: BlockchainBackendSimpleSource(parent)
|
||||
, m_logosAPI(logosAPI)
|
||||
@ -341,13 +381,24 @@ QString BlockchainBackend::getNotes(QString walletAddressHex, QString optionalTi
|
||||
}
|
||||
|
||||
QString BlockchainBackend::channelDepositWithNotes(
|
||||
QString channelIdHex, QStringList inputNoteIdHexes, QString metadataHex,
|
||||
QString channelIdHex, QStringList inputNoteIdHexes, QString metadataBase58,
|
||||
QString changePublicKeyHex, QStringList fundingPublicKeyHexes,
|
||||
QString maxTxFee, QString optionalTipHex)
|
||||
{
|
||||
if (!m_blockchainClient)
|
||||
return QStringLiteral("Error: Module not initialized.");
|
||||
|
||||
// The metadata arrives base58-encoded; the module expects metadata_hex, so
|
||||
// decode to bytes and hex-encode. Empty stays empty (metadata is optional).
|
||||
QString metadataHex;
|
||||
if (!metadataBase58.trimmed().isEmpty()) {
|
||||
bool ok = false;
|
||||
const QByteArray bytes = decodeBase58(metadataBase58, &ok);
|
||||
if (!ok)
|
||||
return QStringLiteral("Error: Invalid base58 metadata.");
|
||||
metadataHex = QString::fromLatin1(bytes.toHex());
|
||||
}
|
||||
|
||||
// 7 positional args exceed the variadic invokeRemoteMethod overloads
|
||||
// (max 5), so pass them through the QVariantList form.
|
||||
QVariantList args;
|
||||
|
||||
@ -51,7 +51,7 @@ public slots:
|
||||
QString getNotes(QString walletAddressHex, QString optionalTipHex) override;
|
||||
QString channelDepositWithNotes(QString channelIdHex,
|
||||
QStringList inputNoteIdHexes,
|
||||
QString metadataHex,
|
||||
QString metadataBase58,
|
||||
QString changePublicKeyHex,
|
||||
QStringList fundingPublicKeyHexes,
|
||||
QString maxTxFee,
|
||||
|
||||
@ -17,7 +17,7 @@ class BlockchainBackend
|
||||
SLOT(QString claimLeaderRewards())
|
||||
SLOT(int generateConfig(QString outputPath, QStringList initialPeers, int netPort, int blendPort, QString httpAddr, QString externalAddress, bool noPublicIpCheck, int deploymentMode, QString deploymentConfigPath, QString statePath))
|
||||
SLOT(QString getNotes(QString walletAddressHex, QString optionalTipHex))
|
||||
SLOT(QString channelDepositWithNotes(QString channelIdHex, QStringList inputNoteIdHexes, QString metadataHex, QString changePublicKeyHex, QStringList fundingPublicKeyHexes, QString maxTxFee, QString optionalTipHex))
|
||||
SLOT(QString channelDepositWithNotes(QString channelIdHex, QStringList inputNoteIdHexes, QString metadataBase58, QString changePublicKeyHex, QStringList fundingPublicKeyHexes, QString maxTxFee, QString optionalTipHex))
|
||||
SLOT(void clearLogs())
|
||||
SLOT(void copyToClipboard(QString text))
|
||||
}
|
||||
|
||||
@ -298,11 +298,11 @@ Rectangle {
|
||||
function(error) { channelDepositView.setNotesResult("Error: " + error) }
|
||||
)
|
||||
}
|
||||
onSubmitRequested: function(channelIdHex, inputNoteIdHexes, metadataHex, changePublicKeyHex, fundingPublicKeyHexes, maxTxFee, optionalTipHex) {
|
||||
onSubmitRequested: function(channelIdHex, inputNoteIdHexes, metadataBase58, changePublicKeyHex, fundingPublicKeyHexes, maxTxFee, optionalTipHex) {
|
||||
if (!root.backend) return
|
||||
logos.watch(
|
||||
root.backend.channelDepositWithNotes(
|
||||
channelIdHex, inputNoteIdHexes, metadataHex,
|
||||
channelIdHex, inputNoteIdHexes, metadataBase58,
|
||||
changePublicKeyHex, fundingPublicKeyHexes, maxTxFee, optionalTipHex),
|
||||
function(result) { channelDepositView.setSubmitResult(result) },
|
||||
function(error) { channelDepositView.setSubmitResult("Error: " + error) }
|
||||
|
||||
@ -21,7 +21,7 @@ ColumnLayout {
|
||||
property bool nodeRunning: false
|
||||
|
||||
signal getNotesRequested(string addressHex, string optionalTipHex)
|
||||
signal submitRequested(string channelIdHex, var inputNoteIdHexes, string metadataHex, string changePublicKeyHex, var fundingPublicKeyHexes, string maxTxFee, string optionalTipHex)
|
||||
signal submitRequested(string channelIdHex, var inputNoteIdHexes, string metadataBase58, string changePublicKeyHex, var fundingPublicKeyHexes, string maxTxFee, string optionalTipHex)
|
||||
signal copyToClipboard(string text)
|
||||
|
||||
// --- Called by the parent after async backend calls return ---
|
||||
@ -77,6 +77,18 @@ ColumnLayout {
|
||||
.filter(function(s) { return s.length > 0 })
|
||||
}
|
||||
|
||||
// --- Metadata (base58-encoded bytes) ---
|
||||
|
||||
// The actual base58 → bytes decoding happens in the C++ backend; here we
|
||||
// only check the input uses the base58 (Bitcoin) alphabet. Plain base58
|
||||
// has no checksum, so a valid-alphabet string always decodes.
|
||||
function metadataIsValid() {
|
||||
var s = metadataField.text.trim()
|
||||
if (s === "")
|
||||
return true // optional
|
||||
return /^[1-9A-HJ-NP-Za-km-z]+$/.test(s)
|
||||
}
|
||||
|
||||
function canAdvance() {
|
||||
switch (step) {
|
||||
case 0:
|
||||
@ -86,6 +98,7 @@ ColumnLayout {
|
||||
&& changeKeyField.text.trim().length > 0
|
||||
&& fundingKeyList().length > 0
|
||||
&& maxFeeField.text.trim().length > 0
|
||||
&& metadataIsValid()
|
||||
default:
|
||||
return true
|
||||
}
|
||||
@ -151,7 +164,7 @@ ColumnLayout {
|
||||
{ k: qsTr("Change public key"), v: changeKeyField.text.trim() },
|
||||
{ k: qsTr("Funding public keys"), v: fundingKeyList().join("\n") },
|
||||
{ k: qsTr("Max tx fee"), v: maxFeeField.text.trim() },
|
||||
{ k: qsTr("Metadata hex"), v: metadataField.text.trim() || qsTr("(none)") },
|
||||
{ k: qsTr("Metadata (base58)"), v: metadataField.text.trim() || qsTr("(none)") },
|
||||
{ k: qsTr("Optional tip hex"), v: tipField.text.trim() || qsTr("(current tip)") }
|
||||
]
|
||||
}
|
||||
@ -326,13 +339,28 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
LogosText {
|
||||
text: qsTr("Metadata hex (optional)")
|
||||
text: qsTr("Metadata (base58, optional)")
|
||||
font.pixelSize: Theme.typography.secondaryText
|
||||
}
|
||||
LogosTextField {
|
||||
id: metadataField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Metadata hex")
|
||||
placeholderText: qsTr("Base58-encoded metadata bytes")
|
||||
}
|
||||
LogosText {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Input must be base58-encoded; it is decoded to bytes before submission.")
|
||||
color: Theme.palette.textSecondary
|
||||
font.pixelSize: Theme.typography.secondaryText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
LogosText {
|
||||
Layout.fillWidth: true
|
||||
visible: metadataField.text.trim() !== "" && !d.metadataIsValid()
|
||||
text: qsTr("Invalid base58 input")
|
||||
color: Theme.palette.error
|
||||
font.pixelSize: Theme.typography.secondaryText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
LogosText {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user