From 48469188a8434aee9325e8afa0809cc778d2ee6b Mon Sep 17 00:00:00 2001
From: konstantin <konstantin.kuharenko@demlabs.net>
Date: Wed, 29 Jan 2025 15:20:20 +0300
Subject: [PATCH] [*] dex and wallet activate

---
 chain/wallet/handlers/DapCommandList.cpp      |  62 ++++----
 .../handlers/DapGetXchangeOrdersList.cpp      |  72 ++++-----
 .../handlers/DapGetXchangeTokenPair.cpp       | 134 ++++++-----------
 .../DapGetXchangeTokenPriceHistory.cpp        | 139 ++++++++----------
 chain/wallet/handlers/DapGetXchangeTxList.cpp |  64 ++++----
 .../DapWalletActivateOrDeactivateCommand.cpp  |  83 ++++++-----
 .../wallet/handlers/DapXchangeOrderCreate.cpp |  56 +++++--
 .../handlers/DapXchangeOrderPurchase.cpp      |  55 +++++--
 .../wallet/handlers/DapXchangeOrderRemove.cpp |  55 +++++--
 9 files changed, 384 insertions(+), 336 deletions(-)

diff --git a/chain/wallet/handlers/DapCommandList.cpp b/chain/wallet/handlers/DapCommandList.cpp
index 90fe2572..3242d39c 100644
--- a/chain/wallet/handlers/DapCommandList.cpp
+++ b/chain/wallet/handlers/DapCommandList.cpp
@@ -608,7 +608,7 @@ QVariant DapCommandList::getXchangeOrdersList(const QString &net)
     }
     auto command = QString("srv_xchange orders -net %1").arg(net);
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// List of all token pairs
@@ -622,7 +622,7 @@ QVariant DapCommandList::getXchangeTokenPairsList(const QString &net)
     auto command = QString("srv_xchange token_pair -net %1 list all")
                        .arg(net);
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// Get average rate for token pair
@@ -630,32 +630,43 @@ QPair<qint64, QString> DapCommandList::getXchangeAverage(const QVariant &args)
 {
     auto nodeAverage = getXchangeAverageCommand(args);
 
-    QString result = nodeAverage.toString().trimmed();
+    auto resultStruct = getJsonResult(nodeAverage, "getXchangeAverage current rate");
 
-    if(result == "Can't find orders for specified token pair")
+    QPair<qint64, QString> resultPair{0, "0.0"} ;
+    auto result = resultStruct.result;
+    if(result.isNull())
     {
-        qint64 dateToSecs = 0;
-        QString rate = "0.0";
-        return {dateToSecs, rate};
+        // qWarning() << "";
+        return resultPair;
     }
+    QJsonArray level1 = result.toArray();
 
-    QRegularExpression regex(R"(Last rate: ([0-9\.]+) Last rate time: (.*)$)");
-    QRegularExpressionMatch match = regex.match(result);
-
-    QPair<qint64, QString> resultPair;
+    if(level1.isEmpty())
+    {
+        return resultPair;
+    }
 
-    if(!match.hasMatch())
+    QJsonObject pairObject = level1[0].toObject();
+    if(pairObject.isEmpty())
     {
-        qWarning() << "The data output from the node has been changed.";
-        return {0, QString()};
+        return resultPair;
     }
 
-    QDateTime date = QDateTime::fromString(match.captured(2), Qt::RFC2822Date).toLocalTime();
+    if(pairObject.contains("errors"))
+    {
+        return resultPair;
+    }
+    if(!pairObject.contains("Last rate") || !pairObject.contains("Last rate time"))
+    {
+        qWarning() << "[getXchangeAverage] Either the structure or the names of the keys have changed.";
+        return resultPair;
+    }
+    QDateTime date = QDateTime::fromString(pairObject["Last rate time"].toString(), Qt::RFC2822Date).toLocalTime();
     date.setTimeSpec(Qt::LocalTime);
     qint64 dateToSecs = date.toSecsSinceEpoch();
-
-    QString rate = match.captured(1);
-    return {dateToSecs, rate};
+    resultPair.first = dateToSecs;
+    resultPair.second = pairObject["Last rate"].toString();
+    return resultPair;
 }
 
 QVariant DapCommandList::getXchangeAverageCommand(const QVariant &args)
