From b518ef77d8a1cfec330eb794db09ca6c460361f9 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 28 Jan 2025 07:32:30 +0000
Subject: [PATCH] Feature 13329

---
 dap-sdk                                     |   2 +-
 modules/net/srv/dap_chain_net_srv.c         | 291 ++++++++++----------
 modules/net/srv/dap_chain_net_srv_order.c   |  47 ++--
 modules/net/srv/include/dap_chain_net_srv.h |  43 +++
 4 files changed, 224 insertions(+), 159 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index db40377b1d..2f34b05c0f 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit db40377b1d32d141e4e59bf0fa830a6b462fd9c2
+Subproject commit 2f34b05c0f69e859315913608937eaf2b101986d
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 269046c9cc..f0a757bc49 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -181,31 +181,32 @@ void dap_chain_net_srv_deinit(void)
  */
 static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
 {
+    json_object **json_arr_reply = (json_object **)a_str_reply;
     int arg_index = 1;
-    dap_chain_net_t * l_net = NULL;
-
+    dap_chain_net_t * l_net = NULL;    
     const char * l_hash_out_type = NULL;
     dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-H", &l_hash_out_type);
     if(!l_hash_out_type)
         l_hash_out_type = "hex";
     if(dap_strcmp(l_hash_out_type, "hex") && dap_strcmp(l_hash_out_type, "base58")) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
-        return -1;
+        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_HASH_ERR, "invalid parameter -H, valid values: -H <hex | base58>");
+        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_HASH_ERR;
     }
 
-
     int l_report = dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "report", NULL);
     if (l_report) {
+        json_object* json_obj_net_srv = json_object_new_object();
         char *l_report_str = dap_stream_ch_chain_net_srv_create_statistic_report();
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_report_str);
-        DAP_DEL_Z(l_report_str);
-        return 0;
+        json_object_object_add(json_obj_net_srv, "report", json_object_new_string(l_report_str));
+        DAP_DELETE(l_report_str);
+
+        json_object_array_add(*json_arr_reply, json_obj_net_srv);
+        return DAP_CHAIN_NET_SRV_CLI_COM_ORDER_OK;
     }
 
-    int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain( &arg_index, argc, argv, a_str_reply, NULL, &l_net,
-                                                               CHAIN_TYPE_INVALID);
+    int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*json_arr_reply, &arg_index, argc, argv, NULL, &l_net, CHAIN_TYPE_INVALID);
+    json_object* json_obj_net_srv = NULL;
     if ( l_net ) {
-        dap_string_t *l_string_ret = dap_string_new("");
 
         const char *l_order_str = NULL;
         dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "order", &l_order_str);
