From 7fd299b085491085065fcb69ac56b4745aed5028 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 7 Oct 2024 18:44:18 +0700
Subject: [PATCH 01/22] ...

---
 dap-sdk                                       |  2 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 60 ++++++++++++-------
 .../include/dap_chain_net_srv_xchange.h       | 20 +++++++
 3 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index ea267c0f94..9dcfc3fb33 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit ea267c0f9432a1fb94d70a4d400c265c63405ef8
+Subproject commit 9dcfc3fb330cb79e55c3753c23e5b41e6d8be294
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index bd3fb71ccb..96498ca5a1 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1973,6 +1973,8 @@ void s_tx_is_order_check(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t
 
 static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 {
+    json_object **json_arr_reply = (json_object **)a_str_reply;
+
     enum {CMD_NONE = 0, CMD_ORDER, CMD_ORDERS, CMD_PURCHASE, CMD_ENABLE, CMD_DISABLE, CMD_TX_LIST, CMD_TOKEN_PAIR };
     int l_arg_index = 1, l_cmd_num = CMD_NONE;
 
@@ -2008,15 +2010,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             l_arg_index++;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'orders' requires parameter -net");
-                return -2;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'orders' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR;
             }
-            dap_string_t *l_reply_str = dap_string_new("");
+            //dap_string_t *l_reply_str = dap_string_new("");
             // Iterate blockchain, find txs with xchange cond out and without cond input
             dap_list_t *l_tx_list = NULL;
             dap_chain_net_get_tx_all(l_net,TX_SEARCH_TYPE_NET, s_tx_is_order_check, &l_tx_list);
@@ -2036,8 +2038,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 else if ( dap_strcmp (l_status_str, "all") == 0 )
                     l_opt_status = 0;
                 else  {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized '-status %s'", l_status_str);
-                    return -3;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR, "Unrecognized '-status %s'", l_status_str);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR;
                 }
             }
 
@@ -2047,8 +2049,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if(l_token_from_str){
                 dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
                 if(!l_token_from_datum){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
-                    return -6;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR, 
+                                            "Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR;
                 }
             }
 
@@ -2056,8 +2059,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if(l_token_to_str){
                 dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
                 if(!l_token_to_datum){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
-                    return -6;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR, 
+                                            "Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR;
                 }
             }
 
@@ -2070,21 +2074,22 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
             size_t l_arr_start = 0;            
             size_t l_arr_end = dap_list_length(l_tx_list);
+            json_object* json_obj_order = json_object_new_object();
             if (l_offset > 0) {
                 l_arr_start = l_offset;
-                dap_string_append_printf(l_reply_str, "offset: %lu\n", l_arr_start);                
+                json_object_object_add(json_obj_order, "offset", json_object_new_uint64(l_arr_start));               
             }
             if (l_limit) {
-                dap_string_append_printf(l_reply_str, "limit: %lu\n", l_limit);
+                json_object_object_add(json_obj_order, "limit", json_object_new_uint64(l_limit));
                 l_arr_end = l_arr_start + l_limit;
                 if (l_arr_end > dap_list_length(l_tx_list)) {
                     l_arr_end = dap_list_length(l_tx_list);
                 }
             }            
             size_t i_tmp = 0;
+            json_object* json_arr_orders_out = json_object_new_array();
             // Print all txs
-            for (dap_list_t *it = l_tx_list; it; it = it->next) {
-                
+            for (dap_list_t *it = l_tx_list; it; it = it->next) {                
                 dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)it->data;
                 dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL);
                 if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID)
@@ -2146,14 +2151,23 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                 const char *l_amount_coins_str = NULL,
                      *l_amount_datoshi_str = l_out_cond_last_tx ? dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str) : NULL;
-                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str,
-                                         l_tmp_buf, l_status_order,
-                                         l_amount_coins_str ? l_amount_coins_str : "0.0",
-                                         l_amount_datoshi_str ? l_amount_datoshi_str : "0",
-                                         l_price->token_sell, l_percent_completed,
-                                         l_price->token_buy, l_price->token_sell,
-                                         l_cp_rate,
-                                         l_price->net->pub.name);
+                json_object* json_obj_orders = json_object_new_object();
+                json_object_object_add(json_obj_orders, "orderHash", json_object_new_string(l_tx_hash_str));
+                json_object_object_add(json_obj_orders, "ts_created", json_object_new_string(l_tmp_buf));
+                json_object_object_add(json_obj_orders, "status", json_object_new_string(l_status_order));
+                json_object_object_add(json_obj_orders, "amount coins", l_amount_coins_str ? 
+                                                json_object_new_string(l_amount_coins_str) : 
+                                                json_object_new_string("0.0"));
+                json_object_object_add(json_obj_orders, "amount datoshi", l_amount_datoshi_str ? 
+                                                json_object_new_string(l_amount_datoshi_str) : 
+                                                json_object_new_string("0"));
+                json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_price->token_sell));
+                json_object_object_add(json_obj_orders, "filled", json_object_new_string(l_percent_completed));
+                json_object_object_add(json_obj_orders, "token buy", json_object_new_string(l_price->token_buy));
+                json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_price->token_sell));
+                json_object_object_add(json_obj_orders, "balance rate", json_object_new_string(l_price->token_sell));
+                json_object_object_add(json_obj_orders, "net name", json_object_new_string(l_price->net->pub.name));
+
                 l_printed_orders_count++;
                 DAP_DEL_MULTY(l_cp_rate, l_price);
             }
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index ecd9291bf1..96cc676e9e 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -64,6 +64,26 @@ void dap_chain_net_srv_xchange_deinit();
 json_object *dap_chain_net_srv_xchange_print_fee_json(dap_chain_net_t *a_net);
 void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a_string_ret);
 
+typedef enum s_com_net_srv_xchange_err{
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCHANGE_OK = 0,
+
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCHANGE_ORDERS_REQ_PARAM_NET,
+
+
+    XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
+    XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
+    XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER,
+    XCHANGE_CREATE_ERROR_RATE_IS_ZERO,
+    XCHANGE_CREATE_ERROR_FEE_IS_ZERO,
+    XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO,
+    XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE,
+    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET,
+    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET,
+    XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
+    XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
+    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL,
+} s_com_net_srv_xchange_err_t;
+
 typedef enum dap_chain_net_srv_xchange_create_error_list{
     XCHANGE_CREATE_ERROR_OK = 0,
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
-- 
GitLab


From 33832d0ce61bd9a5521fe97a8b245cf76635c819 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 7 Oct 2024 19:05:17 +0700
Subject: [PATCH 02/22] ...

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 96498ca5a1..8bb8c90ef6 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2167,10 +2167,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_price->token_sell));
                 json_object_object_add(json_obj_orders, "balance rate", json_object_new_string(l_price->token_sell));
                 json_object_object_add(json_obj_orders, "net name", json_object_new_string(l_price->net->pub.name));
-
+                json_object_array_add(json_arr_orders_out, json_obj_orders);
                 l_printed_orders_count++;
                 DAP_DEL_MULTY(l_cp_rate, l_price);
             }
+            json_object_object_add(json_obj_order, "ORDERS", json_arr_orders_out);
             dap_list_free(l_tx_list);
             if (!l_reply_str->len) {
                 dap_string_append(l_reply_str, "No orders found");
-- 
GitLab


From ec517f4712bf0e30721a2c6cc164245023df1a4e Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 8 Oct 2024 15:32:48 +0700
Subject: [PATCH 03/22] ...

---
 .../service/xchange/include/dap_chain_net_srv_xchange.h   | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 96cc676e9e..0ea9345160 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -65,9 +65,13 @@ json_object *dap_chain_net_srv_xchange_print_fee_json(dap_chain_net_t *a_net);
 void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a_string_ret);
 
 typedef enum s_com_net_srv_xchange_err{
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCHANGE_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_OK = 0,
 
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCHANGE_ORDERS_REQ_PARAM_NET,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR,
 
 
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
-- 
GitLab


From edf2b02554485df314bd728bf17a9202fe7e09e1 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 8 Oct 2024 18:03:19 +0700
Subject: [PATCH 04/22] ...

---
 dap-sdk                                             | 2 +-
 modules/service/xchange/dap_chain_net_srv_xchange.c | 8 ++------
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index 9dcfc3fb33..7774325fa7 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 9dcfc3fb330cb79e55c3753c23e5b41e6d8be294
+Subproject commit 7774325fa7272e4c933f0c5f34ba0191ffc3f5fe
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 8bb8c90ef6..091232ce7e 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2172,19 +2172,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 DAP_DEL_MULTY(l_cp_rate, l_price);
             }
             json_object_object_add(json_obj_order, "ORDERS", json_arr_orders_out);
-            dap_list_free(l_tx_list);
-            if (!l_reply_str->len) {
-                dap_string_append(l_reply_str, "No orders found");
-            }
-            *a_str_reply = dap_string_free(l_reply_str, false);
+            dap_list_free(l_tx_list);            
         } break;
 
-
         case CMD_PURCHASE: {
             const char *l_net_str = NULL, *l_wallet_str = NULL, *l_order_hash_str = NULL, *l_val_buy_str = NULL, *l_val_fee_str = NULL;
             l_arg_index++;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
+                json_object_object_add(json_obj_orders, "token buy", json_object_new_string(l_price->token_buy));
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -net");
                 return -2;
             }
-- 
GitLab


From d1f160f970db6049e4b5969b968ccd3cf0f32168 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Thu, 10 Oct 2024 12:04:40 +0700
Subject: [PATCH 05/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 97 +++++++++++--------
 .../include/dap_chain_net_srv_xchange.h       | 19 +++-
 2 files changed, 73 insertions(+), 43 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 091232ce7e..4e7509a126 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1197,7 +1197,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
  * @param a_str_reply
  * @return
  */
-static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply)
+static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, json_object * a_json_obj_out)
 {
     enum {
         CMD_NONE, CMD_CREATE, CMD_REMOVE, CMD_UPDATE, CMD_HISTORY, CMD_STATUS
@@ -1224,37 +1224,43 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
         case CMD_CREATE: {
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -net");
-                return -2;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'order create' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Command 'order create' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_sell", &l_token_sell_str);
             if (!l_token_sell_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -token_sell");
-                return -5;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR, 
+                                                "Command 'order create' requires parameter -token_sell");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_buy", &l_token_buy_str);
             if (!l_token_buy_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -token_buy");
-                return -5;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR, 
+                                                "Command 'order create' requires parameter -token_buy");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR;
             }
             if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str);
-                return -6;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR, 
+                                                "Token ticker %s not found", l_token_buy_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR;
             }
 
             if (!strcmp(l_token_sell_str, l_token_buy_str)){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "token_buy and token_sell must be different!");
-                return -7;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR, 
+                                                "token_buy and token_sell must be different!");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR;
             }
 
             const char *l_val_sell_str = NULL, *l_val_rate_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_sell_str);
             if (!l_val_sell_str) {
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR, 
+                                                "Command 'order create' requires parameter -value");
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -value");
                 return -8;
             }
@@ -2178,42 +2184,45 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
         case CMD_PURCHASE: {
             const char *l_net_str = NULL, *l_wallet_str = NULL, *l_order_hash_str = NULL, *l_val_buy_str = NULL, *l_val_fee_str = NULL;
             l_arg_index++;
+            json_object* json_obj_orders = json_object_new_object();
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                json_object_object_add(json_obj_orders, "token buy", json_object_new_string(l_price->token_buy));
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -net");
-                return -2;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR, "Command 'purchase' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -w");
-                return -10;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR, "Command 'purchase' requires parameter -w");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR;
             }
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             if (!l_wallet) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet not found");
-                return -11;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR, "Specified wallet not found");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -order");
-                return -12;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR, 
+                                            "Command 'purchase' requires parameter -order");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_buy_str);
             if (!l_val_buy_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -value");
-                return -8;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR, 
+                                            "Command 'purchase' requires parameter -value");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR;
             }
             uint256_t l_datoshi_buy = dap_chain_balance_scan(l_val_buy_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_val_fee_str);
             if (!l_val_fee_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -fee");
-                return  -8;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR, 
+                                            "Command 'purchase' requires parameter -fee");
+                return  -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR;
             }
             uint256_t  l_datoshi_fee = dap_chain_balance_scan(l_val_fee_str);
             dap_hash_fast_t l_tx_hash = {};
@@ -2228,20 +2237,21 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     return 0;
                 }
                 case XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found");
-                    return -13;
+                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND,"Specified order not found");
+                    return -XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND;
                 }
                 case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create price from order");
-                    return -13;
+                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE, "Can't create price from order");
+                    return -XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE;
                 }
                 case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,  "Exchange transaction error");
-                    return -13;
+                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX, "Exchange transaction error");
+                    return -XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX;
                 }
                 default: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "An error occurred with an unknown code: %d.", l_ret_code);
-                    return -14;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR, 
+                                                                "An error occurred with an unknown code: %d.", l_ret_code);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR;
                 }
             }
         } break;
@@ -2283,19 +2293,22 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 else if ( dap_strcmp (l_status_str, "all") == 0 )
                     l_opt_status = TX_STATUS_ALL;
                 else  {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized '-status %s'", l_status_str);
-                    return -3;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR, 
+                                                                "Unrecognized '-status %s'", l_status_str);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR;
                 }
             }
 
             if(!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'tx_list' requires parameter -net");
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR, 
+                                                                "Command 'tx_list' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if(!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR, 
+                                                                "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR;
             }
 
             dap_time_t l_time[2];
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 0ea9345160..0169d35f3e 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -72,7 +72,24 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR,
-
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR,
+
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR,
+
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR,
 
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
     XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