@@ -668,7 +679,7 @@ QVariant DapCommandList::getXchangeAverageCommand(const QVariant &args)
                        .arg(params[1]) // token to
                        .arg(params[2]); // token from
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// Print rate history for token pair
@@ -690,7 +701,7 @@ QVariant DapCommandList::getXchangeHistory(const QVariant &args)
     }
 
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// List of exchange transactions
@@ -711,10 +722,9 @@ QVariant DapCommandList::getXchangeList(const QVariant &args)
                            .arg(params[3]) // time from
                            .arg(params[4]); // time to
     }
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
-// Не проверено
 /// Proc mempool entrie with specified hash for selected chain network
 QVariant DapCommandList::mempoolProcess(const QVariant &args)
 {
@@ -940,7 +950,7 @@ QVariant DapCommandList::walletActivateOrDeactivate(const QVariant &args)
 
     if(activate) command += QString(" -ttl %1").arg(params[3]);
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// Create a new order and tx with specified amount of datoshi to exchange with specified rate (buy / sell)
@@ -958,7 +968,7 @@ QVariant DapCommandList::xchangeOrderCreate(const QVariant &args)
                        .arg(params[5]) // rate
                        .arg(params[6]);// fee
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 QVariant DapCommandList::txCondCreate(const QVariant &args)
@@ -1031,7 +1041,7 @@ QVariant DapCommandList::xchangeOrderPurchase(const QVariant &args)
                        .arg(params[3]) // coins
                        .arg(params[4]);// fee
 
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// Remove order with specified order hash in specified net name
@@ -1044,7 +1054,7 @@ QVariant DapCommandList::xchangeOrderRemove(const QVariant &args)
                        .arg(params[1]) // hash
                        .arg(params[2]) // wallet
                        .arg(params[3]); // fee
-    return requestToNode(QPair<QString*, QString>(m_cliPath,command));
+    return requestToNode(QPair<QString*, QString>(m_cliPath,command), Dap::RequestType::JSON);
 }
 
 /// List mempool (entries or transaction) for (selected chain network or wallet)