@@ -258,47 +259,44 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
         dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-units", &l_units_str);
 
         if (l_order_str){
-            char *l_order_hash_hex_str = NULL;
-            char *l_order_hash_base58_str = NULL;
+            char l_order_hash_hex_str[128] = "", l_order_hash_base58_str[128] = "";
             // datum hash may be in hex or base58 format
             if (l_order_hash_str) {
                 if(!dap_strncmp(l_order_hash_str, "0x", 2) || !dap_strncmp(l_order_hash_str, "0X", 2)) {
-                    l_order_hash_hex_str = dap_strdup(l_order_hash_str);
-                    l_order_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
+                    dap_strncpy(l_order_hash_hex_str, l_order_hash_str, sizeof(l_order_hash_hex_str));
+                    char *l_tmp = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
+                    dap_strncpy(l_order_hash_base58_str, l_tmp, sizeof(l_order_hash_base58_str));
+                    DAP_DELETE(l_tmp);
                 } else {
-                    l_order_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
-                    l_order_hash_base58_str = dap_strdup(l_order_hash_str);
+                    char *l_tmp = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
+                    dap_strncpy(l_order_hash_hex_str, l_tmp, sizeof(l_order_hash_hex_str));
+                    DAP_DELETE(l_tmp);
+                    dap_strncpy(l_order_hash_base58_str, l_order_hash_str, sizeof(l_order_hash_base58_str));
                 }
             }
-            if(l_continent_str && l_continent_num <= 0) {
+            if(l_continent_str && l_continent_num <= 0) {         
                 dap_string_t *l_string_err = dap_string_new("Unrecognized \"-continent\" option=");
                 dap_string_append_printf(l_string_err, "\"%s\". Variants: ", l_continent_str);
-                int i = 0;
-                while(1) {
-                    const char *l_continent = dap_chain_net_srv_order_continent_to_str(i);
-                    if(!l_continent)
-                        break;
-                    if(!i)
-                        dap_string_append_printf(l_string_err, "\"%s\"", l_continent);
-                    else
-                        dap_string_append_printf(l_string_err, ", \"%s\"", l_continent);
-                    i++;
-                }
-                dap_string_append_printf(l_string_ret, "%s\n", l_string_err->str);
+                int i;
+                for (i = 0; i < (int)dap_chain_net_srv_order_continents_count() - 1; ++i)
+                    dap_string_append_printf(l_string_err, "\"%s\", ", dap_chain_net_srv_order_continent_to_str(i));
+                dap_string_append_printf(l_string_err, "\"%s\"", dap_chain_net_srv_order_continent_to_str(i));
+
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CONT_ERR, "%s\n", l_string_err->str);
                 dap_string_free(l_string_err, true);
-                l_ret = -1;
-            } else if(!dap_strcmp(l_order_str, "update")) {
+                l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CONT_ERR;
+            } else if (!dap_strcmp(l_order_str, "update")) {
                 if (!l_order_hash_str) {
-                    l_ret = -1;
-                    dap_string_append(l_string_ret, "Can't find option '-hash'\n");
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_ERR, "Can't find option '-hash'\n");
+                    l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_ERR;
                 } else {
                     dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str);
                     if(!l_order) {
                         l_ret = -2;
                         if(!dap_strcmp(l_hash_out_type,"hex"))
-                            dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_hex_str);
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_HASH_ERR, "Can't find order with hash %s\n", l_order_hash_hex_str);
                         else
-                            dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_base58_str);
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_HASH_ERR, "Can't find order with hash %s\n", l_order_hash_base58_str);
                     } else {
                         if (l_ext) {
                             l_order->ext_size = strlen(l_ext) + 1;
@@ -308,33 +306,31 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                             memcpy(l_order->ext_n_sign, l_ext, l_order->ext_size);
                         } else
                             dap_chain_net_srv_order_set_continent_region(&l_order, l_continent_num, l_region_str);
-                        /*if(l_region_str) {
-                            strncpy(l_order->region, l_region_str, dap_min(sizeof(l_order->region) - 1, strlen(l_region_str) + 1));
-                        }
-                        if(l_continent_num>=0)
-                            l_order->continent = l_continent_num;*/
                         char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order, false);
                         if (l_new_order_hash_str) {
-                            const char *l_cert_str = NULL;
+                            /*const char *l_cert_str = NULL;
                             dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-cert", &l_cert_str);
                             if (!l_cert_str) {
-                                dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee order creation requires parameter -cert");
-                                DAP_DEL_MULTY(l_new_order_hash_str, l_order_hash_hex_str, l_order_hash_base58_str, l_order);
-                                return -7;
+                                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_PARAM_CERT_ERR, "Fee order creation requires parameter -cert");
+                                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_PARAM_CERT_ERR;
                             }
                             dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
                             if (!l_cert) {
-                                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str);
+                                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_LOAD_CERT_ERR, "Can't load cert %s", l_cert_str);
                                 DAP_DEL_MULTY(l_new_order_hash_str, l_order_hash_hex_str, l_order_hash_base58_str, l_order);
-                                return -8;
+                                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_LOAD_CERT_ERR;
                             }
+                            */ // WTF is this? ^^^
                             // delete prev order
                             if(dap_strcmp(l_new_order_hash_str, l_order_hash_hex_str))
                                 dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str);
                             DAP_DELETE(l_new_order_hash_str);