-- 
GitLab


From c0598e56cc7deb15fd2db4418066b51a49100aec Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Fri, 11 Oct 2024 18:52:18 +0700
Subject: [PATCH 06/22] ...

---
 dap-sdk                                       |   2 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 122 ++++++++++--------
 .../include/dap_chain_net_srv_xchange.h       |  13 +-
 3 files changed, 84 insertions(+), 53 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index 7774325fa7..a9e2246ac3 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 7774325fa7272e4c933f0c5f34ba0191ffc3f5fe
+Subproject commit a9e2246ac301ff17538754d94c8fbcd5558930cf
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 4e7509a126..7055550644 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1259,35 +1259,38 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             const char *l_val_sell_str = NULL, *l_val_rate_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_sell_str);
             if (!l_val_sell_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR, 
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR, 
                                                 "Command 'order create' requires parameter -value");
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -value");
-                return -8;
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR;
             }
             uint256_t l_datoshi_sell = dap_chain_balance_scan(l_val_sell_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
             if (!l_val_rate_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -rate");
-                return -8;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR, 
+                                                "Command 'order create' requires parameter -rate");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR;
             }
             uint256_t l_rate = dap_chain_coins_to_balance(l_val_rate_str);
             const char *l_fee_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -fee");
-                return -20;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR, 
+                                                "Command 'order create' requires parameter -fee");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -w");
-                return -10;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR, 
+                                                "Command 'order create' requires parameter -w");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR;
             }
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             const char* l_sign_str = "";
             if (!l_wallet) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet not found");
-                return -11;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR, 
+                                                "Specified wallet not found");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR;
             } else {
                 l_sign_str = dap_chain_wallet_check_sign(l_wallet);
             }
@@ -1296,58 +1299,72 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_chain_wallet_close(l_wallet);
             switch (ret_code) {
                 case XCHANGE_CREATE_ERROR_OK: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSuccessfully created order %s", l_sign_str, l_hash_ret);
+                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("Successfully created"));
+                    json_object_object_add(a_json_obj_out, "sign", json_object_new_string(l_sign_str));
+                    json_object_object_add(a_json_obj_out, "hash", json_object_new_string(l_hash_ret));
                     DAP_DELETE(l_hash_ret);
-                    return 0;
+                    return DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_OK;
                 }
                 case XCHANGE_CREATE_ERROR_INVALID_ARGUMENT: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Some parameters could not be set during a function call");
-                    return -24;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_INVALID_ARGUMENT, 
+                                                "Some parameters could not be set during a function call");
+                    return -XCHANGE_CREATE_ERROR_INVALID_ARGUMENT;
                 }
                 case XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_sell_str);
-                    return -6;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER, 
+                                                "Token ticker %s not found", l_token_sell_str);
+                    return -XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER;
                 }
                 case XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str);
-                    return -6;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER, 
+                                                "Token ticker %s not found", l_token_buy_str);
+                    return -XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER;
                 }
                 case XCHANGE_CREATE_ERROR_RATE_IS_ZERO: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -rate n.n = buy / sell (eg: 1.0, 1.135)");
-                    return -9;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_RATE_IS_ZERO, 
+                                                "Format -rate n.n = buy / sell (eg: 1.0, 1.135)");
+                    return -XCHANGE_CREATE_ERROR_RATE_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_FEE_IS_ZERO: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned integer 256>");
-                    return -21;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_FEE_IS_ZERO, 
+                                                "Format -value <unsigned integer 256>");
+                    return -XCHANGE_CREATE_ERROR_FEE_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned integer 256>");
-                    return -9;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO, 
+                                                "Format -value <unsigned integer 256>");
+                    return -XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE: {
                     log_it(L_ERROR, "Integer overflow with sum of value and fee");
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Integer overflow with sum of value and fee");
-                    return -22;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE, 
+                                                "Integer overflow with sum of value and fee");
+                    return -XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE;
                 }
                 case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nNot enough cash for fee in specified wallet", l_sign_str);
-                    return -23;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET, 
+                                                "%s\nNot enough cash for fee in specified wallet", l_sign_str);
+                    return -XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET;
                 }
                 case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nNot enough cash in specified wallet", l_sign_str);
-                    return -12;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET, 
+                                                "%s\nNot enough cash in specified wallet", l_sign_str);
+                    return -XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET;
                 }
                 case XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Out of memory");
-                    return -1;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED, 
+                                                "Out of memory");
+                    return -XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED;
                 }
                 case XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't compose the conditional transaction", l_sign_str);
-                    return -14;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION, 
+                                                "%s\nCan't compose the conditional transaction", l_sign_str);
+                    return -XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION;
                 }
                 case XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL: {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't compose the conditional transaction", l_sign_str);
-                    return -15;
+                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL, 
+                                                "%s\nCan't compose the conditional transaction", l_sign_str);
+                    return -XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL;
                 }
             }
         } break;
@@ -1355,13 +1372,15 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         case CMD_HISTORY:{
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order history' requires parameter -net");
-                return -2;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR, 
+                                                "Command 'order history' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR, 
+                                                "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR;
             }
 
             const char * l_order_hash_str = NULL;
@@ -1371,32 +1390,33 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_hash_str);
 
             if (!l_order_hash_str && ! l_addr_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order history' requires parameter -order or -addr" );
-                return -12;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR, 
+                                                "Command 'order history' requires parameter -order or -addr" );
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR;
             }
 
             if(l_addr_hash_str){
                 dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_addr_hash_str);
                 if (!l_addr) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Cannot convert "
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR, "Cannot convert "
                                                                    "string '%s' to binary address.", l_addr_hash_str);
-                    return -14;
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR;
                 }
                 if (dap_chain_addr_check_sum(l_addr) != 0 ) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Incorrect address wallet");
-                    return -15;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR, "Incorrect address wallet");
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR;
                 }
                 if (l_addr->net_id.uint64 != l_net->pub.id.uint64) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Address %s does not belong to the %s network.",
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR, "Address %s does not belong to the %s network.",
                                                       l_addr_hash_str, l_net->pub.name);
-                    return -16;
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR;
                 }
                 dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_all_for_addr(l_net,l_addr, c_dap_chain_net_srv_xchange_uid );
-                dap_string_t * l_str_reply = dap_string_new("");
+                json_object* json_obj_t = json_object_new_object();
 
                 if (l_tx_list){
                     dap_list_t *l_tx_list_temp = l_tx_list;
-                    dap_string_append_printf(l_str_reply, "Wallet %s history:\n\n", l_addr_hash_str);
+                    json_object_object_add(json_obj_t, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
                     while(l_tx_list_temp ){
                     dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
                     s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 0169d35f3e..4c7a4eb542 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -76,7 +76,18 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR,
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR,
 
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR,
-- 
GitLab


From bfde5c5cc619afa3ef30656661db16bf97b8e2a2 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 14 Oct 2024 18:32:33 +0700
Subject: [PATCH 07/22] ...

---
 dap-sdk                                       |   2 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 179 ++++++++++++++++++
 2 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/dap-sdk b/dap-sdk
index a9e2246ac3..9dcfc3fb33 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit a9e2246ac301ff17538754d94c8fbcd5558930cf
+Subproject commit 9dcfc3fb330cb79e55c3753c23e5b41e6d8be294
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 7055550644..e5d49a8a13 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1954,6 +1954,185 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
     return true;
 }
 
+/**
+ * @brief Append tx info to the reply string
+ * @param a_json_out
+ * @param a_net
+ * @param a_tx
+ */
+static bool s_string_append_tx_cond_info_json( dap_string_t * a_json_out,
+                                         dap_chain_net_t * a_net,
+                                         dap_chain_datum_tx_t * a_tx,
+                                         tx_opt_status_t a_filter_by_status,
+                                         bool a_print_prev_hash, bool a_print_status, bool a_print_ts)
+{
+    size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx);
+
+    dap_hash_fast_t l_tx_hash = {0};
+
+    dap_hash_fast(a_tx, l_tx_size, &l_tx_hash);
+    const char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
+
+    // Get input token ticker
+    const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash(
+                a_net->pub.ledger, &l_tx_hash);
+    if(!l_tx_input_ticker){
+        log_it(L_WARNING, "Can't get ticker from tx");
+        return false;
+    }
+    dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
+    dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
+    int l_cond_idx = 0;
+
+    xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item);
+
+    bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL);
+    if ((a_filter_by_status == TX_STATUS_ACTIVE && l_is_closed) || (a_filter_by_status == TX_STATUS_INACTIVE && !l_is_closed)
+     || (a_filter_by_status == TX_STATUS_ACTIVE && l_tx_type == TX_TYPE_INVALIDATE))
+        return false;
+
+    if(l_out_prev_cond_item && l_out_prev_cond_item->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE)
+        return false;
+
+    switch(l_tx_type){
+        case TX_TYPE_ORDER:{
+            if (!l_out_cond_item) {
+                log_it(L_ERROR, "Can't find conditional output");
+                return false;
+            }
+            char *l_rate_str = dap_chain_balance_to_coins(l_out_cond_item->subtype.srv_xchange.rate);
+            const char *l_amount_str, *l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str);
+
+            json_object_object_add(a_json_out, "hash", json_object_new_string(l_tx_hash_str));
+            if(a_print_ts){
+                char l_tmp_buf[DAP_TIME_STR_SIZE];
+                dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_tx->header.ts_created);
+                json_object_object_add(a_json_out, "ts_created", json_object_new_string(l_tmp_buf));
+            }
+            if( a_print_status)
+                json_object_object_add(a_json_out, "status", l_is_closed ? json_object_new_string("inactive") 
+                                                                         : json_object_new_string("active"));
+            json_object_object_add(a_json_out, "proposed price", json_object_new_string(l_amount_str));
+            json_object_object_add(a_json_out, "proposed datoshi", json_object_new_string(l_amount_datoshi_str));
+            json_object_object_add(a_json_out, "ticker", json_object_new_string(l_tx_input_ticker));
+            json_object_object_add(a_json_out, "buy token", json_object_new_string(l_out_cond_item->subtype.srv_xchange.buy_token));
+            json_object_object_add(a_json_out, "rate", json_object_new_string(l_rate_str));
+            json_object_object_add(a_json_out, "net", json_object_new_string(a_net->pub.name));
+
+            DAP_DELETE(l_rate_str);
+        } break;
+        case TX_TYPE_EXCHANGE:{
+            dap_chain_tx_in_cond_t *l_in_cond 
+                = (dap_chain_tx_in_cond_t*)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL);
+            char l_tx_prev_cond_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_in_cond->header.tx_prev_hash, l_tx_prev_cond_hash_str, sizeof(l_tx_prev_cond_hash_str));
+
+            if (!l_out_prev_cond_item) {
+                log_it(L_ERROR, "Can't find previous transaction");
+                return false;
+            }
+
+            uint256_t l_rate = l_out_cond_item 
+                ? l_out_cond_item->subtype.srv_xchange.rate
+                : l_out_prev_cond_item->subtype.srv_xchange.rate,
+                     l_value_from = {}, l_value_to = {};
+
+            if (l_out_cond_item)
+                SUBTRACT_256_256(l_out_prev_cond_item->header.value, l_out_cond_item->header.value, &l_value_from);
+            else
+                l_value_from = l_out_prev_cond_item->header.value;
+            MULT_256_COIN(l_value_from, l_rate, &l_value_to);
+
+            char *l_buy_ticker = l_out_cond_item 
+                ? l_out_cond_item->subtype.srv_xchange.buy_token
+                : l_out_prev_cond_item->subtype.srv_xchange.buy_token;
+
+            json_object_object_add(a_json_out, "hash", json_object_new_string(l_tx_hash_str));
+            if(a_print_ts){
+                char l_tmp_buf[DAP_TIME_STR_SIZE];
+                dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_tx->header.ts_created);
+                json_object_object_add(a_json_out, "ts_created", json_object_new_string(l_tmp_buf));
+            }
+            if(a_print_status)
+                json_object_object_add(a_json_out, "status", l_is_closed ? json_object_new_string("inactive") 
+                                                                         : json_object_new_string("active"));
+            
+            const char *l_value_from_str, *l_value_from_datoshi_str = dap_uint256_to_char(l_value_from, &l_value_from_str);
+            json_object_object_add(a_json_out, "changed", json_object_new_string(l_value_from_str));
+            json_object_object_add(a_json_out, "changed datoshi", json_object_new_string(l_value_from_datoshi_str));
+            json_object_object_add(a_json_out, "ticker", json_object_new_string(l_tx_input_ticker));
+
+            const char *l_value_to_str, *l_value_to_datoshi_str = dap_uint256_to_char(l_value_to, &l_value_to_str);
+
+            json_object_object_add(a_json_out, "for", json_object_new_string(l_value_to_str));
+            json_object_object_add(a_json_out, "for datoshi", json_object_new_string(l_value_to_datoshi_str));
+            json_object_object_add(a_json_out, "ticker", json_object_new_string(l_buy_ticker));
+
+            const char *l_rate_str; dap_uint256_to_char(l_rate, &l_rate_str);
+            json_object_object_add(a_json_out, "rate", json_object_new_string(l_rate_str));
+
+            const char *l_amount_str = NULL,
+                 *l_amount_datoshi_str = l_out_cond_item ? dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str) : "0";
+            json_object_object_add(a_json_out, "remain amount", l_amount_str ? json_object_new_string(l_amount_str) 
+                                                                             : json_object_new_string("0.0"));
+            json_object_object_add(a_json_out, "remain amount datoshi", json_object_new_string(l_amount_datoshi_str));
+            json_object_object_add(a_json_out, "ticker", json_object_new_string(l_tx_input_ticker));
+            json_object_object_add(a_json_out, "net", json_object_new_string(a_net->pub.name));
+            if (a_print_prev_hash)
+                json_object_object_add(a_json_out, "Prev cond", json_object_new_string(l_tx_prev_cond_hash_str));
+        } break;
+        case TX_TYPE_INVALIDATE:{
+            dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL);
+            char l_tx_prev_cond_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_in_cond->header.tx_prev_hash,l_tx_prev_cond_hash_str, sizeof(l_tx_prev_cond_hash_str));
+
+            if (!l_out_prev_cond_item) {
+                log_it(L_ERROR, "Can't find previous transaction");
+                return false;
+            }
+
+            dap_chain_datum_tx_t *l_prev_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_in_cond->header.tx_prev_hash);
+            if (!l_prev_tx)
+                return false;
+
+            int l_out_num = l_in_cond->header.tx_out_prev_idx;
+            dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_out_num);
+            if (!l_out_cond) {
+                log_it(L_ERROR, "Can't find datum tx");
+                return false;
+            }
+            dap_hash_fast_t l_order_hash = dap_ledger_get_first_chain_tx_hash(a_net->pub.ledger, a_tx, l_out_cond);
+            if ( dap_hash_fast_is_blank(&l_order_hash) )
+                l_order_hash = l_in_cond->header.tx_prev_hash;
+
+            char *l_value_from_str = dap_chain_balance_to_coins(l_out_prev_cond_item->header.value);
+            char *l_value_from_datoshi_str = dap_chain_balance_print(l_out_prev_cond_item->header.value);
+
+            dap_string_append_printf(a_reply_str, "Hash: %s\n", l_tx_hash_str);
+            if(a_print_ts){
+                char l_tmp_buf[DAP_TIME_STR_SIZE];
+                dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_tx->header.ts_created);
+                dap_string_append_printf(a_reply_str, "  ts_created: %s", l_tmp_buf);
+            }
+            if (a_print_status)
+                dap_string_append_printf(a_reply_str, "  Status: inactive,");
+
+            char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str));
+            dap_string_append_printf(a_reply_str, "  returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str);
+            if(a_print_prev_hash)
+                dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
+
+            DAP_DELETE(l_value_from_str);
+            DAP_DELETE(l_value_from_datoshi_str);
+        } break;
+        default: return false;
+    }
+
+    dap_string_append_printf(a_reply_str, "\n\n");
+    return true;
+}
+
 
 static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_after, dap_time_t a_before,
                                           dap_chain_addr_t *a_addr, int a_opt_status, void **a_str_reply)