diff --git a/chain/wallet/handlers/DapGetXchangeOrdersList.cpp b/chain/wallet/handlers/DapGetXchangeOrdersList.cpp
index 7bd3dc60..5011f597 100644
--- a/chain/wallet/handlers/DapGetXchangeOrdersList.cpp
+++ b/chain/wallet/handlers/DapGetXchangeOrdersList.cpp
@@ -24,44 +24,50 @@ QVariant DapGetXchangeOrdersList::respondToClient(const QVariant &args)
     {
         QJsonArray arrOrders;
 
-        // if string :
-        QString result = cmdList->getXchangeOrdersList(net).toString();
-        if(!result.contains("No orders found"))
-        {
-            result.remove("\r");
+        auto resultJson = cmdList->getXchangeOrdersList(net);
+        auto resultStruct = cmdList->getJsonResult(resultJson, "DapGetXchangeOrdersList get orders");
 
-            QRegularExpression rx(R"(^orderHash: (.+)\n ts_created:(.+)\n Status: (\S+), proposed: (\S+) (\S+), amount: (\S+) \((\S+)\) (\S+), filled: (\S+), rate \((\S+)\): (\S+), net: (\S+))", QRegularExpression::MultilineOption);
-            QRegularExpressionMatchIterator itr = rx.globalMatch(result);
+        auto result = resultStruct.result;
+        if(!result.isArray())
+        {
+            qWarning() << "[DapGetXchangeTokenPriceHistory] Unknow problem";
+            continue;
+        }
 
-            while (itr.hasNext())
+        for(const auto& itemValue: result.toArray())
+        {
+            QJsonObject item = itemValue.toObject();
+            if(!item.contains("token_buy") || !item.contains("token_sell"))
             {
-                QRegularExpressionMatch match = itr.next();
-
-                QJsonObject orderObject;
-                QStringList pair = match.captured(10).split("/");
-
-                if(pair[0].isEmpty() || pair[1].isEmpty())
-                    continue;
-
-                orderObject.insert("order_hash", match.captured(1));
-                QDateTime date = QDateTime::fromString(match.captured(2), Qt::RFC2822Date).toLocalTime();
-                date.setTimeSpec(Qt::LocalTime);
-                orderObject.insert("created", date.toString("yyyy-MM-dd hh:mm:ss")); //D M dd hh:mm:ss YYYY
-                orderObject.insert("created_unix", QString::number(date.toSecsSinceEpoch())); //unix
-                orderObject.insert("status", match.captured(3));
-                orderObject.insert("amount", match.captured(6));
-                orderObject.insert("amount_datoshi", match.captured(7));
-                orderObject.insert("amount_token", match.captured(8));
-                orderObject.insert("sell_token", match.captured(8));
-                orderObject.insert("buy_token", pair[0]);
-                orderObject.insert("filled", match.captured(9));
-                orderObject.insert("rate", match.captured(11));
-                orderObject.insert("network", match.captured(12));
-
-                arrOrders.append(orderObject);
+                continue;
+            }
+            if(!item.contains("amount_coins") || !item.contains("amount_datoshi") ||
+                !item.contains("filled_percent") || !item.contains("net") ||
+                !item.contains("order_hash") || !item.contains("rate") ||
+                !item.contains("status") || !item.contains("ts_created"))
+            {
+                qWarning() << "[DapGetXchangeOrdersList] Either the structure or the names of the keys have changed.";
+                continue;
             }
-            obj.insert(net, arrOrders);
+            QJsonObject orderObject;
+            orderObject.insert("order_hash", item.value("order_hash").toString());
+            QDateTime date = QDateTime::fromString(item.value("ts_created").toString(), Qt::RFC2822Date).toLocalTime();
+            date.setTimeSpec(Qt::LocalTime);
+            orderObject.insert("created", date.toString("yyyy-MM-dd hh:mm:ss")); //D M dd hh:mm:ss YYYY
+            orderObject.insert("created_unix", QString::number(date.toSecsSinceEpoch())); //unix
+            orderObject.insert("status", item.value("status").toString());
+            orderObject.insert("amount", item.value("amount_coins").toString());
+            orderObject.insert("amount_datoshi", item.value("amount_datoshi").toString());
+            orderObject.insert("amount_token", item.value("token_sell").toString());
+            orderObject.insert("sell_token", item.value("token_sell").toString());
+            orderObject.insert("buy_token", item.value("token_buy").toString());
+            orderObject.insert("filled", item.value("filled_percent").toString());
+            orderObject.insert("rate", item.value("rate").toString());
+            orderObject.insert("network", item.value("net").toString());
+
+            arrOrders.append(orderObject);
         }
+        obj.insert(net, arrOrders);
     }
 
     QJsonDocument resultDoc(QJsonObject({{RESULT_KEY, obj}}));
diff --git a/chain/wallet/handlers/DapGetXchangeTokenPair.cpp b/chain/wallet/handlers/DapGetXchangeTokenPair.cpp
index bf7ae90e..8f2f9f2c 100644
--- a/chain/wallet/handlers/DapGetXchangeTokenPair.cpp
+++ b/chain/wallet/handlers/DapGetXchangeTokenPair.cpp
@@ -32,102 +32,56 @@ QVariant DapGetXchangeTokenPair::respondToClient(const QVariant &args)
 
     for (const QString &net : netlist)
     {
-        QString result = cmdList->getXchangeTokenPairsList(net).toString();
-        tempResult.append(result);
+        auto resultJson = cmdList->getXchangeTokenPairsList(net);
+        auto resultStruct = cmdList->getJsonResult(resultJson, "DapGetXchangeTokenPair get pair list");
 
-        int index = result.indexOf("\n");
+        auto result = resultStruct.result;
+        if(result.isNull())
+        {
+            qWarning() << "Result is null";
+            continue;
+        }
+        QJsonArray level1 = result.toArray();
+
+        if(level1.isEmpty())
+        {
+            continue;
+        }
+
+        QJsonObject pairObject = level1[0].toObject();
+        if(pairObject.isEmpty())
+        {
+            continue;
+        }
 
-        QStringList pairs = result.mid(index+1).split(' ', QString::SkipEmptyParts);
-        for(const auto &p : pairs)
+        if(!pairObject.contains("TICKERS PAIR"))
         {
-            if (p.contains(":"))
+            continue;
+        }
+
+        QJsonArray pairArray = pairObject["TICKERS PAIR"].toArray();
+
+        for(const auto& itemValue: pairArray)
+        {
+            QJsonObject item = itemValue.toObject();
+            if(item.count() != 2)
             {
-                QStringList pair = p.split(":");
-
-                QJsonObject orderObj;
-                orderObj.insert("token1", pair.first());
-                orderObj.insert("token2", pair.last());
-
-                if (fullInfo == "full_info")
-                {
-//                        QVariant cmdParams = QVariant::fromValue(QStringList{net, pair.first(), pair.last()});
-//                        QVariant cmdParams2 = QVariant::fromValue(QStringList{net, pair.last(), pair.first()});
-
-//                        auto getData = [&](const QVariant &args) ->QPair<QString, QString>
-//                        {
-//                            QVariant v_result = cmdList->getXchangeAverage(args);
-
-//                            if(v_result.type() == QMetaType::QJsonDocument) {
-//                                qWarning() << "NEED JSON PARSING";
-//                                return {QString(), QString()};
-//                            }
-
-//                            QString result = v_result.toString();
-
-//                            QRegularExpression regex(R"(Last rate: ([0-9\.]+) Last rate time: (.+) \(([0-9]+)\))");
-//                            QRegularExpressionMatch match = regex.match(result);
-
-//                            if(!match.hasMatch())
-//                            {
-//                                qWarning() << "The data output from the node has been changed.";
-//                                return {QString(), QString()};
-//                            }
-//                            auto list = match.capturedTexts();
-//                            QString rate = match.captured(1);
-//                            QString time = match.captured(3);
-//                            return {time, rate};
-//                        };
-
-//                        auto firstData = cmdList->getXchangeAverage(cmdParams);
-//                        auto secondData = cmdList->getXchangeAverage(cmdParams2);
-//                        if(firstData.second.isEmpty() || secondData.second.isEmpty())
-//                        {
-//                            continue;
-//                        }
-
-//                        qint64 firstTime = firstData.first;
-//                        qint64 secondTime = secondData.first;
-
-//                        QString rate;
-//                        if(firstTime > secondTime)
-//                        {
-//                            rate = firstData.second;
-//                        }
-//                        else
-//                        {
-//                            if(secondData.second == "0.0")
-//                            {
-//                                rate = secondData.second;
-//                            }
-//                            else
-//                            {
-//                                QRegularExpression regex(R"((\d+\.\d+))");
-//                                QRegularExpressionMatch match = regex.match(secondData.second);
-
-//                                if(!match.hasMatch())
-//                                {
-//                                    qWarning() << "Problems with the number : " << secondData.second;
-//                                    rate = "1.0";
-//                                }
-//                                else
-//                                {
-//                                    Dap::Coin oneVal = QString("1.0");
-//                                    Dap::Coin priceVal = secondData.second;
-//                                    rate = (oneVal/priceVal).toCoinsString();
-//                                }
-//                            }
-//                        }
-                    orderObj.insert("rate", "-");
-
-                    orderObj.insert("network",  net);
-
-                    orderObj.insert("change", "0%");
-                }
-
-                arrPairs.append(orderObj);
+                continue;
             }
+            if(!item.contains("ticker_1") || !item.contains("ticker_2"))
+            {
+                qWarning() << "[DapGetXchangeTokenPair] The keys for the tokens have been changed.";
+                continue;
+            }
+            QJsonObject pair;
+
+            QString token_1 = item.value("ticker_1").toString();
+            QString token_2 = item.value("ticker_2").toString();
+            pair.insert("token1", token_1);
+            pair.insert("token2", token_2);
+            pair.insert("network",  net);
+            arrPairs.append(pair);
         }
-
     }
 
     QJsonDocument resultDoc(QJsonObject({{RESULT_KEY, arrPairs}}));
diff --git a/chain/wallet/handlers/DapGetXchangeTokenPriceHistory.cpp b/chain/wallet/handlers/DapGetXchangeTokenPriceHistory.cpp
index ba16b7b1..1e3358dd 100644
--- a/chain/wallet/handlers/DapGetXchangeTokenPriceHistory.cpp
+++ b/chain/wallet/handlers/DapGetXchangeTokenPriceHistory.cpp
@@ -18,103 +18,84 @@ QVariant DapGetXchangeTokenPriceHistory::respondToClient(const QVariant &args)
     QJsonArray arrHistory;
     QStringList params = args.toStringList();
 
-    auto updateHistoryList = [&arrHistory, this](const QString& result, bool isContrary = false)
+    auto updateHistoryList = [&arrHistory, this](const QStringList& list, bool isContrary = false)
     {
-        QStringList orderList = result.split("\n");
-        QString hash = "";
-        QString rate = "";
-        QString dateStr = "";
-        QDateTime date;
-        qint64 dateToSecs = date.toMSecsSinceEpoch();
-        QString time = QString::number(dateToSecs);
-
-        for(QString& str: orderList)
+                                                                ///   network    token1    token2     nodeMode
+        auto resultJson = cmdList->getXchangeHistory(QStringList() << list[0] << list[1] << list[2]);
+        auto resultStruct = cmdList->getJsonResult(resultJson, "DapGetXchangeTokenPair get pair list");
+
+        auto result = resultStruct.result;
+        if(result.isNull())
         {
-            str = str.trimmed();
-            if(str.isEmpty())
-            {
-                hash.clear();
-                continue;
-            }
+            qWarning() << "[DapGetXchangeTokenPriceHistory] Unknow problem";
+            return;
+        }
+        QJsonArray level1 = result.toArray();
 
-            if(str.contains("Hash"))
-            {
-                auto list = str.split(": ");
-                if(list.size() != 2)
-                {
-                    qWarning() << "The output of the node has changed";
-                    continue;
-                }
-                hash = list[1];
+        if(level1.isEmpty())
+        {
+            return;
+        }
+        if(!level1[0].isArray())
+        {
+            qWarning() << "[DapGetXchangeTokenPriceHistory] first element is not array";
+            return;
+        }
+
+        QJsonArray orderArray = level1[0].toArray();
 
+        for(const auto& itemValue: orderArray)
+        {
+            QJsonObject itemObject = itemValue.toObject();
+
+            if(itemObject.contains("limit") || !itemObject.contains("changed_coins"))
+            {
                 continue;
             }
-
-            if(hash.isEmpty())
+            if(!itemObject.contains("hash") || !itemObject.contains("rate")
+                || !itemObject.contains("ts_created") )
             {
-                qWarning() << "Hash is not defined.";
+                qWarning() << "[DapGetXchangeTokenPriceHistory] Either the structure or the names of the keys have changed.";
                 continue;
             }
 
-            auto matchTime = REG_TIME.match(str);
-            if(matchTime.hasMatch())
+            QString hash = itemObject["hash"].toString();
+            QString rate = "";
+            QString dateStr = "";
+            QDateTime date;
+            qint64 dateToSecs = date.toMSecsSinceEpoch();
+            QString time = QString::number(dateToSecs);
+
+            dateStr = itemObject["ts_created"].toString();
+            date = QDateTime::fromString(dateStr, Qt::RFC2822Date);
+            dateToSecs = date.toMSecsSinceEpoch();
+            time = QString::number(dateToSecs);
+
+            if(!isContrary)
             {
-                dateStr = matchTime.captured(1);
-                date = QDateTime::fromString(dateStr, Qt::RFC2822Date);
-                dateToSecs = date.toMSecsSinceEpoch();
-                time = QString::number(dateToSecs);
+                rate = itemObject["rate"].toString();
             }
-
-            auto matchRate = REG_RATE.match(str);
-            if(matchRate.hasMatch())
+            else
             {
-                if(!str.contains(TYPE_ORDERS))
-                {
-                    dateStr = "";
-                    dateToSecs = 0;
-                    time = QString::number(dateToSecs);
-                    rate = "";
-                    hash = "";
-                    continue;
-                }
-
-                if(!isContrary)
-                {
-                    rate = matchRate.captured(3);
-                }
-                else
-                {
-                    Dap::Coin oneVal = QString("1.0");
-                    Dap::Coin priceVal = matchRate.captured(3);
-                    QString result = (oneVal/priceVal).toCoinsString();
-                    rate = result;
-                }
-
-
-                QJsonObject rateObject;
-                rateObject.insert("rate",  rate);
-                rateObject.insert("time",  time);
-                rateObject.insert("date",  dateStr);
-                rateObject.insert("hash",  hash);
-                arrHistory.append(std::move(rateObject));
+                Dap::Coin oneVal = QString("1.0");
+                Dap::Coin priceVal = itemObject["rate"].toString();
+                QString result = (oneVal/priceVal).toCoinsString();
+                rate = result;
             }
+
+            QJsonObject rateObject;
+            rateObject.insert("rate",  rate);
+            rateObject.insert("time",  time);
+            rateObject.insert("date",  dateStr);
+            rateObject.insert("hash",  hash);
+            arrHistory.append(std::move(rateObject));
         }
     };
 
     // get rate history
-    QString result = cmdList->getXchangeHistory(args).toString();
-    if(!result.isEmpty())
-    {
-        updateHistoryList(result);
-    }
-    QStringList pairCont = {params[0], params[2], params[1]};
-
-    result = cmdList->getXchangeHistory(QVariant(pairCont)).toString();
-    if(!result.isEmpty())
-    {
-        updateHistoryList(result, true);
-    }
-
+    updateHistoryList(QStringList() << params[0] << params[1] << params[2]);
+    updateHistoryList(QStringList() << params[0] << params[2] << params[1], true);
+    
     QJsonObject resultObject;
     resultObject.insert("history", arrHistory);
     resultObject.insert("token1", params[1]);
diff --git a/chain/wallet/handlers/DapGetXchangeTxList.cpp b/chain/wallet/handlers/DapGetXchangeTxList.cpp
index 38178d0c..e3ae307e 100644
--- a/chain/wallet/handlers/DapGetXchangeTxList.cpp
+++ b/chain/wallet/handlers/DapGetXchangeTxList.cpp
@@ -25,44 +25,46 @@ QVariant DapGetXchangeTxList::respondToClient(const QVariant &args)
     {
         QString walletAddress = cmdList->getWalletAddress(net, params[0]).toString();
 
-        QString result = cmdList->getXchangeList(QStringList() << "GetOrdersPrivate" << net << walletAddress).toString();
+        auto resultJson = cmdList->getXchangeList(QStringList() << "GetOrdersPrivate" << net << walletAddress);
+        auto resultStruct = cmdList->getJsonResult(resultJson, "DapGetXchangeTxList get list");
 
-        auto list = result.split('\n');
+        auto result = resultStruct.result;
+        if(result.isNull())
+        {
+            qWarning() << "[DapGetXchangeTxList] The result block is empty, possibly an error.";
+            continue;
+        }
+        QJsonArray level1 = result.toArray();
 
-        QString hash, status, type;
+        if(level1.isEmpty())
+        {
+            qWarning() << "[DapGetXchangeTxList] The data attachment level has probably been changed.";
+            continue;
+        }
 
-        for(QString& str: list)
+        QJsonObject resultObject = level1[0].toObject();
+        if(resultObject.isEmpty())
         {
-            //str = str.trimmed();
-            if(str.contains("Hash:"))
-            {
-                auto tmpList = str.split(":");
+            qWarning() << "[DapGetXchangeTxList] An empty object was received";
+            continue;
+        }
 
-                hash = tmpList[1].trimmed();
-            }
-            else if(str.contains("Status:"))
-            {
-                if(hash.isEmpty())
-                {
-                    qWarning() << "The hash is empty, apparently there have been some changes in the output of the node.";
-                    continue;
-                }
-                auto tmpList = str.split(",");
-                auto statusList = tmpList[0].split(":");
-                QJsonObject orderObj;
-                orderObj.insert("hash", hash);
-                orderObj.insert("status", statusList[1].trimmed());
-
-                auto typeList = tmpList[1].trimmed().split(" ");
-
-                orderObj.insert("type", typeList[0].trimmed());
-                resultArray.append(orderObj);
-                hash.clear();
-            }
-            else if(str.trimmed().isEmpty())
+        if(!resultObject.contains("transactions"))
+        {
+            qWarning() << "[DapGetXchangeTxList] transactions notfound";
+            continue;
+        }
+        QJsonArray transactions = resultObject.value("transactions").toArray();
+
+        for(const auto& itemValue: transactions)
+        {
+            QJsonObject item = itemValue.toObject();
+            if(!item.contains("hash"))
             {
-                hash.clear();
+                continue;
             }
+            QJsonObject hashObject{{"hash", item.value("hash").toString()}};
+            resultArray.append(hashObject);
         }
     }
 
diff --git a/chain/wallet/handlers/DapWalletActivateOrDeactivateCommand.cpp b/chain/wallet/handlers/DapWalletActivateOrDeactivateCommand.cpp
index df8e4ae5..32ae5bc4 100644
--- a/chain/wallet/handlers/DapWalletActivateOrDeactivateCommand.cpp
+++ b/chain/wallet/handlers/DapWalletActivateOrDeactivateCommand.cpp
@@ -1,19 +1,11 @@
 #include "DapWalletActivateOrDeactivateCommand.h"
 
-/// Overloaded constructor.
-/// @param asServiceName Service name.
-/// @param parent Parent.
-/// @details The parent must be either DapRPCSocket or DapRPCLocalServer.
 DapWalletActivateOrDeactivateCommand::DapWalletActivateOrDeactivateCommand(const QString &asServicename, QObject *parent, const QString &asCliPath)
     : DapAbstractCommand(asServicename, parent, asCliPath)
 {
 
 }
 
-/// Send a response to the client.
-/// @details Performed on the service side.
-/// @param arg1...arg10 Parameters.
-/// @return Reply to client.
 QVariant DapWalletActivateOrDeactivateCommand::respondToClient(const QVariant &args)
 {
     qDebug() << "[" << this->getName() << "] [respondToClient]";
@@ -21,44 +13,65 @@ QVariant DapWalletActivateOrDeactivateCommand::respondToClient(const QVariant &a
 
     QJsonObject resultObj;
 
-    QVariant v_result = cmdList->walletActivateOrDeactivate(args);
+    auto resultJson = cmdList->walletActivateOrDeactivate(args);
+    auto resultStruct = cmdList->getJsonResult(resultJson, "DapWalletActivateOrDeactivateCommand");
 
-    if(v_result.type() == QMetaType::QJsonDocument)
+    auto result = resultStruct.result;
+
+    auto defaultError = [&resultObj, &result, &params, this]() -> QVariant
+    {
+        resultObj.insert("success",QJsonValue(false));
+        resultObj.insert("message",QJsonValue(result));
+        resultObj.insert("cmd",QJsonValue(params[1]));
+        QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
+        return resultDoc.toJson();
+    };
+
+
+    if(result.isNull())
+    {
+        qWarning() << "[DapWalletActivateOrDeactivateCommand] The result block is empty, possibly an error.";
+        return defaultError();
+    }
+
+    QJsonArray level1 = result.toArray();
+
+    if(level1.isEmpty())
+    {
+        qWarning() << "[DapWalletActivateOrDeactivateCommand] The data attachment level has probably been changed.";
+        return defaultError();
+    }
+    QJsonArray level2 = level1[0].toArray();
+
+    if(level2.isEmpty())
+    {
+        qWarning() << "[DapWalletActivateOrDeactivateCommand] The data attachment level has probably been changed.";
+        return defaultError();
+    }
+    QJsonObject objectData = level2[0].toObject();
+    if(objectData.contains("errors"))
+    {
+        resultObj.insert("success",QJsonValue(false));
+        resultObj.insert("message",QJsonValue("Invalid password"));
+        resultObj.insert("cmd",QJsonValue(params[1]));
+    }
+    else if(!objectData.contains("protection"))
     {
-        // if json
-        qWarning() << "NEED JSON PARSING";
-        //TODO
+        return defaultError();
     }
     else
     {
-        // if string
-        QString result = v_result.toString();
-        if(result.contains("deactivated")){
+        QString protection = objectData.value("protection").toString();
+        if(protection == "is deactivated")
+        {
             resultObj.insert("success",QJsonValue(true));
             resultObj.insert("message",QJsonValue("Wallet deactivated"));
             resultObj.insert("cmd",QJsonValue(params[1]));
         }
-        else if(result.contains("activated")){
-            resultObj.insert("success",QJsonValue(true));
-            resultObj.insert("message",QJsonValue("Wallet activated"));
-            resultObj.insert("cmd",QJsonValue(params[1]));
-        }
-        else if(result.contains("Invalid"))
-        {
-            resultObj.insert("success",QJsonValue(false));
-            resultObj.insert("message",QJsonValue("Invalid password"));
-            resultObj.insert("cmd",QJsonValue(params[1]));
-        }
-        else if(result.contains("not found"))
-        {
-            resultObj.insert("success",QJsonValue(false));
-            resultObj.insert("message",QJsonValue("Wallet not found"));
-            resultObj.insert("cmd",QJsonValue(params[1]));
-        }
         else
         {
-            resultObj.insert("success",QJsonValue(false));
-            resultObj.insert("message",QJsonValue(result));
+            resultObj.insert("success",QJsonValue(true));
+            resultObj.insert("message",QJsonValue("Wallet activated"));
             resultObj.insert("cmd",QJsonValue(params[1]));
         }
     }
diff --git a/chain/wallet/handlers/DapXchangeOrderCreate.cpp b/chain/wallet/handlers/DapXchangeOrderCreate.cpp
index 6b6e241d..a418e296 100644
--- a/chain/wallet/handlers/DapXchangeOrderCreate.cpp
+++ b/chain/wallet/handlers/DapXchangeOrderCreate.cpp
@@ -11,28 +11,54 @@ QVariant DapXchangeOrderCreate::respondToClient(const QVariant &args)
 
     QJsonObject resultObj;
 
-    QVariant v_result = cmdList->xchangeOrderCreate(args);
+    auto resultJson = cmdList->xchangeOrderCreate(args);
+    auto resultStruct = cmdList->getJsonResult(resultJson, "DapXchangeOrderCreate");
 
-    // if string
-    QString result = v_result.toString();
+    auto result = resultStruct.result;
 
-    if(result.contains("Successfully created order"))
-    {
-        resultObj.insert(SUCCESS,QJsonValue(true));
-        resultObj.insert(MESSAGE,QJsonValue("Successfully created order"));
-
-        QRegularExpressionMatch match = REGULAR_HASH.match(result);
-        if(match.hasMatch())
-        {
-            resultObj.insert(HASH, QJsonValue(match.captured(1)));
-        }
-    }
-    else
+    auto failTransaction = [&result, this]() -> QVariant
     {
+        QJsonObject resultObj;
         resultObj.insert(SUCCESS,QJsonValue(false));
         resultObj.insert(MESSAGE,QJsonValue(result));
+        QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
+        return resultDoc.toJson();
+    };
+
+    if(result.isNull())
+    {
+        qWarning() << "Result is null";
+        return failTransaction();
+    }
+    QJsonArray level1 = result.toArray();
+
+    if(level1.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] Jason's structure has changed.";
+        return failTransaction();
+    }
+
+    QJsonObject infoTransactions = level1[0].toObject();
+
+    if(!infoTransactions.contains("hash") || !infoTransactions.contains("status"))
+    {
+        qDebug() << "[DapXchangeOrderCreate] Jason's structure has changed. Or the transaction is rejected";
+        return failTransaction();
+    }
+
+    QString hash = infoTransactions.value("hash").toString();
+    QString status = infoTransactions.value("status").toString();
+
+    if(hash.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] The hash string is empty.";
+        return failTransaction();
     }
 
+    resultObj.insert(SUCCESS,QJsonValue(true));
+    resultObj.insert(MESSAGE,QJsonValue("Successfully created order"));
+    resultObj.insert(HASH, QJsonValue(hash));
+
     QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
     return resultDoc.toJson();
 }
diff --git a/chain/wallet/handlers/DapXchangeOrderPurchase.cpp b/chain/wallet/handlers/DapXchangeOrderPurchase.cpp
index 1b68d356..51901477 100644
--- a/chain/wallet/handlers/DapXchangeOrderPurchase.cpp
+++ b/chain/wallet/handlers/DapXchangeOrderPurchase.cpp
@@ -15,25 +15,52 @@ QVariant DapXchangeOrderPurchase::respondToClient(const QVariant &args)
 
     QJsonObject resultObj;
 
-    QVariant v_result = cmdList->xchangeOrderPurchase(args);
+    auto resultJson = cmdList->xchangeOrderPurchase(args);
+    auto resultStruct = cmdList->getJsonResult(resultJson, "DapXchangeOrderPurchase");
 
-    // if string
-    QString result = v_result.toString();
-    if(result.contains("Exchange transaction has done"))
-    {
-        resultObj.insert(SUCCESS,QJsonValue(true));
-        resultObj.insert(MESSAGE,QJsonValue("Exchange transaction has done"));
-        QRegularExpressionMatch match = REGULAR_HASH.match(result);
-        if(match.hasMatch())
-        {
-            resultObj.insert(HASH, QJsonValue(match.captured(1)));
-        }
-    }
-    else
+    auto result = resultStruct.result;
+    auto failTransaction = [&result, this]() -> QVariant
     {
+        QJsonObject resultObj;
         resultObj.insert(SUCCESS,QJsonValue(false));
         resultObj.insert(MESSAGE,QJsonValue(result));
+        QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
+        return resultDoc.toJson();
+    };
+
+    if(result.isNull())
+    {
+        qWarning() << "Result is null";
+        return failTransaction();
+    }
+    QJsonArray level1 = result.toArray();
+
+    if(level1.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] Jason's structure has changed.";
+        return failTransaction();
+    }
+
+    QJsonObject infoTransactions = level1[0].toObject();
+
+    if(!infoTransactions.contains("hash") || !infoTransactions.contains("status"))
+    {
+        qDebug() << "[DapXchangeOrderCreate] Jason's structure has changed. Or the transaction is rejected";
+        return failTransaction();
+    }
+
+    QString hash = infoTransactions.value("hash").toString();
+    QString status = infoTransactions.value("status").toString();
+
+    if(hash.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] The hash string is empty.";
+        return failTransaction();
     }
