From bcbcf612a8089142af996fb1dd59ad6f0e8d37be Mon Sep 17 00:00:00 2001
From: "denis.sumin" <denis.smolov@demlabs.net>
Date: Tue, 4 Mar 2025 13:45:24 +0300
Subject: [PATCH 1/5] [*] show null address

---
 chain/wallet/handlers/DapGetAllWalletHistoryCommandBase.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/chain/wallet/handlers/DapGetAllWalletHistoryCommandBase.cpp b/chain/wallet/handlers/DapGetAllWalletHistoryCommandBase.cpp
index a8acc85c..5f395627 100644
--- a/chain/wallet/handlers/DapGetAllWalletHistoryCommandBase.cpp
+++ b/chain/wallet/handlers/DapGetAllWalletHistoryCommandBase.cpp
@@ -166,12 +166,14 @@ QString DapGetAllWalletHistoryCommandBase::getHistory(const QString& net, const
                         txHeader.insert(DIRECTION_KEY, dataTransaction[typeHistoryData::NULL_ADDR].direction);
                         txHeader.insert(TOKEN_KEY, dataTransaction[typeHistoryData::NULL_ADDR].token);
                         txHeader.insert(STATUS_KEY, getStatus(dataTransaction[typeHistoryData::NULL_ADDR].status));
+                        txHeader.insert(ADDRESS_KEY, "null");
                     }
                     if(!isBase && !isEmission && isStateLock && isNullAddr)
                     {
                         txHeader.insert(M_VALUE_KEY, dataTransaction[typeHistoryData::NULL_ADDR].value);
                         txHeader.insert(M_DIRECTION_KEY, dataTransaction[typeHistoryData::NULL_ADDR].direction);
                         txHeader.insert(M_TOKEN, dataTransaction[typeHistoryData::NULL_ADDR].token);
+                        txHeader.insert(ADDRESS_KEY, "null");
                     }
 
                     if(isBase)
-- 
GitLab


From 69a9f239e070b8b6eade9071abb96b4dc64fe7db Mon Sep 17 00:00:00 2001
From: Konstantin <konstatin.kuharenko@demlabs.net>
Date: Thu, 6 Mar 2025 08:05:16 +0300
Subject: [PATCH 2/5] [*] add new master node command

---
 chain/wallet/handlers/DapCommandList.cpp      |  33 +++++
 chain/wallet/handlers/DapCommandList.h        |   2 +
 .../DapCreateOrderValidatorCommand.cpp        |  78 +++++++++++
 .../handlers/DapCreateOrderValidatorCommand.h |  14 ++
 .../handlers/DapOrderCreateStakerCommand.cpp  | 127 ++++++++++++++++++
 .../handlers/DapOrderCreateStakerCommand.h    |  18 +++
 .../stackCommand/DapCommandStackManager.cpp   |   6 +-
 .../DapOrderCreateStakerCommandStack.cpp      |  48 +++++++
 .../DapOrderCreateStakerCommandStack.h        |  22 +++
 chain/wallet/libdap-qt-chain-wallet.pri       |   6 +
 10 files changed, 353 insertions(+), 1 deletion(-)
 create mode 100644 chain/wallet/handlers/DapCreateOrderValidatorCommand.cpp
 create mode 100644 chain/wallet/handlers/DapCreateOrderValidatorCommand.h
 create mode 100644 chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
 create mode 100644 chain/wallet/handlers/DapOrderCreateStakerCommand.h
 create mode 100644 chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.cpp
 create mode 100644 chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.h

diff --git a/chain/wallet/handlers/DapCommandList.cpp b/chain/wallet/handlers/DapCommandList.cpp
index 07c93eb3..b31ab5f6 100644
--- a/chain/wallet/handlers/DapCommandList.cpp
+++ b/chain/wallet/handlers/DapCommandList.cpp
@@ -1149,6 +1149,39 @@ QVariant DapCommandList::createStakeOrder(const QVariant &args)
     return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