-- 
GitLab


From 861f195c755c2c98981d45269b71863e160d6b1f Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 14 Oct 2024 18:35:05 +0700
Subject: [PATCH 08/22] ...

---
 modules/service/xchange/include/dap_chain_net_srv_xchange.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 4c7a4eb542..941d669293 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -84,7 +84,6 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR,
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR,
@@ -113,7 +112,7 @@ typedef enum s_com_net_srv_xchange_err{
     XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET,
     XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
     XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
-    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL,
+    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL
 } s_com_net_srv_xchange_err_t;
 
 typedef enum dap_chain_net_srv_xchange_create_error_list{
-- 
GitLab


From 883ac636b5ca1114426c906d8d43a8bc029e6f1a Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 15 Oct 2024 19:00:53 +0700
Subject: [PATCH 09/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 53 ++++++++++---------
 .../include/dap_chain_net_srv_xchange.h       |  4 ++
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index e5d49a8a13..5e84f1df79 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1419,13 +1419,12 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                     json_object_object_add(json_obj_t, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
                     while(l_tx_list_temp ){
                     dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                    s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                    s_string_append_tx_cond_info_json(json_obj_t, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
                     l_tx_list_temp = l_tx_list_temp->next;
                     }
                     dap_list_free(l_tx_list);
-                    *a_str_reply = dap_string_free(l_str_reply, false);
                 }else{
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "No history");
+                    json_object_object_add(json_obj_t, "status", json_object_new_string("No history"));
                 }
                 DAP_DELETE(l_addr);
             }
@@ -1434,32 +1433,32 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                 dap_hash_fast_t l_order_tx_hash = {};
                 dap_chain_hash_fast_from_str(l_order_hash_str, &l_order_tx_hash);
                 dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash(l_net, &l_order_tx_hash, TX_SEARCH_TYPE_NET);
+                json_object* json_obj_t = json_object_new_object();
                 
                 if( l_tx){
                     xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, NULL, NULL, NULL);
                     char *l_tx_hash = dap_chain_hash_fast_to_str_new(&l_order_tx_hash);
                     if(l_tx_type != TX_TYPE_ORDER){
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum with hash %s is not order. Check hash.", l_tx_hash);
+                        json_object_object_add(json_obj_t, "datum status", json_object_new_string("is not order"));
+                        json_object_object_add(json_obj_t, "datum hash", json_object_new_string(l_tx_hash));
                     } else {
                         int l_rc = s_tx_check_for_open_close(l_net,l_tx);
                         if(l_rc == 0){
-                            dap_cli_server_cmd_set_reply_text(a_str_reply, "WRONG TX %s", l_tx_hash);
+                            json_object_object_add(json_obj_t, "WRONG TX", json_object_new_string(l_tx_hash));
                         }else{
-                            dap_string_t * l_str_reply = dap_string_new("");
-                            dap_string_append_printf(l_str_reply, "Order %s history:\n\n", l_order_hash_str);
+                            json_object_object_add(json_obj_t, "history for order", json_object_new_string(l_order_hash_str));
                             dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_chain(l_net, &l_order_tx_hash, c_dap_chain_net_srv_xchange_uid );
                             dap_list_t *l_tx_list_temp = l_tx_list;
                             while(l_tx_list_temp ){
                                 dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                                s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                                s_string_append_tx_cond_info_json(json_obj_t, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
                                 l_tx_list_temp = l_tx_list_temp->next;
                             }
                             dap_list_free(l_tx_list);
-                            *a_str_reply = dap_string_free(l_str_reply, false);
                         }
                     }
                 }else{
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "No history");
+                    json_object_object_add(json_obj_t, "status", json_object_new_string("No history"));
                 }
             }
         } break;
@@ -1470,26 +1469,29 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             const char * l_fee_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order %s' requires parameter -net",
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR, "Command 'order %s' requires parameter -net",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
-                return -2;
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR, 
+                                                                            "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order %s' requires parameter -w",
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR, 
+                                                                            "Command 'order %s' requires parameter -w",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
-                return -10;
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR;
             }
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             const char* l_sign_str = "";
             if (!l_wallet) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet not found");
-                return -11;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR, 
+                                                                            "Specified wallet not found");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR;
             } else {
                 l_sign_str = dap_chain_wallet_check_sign(l_wallet);
             }
@@ -2108,28 +2110,29 @@ static bool s_string_append_tx_cond_info_json( dap_string_t * a_json_out,
             char *l_value_from_str = dap_chain_balance_to_coins(l_out_prev_cond_item->header.value);
             char *l_value_from_datoshi_str = dap_chain_balance_print(l_out_prev_cond_item->header.value);
 
-            dap_string_append_printf(a_reply_str, "Hash: %s\n", l_tx_hash_str);
+            json_object_object_add(a_json_out, "hash", json_object_new_string(l_tx_hash_str));
             if(a_print_ts){
                 char l_tmp_buf[DAP_TIME_STR_SIZE];
                 dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_tx->header.ts_created);
-                dap_string_append_printf(a_reply_str, "  ts_created: %s", l_tmp_buf);
+                json_object_object_add(a_json_out, "ts_created", json_object_new_string(l_tmp_buf));
             }
             if (a_print_status)
-                dap_string_append_printf(a_reply_str, "  Status: inactive,");
+                json_object_object_add(a_json_out, "status", json_object_new_string("inactive"));
 
             char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
             dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str));
-            dap_string_append_printf(a_reply_str, "  returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str);
+            json_object_object_add(a_json_out, "returned from", json_object_new_string(l_value_from_str));
+            json_object_object_add(a_json_out, "returned datoshi", json_object_new_string(l_value_from_datoshi_str));
+            json_object_object_add(a_json_out, "ticker", json_object_new_string(l_tx_input_ticker));
+            json_object_object_add(a_json_out, "order hash", json_object_new_string(l_order_hash_str));
             if(a_print_prev_hash)
-                dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
+                json_object_object_add(a_json_out, "prev cond hash", json_object_new_string(l_tx_prev_cond_hash_str));
 
             DAP_DELETE(l_value_from_str);
             DAP_DELETE(l_value_from_datoshi_str);
         } break;
         default: return false;
     }
-
-    dap_string_append_printf(a_reply_str, "\n\n");
     return true;
 }
 
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 941d669293..7efd86c032 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -87,6 +87,10 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR,    
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR,
 
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR,
-- 
GitLab


From c64a19567285967247189a5a5f80c6317366410c Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Wed, 16 Oct 2024 16:39:36 +0700
Subject: [PATCH 10/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 116 ++++++++++--------
 .../include/dap_chain_net_srv_xchange.h       |  15 ++-
 2 files changed, 79 insertions(+), 52 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 5e84f1df79..ef3517599a 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1412,19 +1412,18 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR;
                 }
                 dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_all_for_addr(l_net,l_addr, c_dap_chain_net_srv_xchange_uid );
-                json_object* json_obj_t = json_object_new_object();
-
+                
                 if (l_tx_list){
                     dap_list_t *l_tx_list_temp = l_tx_list;
-                    json_object_object_add(json_obj_t, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
+                    json_object_object_add(a_json_obj_out, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
                     while(l_tx_list_temp ){
                     dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                    s_string_append_tx_cond_info_json(json_obj_t, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                    s_string_append_tx_cond_info_json(a_json_obj_out, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
                     l_tx_list_temp = l_tx_list_temp->next;
                     }
                     dap_list_free(l_tx_list);
                 }else{
-                    json_object_object_add(json_obj_t, "status", json_object_new_string("No history"));
+                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("No history"));
                 }
                 DAP_DELETE(l_addr);
             }
@@ -1433,32 +1432,31 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                 dap_hash_fast_t l_order_tx_hash = {};
                 dap_chain_hash_fast_from_str(l_order_hash_str, &l_order_tx_hash);
                 dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash(l_net, &l_order_tx_hash, TX_SEARCH_TYPE_NET);
-                json_object* json_obj_t = json_object_new_object();
                 
                 if( l_tx){
                     xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, NULL, NULL, NULL);
                     char *l_tx_hash = dap_chain_hash_fast_to_str_new(&l_order_tx_hash);
                     if(l_tx_type != TX_TYPE_ORDER){
-                        json_object_object_add(json_obj_t, "datum status", json_object_new_string("is not order"));
-                        json_object_object_add(json_obj_t, "datum hash", json_object_new_string(l_tx_hash));
+                        json_object_object_add(a_json_obj_out, "datum status", json_object_new_string("is not order"));
+                        json_object_object_add(a_json_obj_out, "datum hash", json_object_new_string(l_tx_hash));
                     } else {
                         int l_rc = s_tx_check_for_open_close(l_net,l_tx);
                         if(l_rc == 0){
-                            json_object_object_add(json_obj_t, "WRONG TX", json_object_new_string(l_tx_hash));
+                            json_object_object_add(a_json_obj_out, "WRONG TX", json_object_new_string(l_tx_hash));
                         }else{
-                            json_object_object_add(json_obj_t, "history for order", json_object_new_string(l_order_hash_str));
+                            json_object_object_add(a_json_obj_out, "history for order", json_object_new_string(l_order_hash_str));
                             dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_chain(l_net, &l_order_tx_hash, c_dap_chain_net_srv_xchange_uid );
                             dap_list_t *l_tx_list_temp = l_tx_list;
                             while(l_tx_list_temp ){
                                 dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                                s_string_append_tx_cond_info_json(json_obj_t, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                                s_string_append_tx_cond_info_json(a_json_obj_out, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
                                 l_tx_list_temp = l_tx_list_temp->next;
                             }
                             dap_list_free(l_tx_list);
                         }
                     }
                 }else{
-                    json_object_object_add(json_obj_t, "status", json_object_new_string("No history"));
+                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("No history"));
                 }
             }
         } break;
@@ -1497,15 +1495,17 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order %s' requires parameter -order",
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR, 
+                                                                            "Command 'order %s' requires parameter -order",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
-                return -12;
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order %s' requires parameter -fee",
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR, 
+                                                                            "Command 'order %s' requires parameter -fee",
                                                   l_cmd_num == CMD_REMOVE ? "remove" : "update");
-                return -12;
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
             dap_hash_fast_t l_tx_hash = {};