+    
+    resultObj.insert(SUCCESS,QJsonValue(true));
+    resultObj.insert(MESSAGE,QJsonValue("Exchange transaction has done"));
+    resultObj.insert(HASH, QJsonValue(hash));
 
     QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
     return resultDoc.toJson();
diff --git a/chain/wallet/handlers/DapXchangeOrderRemove.cpp b/chain/wallet/handlers/DapXchangeOrderRemove.cpp
index 9aaf7b6b..e59b1eab 100644
--- a/chain/wallet/handlers/DapXchangeOrderRemove.cpp
+++ b/chain/wallet/handlers/DapXchangeOrderRemove.cpp
@@ -15,23 +15,52 @@ QVariant DapXchangeOrderRemove::respondToClient(const QVariant &args)
 
     QJsonObject resultObj;
 
-    // if string
-    QString result = cmdList->xchangeOrderRemove(args).toString();
-    if(result.contains("successfully removed"))
-    {
-        resultObj.insert(SUCCESS,QJsonValue(true));
-        resultObj.insert(MESSAGE,QJsonValue("Order successfully removed"));
-        QRegularExpressionMatch match = REGULAR_HASH.match(result);
-        if(match.hasMatch())
-        {
-            resultObj.insert(HASH, QJsonValue(match.captured(1)));
-        }
-    }
-    else
+    auto resultJson = cmdList->xchangeOrderRemove(args);
+    auto resultStruct = cmdList->getJsonResult(resultJson, "DapXchangeOrderRemove");
+
+    auto result = resultStruct.result;
+    auto failTransaction = [&result, this]() -> QVariant
     {
+        QJsonObject resultObj;
         resultObj.insert(SUCCESS,QJsonValue(false));
         resultObj.insert(MESSAGE,QJsonValue(result));
+        QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
+        return resultDoc.toJson();
+    };
+
+    if(result.isNull())
+    {
+        qWarning() << "Result is null";
+        return failTransaction();
     }
+    QJsonArray level1 = result.toArray();
+
+    if(level1.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] Jason's structure has changed.";
+        return failTransaction();
+    }
+
+    QJsonObject infoTransactions = level1[0].toObject();
+
+    if(!infoTransactions.contains("Created inactivate tx with hash") || !infoTransactions.contains("status"))
+    {
+        qDebug() << "[DapXchangeOrderCreate] Jason's structure has changed. Or the transaction is rejected";
+        return failTransaction();
+    }
+
+    QString hash = infoTransactions.value("Created inactivate tx with hash").toString();
+    QString status = infoTransactions.value("status").toString();
+
+    if(hash.isEmpty())
+    {
+        qWarning() << "[DapXchangeOrderCreate] The hash string is empty.";
+        return failTransaction();
+    }
+
+    resultObj.insert(SUCCESS,QJsonValue(true));
+    resultObj.insert(MESSAGE,QJsonValue("Order successfully removed"));
+    resultObj.insert(HASH, QJsonValue(hash));
 
     QJsonDocument resultDoc(QJsonObject{{RESULT_KEY, resultObj}});
     return resultDoc.toJson();
-- 
GitLab