+QVariant DapCommandList::createOrderValidator(const QVariant &args)
+{
+    QStringList params = args.toStringList();
+
+    auto command = QString("srv_stake order create validator -net %1 -value_min %2 -value_max %3 -tax %4 -cert %5")
+                       .arg(params[0])   // network
+                       .arg(params[1])   // minimum_stake_value
+                       .arg(params[2])   // maximum_stake_value
+                       .arg(params[3])   // percent
+                       .arg(params[4]);  // cert
+
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
+}
+
+QVariant DapCommandList::createOrderStaker(const QVariant &args)
+{
+    QStringList params = args.toStringList();
+
+    auto command = QString("srv_stake order create staker -net %1 -w %2 -value %3 -fee %4 -tax %5")
+                       .arg(params[0])   // network
+                       .arg(params[1])   // wallet name
+                       .arg(params[2])   // value
+                       .arg(params[4])   // value fee validator
+                       .arg(params[3]);  // tax
+
+    if(params.size() == 6)
+    {
+        command.append(QString(" -addr %1").arg(params[5]));
+    }
+
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
+}
+
 QVariant DapCommandList::getListKeysCommand(const QString &net)
 {
     QString command = QString("srv_stake list keys -net %1").arg(net);
diff --git a/chain/wallet/handlers/DapCommandList.h b/chain/wallet/handlers/DapCommandList.h
index f5f6ddcb..f46fe4f0 100644
--- a/chain/wallet/handlers/DapCommandList.h
+++ b/chain/wallet/handlers/DapCommandList.h
@@ -193,6 +193,8 @@ public:
     QVariant getWalletAddress(const QString &net, const QString &wallet);
     QVariant createVPNOrder(const QVariant &args);
     QVariant createStakeOrder(const QVariant &args);
+    QVariant createOrderStaker(const QVariant &args);
+    QVariant createOrderValidator(const QVariant &args);
     QVariant getListKeysCommand(const QString &net);
     QVariant getListChains();
     QVariant addNode(const QVariant &args);
diff --git a/chain/wallet/handlers/DapCreateOrderValidatorCommand.cpp b/chain/wallet/handlers/DapCreateOrderValidatorCommand.cpp
new file mode 100644
index 00000000..0962add3
--- /dev/null
+++ b/chain/wallet/handlers/DapCreateOrderValidatorCommand.cpp
@@ -0,0 +1,78 @@
+#include "DapCreateOrderValidatorCommand.h"
+
+DapCreateOrderValidatorCommand::DapCreateOrderValidatorCommand(const QString &asServicename, QObject *parent, const QString &asCliPath)
+    : DapAbstractCommand(asServicename, parent, asCliPath)
+{
+
+}
+
+QVariant DapCreateOrderValidatorCommand::respondToClient(const QVariant &args)
+{
+    DapAbstractCommand::respondToClient(args);
+    auto result = cmdList->createOrderValidator(args);
+    QJsonObject reply = result.toJsonObject();
+
+    auto returnError = [this, &args](const QJsonObject& object) -> QVariant
+    {
+        QJsonObject errorObject;
+        errorObject.insert(ERROR_KEY, object);
+        addWeb3Result(errorObject, args);
+
+        QJsonDocument resultDoc;
+        resultDoc.setObject(errorObject);
+        return resultDoc.toJson();
+    };
+
+    QJsonObject resultObject;
+    if(reply.isEmpty())
+    {
+        return returnError({{"message", "Error. Node gave an empty answer."}});
+    }
+    if(reply.contains("errors"))
+    {
+        return returnError({{"message", reply["errors"].toString()}});
+    }
+    if(!reply["result"].isArray())
+    {
+        return returnError({{"message", "Error. Answer is does't array."}});
+    }
+    auto replyResult = reply["result"].toArray();
+    if(replyResult.isEmpty() || !replyResult.first().isObject())
+    {
+        return returnError({{"message", "Error. Answer is does't array."}});
+    }
+    QJsonObject replyObject = replyResult.first().toObject();
+    QJsonObject respondObject;
+    if(replyObject.contains("order_hash") && replyObject.contains("status"))
+    {
+        respondObject.insert("hash", replyObject["order_hash"].toString());
+        respondObject.insert("status", replyObject["status"].toString());
+    }
+    else if(replyObject.contains("errors"))
+    {
+        auto errorArray = replyObject.value("errors").toArray();
+        if(errorArray.isEmpty())
+        {
+            return returnError({{"message", "Error. The structure of the json output for displaying the error has changed."}});
+        }
+        auto errorObject = errorArray.first().toObject();
+        if(!errorObject.contains("message") && !errorObject.contains("code"))
+        {
+            return returnError({{"message", "Error. The message or/and error code items were not found."}});
+        }
+
+        return returnError({{"message", errorObject.value("message")}
+                           ,{"code", errorObject.value("code")}});
+    }
+    else
+    {
+        return returnError({{"message", "Error. Unknown error."}});
+    }
+
+    resultObject.insert(RESULT_KEY, std::move(respondObject));
+    addWeb3Result(resultObject, args);
+
+    QJsonDocument resultDoc;
+    resultDoc.setObject(resultObject);
+    return resultDoc.toJson();
+}
diff --git a/chain/wallet/handlers/DapCreateOrderValidatorCommand.h b/chain/wallet/handlers/DapCreateOrderValidatorCommand.h
new file mode 100644
index 00000000..e3c302cd
--- /dev/null
+++ b/chain/wallet/handlers/DapCreateOrderValidatorCommand.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "DapAbstractCommand.h"
+#include <QRegularExpression>
+
+class DapCreateOrderValidatorCommand : public DapAbstractCommand
+{
+public:
+    explicit DapCreateOrderValidatorCommand(const QString &asServicename, QObject *parent = nullptr, const QString &asCliPath = QString());
+
+public slots:
+    QVariant respondToClient(const QVariant &args = QVariant()) override;
+
+};
diff --git a/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
new file mode 100644
index 00000000..4ca2bba5
--- /dev/null
+++ b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
@@ -0,0 +1,127 @@
+#include "DapOrderCreateStakerCommand.h"
+
+DapOrderCreateStakerCommand::DapOrderCreateStakerCommand(const QString &asServicename, QObject *parent, const QString &asCliPath)
+    : DapAbstractCommand(asServicename, parent, asCliPath)
+{
+}
+
+QVariant DapOrderCreateStakerCommand::respondToClient(const QVariant &args)
+{
+    DapAbstractCommand::respondToClient(args);
+    QString errorMsg;
+    QStringList params = args.toStringList();
+    if(!params.contains("feeAdded"))
+    {
+        QString fee = "50000000000000000";
+        auto docFee = cmdList->getFee(params[0]);
+        if(!docFee.validatorFeeList["median"].datoshi.isEmpty())
+            fee = docFee.validatorFeeList["median"].datoshi;
+        params.insert(4, fee);
+    }
+
+    QJsonObject transactionObj, resultObject;
+
+    bool isWalletBlocked = false;
+    QString tmpParam;
+    cmdList->getParamForPairList(params, "walletName", tmpParam);
+    if(!tmpParam.isEmpty())
+    {
+        auto wallets = getListWallets();
+        if(wallets.contains(tmpParam) && wallets[tmpParam] == WALLET_NON_ACTIVE_KEY)
+        {
+            resultObject.insert(ERROR_KEY, "The wallet is blocked.");
+            transactionObj.insert(SUCCESS,QJsonValue(false));
+            transactionObj.insert(MESSAGE,QJsonValue(""));
+            isWalletBlocked = true;
+        }
+    }
+
+    if(!isWalletBlocked)
+    {
+        auto returnError = [this, &args](const QJsonObject& object) -> QVariant
+        {
+            QJsonObject errorObject;
+            errorObject.insert(ERROR_KEY, object);
+            QJsonObject transactionObj;
+            transactionObj.insert(SUCCESS,QJsonValue(false));
+            transactionObj.insert(MESSAGE,QJsonValue(""));
+            errorObject.insert(RESULT_KEY, transactionObj);
+            addWeb3Result(errorObject, args);
+
+            QJsonDocument resultDoc;
+            resultDoc.setObject(errorObject);
+            return resultDoc.toJson();
+        };
+        auto requestDoc = cmdList->createOrderStaker(params);
+        auto request = requestDoc.toJsonObject();
+        if(!request["errors"].isNull())
+        {
+            QJsonArray errArr = request["errors"].toArray();
+            QJsonObject errObj = errArr[0].toObject()["error"].toObject();
+            return returnError({{"message", errObj["message"].toString()}});
+        }
+        else
+        {
+            QJsonArray result;
+            bool isSuccess = false;
+            QString hash;
+            QString orderHash;
+            if(request.contains("result"))
+            {
+                result = request["result"].toArray();
+
+            }
+            if(result.isEmpty())
+            {
+                return returnError({{"message", "It is possible to change the output of the node. there is no result."}});
+            }
+            else
+            {
+                QJsonObject firstValue = result[0].toObject();
+                for(const QString& itemKey: firstValue.keys())
+                {
+                    if(itemKey == "status" && firstValue.value(itemKey).toString() == "success")
+                    {
+                        isSuccess = true;
+                        hash = firstValue.value("tx_hash").toString();
+                        orderHash = firstValue.value("order_hash").toString();
+                    }
+                    if(itemKey == "errors")
+                    {
+                        auto errorArray = firstValue.value(itemKey).toArray();
+                        if(errorArray.isEmpty())
+                        {
+                            return returnError({{"message", "Error. The structure of the json output for displaying the error has changed."}});
+                        }
+                        auto errorObject = errorArray.first().toObject();
+                        if(!errorObject.contains("message") && !errorObject.contains("code"))
+                        {
+                            return returnError({{"message", "Error. The message or/and error code items were not found."}});
+                        }
+
+                        return returnError({{"message", errorObject.value("message")}
+                                            ,{"code", errorObject.value("code")}});
+                    }
+                }
+            }
+
+            transactionObj.insert(SUCCESS,QJsonValue(isSuccess));
+            transactionObj.insert(MESSAGE,QJsonValue(result));
+            if(isSuccess)
+            {
+                transactionObj.insert(HASH, QJsonValue(hash));
+                transactionObj.insert(HASH_ORDER, QJsonValue(orderHash));
+            }
+        }
+    }
+
+    if(!errorMsg.isEmpty())
+    {
+        resultObject.insert(ERROR_KEY, errorMsg);
+    }
+    addWeb3Result(resultObject, args);
+    resultObject.insert(RESULT_KEY, transactionObj);
+    QJsonDocument resultDoc;
+    resultDoc.setObject(resultObject);
+    return resultDoc.toJson();
+}
diff --git a/chain/wallet/handlers/DapOrderCreateStakerCommand.h b/chain/wallet/handlers/DapOrderCreateStakerCommand.h
new file mode 100644
index 00000000..28081558
--- /dev/null
+++ b/chain/wallet/handlers/DapOrderCreateStakerCommand.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "DapAbstractCommand.h"
+
+class DapOrderCreateStakerCommand : public DapAbstractCommand
+{
+public:
+    explicit DapOrderCreateStakerCommand(const QString &asServicename, QObject *parent = nullptr, const QString &asCliPath = QString());
+
+public slots:
+    QVariant respondToClient(const QVariant &args = QVariant()) override;
+
+private:
+    const QString SUCCESS = "success";
+    const QString MESSAGE = "message";
+    const QString HASH = "tx_hash";
+    const QString HASH_ORDER = "order_hash";
+};
diff --git a/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp b/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
index efba9f54..5f27698f 100644
--- a/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
+++ b/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
@@ -84,7 +84,11 @@ QVariant DapCommandStackManager::respondToClient(const QVariant &args)
             if(object.contains("tx_hash"))
             {
                 hash = object["tx_hash"].toString();
-                resultObj.insert("tx_hash", hash);
+                for(const QString& key: object.keys())
+                {
+                    resultObj.insert(key, object.value(key));
+                }
+                // resultObj.insert("tx_hash", hash);
 
                 qInfo() << QString("[Queue] The transaction got into the mempool and received a hash of %1").arg(hash);
 
diff --git a/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.cpp b/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.cpp
new file mode 100644
index 00000000..1fae1993
--- /dev/null
+++ b/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.cpp
@@ -0,0 +1,48 @@
+#include "DapOrderCreateStakerCommandStack.h"
+#include "TransactionQueue/DapTransactionQueueController.h"
+
+DapOrderCreateStakerCommandStack::DapOrderCreateStakerCommandStack(const QString &asServicename, QObject *parent, const QString &asCliPath)
+    : DapOrderCreateStakerCommand(asServicename, parent, asCliPath)
+    , m_commandManager(new DapCommandStackManager(this))
+{
+    m_commandManager->setCommandCalback([&](const QVariant &args) -> QVariant { return this->respondToClient(args);});
+    m_commandManager->setParentCalback([&](const QVariant &args) -> QVariant { return DapOrderCreateStakerCommand::respondToClient(args); });
+    m_commandManager->setWalletNameCalback([&](const QStringList &list) -> QString { return list[1]; });
+    m_commandManager->setNetworkNameCalback([&](const QStringList &list) -> QString { return list[0];});
+    m_commandManager->setWeb3UpdateCalback([&](QJsonObject& result, const QVariant& args){ addWeb3Result(result, args); });
+
+
+    DapTransactionQueueController* controller = DapTransactionQueueController::getTransactionController();
+    DapTransactionQueueController::ParamsFromCommand callbacks;
+    callbacks.addressCallback       = [](const QStringList &list) -> QString { return "master node";};
+    callbacks.feeCallback           = [](const QStringList &list) -> QString { return list[4];};
+    callbacks.tokenCallback         = [this](const QStringList &list) -> QString { return m_tokens.value(list[0]).first;};
+    callbacks.valueCallback         = [](const QStringList &list) -> QString { return list[2];};
+    callbacks.walletNameCallback    = [](const QStringList &list) -> QString { return list[1];};
+    callbacks.directionCallback     = [](const QStringList &list) -> QString { return "to";};
+    callbacks.testExpenses          = []() -> bool { return true;};
+    callbacks.feeInfo               = [&]() -> const QMap<QString, NetworkSpace::FeeInfoStruct> { return getFee();};
+    controller->setParamsCommandCallback(this->getName(), callbacks);
+}
+
+QVariant DapOrderCreateStakerCommandStack::respondToClient(const QVariant &args)
+{
+    QStringList params = args.toStringList();
+    if(!params.contains("self") && params.contains(WEB3_KEY) && !params.contains("feeAdded"))
+    {
+        QString fee = "50000000000000000";
+        auto docFee = getFee()[params[0]];
+        if(!docFee.validatorFeeList["median"].datoshi.isEmpty())
+            fee = docFee.validatorFeeList["median"].datoshi;
+
+        params.insert(4, fee);
+        params.append("feeAdded");
+        return m_commandManager->respondToClient(params);
+    }
+    return m_commandManager->respondToClient(args);
+}
+
+DapOrderCreateStakerCommandStack::~DapOrderCreateStakerCommandStack()
+{
+    delete m_commandManager;
+}
diff --git a/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.h b/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.h
new file mode 100644
index 00000000..58273c01
--- /dev/null
+++ b/chain/wallet/handlers/stackCommand/DapOrderCreateStakerCommandStack.h
@@ -0,0 +1,22 @@
+#pragma once
+#include "../DapOrderCreateStakerCommand.h"
+#include "DapCommandStackManager.h"
+
+class DapOrderCreateStakerCommandStack : public DapOrderCreateStakerCommand
+{
+public:
+    DapOrderCreateStakerCommandStack(const QString &asServicename, QObject *parent = nullptr, const QString &asCliPath = QString());
+    ~DapOrderCreateStakerCommandStack();
+public slots:
+    QVariant respondToClient(const QVariant &args = QVariant()) override;
+private:
+    DapCommandStackManager* m_commandManager = nullptr;
+
+    const QMap<QString, QPair<QString, QString>> m_tokens = {{"Backbone", qMakePair(QString("mCELL"), QString("CELL"))},
+                                                             {"KelVPN", qMakePair(QString("mKEL"), QString("KEL"))},
+                                                             {"raiden", qMakePair(QString("mtCELL"), QString("tCELL"))},
+                                                             {"riemann", qMakePair(QString("mtKEL"), QString("tKEL"))},
+                                                             {"mileena", qMakePair(QString("mtMIL"), QString("tMIL"))},
+                                                             {"subzero", qMakePair(QString("mtCELL"), QString("tCELL"))}};
+};
+
diff --git a/chain/wallet/libdap-qt-chain-wallet.pri b/chain/wallet/libdap-qt-chain-wallet.pri
index ccef29d1..7843e77e 100644
--- a/chain/wallet/libdap-qt-chain-wallet.pri
+++ b/chain/wallet/libdap-qt-chain-wallet.pri
@@ -32,6 +32,7 @@ HEADERS += \
     $$PWD/autocomplete/HelpDictionaryServiceController.h \
     $$PWD/autocomplete/HelpDictionaryController.h \
     $$PWD/handlers/DapAddNodeCommand.h \
+    $$PWD/handlers/DapCreateOrderValidatorCommand.h \
     $$PWD/handlers/DapGetListKeysCommand.h \
     $$PWD/handlers/DapGetNodeIPCommand.h \
     $$PWD/handlers/DapGetNodeStatus.h \
@@ -42,6 +43,7 @@ HEADERS += \
     $$PWD/handlers/DapMoveWalletCommand.h \
     $$PWD/handlers/DapNodeDumpCommand.h \
     $$PWD/handlers/DapNodeListCommand.h \
+    $$PWD/handlers/DapOrderCreateStakerCommand.h \
     $$PWD/handlers/DapRcvNotify.h \
     $$PWD/handlers/DapSrvStakeDelegateCommand.h \
     $$PWD/handlers/DapTransactionsInfoQueueCommand.h \
@@ -51,6 +53,7 @@ HEADERS += \
     $$PWD/handlers/DapVoitingDumpCommand.h \
     $$PWD/handlers/stackCommand/DapCommandStackManager.h \
     $$PWD/handlers/stackCommand/DapCreateTransactionCommandStack.h \
+    $$PWD/handlers/stackCommand/DapOrderCreateStakerCommandStack.h \
     $$PWD/handlers/stackCommand/DapSrvStakeDelegateCommandStack.h \
     $$PWD/handlers/stackCommand/DapSrvStakeInvalidateStack.h \
     $$PWD/handlers/stackCommand/DapXchangeOrderCreateStack.h \
@@ -168,6 +171,7 @@ SOURCES += \
     $$PWD/autocomplete/HelpDictionaryServiceController.cpp \
     $$PWD/autocomplete/HelpDictionaryController.cpp \
     $$PWD/handlers/DapAddNodeCommand.cpp \
+    $$PWD/handlers/DapCreateOrderValidatorCommand.cpp \
     $$PWD/handlers/DapGetListKeysCommand.cpp \
     $$PWD/handlers/DapGetNodeIPCommand.cpp \
     $$PWD/handlers/DapGetNodeStatus.cpp \
@@ -178,6 +182,7 @@ SOURCES += \
     $$PWD/handlers/DapMoveWalletCommand.cpp \
     $$PWD/handlers/DapNodeDumpCommand.cpp \
     $$PWD/handlers/DapNodeListCommand.cpp \
+    $$PWD/handlers/DapOrderCreateStakerCommand.cpp \
     $$PWD/handlers/DapRcvNotify.cpp \
     $$PWD/handlers/DapSrvStakeDelegateCommand.cpp \
     $$PWD/handlers/DapTransactionsInfoQueueCommand.cpp \
@@ -187,6 +192,7 @@ SOURCES += \
     $$PWD/handlers/DapVoitingDumpCommand.cpp \
     $$PWD/handlers/stackCommand/DapCommandStackManager.cpp \
     $$PWD/handlers/stackCommand/DapCreateTransactionCommandStack.cpp \
+    $$PWD/handlers/stackCommand/DapOrderCreateStakerCommandStack.cpp \
     $$PWD/handlers/stackCommand/DapSrvStakeDelegateCommandStack.cpp \
     $$PWD/handlers/stackCommand/DapSrvStakeInvalidateStack.cpp \
     $$PWD/handlers/stackCommand/DapXchangeOrderCreateStack.cpp \
-- 
GitLab


From 462f8d0069996268c991fbd98bb2d8666b2c4aed Mon Sep 17 00:00:00 2001
From: Konstantin <konstatin.kuharenko@demlabs.net>
Date: Thu, 6 Mar 2025 09:29:58 +0300
Subject: [PATCH 3/5] [*] fix staker address

---
 chain/wallet/handlers/DapCommandList.cpp              | 2 +-
 chain/wallet/handlers/DapOrderCreateStakerCommand.cpp | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/chain/wallet/handlers/DapCommandList.cpp b/chain/wallet/handlers/DapCommandList.cpp
index b31ab5f6..5e0f8a2a 100644
--- a/chain/wallet/handlers/DapCommandList.cpp
+++ b/chain/wallet/handlers/DapCommandList.cpp
@@ -1174,7 +1174,7 @@ QVariant DapCommandList::createOrderStaker(const QVariant &args)
                        .arg(params[4])   // value fee validator
                        .arg(params[3]);  // tax
 
-    if(params.size() == 6)
+    if(params.size() > 5 && (params[5] != "web3" &&  params[5] != "feeAdded" && params[5] != "queueHash"))
     {
         command.append(QString(" -addr %1").arg(params[5]));
     }
diff --git a/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
index 4ca2bba5..ebd0f46d 100644
--- a/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
+++ b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
@@ -22,12 +22,11 @@ QVariant DapOrderCreateStakerCommand::respondToClient(const QVariant &args)
     QJsonObject transactionObj, resultObject;
 
     bool isWalletBlocked = false;
-    QString tmpParam;
-    cmdList->getParamForPairList(params, "walletName", tmpParam);
-    if(!tmpParam.isEmpty())
+    QString walletName = params[1];
+    if(!walletName.isEmpty())
     {
         auto wallets = getListWallets();
-        if(wallets.contains(tmpParam) && wallets[tmpParam] == WALLET_NON_ACTIVE_KEY)
+        if(wallets.contains(walletName) && wallets[walletName] == WALLET_NON_ACTIVE_KEY)
         {
             resultObject.insert(ERROR_KEY, "The wallet is blocked.");
             transactionObj.insert(SUCCESS,QJsonValue(false));
-- 
GitLab


From 72e4d114c37173d21acbc6e5abda2930fcb7bd5b Mon Sep 17 00:00:00 2001
From: Konstantin <konstatin.kuharenko@demlabs.net>
Date: Thu, 6 Mar 2025 10:37:32 +0300
Subject: [PATCH 4/5] [*] fix port node list

---
 chain/wallet/handlers/DapGetNodeIPCommand.cpp | 2 +-
 chain/wallet/handlers/DapNodeListCommand.cpp  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/chain/wallet/handlers/DapGetNodeIPCommand.cpp b/chain/wallet/handlers/DapGetNodeIPCommand.cpp
index 58772598..4ef0bf3e 100644
--- a/chain/wallet/handlers/DapGetNodeIPCommand.cpp
+++ b/chain/wallet/handlers/DapGetNodeIPCommand.cpp
@@ -41,7 +41,7 @@ QVariant DapGetNodeIPCommand::respondToClient(const QVariant &args)
         auto result = cmdList->nodeListCommand(net).toString();
         QMap<QString,QString> dumpInfo;
         QRegularExpression regular(
-            R"(^(\b(?:[0-9A-Fa-f]{4}::){3}[0-9A-Fa-f]{4})(\s*)(\S*)(\s*)(\S*)(\s*)(\S*)(\s*)(.+)   )", QRegularExpression::MultilineOption);
+            R"(^(\b(?:[0-9A-Fa-f]{4}::){3}[0-9A-Fa-f]{4})(\s*)(\S*)(\s*)(\S*)(\s*)(.+) )", QRegularExpression::MultilineOption);
         QRegularExpressionMatchIterator matchItr = regular.globalMatch(result);
 
         if(matchItr.hasNext())
diff --git a/chain/wallet/handlers/DapNodeListCommand.cpp b/chain/wallet/handlers/DapNodeListCommand.cpp
index 22a0ec69..ffaf696c 100644
--- a/chain/wallet/handlers/DapNodeListCommand.cpp
+++ b/chain/wallet/handlers/DapNodeListCommand.cpp
@@ -22,7 +22,7 @@ QVariant DapNodeListCommand::respondToClient(const QVariant &args)
     QJsonObject resultObj;
 
     QRegularExpression regular(
-        R"(^(\b(?:[0-9A-Fa-f]{4}::){3}[0-9A-Fa-f]{4})(\s*)(\S*)(\s*)(\S*)    (.+) )", QRegularExpression::MultilineOption);
+        R"(^(\b(?:[0-9A-Fa-f]{4}::){3}[0-9A-Fa-f]{4})(\s*)(\S*)(\s*)(\S*)(\s*)(.+) )", QRegularExpression::MultilineOption);
     QRegularExpressionMatchIterator matchItr = regular.globalMatch(result);
 
     if(matchItr.hasNext())
@@ -38,7 +38,7 @@ QVariant DapNodeListCommand::respondToClient(const QVariant &args)
             obj.insert("node address", match.captured(1));
             obj.insert("ipv4", match.captured(3));
             obj.insert("port", match.captured(5));
-            obj.insert("date", match.captured(6));
+            obj.insert("date", match.captured(7));
 
             arr.append(obj);
         }
-- 
GitLab


From 6c2f297e862c27f2c88569e391c6b09aa4e7d64a Mon Sep 17 00:00:00 2001
From: Konstantin <konstatin.kuharenko@demlabs.net>
Date: Thu, 6 Mar 2025 12:14:32 +0300
Subject: [PATCH 5/5] [*] fix problem double message result and show error

---
 .../handlers/DapOrderCreateStakerCommand.cpp  |  5 ++++-
 .../stackCommand/DapCommandStackManager.cpp   | 21 ++++++++++++-------
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
index ebd0f46d..30e0b8f5 100644
--- a/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
+++ b/chain/wallet/handlers/DapOrderCreateStakerCommand.cpp
@@ -105,12 +105,15 @@ QVariant DapOrderCreateStakerCommand::respondToClient(const QVariant &args)
             }
 
             transactionObj.insert(SUCCESS,QJsonValue(isSuccess));