@@ -1515,27 +1515,28 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_chain_wallet_close(l_wallet);
             switch (l_ret_code) {
                 case XCHANGE_REMOVE_ERROR_OK:
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Order successfully removed. Created inactivate tx with hash %s", l_tx_hash_ret);
+                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("Order successfully removed"));
+                    json_object_object_add(a_json_obj_out, "Created inactivate tx with hash", json_object_new_string(l_tx_hash_ret));
                     DAP_DELETE(l_tx_hash_ret);
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX:
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSpecified order not found", l_sign_str);
+                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX, "%s\nSpecified order not found", l_sign_str);
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE:
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't create price object from order", l_sign_str);
+                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE, "%s\nCan't create price object from order", l_sign_str);
                     break;
                 case XCHANGE_REMOVE_ERROR_FEE_IS_ZERO:
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get fee value.");
+                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_FEE_IS_ZERO, "Can't get fee value.");
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX: {
                     dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
                     dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_fee, false);
                     const char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_price->tx_hash);
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create invalidate transaction from: %s\n", l_final_tx_hash_str);
+                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX, "Can't create invalidate transaction from: %s\n", l_final_tx_hash_str);
                     DAP_DELETE(l_price);
                 } break;
                 default:
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "An error occurred with an unknown code: %d.", l_ret_code);
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_UNKNOWN_ERR, "An error occurred with an unknown code: %d.", l_ret_code);
                     break;
             }
             return l_ret_code;
@@ -1544,39 +1545,45 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         case CMD_STATUS: {
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order status' requires parameter -net");
-                return -2;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR, 
+                                                            "Command 'order status' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR, 
+                                                            "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR;
             }
             const char * l_order_hash_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order history' requires parameter -order or -addr" );
-                return -12;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR, 
+                                                            "Command 'order status' requires parameter -order or -addr" );
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR;
             }
             dap_hash_fast_t l_order_tx_hash = {};
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_order_tx_hash);
             dap_chain_datum_tx_t * l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order_tx_hash);
             if (!l_tx){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s", l_order_hash_str);
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR, 
+                                                            "Can't find order %s", l_order_hash_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR;
             }
 
             dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL);
             if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order");
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR, 
+                                                            "It's not an order");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR;
             }
 
             // TODO add filters to list (tokens, network, etc.)
             dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_tx, NULL, true);
             if( !l_price ){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get price from order");
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR, 
+                                                            "Can't get price from order");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR;
             }
 
             dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name);
@@ -1584,14 +1591,16 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             char* l_status_order = NULL;
             dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
             if( dap_hash_fast_is_blank(&l_last_tx_hash) ){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get last tx cond hash from order");
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR, 
+                                                            "Can't get last tx cond hash from order");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR;
             }
 
             dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_last_tx_hash);
             if (!l_last_tx){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find last tx");
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR, 
+                                                            "Can't find last tx");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR;
             }
 
             switch (dap_chain_net_srv_xchange_get_order_status(l_net, l_order_tx_hash))
@@ -1628,24 +1637,29 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             if (l_out_cond_last_tx)
                 l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str);
 
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n",
-                                     dap_chain_hash_fast_to_str_static(&l_tx_hash),
-                                     l_tmp_buf, l_status_order,
-                                     l_amount_coins_str ? l_amount_coins_str : "0.0",
-                                     l_amount_datoshi_str ? l_amount_datoshi_str : "0",
-                                     l_price->token_sell, l_percent_completed,
-                                     l_price->token_buy, l_price->token_sell,
-                                     l_cp_rate,
-                                     l_price->net->pub.name);
-
-
+            json_object_object_add(a_json_obj_out, "orderHash", json_object_new_string(dap_chain_hash_fast_to_str_static(&l_tx_hash)));
+            json_object_object_add(a_json_obj_out, "ts_created", json_object_new_string(l_tmp_buf));
+            json_object_object_add(a_json_obj_out, "status", json_object_new_string(l_status_order));
+            json_object_object_add(a_json_obj_out, "amount coins", l_amount_coins_str ? json_object_new_string(l_amount_coins_str) 
+                                                                                : json_object_new_string("0.0"));
+            json_object_object_add(a_json_obj_out, "amount datoshi", l_amount_datoshi_str ? json_object_new_string(l_amount_datoshi_str) 
+                                                                                : json_object_new_string("0"));
+            json_object_object_add(a_json_obj_out, "token", json_object_new_string(l_price->token_sell));
+            char *l_filled = dap_strdup_printf("%lu%%", l_percent_completed);
+            json_object_object_add(a_json_obj_out, "filled", json_object_new_string(l_filled));
+            DAP_DELETE(l_filled);
+            json_object_object_add(a_json_obj_out, "rate token", json_object_new_string(l_price->token_buy));
+            json_object_object_add(a_json_obj_out, "rate", json_object_new_string(l_cp_rate));
+            json_object_object_add(a_json_obj_out, "net", json_object_new_string(l_price->net->pub.name));
+            
             DAP_DEL_Z(l_cp_rate);
             DAP_DEL_Z(l_price);
         } break;
 
         default: {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand %s not recognized", a_argv[a_arg_index]);
-            return -4;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR, 
+                                                            "Subcommand %s not recognized", a_argv[a_arg_index]);
+            return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR;
         }
     }
     return 0;
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 7efd86c032..a94de8a923 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -90,7 +90,20 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR,    
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_UNKNOWN_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUN_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR,
 
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR,
-- 
GitLab


From 502b73c3fa002cec81f7a27aabe7609e39d49def Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Thu, 17 Oct 2024 22:18:03 +0700
Subject: [PATCH 11/22] ...

---
 modules/common/dap_chain_common.c             |  4 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 37 ++++++++++---------
 .../include/dap_chain_net_srv_xchange.h       |  1 +
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index b9d0400a7a..2db9542b22 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -223,12 +223,12 @@ void s_set_offset_limit_json(json_object * a_json_obj_out, size_t *a_start, size
     json_object* json_obj_lim = json_object_new_object();
     if (a_offset > 0) {
         *a_start = a_offset;
-        json_object_object_add(json_obj_lim, "offset", json_object_new_int(*a_start));                
+        json_object_object_add(json_obj_lim, "offset", json_object_new_uint64(*a_start));
     }
     *a_and = a_and_count;
     if (a_limit > 0) {
         *a_and = *a_start + a_limit;
-        json_object_object_add(json_obj_lim, "limit", json_object_new_int(*a_and - *a_start));
+        json_object_object_add(json_obj_lim, "limit", json_object_new_uint64(*a_and - *a_start));
     }
     else
         json_object_object_add(json_obj_lim, "limit", json_object_new_string("unlimit"));
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index ef3517599a..8e79cd6d03 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2224,8 +2224,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
 
     switch (l_cmd_num) {
-        case CMD_ORDER:
-            return s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, a_str_reply);
+        case CMD_ORDER: {
+            json_object* json_obj_order = json_object_new_object();
+            int res = s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, json_obj_order);
+            json_object_array_add(*json_arr_reply, json_obj_order);
+            return res;
+        }
         case CMD_ORDERS: {
             const char *l_net_str = NULL;
             const char *l_status_str = NULL;
@@ -2295,19 +2299,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
             size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
             size_t l_arr_start = 0;            
-            size_t l_arr_end = dap_list_length(l_tx_list);
+            size_t l_arr_end = 0;
             json_object* json_obj_order = json_object_new_object();
-            if (l_offset > 0) {
-                l_arr_start = l_offset;
-                json_object_object_add(json_obj_order, "offset", json_object_new_uint64(l_arr_start));               
-            }
-            if (l_limit) {
-                json_object_object_add(json_obj_order, "limit", json_object_new_uint64(l_limit));
-                l_arr_end = l_arr_start + l_limit;
-                if (l_arr_end > dap_list_length(l_tx_list)) {
-                    l_arr_end = dap_list_length(l_tx_list);
-                }
-            }            
+            s_set_offset_limit_json(json_obj_order, &l_arr_start, &l_arr_end, l_limit, l_offset, dap_list_length(l_tx_list));
             size_t i_tmp = 0;
             json_object* json_arr_orders_out = json_object_new_array();
             // Print all txs
@@ -2394,13 +2388,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 DAP_DEL_MULTY(l_cp_rate, l_price);
             }
             json_object_object_add(json_obj_order, "ORDERS", json_arr_orders_out);
+            json_object_array_add(*json_arr_reply, json_obj_order);
             dap_list_free(l_tx_list);            
         } break;
 
         case CMD_PURCHASE: {
             const char *l_net_str = NULL, *l_wallet_str = NULL, *l_order_hash_str = NULL, *l_val_buy_str = NULL, *l_val_fee_str = NULL;
-            l_arg_index++;
-            json_object* json_obj_orders = json_object_new_object();
+            l_arg_index++;            
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
                 dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR, "Command 'purchase' requires parameter -net");
@@ -2448,7 +2442,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                                                 l_wallet, &l_str_ret_hash);
             switch (l_ret_code) {
                 case XCHANGE_PURCHASE_ERROR_OK: {
+                    json_object* json_obj_orders = json_object_new_object();
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Exchange transaction has done. tx hash: %s", l_str_ret_hash);
+                    json_object_object_add(json_obj_orders, "status", json_object_new_string("Exchange transaction has done"));
+                    json_object_object_add(json_obj_orders, "hash", json_object_new_string(l_str_ret_hash));
+                    json_object_array_add(*json_arr_reply, json_obj_orders);
                     DAP_DELETE(l_str_ret_hash);
                     return 0;
                 }
@@ -2534,8 +2532,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             /* Dispatch request processing to ... */
             if ( l_addr_str )
             {
-                if ( !(l_addr = dap_chain_addr_from_str(l_addr_str)) )
-                    return  dap_cli_server_cmd_set_reply_text(a_str_reply, "Cannot convert -addr '%s' to internal representative", l_addr_str), -EINVAL;
+                if ( !(l_addr = dap_chain_addr_from_str(l_addr_str)) ) {
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_LIST_CAN_NOT_CONVERT_ERR,
+                                           "Cannot convert -addr '%s' to internal representative", l_addr_str);
+                    return -EINVAL;
+                }
 
                 return  s_cli_srv_xchange_tx_list_addr (l_net, l_time[0], l_time[1], l_addr, l_opt_status, a_str_reply);
             }
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index a94de8a923..b3ccc0bf6d 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -104,6 +104,7 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_LIST_CAN_NOT_CONVERT_ERR,
 
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR,
-- 
GitLab


From 87dd415670a778531434112ac7af75452e2fb18c Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 21 Oct 2024 07:40:16 +0700
Subject: [PATCH 12/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 68 +++++++++++--------
 .../include/dap_chain_net_srv_xchange.h       |  5 ++
 2 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 8e79cd6d03..518fc2c2e0 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2151,18 +2151,15 @@ static bool s_string_append_tx_cond_info_json( dap_string_t * a_json_out,
 }
 
 
-static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_after, dap_time_t a_before,
-                                          dap_chain_addr_t *a_addr, int a_opt_status, void **a_str_reply)
+static int s_cli_srv_xchange_tx_list_addr_json(dap_chain_net_t *a_net, dap_time_t a_after, dap_time_t a_before,
+                                          dap_chain_addr_t *a_addr, int a_opt_status, json_object* json_obj_out)
 {
 dap_chain_hash_fast_t l_tx_first_hash = {0};
 dap_chain_datum_tx_t    *l_datum_tx;
-dap_string_t *l_reply_str;
 size_t l_tx_total;
 
-    if ( !(l_reply_str = dap_string_new("")) )                              /* Prepare output string discriptor*/
-        return  log_it(L_CRITICAL, "%s", c_error_memory_alloc), -ENOMEM;
-
     memset(&l_tx_first_hash, 0, sizeof(dap_chain_hash_fast_t));             /* Initial hash == zero */
+    json_object* json_arr_datum_out = json_object_new_array();
 
     size_t l_tx_count = 0;
     for (l_tx_total = 0;
@@ -2175,13 +2172,17 @@ size_t l_tx_total;
 
         if ( a_before && (l_datum_tx->header.ts_created > a_before) )
             continue;
-
-        if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, a_opt_status, false, true, false))
+        json_object* json_obj_tx = json_object_new_object();
+        if (s_string_append_tx_cond_info_json(json_obj_tx, a_net, l_datum_tx, a_opt_status, false, true, false)) {
+            json_object_array_add(json_arr_datum_out, json_obj_tx);
             l_tx_count++;
+        }
     }
 
-    dap_string_append_printf(l_reply_str, "\nFound %"DAP_UINT64_FORMAT_U" transactions", l_tx_count);
-    *a_str_reply = dap_string_free(l_reply_str, false);                     /* Free string descriptor, but keep ASCIZ buffer itself */
+    json_object_object_add(json_obj_out, "transactions", json_arr_datum_out);
+    char *l_transactions = dap_strdup_printf("\nFound %"DAP_UINT64_FORMAT_U" transactions", l_tx_count);
+    json_object_object_add(json_obj_out, "number of transactions", json_object_new_string(l_transactions));
+    DAP_DELETE(l_transactions);                    /* Free string descriptor, but keep ASCIZ buffer itself */
     return  0;
 }
 