-                            dap_string_append_printf(l_string_ret, "order updated\n");
-                        } else
-                            dap_string_append_printf(l_string_ret, "Order did not updated\n");
+                            json_obj_net_srv = json_object_new_object();
+                            json_object_object_add(json_obj_net_srv, "status", json_object_new_string("updated"));
+                        } else {
+                            json_obj_net_srv = json_object_new_object();
+                            json_object_object_add(json_obj_net_srv, "status", json_object_new_string("not updated"));
+                        }
                         DAP_DELETE(l_order);
                     }
                 }
@@ -374,17 +370,17 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                         l_direction = SERV_DIR_SELL;
                     else if (!strcmp(l_direction_str, "buy"))
                         l_direction = SERV_DIR_BUY;
-                    else {
-                        dap_string_free(l_string_ret, true);
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong direction of the token was "
+                    else {                        
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_PARAM_CERT_ERR, "Wrong direction of the token was "
                                                                        "specified, possible directions: buy, sell.");
-                        return -18;
+                        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_PARAM_CERT_ERR;
                     }
                 }
 
                 if (l_srv_uid_str && dap_id_uint64_parse(l_srv_uid_str ,&l_srv_uid.uint64)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
-                    return -21;
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_HEX_ERR,
+                                                                        "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
+                    return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_HEX_ERR;
                 }
 
                 if ( l_price_min_str )
@@ -402,30 +398,38 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                                                         l_price_min, l_price_max,
                                                         &l_orders, &l_orders_num) )
                 {
-                    dap_string_append_printf(l_string_ret, "Found %zu orders:\n", l_orders_num);
+                    json_obj_net_srv = json_object_new_object();
+                    json_object_object_add(json_obj_net_srv, "count", json_object_new_uint64(l_orders_num));
+                    json_object* json_arr_out = json_object_new_array();
                     for (dap_list_t *l_temp = l_orders; l_temp; l_temp = l_temp->next){
+                        json_object* json_obj_order = json_object_new_object();
                         dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t*)l_temp->data;
-                        dap_chain_net_srv_order_dump_to_string(l_order, l_string_ret, l_hash_out_type, l_net->pub.native_ticker);
-                        dap_string_append(l_string_ret,"\n");
+                        dap_chain_net_srv_order_dump_to_json(l_order, json_obj_order, l_hash_out_type, l_net->pub.native_ticker);
+                        json_object_array_add(json_arr_out, json_obj_order);
                     }
+                    json_object_object_add(json_obj_net_srv, "orders", json_arr_out);
                     l_ret = 0;
                     dap_list_free_full(l_orders, NULL);