-            transactionObj.insert(MESSAGE,QJsonValue(result));
             if(isSuccess)
             {
                 transactionObj.insert(HASH, QJsonValue(hash));
                 transactionObj.insert(HASH_ORDER, QJsonValue(orderHash));
             }
+            else
+            {
+                transactionObj.insert(MESSAGE,QJsonValue(result));
+            }
         }
     }
 
diff --git a/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp b/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
index 5f27698f..63fef8c9 100644
--- a/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
+++ b/chain/wallet/handlers/stackCommand/DapCommandStackManager.cpp
@@ -25,8 +25,8 @@ DapCommandStackManager::DapCommandStackManager(const DapAbstractCommand *command
 
 QVariant DapCommandStackManager::respondToClient(const QVariant &args)
 {
-    QString error;
-    QJsonObject resultObj, mainObject;
+    QJsonObject error;
+    QJsonObject resultObj;
     bool isQueue = false;
     QString hash, queueHash;
     QJsonValue successValue;
@@ -76,7 +76,14 @@ QVariant DapCommandStackManager::respondToClient(const QVariant &args)
 
             if(replyObj.contains("error"))
             {
-                error = replyObj["error"].toString();
+                if(replyObj.value("error").isString())
+                {
+                    error.insert("message", replyObj.value("error").toString());
+                }
+                else
+                {
+                    error = replyObj.value("error").toObject();
+                }
             }
 
             QJsonObject object = replyObj["result"].toObject();
@@ -113,7 +120,7 @@ QVariant DapCommandStackManager::respondToClient(const QVariant &args)
                 }
                 if(error.isEmpty())
                 {
-                    error = object["message"].toString();
+                    error.insert("message", object["message"].toString());
                 }
             }
         }
@@ -130,7 +137,7 @@ QVariant DapCommandStackManager::respondToClient(const QVariant &args)
     {
         if(!resultObj["tx_hash"].toString().contains(QRegularExpression(R"(0x[a-fA-F0-9])")))
         {
-            error = "An invalid hash value was received. Perhaps the answer has changed in the node.";
+            error.insert("message", "An invalid hash value was received. Perhaps the answer has changed in the node.");
         }
     }
 
@@ -139,14 +146,12 @@ QVariant DapCommandStackManager::respondToClient(const QVariant &args)
     resultObj.insert("success", isQueue ? true : successValue);
 
     QJsonDocument resultDoc;
+    QJsonObject mainObject;
     if(!error.isEmpty())
     {
         mainObject.insert("error", error);
-        resultObj.insert("error", error);
     }
 
-    mainObject.insert("result", resultObj);
-
     mainObject.insert("result", resultObj);
     if(m_addWeb3InfoCallBack)
     {
-- 
GitLab