@@ -2443,7 +2444,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             switch (l_ret_code) {
                 case XCHANGE_PURCHASE_ERROR_OK: {
                     json_object* json_obj_orders = json_object_new_object();
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Exchange transaction has done. tx hash: %s", l_str_ret_hash);
                     json_object_object_add(json_obj_orders, "status", json_object_new_string("Exchange transaction has done"));
                     json_object_object_add(json_obj_orders, "hash", json_object_new_string(l_str_ret_hash));
                     json_object_array_add(*json_arr_reply, json_obj_orders);
@@ -2537,12 +2537,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                            "Cannot convert -addr '%s' to internal representative", l_addr_str);
                     return -EINVAL;
                 }
-
-                return  s_cli_srv_xchange_tx_list_addr (l_net, l_time[0], l_time[1], l_addr, l_opt_status, a_str_reply);
+                json_object* json_obj_order = json_object_new_object();
+                s_cli_srv_xchange_tx_list_addr_json(l_net, l_time[0], l_time[1], l_addr, l_opt_status, json_obj_order);
+                json_object_array_add(*json_arr_reply, json_obj_order);
+                return 0;
             }
 
-            // Prepare output string
-            dap_string_t *l_reply_str = dap_string_new("");
 
             // Find transactions using filter function s_filter_tx_list()
             dap_list_t *l_datum_list0 = dap_chain_datum_list(l_net, NULL, s_filter_tx_list, l_time);
@@ -2551,20 +2551,28 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if (l_datum_num > 0) {
                 log_it(L_DEBUG,  "Found %zu transactions:\n", l_datum_num);
                 dap_list_t *l_datum_list = l_datum_list0;
+                json_object* json_arr_bl_out = json_object_new_array();
+                json_object* json_obj_order = json_object_new_object();
                 while(l_datum_list) {
-
+                    json_object* json_obj_order = json_object_new_object();
                     dap_chain_datum_tx_t *l_datum_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_datum_list->data)->data;
-                    if (s_string_append_tx_cond_info(l_reply_str, l_net, l_datum_tx, l_opt_status, false, true, false))
+                    if (s_string_append_tx_cond_info_json(json_obj_order, l_net, l_datum_tx, l_opt_status, false, true, false)){
+
+                        json_object_array_add(json_arr_bl_out, json_obj_order);
                         l_show_tx_nr++;
+                    }
                     l_datum_list = dap_list_next(l_datum_list);
                 }
-                dap_string_append_printf(l_reply_str, "Found %d transactions", l_show_tx_nr);
+                json_object_object_add(json_obj_order, "transactions", json_arr_bl_out);
+                json_object_object_add(json_obj_order, "number of transactions", json_object_new_int(l_show_tx_nr));
+                json_object_array_add(*json_arr_reply, json_obj_order);
             }
             else{
-                dap_string_append(l_reply_str, "Transactions not found");
+                json_object* json_obj_order = json_object_new_object();
+                json_object_object_add(json_obj_order, "status", json_object_new_string("Transactions not found"));
+                json_object_array_add(*json_arr_reply, json_obj_order);
             }
             dap_list_free_full(l_datum_list0, NULL);
-            *a_str_reply = dap_string_free(l_reply_str, false);
         } break;
         // Token pair control
         case CMD_TOKEN_PAIR: {
@@ -2573,13 +2581,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             const char *l_net_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if(!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'token_pair' requires parameter -net");
-                return -3;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR,
+                                       "Command 'token_pair' requires parameter -net");
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if(!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR,
+                                       "Network %s not found", l_net_str);
+                return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR;
             }
 
             // Select subcommands
@@ -2592,13 +2602,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 const char * l_token_from_str = NULL;
                 dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_from", &l_token_from_str);
                 if(!l_token_from_str){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_from'");
-                    return -5;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR,
+                                           "No argument '-token_from'");
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR;
                 }
                 dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
                 if(!l_token_from_datum){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
-                    return -6;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
+                                           "Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR;
                 }
 
                 // Check for token_to
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index b3ccc0bf6d..f750994b3d 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -119,6 +119,11 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR,
 
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
+
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
     XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
     XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER,
-- 
GitLab


From 33c39e08c41c6727525f1a9198a8e937528df939 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Mon, 21 Oct 2024 16:01:29 +0700
Subject: [PATCH 13/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 72 +++++++++----------
 .../include/dap_chain_net_srv_xchange.h       |  3 +
 2 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 518fc2c2e0..d1764a4ad6 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2302,7 +2302,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             size_t l_arr_start = 0;            
             size_t l_arr_end = 0;
             json_object* json_obj_order = json_object_new_object();
-            s_set_offset_limit_json(json_obj_order, &l_arr_start, &l_arr_end, l_limit, l_offset, dap_list_length(l_tx_list));
+            dap_chain_set_offset_limit_json(json_obj_order, &l_arr_start, &l_arr_end, l_limit, l_offset, dap_list_length(l_tx_list));
             size_t i_tmp = 0;
             json_object* json_arr_orders_out = json_object_new_array();
             // Print all txs
@@ -2617,13 +2617,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 const char * l_token_to_str = NULL;
                 dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_to", &l_token_to_str);
                 if(!l_token_to_str){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"No argument '-token_to'");
-                    return -5;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
+                                           "No argument '-token_to'");
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR;
                 }
                 dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
                 if(!l_token_to_datum){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,"Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
-                    return -6;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
+                                           "Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR;
                 }
 
                 // Read time_from
@@ -2640,7 +2642,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                 // Check for price subcommand
                 if (strcmp(l_price_subcommand,"average") == 0){
-                    dap_string_t *l_reply_str = dap_string_new("");
 
                     dap_list_t *l_tx_cond_list = dap_chain_net_get_tx_cond_all_by_srv_uid(l_net, c_dap_chain_net_srv_xchange_uid,
                                                                                           0,0,TX_SEARCH_TYPE_NET );
@@ -2702,11 +2703,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     char l_tmp_buf[DAP_TIME_STR_SIZE];
                     dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_last_rate_time);
                     const char *l_rate_average_str; dap_uint256_to_char(l_rate_average, &l_rate_average_str);
-                    dap_string_append_printf(l_reply_str,"Average rate: %s\n", l_rate_average_str);
+                    json_object* json_obj_order = json_object_new_object();
+                    json_object_object_add(json_obj_order, "Average rate", json_object_new_string(l_rate_average_str));
                     const char *l_last_rate_str; dap_uint256_to_char(l_rate, &l_last_rate_str);
-                    dap_string_append_printf(l_reply_str, "Last rate: %s Last rate time: %s",
-                                             l_last_rate_str, l_tmp_buf);
-                    *a_str_reply = dap_string_free(l_reply_str, false);
+                    json_object_object_add(json_obj_order, "Last rate", json_object_new_string(l_last_rate_str));
+                    json_object_object_add(json_obj_order, "Last rate time", json_object_new_string(l_tmp_buf));
+                    json_object_array_add(*json_arr_reply, json_obj_order);
                     break;
                 }else if (strcmp(l_price_subcommand,"history") == 0){
                     const char *l_limit_str = NULL, *l_offset_str = NULL;
@@ -2715,7 +2717,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
                     size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
 
-                    dap_string_t *l_reply_str = dap_string_new("");
                     dap_time_t l_time[2];
                     l_time[0] = l_time_from;
                     l_time[1] = l_time_to;
@@ -2725,19 +2726,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     size_t l_datum_num = dap_list_length(l_datum_list0);
 
                     if (l_datum_num == 0){
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find transactions");
-                        return -6;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
+                                           "Can't find transactions");
+                        return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR;
                     }
+                    json_object* json_arr_bl_cache_out = json_object_new_array();
                     size_t l_arr_start = 0;
-                    size_t l_arr_end  = l_datum_num;
-                    if (l_offset > 0) {
-                        l_arr_start = l_offset;
-                        dap_string_append_printf(l_reply_str, "offset: %lu\n", l_arr_start);
-                    }
-                    if (l_limit) {
-                        l_arr_end = l_arr_start + l_limit;
-                        dap_string_append_printf(l_reply_str, "limit: %lu\n", l_limit);
-                    }
+                    size_t l_arr_end  = 0;
+                    dap_chain_set_offset_limit_json(json_arr_bl_cache_out, &l_arr_start, &l_arr_end, l_limit, l_offset, l_datum_num);
+                    
                     size_t i_tmp = 0;
 
                     dap_list_t * l_cur = l_datum_list0;
@@ -2780,19 +2777,20 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                 continue;
                             }
                             i_tmp++;
-
-                            s_string_append_tx_cond_info(l_reply_str, l_net, l_tx, TX_STATUS_ALL, false, false, true);
+                            json_object* json_obj_out = json_object_new_object();
+                            s_string_append_tx_cond_info_json(json_obj_out, l_net, l_tx, TX_STATUS_ALL, false, false, true);
+                            json_object_array_add(json_arr_bl_cache_out, json_obj_out);
                         }
                         l_cur = dap_list_next(l_cur);
                     }
 
-                    *a_str_reply = dap_string_free(l_reply_str, false);
+                    json_object_array_add(*json_arr_reply, json_arr_bl_cache_out);
                     break;
 
                 } else {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'",
-                                                      l_price_subcommand);
-                    return -38;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
+                                           "Unrecognized subcommand '%s'", l_price_subcommand);                    
+                    return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR;
                 }
             }
 
@@ -2805,7 +2803,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str);
                     size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
                     size_t l_limit  = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0;
-                    dap_string_t *l_reply_str = dap_string_new("");
+                    
                     char ** l_tickers = NULL;
                     size_t l_tickers_count = 0;
                     dap_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count);
@@ -2813,13 +2811,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     size_t l_pairs_count = 0;
                     if(l_tickers){
                         size_t l_arr_start = 0;
-                        size_t l_arr_end  = l_tickers_count;
-                        if (l_offset > 1) {
-                            l_arr_start = l_limit * l_offset;
-                        }
-                        if (l_limit) {
-                            l_arr_end = l_arr_start + l_limit;
-                        }
+                        size_t l_arr_end  = 0;
+                        json_object* json_arr_bl_cache_out = json_object_new_array();
+                        dap_chain_set_offset_limit_json(json_arr_bl_cache_out, &l_arr_start, &l_arr_end, l_limit, l_offset, l_tickers_count);                        
                         size_t i_tmp = 0;
                         for(size_t i = 0; i< l_tickers_count; i++){
                             for(size_t j = i+1; j< l_tickers_count; j++){
@@ -2829,12 +2823,16 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                         continue;
                                     }
                                     i_tmp++;
-                                    dap_string_append_printf(l_reply_str,"%s:%s ", l_tickers[i], l_tickers[j]);
+                                    json_object* json_obj_bl = json_object_new_object();
+                                    json_object_object_add(json_obj_bl, "ticker_1",json_object_new_string(l_tickers[i]));
+                                    json_object_object_add(json_obj_bl, "ticker_2",json_object_new_string(l_tickers[j]));
+                                    json_object_array_add(json_arr_bl_cache_out, json_obj_bl);
                                     l_pairs_count++;
                                 }
                             }
 
                         }
+                        json_object_array_add(*json_arr_reply, json_arr_bl_cache_out);
 
                         // Free tickers array
                         for(size_t i = 0; i< l_tickers_count; i++){
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index f750994b3d..bacd683fa2 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -123,6 +123,9 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
 
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
     XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
-- 
GitLab


From 3679b9b54f8b0decde8315dfccaca4e9f6d7a07f Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 12:07:14 +0700
Subject: [PATCH 14/22] ...

---
 modules/common/dap_chain_common.c              |  2 +-
 modules/common/include/dap_chain_common.h      |  2 +-
 modules/net/dap_chain_ledger.c                 |  4 ++--
 modules/net/dap_chain_node_cli_cmd_tx.c        |  4 ++--
 .../xchange/dap_chain_net_srv_xchange.c        | 18 +++++++++++-------
 .../include/dap_chain_net_srv_xchange.h        |  3 +++
 modules/type/blocks/dap_chain_cs_blocks.c      |  2 +-
 modules/type/dag/dap_chain_cs_dag.c            |  6 +++---
 8 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index 2db9542b22..8102252783 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -218,7 +218,7 @@ int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr)
     return memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw));
 }
 
-void s_set_offset_limit_json(json_object * a_json_obj_out, size_t *a_start, size_t *a_and, size_t a_limit, size_t a_offset, size_t a_and_count)
+void dap_chain_set_offset_limit_json(json_object * a_json_obj_out, size_t *a_start, size_t *a_and, size_t a_limit, size_t a_offset, size_t a_and_count)
 {
     json_object* json_obj_lim = json_object_new_object();
     if (a_offset > 0) {
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index 5d538a307d..d22dd40faf 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -224,7 +224,7 @@ int dap_chain_addr_fill_from_key(dap_chain_addr_t *a_addr, dap_enc_key_t *a_key,
 int dap_chain_addr_fill_from_sign(dap_chain_addr_t *a_addr, dap_sign_t *a_sign, dap_chain_net_id_t a_net_id);
 
 int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr);
-void s_set_offset_limit_json(json_object * a_json_obj_out, size_t *a_start, size_t *a_and, size_t a_limit, size_t a_offset, size_t a_and_count);
+void dap_chain_set_offset_limit_json(json_object * a_json_obj_out, size_t *a_start, size_t *a_and, size_t a_limit, size_t a_offset, size_t a_and_count);
 
 DAP_STATIC_INLINE bool dap_chain_addr_compare(const dap_chain_addr_t *a_addr1, const dap_chain_addr_t *a_addr2)
 {
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index af0c71dcfa..17e5ba98e8 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -1956,7 +1956,7 @@ json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, s
     uint32_t l_counter = 0;
     size_t l_arr_start = 0;
     size_t l_arr_end = 0;
-    s_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, HASH_COUNT(l_ledger_pvt->threshold_txs));
+    dap_chain_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, HASH_COUNT(l_ledger_pvt->threshold_txs));
 
     pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock);
     if (a_threshold_hash) {
@@ -2025,7 +2025,7 @@ json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, siz
     dap_ledger_wallet_balance_t *l_balance_item, *l_balance_tmp;
     size_t l_arr_start = 0;
     size_t l_arr_end = 0;
-    s_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, HASH_COUNT(l_ledger_pvt->balance_accounts));
+    dap_chain_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, HASH_COUNT(l_ledger_pvt->balance_accounts));
 
     size_t i_tmp = 0;
     if (a_head)
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index a59d2e279b..8dd7882259 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -346,7 +346,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
     bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
     size_t l_arr_start = 0;
     size_t l_arr_end = 0;