-                } else {
-                    l_ret = -5 ;
-                    dap_string_append(l_string_ret,"Can't get orders: some internal error or wrong params\n");
+                } else {                    
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_CANT_GET_ERR, "Can't get orders: some internal error or wrong params");
+                    l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_CANT_GET_ERR ;
                 }
             } else if(!dap_strcmp( l_order_str, "dump" )) {
                 // Select with specified service uid
                 if ( l_order_hash_str ){
-                    dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash_str( l_net, l_order_hash_hex_str );                    if (l_order) {
-                        dap_chain_net_srv_order_dump_to_string(l_order,l_string_ret, l_hash_out_type, l_net->pub.native_ticker);
+                    dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash_str( l_net, l_order_hash_hex_str );
+                    json_obj_net_srv = json_object_new_object();                    
+                    if (l_order) {
+                        dap_chain_net_srv_order_dump_to_json(l_order, json_obj_net_srv, l_hash_out_type, l_net->pub.native_ticker);
                         l_ret = 0;
-                    }else{
-                        l_ret = -7 ;
+                    }else{                        
                         if(!dap_strcmp(l_hash_out_type,"hex"))
-                            dap_string_append_printf(l_string_ret,"Can't find order with hash %s\n", l_order_hash_hex_str );
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DUMP_CANT_FIND_ERR,
+                                                        "Can't find order with hash %s\n", l_order_hash_hex_str );
                         else
-                            dap_string_append_printf(l_string_ret,"Can't find order with hash %s\n", l_order_hash_base58_str );
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DUMP_CANT_FIND_ERR,
+                                                        "Can't find order with hash %s\n", l_order_hash_base58_str );
+                        l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DUMP_CANT_FIND_ERR ;
                     }
                 } else {
                     dap_list_t * l_orders = NULL;
@@ -437,38 +441,41 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                     dap_chain_net_srv_order_direction_t l_direction = SERV_DIR_UNDEFINED;
 
                     if( !dap_chain_net_srv_order_find_all_by( l_net,l_direction,l_srv_uid,l_price_unit, NULL, l_price_min, l_price_max,&l_orders,&l_orders_num) ){
-                        dap_string_append_printf(l_string_ret,"Found %zd orders:\n",l_orders_num);
+                        json_obj_net_srv = json_object_new_object();
+                        json_object_object_add(json_obj_net_srv, "count", json_object_new_uint64(l_orders_num));
+                        json_object* json_arr_out = json_object_new_array();
                         for(dap_list_t *l_temp = l_orders;l_temp; l_temp = l_orders->next) {
+                            json_object* json_obj_order = json_object_new_object();
                             dap_chain_net_srv_order_t *l_order =(dap_chain_net_srv_order_t *) l_temp->data;
-                            dap_chain_net_srv_order_dump_to_string(l_order, l_string_ret, l_hash_out_type, l_net->pub.native_ticker);
-                            dap_string_append(l_string_ret, "\n");
+                            dap_chain_net_srv_order_dump_to_json(l_order, json_obj_order, l_hash_out_type, l_net->pub.native_ticker);
+                            json_object_array_add(json_arr_out, json_obj_order);
                         }
+                        json_object_object_add(json_obj_net_srv, "orders", json_arr_out);
                         l_ret = 0;
                     }else{
-                        l_ret = -5 ;
-                        dap_string_append(l_string_ret,"Can't get orders: some internal error or wrong params\n");
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_CANT_GET_ERR,"Can't get orders: some internal error or wrong params");
+                        l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_CANT_GET_ERR ;
                     }
                     dap_list_free_full(l_orders, NULL);
                 }
             } else if (!dap_strcmp(l_order_str, "delete")) {
                 if (l_order_hash_str) {
-                    
+                    json_obj_net_srv = json_object_new_object();
                     l_ret = dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str);
                     if (!l_ret)
-                        dap_string_append_printf(l_string_ret, "Deleted order %s\n", l_order_hash_str);
+                        json_object_object_add(json_obj_net_srv, "order_hash", json_object_new_string(l_order_hash_str));
                     else {
-                        l_ret = -8;
-                        dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_str);
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_CANT_FIND_HASH_ERR, "Can't find order with hash %s\n", l_order_hash_str);
+                        l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_CANT_FIND_HASH_ERR;
                     }
                 } else {
-                    l_ret = -9 ;
-                    dap_string_append(l_string_ret,"need -hash param to obtain what the order we need to dump\n");
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_NEED_HASH_PARAM_ERR, "need -hash param to obtain what the order we need to dump\n");
+                    l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_NEED_HASH_PARAM_ERR;
                 }
-
             } else if(!dap_strcmp( l_order_str, "create" )) {
                 if (dap_chain_net_get_role(l_net).enums > NODE_ROLE_MASTER) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Node role should be not lower than master\n");
-                    return -4;
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ROLE_ERR, "Node role should be not lower than master\n");
+                    return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ROLE_ERR;
                 }
                 const char *l_order_cert_name = NULL;
                 dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-cert", &l_order_cert_name);
@@ -490,30 +497,31 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                             log_it(L_DEBUG, "Created order to buy");
                         } else {
                             log_it(L_WARNING, "Undefined order direction");
-                            dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong direction of the token was "
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_ORDER_DIR_ERR, "Wrong direction of the token was "
                                                                            "specified, possible directions: buy, sell.");