-    s_set_offset_limit_json(json_obj_datum, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
+    dap_chain_set_offset_limit_json(json_obj_datum, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
     
     size_t i_tmp = 0;
     size_t
@@ -779,7 +779,7 @@ json_object *dap_db_history_tx_all(dap_chain_t *a_chain, dap_chain_net_t *a_net,
         json_object * json_tx_history = NULL;        
         size_t l_arr_start = 0;
         size_t l_arr_end = 0;
-        s_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
+        dap_chain_set_offset_limit_json(json_arr_out, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
         
         bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
         // load transactions
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index d1764a4ad6..9e8526a0a7 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2807,7 +2807,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     char ** l_tickers = NULL;
                     size_t l_tickers_count = 0;
                     dap_ledger_addr_get_token_ticker_all( l_net->pub.ledger,NULL,&l_tickers,&l_tickers_count);
-
+                    json_object* json_obj_out = json_object_new_object();
                     size_t l_pairs_count = 0;
                     if(l_tickers){
                         size_t l_arr_start = 0;
@@ -2832,7 +2832,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                             }
 
                         }
-                        json_object_array_add(*json_arr_reply, json_arr_bl_cache_out);
+                        json_object_object_add(json_obj_out, "TICKERS PAIR", json_arr_bl_cache_out);
 
                         // Free tickers array
                         for(size_t i = 0; i< l_tickers_count; i++){
@@ -2840,20 +2840,24 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                         }
                         DAP_DELETE(l_tickers);
                     }
-                    dap_string_prepend_printf( l_reply_str,"Tokens count pair: %zd\n", l_pairs_count);
-                    *a_str_reply = dap_string_free(l_reply_str, false);
+                    json_object_object_add(json_obj_out, "pair count", json_object_new_uint64(l_pairs_count));
+                    json_object_array_add(*json_arr_reply, json_obj_out);
                     break;
                 }
             }
 
             // No subcommand selected
-            dap_cli_server_cmd_set_reply_text(a_str_reply,"Command 'token pair' requires proper subcommand, please read its manual with command 'help srv_xchange'");
+            json_object* json_obj_out = json_object_new_object();
+            json_object_object_add(json_obj_out, "token pair status", json_object_new_string("Command 'token pair' requires proper subcommand," 
+                                                                                        "please read its manual with command 'help srv_xchange'"));
+            json_object_array_add(*json_arr_reply, json_obj_out);
 
         } break;
 
         default: {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command %s not recognized", a_argv[l_arg_index]);
-            return -1;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR,
+                                           "Command %s not recognized", a_argv[l_arg_index]);
+            return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR;
         }
     }
     return 0;
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index bacd683fa2..38b096f207 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -126,6 +126,9 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
+
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR,
 
     XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
     XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 3f03db28c6..316fa93d98 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -919,7 +919,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             json_object* json_arr_bl_cache_out = json_object_new_array();
             size_t l_start_arr = 0;
             size_t l_arr_end = 0;
-            s_set_offset_limit_json(json_arr_bl_cache_out, &l_start_arr, &l_arr_end, l_limit, l_offset, PVT(l_blocks)->blocks_count);
+            dap_chain_set_offset_limit_json(json_arr_bl_cache_out, &l_start_arr, &l_arr_end, l_limit, l_offset, PVT(l_blocks)->blocks_count);
             
             size_t i_tmp = 0;
             dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks;
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index f81527ebc8..756414a057 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -1687,7 +1687,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                         l_objs = dap_global_db_get_all_sync(l_gdb_group_events,&l_objs_count);
                         size_t l_arr_start = 0;
                         size_t l_arr_end = 0;
-                        s_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, l_objs_count);
+                        dap_chain_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, l_objs_count);
                         
                         json_object_object_add(json_obj_event_list,"net name", json_object_new_string(l_net->pub.name));
                         json_object_object_add(json_obj_event_list,"chain", json_object_new_string(l_chain->name));
@@ -1712,7 +1712,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                     pthread_mutex_lock(&PVT(l_dag)->events_mutex);
                     size_t l_arr_start = 0;
                     size_t l_arr_end = 0;
-                    s_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, HASH_COUNT(PVT(l_dag)->events));
+                    dap_chain_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, HASH_COUNT(PVT(l_dag)->events));
                     
                     size_t i_tmp = 0;
                     dap_chain_cs_dag_event_item_t * l_event_item = NULL,*l_event_item_tmp = NULL;
@@ -1752,7 +1752,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                     dap_chain_cs_dag_event_item_t * l_event_item = NULL,*l_event_item_tmp = NULL;
                     size_t l_arr_start = 0;
                     size_t l_arr_end = 0;
-                    s_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, HASH_COUNT(PVT(l_dag)->events_treshold));
+                    dap_chain_set_offset_limit_json(json_arr_obj_event, &l_arr_start, &l_arr_end, l_limit, l_offset, HASH_COUNT(PVT(l_dag)->events_treshold));
 
                     size_t i_tmp = 0;
                     if (l_head){
-- 
GitLab


From 5fe8fa6533bd24a996bfed385f03effed0f0af17 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 15:44:18 +0700
Subject: [PATCH 15/22] ...

---
 .../xchange/dap_chain_net_srv_xchange.c       | 229 +++++++++---------
 1 file changed, 119 insertions(+), 110 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 62f8216664..8075505cb2 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -71,6 +71,7 @@ static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usag
 static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx);
 static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
+static bool s_string_append_tx_cond_info_json( json_object * a_json_out, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_print_prev_hash, bool a_print_status, bool a_print_ts);
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, uint256_t *a_fee, bool a_ret_is_invalid);
 
 static dap_chain_net_srv_xchange_t *s_srv_xchange;
@@ -1203,7 +1204,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
  * @param a_str_reply
  * @return
  */
-static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, json_object * a_json_obj_out)
+static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply)
 {
     enum {
         CMD_NONE, CMD_CREATE, CMD_REMOVE, CMD_UPDATE, CMD_HISTORY, CMD_STATUS
@@ -1230,34 +1231,34 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         case CMD_CREATE: {
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'order create' requires parameter -net");
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'order create' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Command 'order create' requires parameter -net");
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Command 'order create' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_sell", &l_token_sell_str);
             if (!l_token_sell_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR, 
                                                 "Command 'order create' requires parameter -token_sell");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_SELL_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_buy", &l_token_buy_str);
             if (!l_token_buy_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR, 
                                                 "Command 'order create' requires parameter -token_buy");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TOKEN_BUY_ERR;
             }
             if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR, 
                                                 "Token ticker %s not found", l_token_buy_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_PARAM_TICKR_NOTF_ERR;
             }
 
             if (!strcmp(l_token_sell_str, l_token_buy_str)){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR, 
                                                 "token_buy and token_sell must be different!");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_TOKEN_EQUAL_ERR;
             }
@@ -1265,14 +1266,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             const char *l_val_sell_str = NULL, *l_val_rate_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_sell_str);
             if (!l_val_sell_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR, 
                                                 "Command 'order create' requires parameter -value");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_VALUE_ERR;
             }
             uint256_t l_datoshi_sell = dap_chain_balance_scan(l_val_sell_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
             if (!l_val_rate_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR, 
                                                 "Command 'order create' requires parameter -rate");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_RATE_ERR;
             }
@@ -1280,21 +1281,21 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             const char *l_fee_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR, 
                                                 "Command 'order create' requires parameter -fee");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_FEE_ERR;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR, 
                                                 "Command 'order create' requires parameter -w");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_REQ_PARAM_W_ERR;
             }
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             const char* l_sign_str = "";
             if (!l_wallet) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR, 
                                                 "Specified wallet not found");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CRTE_WALLET_NOT_FOUND_ERR;
             } else {
@@ -1305,70 +1306,72 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_chain_wallet_close(l_wallet);
             switch (ret_code) {
                 case XCHANGE_CREATE_ERROR_OK: {
-                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("Successfully created"));
-                    json_object_object_add(a_json_obj_out, "sign", json_object_new_string(l_sign_str));
-                    json_object_object_add(a_json_obj_out, "hash", json_object_new_string(l_hash_ret));
+                    json_object* json_obj_order = json_object_new_object();
+                    json_object_object_add(json_obj_order, "status", json_object_new_string("Successfully created"));
+                    json_object_object_add(json_obj_order, "sign", json_object_new_string(l_sign_str));
+                    json_object_object_add(json_obj_order, "hash", json_object_new_string(l_hash_ret));
+                    json_object_array_add(*a_json_arr_reply, json_obj_order);
                     DAP_DELETE(l_hash_ret);
                     return DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_OK;
                 }
                 case XCHANGE_CREATE_ERROR_INVALID_ARGUMENT: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_INVALID_ARGUMENT, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_INVALID_ARGUMENT, 
                                                 "Some parameters could not be set during a function call");
                     return -XCHANGE_CREATE_ERROR_INVALID_ARGUMENT;
                 }
                 case XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER, 
                                                 "Token ticker %s not found", l_token_sell_str);
                     return -XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER;
                 }
                 case XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER, 
                                                 "Token ticker %s not found", l_token_buy_str);
                     return -XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER;
                 }
                 case XCHANGE_CREATE_ERROR_RATE_IS_ZERO: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_RATE_IS_ZERO, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_RATE_IS_ZERO, 
                                                 "Format -rate n.n = buy / sell (eg: 1.0, 1.135)");
                     return -XCHANGE_CREATE_ERROR_RATE_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_FEE_IS_ZERO: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_FEE_IS_ZERO, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_FEE_IS_ZERO, 
                                                 "Format -value <unsigned integer 256>");
                     return -XCHANGE_CREATE_ERROR_FEE_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO, 
                                                 "Format -value <unsigned integer 256>");
                     return -XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO;
                 }
                 case XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE: {
                     log_it(L_ERROR, "Integer overflow with sum of value and fee");
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE, 
                                                 "Integer overflow with sum of value and fee");
                     return -XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE;
                 }
                 case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET, 
                                                 "%s\nNot enough cash for fee in specified wallet", l_sign_str);
                     return -XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET;
                 }
                 case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET, 
                                                 "%s\nNot enough cash in specified wallet", l_sign_str);
                     return -XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET;
                 }
                 case XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED, 
                                                 "Out of memory");
                     return -XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED;
                 }
                 case XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION, 
                                                 "%s\nCan't compose the conditional transaction", l_sign_str);
                     return -XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION;
                 }
                 case XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL: {
-                    dap_json_rpc_error_add(XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL, 
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL, 
                                                 "%s\nCan't compose the conditional transaction", l_sign_str);
                     return -XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL;
                 }
@@ -1376,15 +1379,16 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         } break;
 
         case CMD_HISTORY:{
+            json_object* l_json_obj_order = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR, 
                                                 "Command 'order history' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR, 
                                                 "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_NET_NOT_FOUND_ERR;
             }
@@ -1396,7 +1400,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_hash_str);
 
             if (!l_order_hash_str && ! l_addr_hash_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR, 
                                                 "Command 'order history' requires parameter -order or -addr" );
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_REQ_PARAM_ORDER_ADDR_ERR;
             }
@@ -1404,32 +1408,33 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             if(l_addr_hash_str){
                 dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_addr_hash_str);
                 if (!l_addr) {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR, "Cannot convert "
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR, "Cannot convert "
                                                                    "string '%s' to binary address.", l_addr_hash_str);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR;
                 }
                 if (dap_chain_addr_check_sum(l_addr) != 0 ) {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR, "Incorrect address wallet");
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR, "Incorrect address wallet");
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR;
                 }
                 if (l_addr->net_id.uint64 != l_net->pub.id.uint64) {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR, "Address %s does not belong to the %s network.",
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR, "Address %s does not belong to the %s network.",
                                                       l_addr_hash_str, l_net->pub.name);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR;
                 }
                 dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_all_for_addr(l_net,l_addr, c_dap_chain_net_srv_xchange_uid );
                 
                 if (l_tx_list){
+                    l_json_obj_order = json_object_new_object();
                     dap_list_t *l_tx_list_temp = l_tx_list;
-                    json_object_object_add(a_json_obj_out, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
+                    json_object_object_add(l_json_obj_order, "Wallet addr hash", json_object_new_string(l_addr_hash_str));
                     while(l_tx_list_temp ){
-                    dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                    s_string_append_tx_cond_info_json(a_json_obj_out, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
-                    l_tx_list_temp = l_tx_list_temp->next;
+                        dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
+                        s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                        l_tx_list_temp = l_tx_list_temp->next;
                     }
                     dap_list_free(l_tx_list);
                 }else{
-                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("No history"));
+                    json_object_object_add(l_json_obj_order, "status", json_object_new_string("No history"));
                 }
                 DAP_DELETE(l_addr);
             }
@@ -1443,28 +1448,29 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                     xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, NULL, NULL, NULL);
                     char *l_tx_hash = dap_chain_hash_fast_to_str_new(&l_order_tx_hash);
                     if(l_tx_type != TX_TYPE_ORDER){
-                        json_object_object_add(a_json_obj_out, "datum status", json_object_new_string("is not order"));
-                        json_object_object_add(a_json_obj_out, "datum hash", json_object_new_string(l_tx_hash));
+                        json_object_object_add(l_json_obj_order, "datum status", json_object_new_string("is not order"));
+                        json_object_object_add(l_json_obj_order, "datum hash", json_object_new_string(l_tx_hash));
                     } else {
                         int l_rc = s_tx_check_for_open_close(l_net,l_tx);
                         if(l_rc == 0){
-                            json_object_object_add(a_json_obj_out, "WRONG TX", json_object_new_string(l_tx_hash));
+                            json_object_object_add(l_json_obj_order, "WRONG TX", json_object_new_string(l_tx_hash));
                         }else{
-                            json_object_object_add(a_json_obj_out, "history for order", json_object_new_string(l_order_hash_str));
+                            json_object_object_add(l_json_obj_order, "history for order", json_object_new_string(l_order_hash_str));
                             dap_list_t *l_tx_list = dap_chain_net_get_tx_cond_chain(l_net, &l_order_tx_hash, c_dap_chain_net_srv_xchange_uid );
                             dap_list_t *l_tx_list_temp = l_tx_list;
                             while(l_tx_list_temp ){
                                 dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
-                                s_string_append_tx_cond_info_json(a_json_obj_out, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                                s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false);
                                 l_tx_list_temp = l_tx_list_temp->next;
                             }
                             dap_list_free(l_tx_list);
                         }
                     }
                 }else{
-                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("No history"));
+                    json_object_object_add(l_json_obj_order, "status", json_object_new_string("No history"));
                 }
             }
+            json_object_array_add(*a_json_arr_reply, l_json_obj_order);
         } break;
 
         case CMD_REMOVE:
@@ -1473,19 +1479,19 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             const char * l_fee_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR, "Command 'order %s' requires parameter -net",
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR, "Command 'order %s' requires parameter -net",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR, 
                                                                             "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR, 
                                                                             "Command 'order %s' requires parameter -w",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR;
@@ -1493,7 +1499,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             const char* l_sign_str = "";
             if (!l_wallet) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR,
                                                                             "Specified wallet not found");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_WALLET_NOT_FOUND_ERR;
             } else {
@@ -1501,14 +1507,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR, 
                                                                             "Command 'order %s' requires parameter -order",
                                                                 l_cmd_num == CMD_REMOVE ? "remove" : "update");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_ORDER_ADDR_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR, 
                                                                             "Command 'order %s' requires parameter -fee",
                                                   l_cmd_num == CMD_REMOVE ? "remove" : "update");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_FEE_ERR;
@@ -1519,30 +1525,33 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             char *l_tx_hash_ret = NULL;
             int l_ret_code = dap_chain_net_srv_xchange_remove(l_net, &l_tx_hash, l_fee, l_wallet, &l_tx_hash_ret);
             dap_chain_wallet_close(l_wallet);
+            
             switch (l_ret_code) {
                 case XCHANGE_REMOVE_ERROR_OK:
-                    json_object_object_add(a_json_obj_out, "status", json_object_new_string("Order successfully removed"));
-                    json_object_object_add(a_json_obj_out, "Created inactivate tx with hash", json_object_new_string(l_tx_hash_ret));
+                    json_object* json_obj_order = json_object_new_object();
+                    json_object_object_add(json_obj_order, "status", json_object_new_string("Order successfully removed"));
+                    json_object_object_add(json_obj_order, "Created inactivate tx with hash", json_object_new_string(l_tx_hash_ret));
+                    json_object_array_add(*a_json_arr_reply, json_obj_order);
                     DAP_DELETE(l_tx_hash_ret);
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX:
-                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX, "%s\nSpecified order not found", l_sign_str);
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX, "%s\nSpecified order not found", l_sign_str);
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE:
-                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE, "%s\nCan't create price object from order", l_sign_str);
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE, "%s\nCan't create price object from order", l_sign_str);
                     break;
                 case XCHANGE_REMOVE_ERROR_FEE_IS_ZERO:
-                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_FEE_IS_ZERO, "Can't get fee value.");
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_REMOVE_ERROR_FEE_IS_ZERO, "Can't get fee value.");
                     break;
                 case XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX: {
                     dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
                     dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_fee, false);
                     const char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_price->tx_hash);
-                    dap_json_rpc_error_add(XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX, "Can't create invalidate transaction from: %s\n", l_final_tx_hash_str);
+                    dap_json_rpc_error_add(*a_json_arr_reply, XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX, "Can't create invalidate transaction from: %s\n", l_final_tx_hash_str);
                     DAP_DELETE(l_price);
                 } break;
                 default:
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_UNKNOWN_ERR, "An error occurred with an unknown code: %d.", l_ret_code);
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_UNKNOWN_ERR, "An error occurred with an unknown code: %d.", l_ret_code);
                     break;
             }
             return l_ret_code;
@@ -1551,20 +1560,20 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         case CMD_STATUS: {
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR, 
                                                             "Command 'order status' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_NET_ERR;
             }
             l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR, 
                                                             "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_NET_NOT_FOUND_ERR;
             }
             const char * l_order_hash_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR, 
                                                             "Command 'order status' requires parameter -order or -addr" );
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_REQ_PARAM_ORDER_ADDR_ERR;
             }
@@ -1572,14 +1581,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_order_tx_hash);
             dap_chain_datum_tx_t * l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order_tx_hash);
             if (!l_tx){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR, 
                                                             "Can't find order %s", l_order_hash_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_ORDER_ERR;
             }
 
             dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL);
             if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR, 
                                                             "It's not an order");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_ITS_NOT_ORDER_ERR;
             }
@@ -1587,7 +1596,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             // TODO add filters to list (tokens, network, etc.)
             dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_tx, NULL, true);
             if( !l_price ){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR, 
                                                             "Can't get price from order");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_PRICE_ERR;
             }
@@ -1597,14 +1606,14 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             char* l_status_order = NULL;
             dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
             if( dap_hash_fast_is_blank(&l_last_tx_hash) ){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR, 
                                                             "Can't get last tx cond hash from order");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_GET_LAST_TX_ERR;
             }
 
             dap_chain_datum_tx_t * l_last_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_last_tx_hash);
             if (!l_last_tx){
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR, 
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR, 
                                                             "Can't find last tx");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_STATUS_CANT_FIND_LAST_TX_ERR;
             }
@@ -1636,28 +1645,30 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_tx->header.ts_created);
             if (l_out_cond_last_tx)
                 l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str);
+            
+            json_object* json_obj_order = json_object_new_object();
 
-            json_object_object_add(a_json_obj_out, "orderHash", json_object_new_string(dap_chain_hash_fast_to_str_static(&l_tx_hash)));
-            json_object_object_add(a_json_obj_out, "ts_created", json_object_new_string(l_tmp_buf));
-            json_object_object_add(a_json_obj_out, "status", json_object_new_string(l_status_order));
-            json_object_object_add(a_json_obj_out, "amount coins", l_amount_coins_str ? json_object_new_string(l_amount_coins_str) 
+            json_object_object_add(json_obj_order, "orderHash", json_object_new_string(dap_chain_hash_fast_to_str_static(&l_tx_hash)));
+            json_object_object_add(json_obj_order, "ts_created", json_object_new_string(l_tmp_buf));
+            json_object_object_add(json_obj_order, "status", json_object_new_string(l_status_order));
+            json_object_object_add(json_obj_order, "amount coins", l_amount_coins_str ? json_object_new_string(l_amount_coins_str) 
                                                                                 : json_object_new_string("0.0"));
-            json_object_object_add(a_json_obj_out, "amount datoshi", l_amount_datoshi_str ? json_object_new_string(l_amount_datoshi_str) 
+            json_object_object_add(json_obj_order, "amount datoshi", l_amount_datoshi_str ? json_object_new_string(l_amount_datoshi_str) 
                                                                                 : json_object_new_string("0"));
-            json_object_object_add(a_json_obj_out, "token", json_object_new_string(l_price->token_sell));
+            json_object_object_add(json_obj_order, "token", json_object_new_string(l_price->token_sell));
             char *l_filled = dap_strdup_printf("%lu%%", l_percent_completed);
-            json_object_object_add(a_json_obj_out, "filled", json_object_new_string(l_filled));
+            json_object_object_add(json_obj_order, "filled", json_object_new_string(l_filled));
             DAP_DELETE(l_filled);
-            json_object_object_add(a_json_obj_out, "rate token", json_object_new_string(l_price->token_buy));
-            json_object_object_add(a_json_obj_out, "rate", json_object_new_string(l_cp_rate));
-            json_object_object_add(a_json_obj_out, "net", json_object_new_string(l_price->net->pub.name));
-            
+            json_object_object_add(json_obj_order, "rate token", json_object_new_string(l_price->token_buy));
+            json_object_object_add(json_obj_order, "rate", json_object_new_string(l_cp_rate));
+            json_object_object_add(json_obj_order, "net", json_object_new_string(l_price->net->pub.name));
+            json_object_array_add(*a_json_arr_reply, json_obj_order);
             DAP_DEL_Z(l_cp_rate);
             DAP_DEL_Z(l_price);
         } break;
 
         default: {
-            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR, 
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR, 
                                                             "Subcommand %s not recognized", a_argv[a_arg_index]);
             return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_SUB_NOT_FOUND_ERR;
         }
@@ -1966,7 +1977,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
  * @param a_net
  * @param a_tx
  */
-static bool s_string_append_tx_cond_info_json( dap_string_t * a_json_out,
+static bool s_string_append_tx_cond_info_json( json_object * a_json_out,
                                          dap_chain_net_t * a_net,
                                          dap_chain_datum_tx_t * a_tx,
                                          tx_opt_status_t a_filter_by_status,
@@ -2216,9 +2227,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
     switch (l_cmd_num) {
         case CMD_ORDER: {
-            json_object* json_obj_order = json_object_new_object();
-            int res = s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, json_obj_order);
-            json_object_array_add(*json_arr_reply, json_obj_order);
+            int res = s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, *json_arr_reply);
             return res;
         }
         case CMD_ORDERS: {
@@ -2227,12 +2236,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             l_arg_index++;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'orders' requires parameter -net");
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR, "Command 'orders' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_NET_NOT_FOUND_ERR;
             }
             //dap_string_t *l_reply_str = dap_string_new("");
@@ -2255,7 +2264,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 else if ( dap_strcmp (l_status_str, "all") == 0 )
                     l_opt_status = 0;
                 else  {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR, "Unrecognized '-status %s'", l_status_str);
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR, "Unrecognized '-status %s'", l_status_str);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_UNREC_STATUS_ERR;
                 }
             }
@@ -2266,7 +2275,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if(l_token_from_str){
                 dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
                 if(!l_token_from_datum){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR, 
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR, 
                                             "Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_FROM_ERR;
                 }
@@ -2276,7 +2285,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if(l_token_to_str){
                 dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
                 if(!l_token_to_datum){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR, 
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR, 
                                             "Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_CANT_FIND_TOKEN_TO_ERR;
                 }
@@ -2388,40 +2397,40 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             l_arg_index++;            
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR, "Command 'purchase' requires parameter -net");
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR, "Command 'purchase' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if (!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR, "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_NET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR, "Command 'purchase' requires parameter -w");
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR, "Command 'purchase' requires parameter -w");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_W_ERR;
             }
             dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
             if (!l_wallet) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR, "Specified wallet not found");
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR, "Specified wallet not found");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_WALLET_NOT_FOUND_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
             if (!l_order_hash_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR, 
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR, 
                                             "Command 'purchase' requires parameter -order");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_ORDER_ERR;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_buy_str);
             if (!l_val_buy_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR, 
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR, 
                                             "Command 'purchase' requires parameter -value");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_VALUE_ERR;
             }
             uint256_t l_datoshi_buy = dap_chain_balance_scan(l_val_buy_str);
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_val_fee_str);
             if (!l_val_fee_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR, 
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR, 
                                             "Command 'purchase' requires parameter -fee");
                 return  -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_REQ_PARAM_FEE_ERR;
             }
@@ -2441,19 +2450,19 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     return 0;
                 }
                 case XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND: {
-                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND,"Specified order not found");
+                    dap_json_rpc_error_add(*json_arr_reply, XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND,"Specified order not found");
                     return -XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND;
                 }
                 case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE: {
-                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE, "Can't create price from order");
+                    dap_json_rpc_error_add(*json_arr_reply, XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE, "Can't create price from order");
                     return -XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE;
                 }
                 case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX: {
-                    dap_json_rpc_error_add(XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX, "Exchange transaction error");
+                    dap_json_rpc_error_add(*json_arr_reply, XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX, "Exchange transaction error");
                     return -XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX;
                 }
                 default: {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR, 
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR, 
                                                                 "An error occurred with an unknown code: %d.", l_ret_code);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PURCHASE_UNKNOWN_ERR;
                 }