-                            return -18;
+                            return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_ORDER_DIR_ERR;
                         }
                     }
 
                     if (l_expires_str)
                         l_expires = (dap_time_t ) atoll( l_expires_str);
                     if (l_srv_uid_str && dap_id_uint64_parse(l_srv_uid_str ,&l_srv_uid.uint64)) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
-                        return -21;
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_RECOGNIZE_ERR,
+                                                    "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
+                        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_RECOGNIZE_ERR;
                     }else if (!l_srv_uid_str){
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter -srv_uid is required.");
-                        return -22;
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_REQUIRED_PARAM_UID_ERR, "Parameter -srv_uid is required.");
+                        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_REQUIRED_PARAM_UID_ERR;
                     }
                     if (l_node_addr_str){
                         if (dap_chain_node_addr_str_check(l_node_addr_str)) {
                             dap_chain_node_addr_from_str( &l_node_addr, l_node_addr_str );
                         } else {
                             log_it(L_ERROR, "Can't parse \"%s\" as node addr", l_node_addr_str);
-                            dap_cli_server_cmd_set_reply_text(a_str_reply, "The order has not been created. "
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_PARSE_NODE_ADDR_ERR, "The order has not been created. "
                                                                            "Failed to convert string representation of '%s' "
                                                                            "to node address.", l_node_addr_str);
-                            return -17;
+                            return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_PARSE_NODE_ADDR_ERR;
                         }
                     } else {
                         l_node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
@@ -541,10 +549,10 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                         l_price_unit.enm = SERV_UNIT_PCS;
                     } else {
                         log_it(L_ERROR, "Undefined price unit");
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong unit type sepcified, possible values: B, KB, MB, SEC, DAY, PCS");
-                        return -18;
-                    } 
-                    
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_PRICE_UNIT_ERR,
+                                                    "Wrong unit type sepcified, possible values: B, KB, MB, SEC, DAY, PCS");
+                        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_PRICE_UNIT_ERR;
+                    }                     
                     strncpy(l_price_token, l_price_token_str, DAP_CHAIN_TICKER_SIZE_MAX - 1);
                     size_t l_ext_len = l_ext? strlen(l_ext) + 1 : 0;
                     // get cert to order sign
@@ -556,41 +564,47 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                             l_key = l_cert->enc_key;
                             if (!l_key->priv_key_data || !l_key->priv_key_data_size) {
                                 log_it(L_ERROR, "Certificate '%s' doesn't contain a private key", l_order_cert_name);
-                                dap_cli_server_cmd_set_reply_text(a_str_reply, "Certificate '%s' doesn't contain a private key", l_order_cert_name);
-                                return -25;
+                                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_WITHOUT_KEY_ERR,
+                                                    "Certificate '%s' doesn't contain a private key", l_order_cert_name);
+                                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_WITHOUT_KEY_ERR;
                             }
                         } else {
                             log_it(L_ERROR, "Can't load cert '%s' for sign order", l_order_cert_name);
-                            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't load cert '%s' for sign "
+                            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_LOAD_CERT_ERR, "Can't load cert '%s' for sign "
                                                                            "order", l_order_cert_name);