@@ -2497,20 +2506,20 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 else if ( dap_strcmp (l_status_str, "all") == 0 )
                     l_opt_status = TX_STATUS_ALL;
                 else  {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR, 
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR, 
                                                                 "Unrecognized '-status %s'", l_status_str);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_UNREC_STATUS_ERR;
                 }
             }
 
             if(!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR, 
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR, 
                                                                 "Command 'tx_list' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if(!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR, 
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR, 
                                                                 "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_LIST_NET_NOT_FOUND_ERR;
             }
@@ -2523,7 +2532,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             if ( l_addr_str )
             {
                 if ( !(l_addr = dap_chain_addr_from_str(l_addr_str)) ) {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_LIST_CAN_NOT_CONVERT_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_LIST_CAN_NOT_CONVERT_ERR,
                                            "Cannot convert -addr '%s' to internal representative", l_addr_str);
                     return -EINVAL;
                 }
@@ -2571,13 +2580,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             const char *l_net_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if(!l_net_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR,
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR,
                                        "Command 'token_pair' requires parameter -net");
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_REQ_PARAM_NET_ERR;
             }
             dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
             if(!l_net) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR,
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR,
                                        "Network %s not found", l_net_str);
                 return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_NET_NOT_FOUND_ERR;
             }
@@ -2592,13 +2601,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 const char * l_token_from_str = NULL;
                 dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_from", &l_token_from_str);
                 if(!l_token_from_str){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR,
                                            "No argument '-token_from'");
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ARG_ERR;
                 }
                 dap_chain_datum_token_t * l_token_from_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_from_str);
                 if(!l_token_from_datum){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
                                            "Can't find \"%s\" token in network \"%s\" for argument '-token_from' ", l_token_from_str, l_net->pub.name);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR;
                 }
@@ -2607,13 +2616,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 const char * l_token_to_str = NULL;
                 dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_to", &l_token_to_str);
                 if(!l_token_to_str){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
                                            "No argument '-token_to'");
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR;
                 }
                 dap_chain_datum_token_t * l_token_to_datum = dap_ledger_token_ticker_check( l_net->pub.ledger, l_token_to_str);
                 if(!l_token_to_datum){
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
                                            "Can't find \"%s\" token in network \"%s\" for argument '-token_to' ", l_token_to_str, l_net->pub.name);
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR;
                 }
@@ -2716,7 +2725,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     size_t l_datum_num = dap_list_length(l_datum_list0);
 
                     if (l_datum_num == 0){
-                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
                                            "Can't find transactions");
                         return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR;
                     }
@@ -2778,7 +2787,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     break;
 
                 } else {
-                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
                                            "Unrecognized subcommand '%s'", l_price_subcommand);                    
                     return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR;
                 }
@@ -2845,7 +2854,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
         } break;
 
         default: {
-            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR,
+            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR,
                                            "Command %s not recognized", a_argv[l_arg_index]);
             return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR;
         }
-- 
GitLab


From 7970ab9dabdfb21866cb2641e665029a3e979622 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 16:06:53 +0700
Subject: [PATCH 16/22] ...

---
 .../service/xchange/dap_chain_net_srv_xchange.c  |  3 ++-
 .../xchange/include/dap_chain_net_srv_xchange.h  | 16 ++--------------
 2 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 8075505cb2..a6bb075c43 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1477,6 +1477,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
         {
             const char * l_order_hash_str = NULL;
             const char * l_fee_str = NULL;
+            json_object* json_obj_order = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
                 dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR, "Command 'order %s' requires parameter -net",
@@ -1528,7 +1529,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
             
             switch (l_ret_code) {
                 case XCHANGE_REMOVE_ERROR_OK:
-                    json_object* json_obj_order = json_object_new_object();
+                    json_obj_order = json_object_new_object();
                     json_object_object_add(json_obj_order, "status", json_object_new_string("Order successfully removed"));
                     json_object_object_add(json_obj_order, "Created inactivate tx with hash", json_object_new_string(l_tx_hash_ret));
                     json_object_array_add(*a_json_arr_reply, json_obj_order);
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 38b096f207..2ddd96d1e3 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -128,20 +128,8 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
 
-    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_UNKNOWN_COMMAND_ERR
 
-    XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
-    XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
-    XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER,
-    XCHANGE_CREATE_ERROR_RATE_IS_ZERO,
-    XCHANGE_CREATE_ERROR_FEE_IS_ZERO,
-    XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO,
-    XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE,
-    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET,
-    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET,
-    XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
-    XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
-    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL
 } s_com_net_srv_xchange_err_t;
 
 typedef enum dap_chain_net_srv_xchange_create_error_list{
@@ -157,7 +145,7 @@ typedef enum dap_chain_net_srv_xchange_create_error_list{
     XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET,
     XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
     XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
-    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL,
+    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL
 } dap_chain_net_srv_xchange_create_error_t;
 dap_chain_net_srv_xchange_create_error_t dap_chain_net_srv_xchange_create(dap_chain_net_t *a_net, const char *a_token_buy,
                                      const char *a_token_sell, uint256_t a_datoshi_sell,
-- 
GitLab


From a3d7aeafeb9c80bfb5225aef33bed644b38dd44a Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 16:45:06 +0700
Subject: [PATCH 17/22] sub update

---
 dap-sdk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dap-sdk b/dap-sdk
index 9dcfc3fb33..201eed01ce 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 9dcfc3fb330cb79e55c3753c23e5b41e6d8be294
+Subproject commit 201eed01ceb2b87eac89f3f810ac73380ffe435c
-- 
GitLab


From 2648b6e5e1e9abb0b8b8119462dbf0e15e109fe7 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 17:43:57 +0700
Subject: [PATCH 18/22] ...

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index a6bb075c43..af6fd590a7 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2228,7 +2228,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
     switch (l_cmd_num) {
         case CMD_ORDER: {
-            int res = s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, *json_arr_reply);
+            int res = s_cli_srv_xchange_order(a_argc, a_argv, l_arg_index + 1, json_arr_reply);
             return res;
         }
         case CMD_ORDERS: {
-- 
GitLab


From f2f43a73af7b2f7526012b9568b45a45f77722a9 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 22 Oct 2024 17:52:20 +0700
Subject: [PATCH 19/22] ...

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index af6fd590a7..b671e081a6 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2379,7 +2379,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                                 json_object_new_string(l_amount_datoshi_str) : 
                                                 json_object_new_string("0"));
                 json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_price->token_sell));
-                json_object_object_add(json_obj_orders, "filled", json_object_new_string(l_percent_completed));
+                json_object_object_add(json_obj_orders, "filled", json_object_new_uint64(l_percent_completed));
                 json_object_object_add(json_obj_orders, "token buy", json_object_new_string(l_price->token_buy));
                 json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_price->token_sell));
                 json_object_object_add(json_obj_orders, "balance rate", json_object_new_string(l_price->token_sell));
-- 
GitLab


From 57e4abea1854b85db7e8794cb502675d0198b3b5 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Thu, 16 Jan 2025 18:43:35 +0700
Subject: [PATCH 20/22] ...

---
 .../service/stake/dap_chain_net_srv_stake_pos_delegate.c    | 2 +-
 modules/service/xchange/dap_chain_net_srv_xchange.c         | 6 +++---
 modules/service/xchange/include/dap_chain_net_srv_xchange.h | 2 ++
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index 581c26b64c..2d6760c62d 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -3514,7 +3514,7 @@ static json_object* s_dap_chain_net_srv_stake_reward_all(json_object* a_json_arr
 
     size_t l_arr_start = 0;
     size_t l_arr_end = 0;
-    s_set_offset_limit_json(json_obj_reward, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
+    dap_chain_set_offset_limit_json(json_obj_reward, &l_arr_start, &l_arr_end, a_limit, a_offset, a_chain->callback_count_tx(a_chain));
 
     if (a_node_info){
         json_object* json_obj_addr = json_object_new_object();
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 2f3e158267..e4d27f9372 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -120,7 +120,7 @@ static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usag
 static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
 
 static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx);
-static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
+static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
 static bool s_string_append_tx_cond_info_json( json_object * a_json_out, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_print_prev_hash, bool a_print_status, bool a_print_ts);
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, dap_hash_fast_t *a_order_hash, uint256_t *a_fee, bool a_ret_is_invalid);
 static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chan_ledger_notify_opcodes_t a_opcode);
@@ -1523,7 +1523,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                             if (!l_item)
                                 continue;
                         }
-                        if (s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false))
+                        if (s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_datum_tx, TX_STATUS_ALL, true, true, false))
                             l_total++;
                     }
                     dap_chain_wallet_cache_iter_delete(l_iter);
@@ -1547,7 +1547,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                             dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
                             dap_hash_fast_t l_hash = {};
                             dap_hash_fast(l_tx_cur, dap_chain_datum_tx_get_size(l_tx_cur), &l_hash);
-                            if (s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false))
+                            if (s_string_append_tx_cond_info_json(l_json_obj_order, l_net, l_tx_cur, TX_STATUS_ALL, true, true, false))
                                 l_total++;
                             l_tx_list_temp = l_tx_list_temp->next;
                         }
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index a04e142b69..7295c0ea2f 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -86,6 +86,7 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_CAN_NOT_CONVERT_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_INCORRECT_ADDR_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NOT_BELONG_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NO_HISTORY_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_NET_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_NET_NOT_FOUND_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_RMOVE_REQ_PARAM_W_ERR,    
@@ -124,6 +125,7 @@ typedef enum s_com_net_srv_xchange_err{
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_FROM_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_TOKEN_TO_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TOKEN_ERR,
+    DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_ORDER_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_CANT_FIND_TX_ERR,
     DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_PAIR_UNKNOWN_ERR,
 
-- 
GitLab


From 68967186d4b0ca002d5df9a999d7760f49b2a0ba Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Thu, 16 Jan 2025 18:48:11 +0700
Subject: [PATCH 21/22] sub update

---
 dap-sdk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dap-sdk b/dap-sdk
index 201eed01ce..34c35f6428 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 201eed01ceb2b87eac89f3f810ac73380ffe435c
+Subproject commit 34c35f6428e8a0e5e3fe4cc6678ecbfab00012d5
-- 
GitLab


From 5aa71d2a63f3331d62c2964acf95c6e1097de920 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Fri, 17 Jan 2025 19:43:27 +0700
Subject: [PATCH 22/22] ...

---
 dap-sdk                                             |  2 +-
 modules/service/xchange/dap_chain_net_srv_xchange.c | 13 ++++++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index 34c35f6428..17c74e6b7f 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 34c35f6428e8a0e5e3fe4cc6678ecbfab00012d5
+Subproject commit 17c74e6b7fa113bfdc051fd29fdb5db110775454
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index e4d27f9372..8ff1a56bc8 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -239,7 +239,7 @@ int dap_chain_net_srv_xchange_init()
 
     "srv_xchange token_pair -net <net_name> list all [-limit <limit>] [-offset <offset>]\n"
         "\tList of all token pairs\n"
-    "srv_xchange token_pair -net <net_name> rate average -token_from <token_ticker> -token_to <token_ticker>\n"
+    "srv_xchange token_pair -net <net_name> rate average [-time_from <From_time>] [-time_to <To_time>]\n"
         "\tGet average rate for token pair <token from>:<token to> from <From time> to <To time> \n"
     "srv_xchange token_pair -net <net_name> rate history -token_from <token_ticker> -token_to <token_ticker> [-time_from <From_time>] [-time_to <To_time>] [-limit <limit>] [-offset <offset>]\n"
         "\tPrint rate history for token pair <token from>:<token to> from <From time> to <To time>\n"
@@ -2562,9 +2562,10 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             size_t l_arr_start = 0;            
             size_t l_arr_end = 0;
             json_object* json_obj_order = json_object_new_object();
-            dap_chain_set_offset_limit_json(json_obj_order, &l_arr_start, &l_arr_end, l_limit, l_offset, dap_list_length(l_list));
-            size_t i_tmp = 0;
             json_object* json_arr_orders_out = json_object_new_array();
+            dap_chain_set_offset_limit_json(json_arr_orders_out, &l_arr_start, &l_arr_end, l_limit, l_offset, dap_list_length(l_list));
+            size_t i_tmp = 0;
+            
             // Print all txs
             for (dap_list_t *it = l_list; it; it = it->next) {
                 dap_chain_datum_tx_t *l_tx = NULL;
@@ -2793,10 +2794,16 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
             }
         } break;
         case CMD_ENABLE: {
+            json_object* json_obj_orders_enable = json_object_new_object();
             s_srv_xchange->enabled = true;
+            json_object_object_add(json_obj_orders_enable, "status", json_object_new_string("enable"));
+            json_object_array_add(*json_arr_reply, json_obj_orders_enable);
         } break;
         case CMD_DISABLE: {
+            json_object* json_obj_orders_enable = json_object_new_object();
             s_srv_xchange->enabled = false;
+            json_object_object_add(json_obj_orders_enable, "status", json_object_new_string("disable"));
+            json_object_array_add(*json_arr_reply, json_obj_orders_enable);
         } break;
         case CMD_TX_LIST: {
             const char *l_net_str = NULL, *l_time_begin_str = NULL, *l_time_end_str = NULL;
-- 
GitLab