-                            return -19;
+                            return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_LOAD_CERT_ERR;
                         }
                     } else {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "The certificate name was not "
-                                                                       "specified. Since version 5.2 it is not possible to "
-                                                                       "create unsigned orders.");
-                        return -20;
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_NAME_NOT_WALID_ERR,
+                                                                        "The certificate name was not "
+                                                                        "specified. Since version 5.2 it is not possible to "
+                                                                        "create unsigned orders.");
+                        return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_NAME_NOT_WALID_ERR;
                     }
                 // create order
                     char * l_order_new_hash_str = dap_chain_net_srv_order_create(
                         l_net,l_direction, l_srv_uid, l_node_addr,l_tx_cond_hash, &l_price, l_price_unit,
-                        l_price_token, l_expires, (uint8_t *)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key);
-                    if (l_order_new_hash_str)
-                        dap_string_append_printf( l_string_ret, "Created order %s\n", l_order_new_hash_str);
+                        l_price_token, l_expires, (uint8_t*)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key);
+                    if (l_order_new_hash_str) {
+                        json_obj_net_srv = json_object_new_object();
+                        json_object_object_add(json_obj_net_srv, "order_hash", json_object_new_string(l_order_new_hash_str));
+                        DAP_DELETE(l_order_new_hash_str);
+                    }
                     else {
-                        dap_string_append_printf( l_string_ret, "Error! Can't created order\n");
-                        l_ret = -4;
+                        dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ORDER_ERR,
+                                                                        "Error! Can't created order\n");
+                        l_ret = -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ORDER_ERR;
                     }
                 } else {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Missed some required params\n");
-                    return -5;
+                    dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_MISSED_PARAM_ERR,
+                                                                        "Missed some required params\n");
+                    return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_MISSED_PARAM_ERR;
                 }
             } else if (l_order_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", l_order_str);
-                return -14;
-            }
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_string_ret->str);
-
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN_SUB_COM_ERR,
+                                                                        "Unrecognized subcommand '%s'", l_order_str);
+                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN_SUB_COM_ERR;
+            }            
         } else if (l_get_limits_str){
             const char *l_provider_pkey_hash_str = NULL;
             dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-provider_pkey_hash", &l_provider_pkey_hash_str);
@@ -599,26 +613,26 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
             dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-client_pkey_hash", &l_client_pkey_hash_str);
 
             if (!l_provider_pkey_hash_str){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'get_limits' require the parameter provider_pkey_hash");
-                dap_string_free(l_string_ret, true);
-                return -15;
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_PPKHASH_ERR,
+                                            "Command 'get_limits' require the parameter provider_pkey_hash");
+                 return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_PPKHASH_ERR;
             }
 
             if (!l_client_pkey_hash_str){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'get_limits' require the parameter client_pkey_hash");
-                dap_string_free(l_string_ret, true);
-                return -16;
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_CPKHASH_ERR,
+                                            "Command 'get_limits' require the parameter client_pkey_hash");
+                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_CPKHASH_ERR;
             }
 
             dap_chain_net_srv_uid_t l_srv_uid={{0}};
             if (l_srv_uid_str && dap_id_uint64_parse(l_srv_uid_str ,&l_srv_uid.uint64)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
-                dap_string_free(l_string_ret, true);
-                return -21;
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_REC_UID_STR_ERR,
+                                            "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str);
+                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_REC_UID_STR_ERR;
             } else if (!l_srv_uid_str){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Parameter -srv_uid is required.");
-                dap_string_free(l_string_ret, true);
-                return -22;
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_UID_ERR,
+                                            "Parameter -srv_uid is required.");
+                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_UID_ERR;
             }
 
             dap_stream_ch_chain_net_srv_remain_service_store_t *l_remain_service = NULL;
@@ -631,24 +645,25 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
             DAP_DELETE(l_remain_limits_gdb_group);
 
             if(!l_remain_service || !l_remain_service_size){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get remain service data");
-                dap_string_free(l_string_ret, true);
-                return -21;
+                dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_GET_REM_SERV_DATA_ERR,
+                                            "Can't get remain service data");
+                return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_GET_REM_SERV_DATA_ERR;
             }
+            json_obj_net_srv = json_object_new_object();
 
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Provider %s. Client %s remain service values:\n"
-                                                   "SEC: %"DAP_UINT64_FORMAT_U"\n"
-                                                   "BYTES: %"DAP_UINT64_FORMAT_U"\n", l_provider_pkey_hash_str, l_client_pkey_hash_str,
-                                              (uint64_t)l_remain_service->limits_ts, (uint64_t)l_remain_service->limits_bytes);
-
-            dap_string_free(l_string_ret, true);
+            json_object_object_add(json_obj_net_srv, "provider", json_object_new_string(l_provider_pkey_hash_str));
+            json_object_object_add(json_obj_net_srv, "client", json_object_new_string(l_client_pkey_hash_str));
+            json_object_object_add(json_obj_net_srv, "sec", json_object_new_uint64((uint64_t)l_remain_service->limits_ts));
+            json_object_object_add(json_obj_net_srv, "bytes", json_object_new_uint64((uint64_t)l_remain_service->limits_bytes));
             DAP_DELETE(l_remain_service);
         } else {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized bcommand.");
-            dap_string_free(l_string_ret, true);
-            return -17;
+            dap_json_rpc_error_add(*json_arr_reply, DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN,
+                                            "Unrecognized command.");
+            return -DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN;
         }
     }
+    if (json_obj_net_srv != NULL)
+                json_object_array_add(*json_arr_reply, json_obj_net_srv);
     return l_ret;
 }
 
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index 0f7153474c..aaccef0c4f 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -209,10 +209,7 @@ size_t dap_chain_net_srv_order_continents_count(void)
  */
 const char* dap_chain_net_srv_order_continent_to_str(int8_t a_num)
 {
-    int8_t l_count = dap_chain_net_srv_order_continents_count();
-    if(a_num >= l_count)
-        return NULL;
-    return s_server_continents[a_num];
+    return a_num < (int8_t)dap_chain_net_srv_order_continents_count() ? s_server_continents[a_num] : NULL;
 }
 
 /**
@@ -520,7 +517,7 @@ void dap_chain_net_srv_order_dump_to_string(const dap_chain_net_srv_order_t *a_o
         dap_time_to_str_rfc822(buf_time, DAP_TIME_STR_SIZE, a_order->ts_created);
         dap_string_append_printf(a_str_out, "  created:          %s\n", buf_time);
         dap_string_append_printf(a_str_out, "  srv_uid:          0x%016"DAP_UINT64_FORMAT_X"\n", a_order->srv_uid.uint64 );
-        
+
         const char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins);
         dap_string_append_printf(a_str_out, "  price:            %s (%s)\n", l_balance_coins, l_balance);
         dap_string_append_printf(a_str_out, "  price_token:      %s\n",  (*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker);
@@ -558,8 +555,11 @@ void dap_chain_net_srv_order_dump_to_string(const dap_chain_net_srv_order_t *a_o
     }
 }
 
-
-
+/**
+ * @brief dap_chain_net_srv_order_dump_to_json
+ * @param a_orders
+ * @param a_str_out
+ */
 void dap_chain_net_srv_order_dump_to_json(const dap_chain_net_srv_order_t *a_order, json_object *a_json_obj_out,
                                             const char *a_hash_out_type, const char *a_native_ticker)
 {
@@ -571,7 +571,7 @@ void dap_chain_net_srv_order_dump_to_json(const dap_chain_net_srv_order_t *a_ord
                 : dap_chain_hash_fast_to_str_static(&l_hash);
 
         json_object_object_add(a_json_obj_out, "order", json_object_new_string(l_hash_str));
-        json_object_object_add(a_json_obj_out, "version", json_object_new_int(a_order->version));
+        json_object_object_add(a_json_obj_out, "version", json_object_new_uint64(a_order->version));
 
         switch ( a_order->direction) {
         case SERV_DIR_UNDEFINED:    json_object_object_add(a_json_obj_out, "direction", json_object_new_string("SERV_DIR_UNDEFINED"));   break;
@@ -588,16 +588,21 @@ void dap_chain_net_srv_order_dump_to_json(const dap_chain_net_srv_order_t *a_ord
         json_object_object_add(a_json_obj_out, "srv_uid", json_object_new_string(buf_srv_uid));
         
         const char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins);
-        json_object_object_add(a_json_obj_out, "price_coins", json_object_new_string(l_balance_coins));
-        json_object_object_add(a_json_obj_out, "price_datoshi", json_object_new_string(l_balance));
-        json_object_object_add(a_json_obj_out, "price_token", json_object_new_string((*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker));
-        json_object_object_add(a_json_obj_out, "units", json_object_new_int(a_order->units));
-        if( a_order->price_unit.uint32 )
-            json_object_object_add(a_json_obj_out, "price_unit", json_object_new_string(dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit)));
+        json_object_object_add(a_json_obj_out, "created", json_object_new_string(buf_time));
+
+        json_object_object_add(a_json_obj_out, "price coins", json_object_new_string(l_balance_coins));
+        json_object_object_add(a_json_obj_out, "price datoshi", json_object_new_string(l_balance));
+        json_object_object_add(a_json_obj_out, "price token", (*a_order->price_ticker) ?
+                                                              json_object_new_string(a_order->price_ticker) :
+                                                              json_object_new_string(a_native_ticker));
+        json_object_object_add(a_json_obj_out, "units", json_object_new_uint64(a_order->units));
+
+        if ( a_order->price_unit.uint32 )
+            json_object_object_add(a_json_obj_out, "price unit", json_object_new_string(dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit)));
         if ( a_order->node_addr.uint64) {
-            char buf_node_addr[64];
-            snprintf(buf_node_addr, sizeof(buf_node_addr), ""NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(a_order->node_addr));
-            json_object_object_add(a_json_obj_out, "node_addr", json_object_new_string(buf_node_addr));
+            char *node_addr = dap_strdup_printf(""NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(a_order->node_addr));
+            json_object_object_add(a_json_obj_out, "node_addr", json_object_new_string(node_addr));
+            DAP_DELETE(node_addr);
         }
 
         char *l_region = NULL;
@@ -605,9 +610,11 @@ void dap_chain_net_srv_order_dump_to_json(const dap_chain_net_srv_order_t *a_ord
         const char *l_continent_str = NULL;
         if(dap_chain_net_srv_order_get_continent_region(a_order, &l_continent_num, &l_region))
             l_continent_str = dap_chain_net_srv_order_continent_to_str(l_continent_num);
-        char buf_location[64];
-        snprintf(buf_location, sizeof(buf_location), "%s - %s", l_continent_str ? l_continent_str : "None" , l_region ? l_region : "None");
-        json_object_object_add(a_json_obj_out, "node_location", json_object_new_string(buf_location));
+
+        char *node_location = dap_strdup_printf("%s - %s", l_continent_str ? l_continent_str : "None" , l_region ? l_region : "None");
+        json_object_object_add(a_json_obj_out, "node_location", json_object_new_string(node_location));
+        DAP_DELETE(node_location);
+
         DAP_DELETE(l_region);
 
         l_hash_str = dap_strcmp(a_hash_out_type, "hex")
diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h
index 1aa967f4eb..c8b252b9af 100755
--- a/modules/net/srv/include/dap_chain_net_srv.h
+++ b/modules/net/srv/include/dap_chain_net_srv.h
@@ -280,3 +280,46 @@ DAP_STATIC_INLINE const char *dap_chain_net_srv_fee_type_to_str(dap_chain_net_sr
         default: return "UNKNOWN";
     }
 }
+
+typedef enum s_com_net_srv_err{
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_OK = 0,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_HASH_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CONT_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_HASH_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_PARAM_CERT_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UPDATE_LOAD_CERT_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_PARAM_CERT_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_HEX_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_FIND_CANT_GET_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DUMP_CANT_FIND_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_CANT_FIND_HASH_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_DEL_NEED_HASH_PARAM_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ROLE_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_ORDER_DIR_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_RECOGNIZE_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_REQUIRED_PARAM_UID_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_PARSE_NODE_ADDR_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_UNDEF_PRICE_UNIT_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_WITHOUT_KEY_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CANT_LOAD_CERT_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_CERT_NAME_NOT_WALID_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_ORDER_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_CREATE_MISSED_PARAM_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_PPKHASH_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_CPKHASH_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_REC_UID_STR_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_REQUIRED_PARAM_UID_ERR,
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_GETLIM_CANT_GET_REM_SERV_DATA_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN_SUB_COM_ERR,
+
+    DAP_CHAIN_NET_SRV_CLI_COM_ORDER_UNKNOWN    
+
+} s_com_net_srv_err_t;
-- 
GitLab