diff --git a/modules/net-srv/dap_chain_net_srv_ch.c b/modules/net-srv/dap_chain_net_srv_ch.c
index 2e3ca71ba2ee89b9b9110fff37667e8aa86a8e4d..8af2e74bfcfd6494fe935e4de442032b538e0c77 100644
--- a/modules/net-srv/dap_chain_net_srv_ch.c
+++ b/modules/net-srv/dap_chain_net_srv_ch.c
@@ -31,7 +31,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "rand/dap_rand.h"
 
 #include "dap_chain_net_srv_stream_session.h"
-
+#include "dap_chain_srv.h"
 #include "dap_stream.h"
 #include "dap_stream_ch.h"
 #include "dap_stream_ch_pkt.h"
@@ -1090,6 +1090,12 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
             return false;
         }
         pkt_test_t *l_request = (pkt_test_t*)l_ch_pkt->data;
+        if (dap_chain_srv_get_internal(l_request->net_id, l_request->srv_uid) == NULL) {
+            log_it(L_WARNING, "Can't find service with id %"DAP_UINT64_FORMAT_U, l_request->srv_uid.uint64);
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND;
+            dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
+            return false;
+        }
         if (l_request->data_size_recv > DAP_CHAIN_NET_SRV_CH_REQUEST_SIZE_MAX || l_request->data_size > DAP_CHAIN_NET_SRV_CH_REQUEST_SIZE_MAX) {
             log_it(L_WARNING, "Too large payload %zu [pkt seq %"DAP_UINT64_FORMAT_U"]", l_request->data_size_recv, l_ch_pkt->hdr.seq_id);
             l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_BIG_SIZE;
diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index 40f2370cfdeb17470baa59ceabfe70f297335d66..0c7deec0d1c81360d1088321ac458325a7411773 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -1215,13 +1215,13 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n
                 l_sign_list = dap_list_append(l_sign_list, l_json_item_obj);
                 break;
             }
-            const char *l_sign_b64_str = json_object_get_string(l_json_item_obj);
+            const char *l_sign_b64_str = json_object_get_string(l_jobj_sign);
             if ( !l_sign_b64_str ) {
                 json_object_array_add(l_jobj_errors, json_object_new_string("Can't get base64-encoded sign"));
                 log_it(L_ERROR, "Json TX: Can't get base64-encoded sign!");
                 break;
             }
-            int64_t l_sign_size = 0, l_sign_b64_strlen = json_object_get_string_len(l_json_item_obj),
+            int64_t l_sign_size = 0, l_sign_b64_strlen = json_object_get_string_len(l_jobj_sign),
                     l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(l_sign_b64_strlen);
             if ( !s_json_get_int64(l_json_item_obj, "sig_size", &l_sign_size) )
                 log_it(L_NOTICE, "Json TX: \"sig_size\" unspecified, will be calculated automatically");
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 0d06ece6762efd3950dc842ca77166c7bb041ba1..f7922d7f03e277a4ec0e98ced3c76ee7569d078f 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -331,7 +331,7 @@ void dap_chain_node_client_close_unsafe(dap_chain_node_client_t *a_node_client)
     if (a_node_client->reconnect_timer)
         dap_timerfd_delete(a_node_client->reconnect_timer->worker, a_node_client->reconnect_timer->esocket_uuid);
     if (a_node_client->callbacks.delete)
-        a_node_client->callbacks.delete(a_node_client, a_node_client->net);
+        a_node_client->callbacks.delete(a_node_client, a_node_client->callbacks_arg);
 
     if (a_node_client->stream_worker) {
         dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_node_client->stream_worker, a_node_client->ch_chain_net_uuid);
diff --git a/modules/node-cli/dap_chain_node_cli_cmd.c b/modules/node-cli/dap_chain_node_cli_cmd.c
index 8a68dfbb4d94be8f7ab5f6a59f3ce27bb0e59a00..0b7bd8d452e920e0bcd3fc3644641723b5cbaf99 100644
--- a/modules/node-cli/dap_chain_node_cli_cmd.c
+++ b/modules/node-cli/dap_chain_node_cli_cmd.c
@@ -1727,12 +1727,6 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
             break;
         }
         case CMD_WALLET_OUTPUTS: {
-            if(!l_net) {
-                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR,
-                                        "Subcommand info requires parameter '-net'");
-                json_object_put(json_arr_out);
-                return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR;
-            }
             if ((l_wallet_name && l_addr_str) || (!l_wallet_name && !l_addr_str)) {
                 dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NAME_ERR,
                 "You should use either the -w or -addr option for the wallet info command.");
@@ -1740,6 +1734,12 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NAME_ERR;
             }
             if(l_wallet_name) {
+                if(!l_net) {
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR,
+                                            "Subcommand info requires parameter '-net'");
+                    json_object_put(json_arr_out);
+                    return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR;
+                }
                 l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path, NULL);
                 if (!l_wallet){
                     dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR,
@@ -1756,6 +1756,15 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 }
             } else {
                 l_addr = dap_chain_addr_from_str(l_addr_str);
+                if (!l_net)
+                    l_net = dap_chain_net_by_id(l_addr->net_id);
+                
+                if(!l_net) {
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR,
+                                            "Can't get net from wallet addr");
+                    json_object_put(json_arr_out);
+                    return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR;
+                }
             }
 
             const char* l_token_tiker = NULL;
diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c
index b620ce583d425bec2c375481d7946701d2f2e03a..7f5f6b43232eddf894edde76aa070043c2ed5bb3 100644
--- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c
+++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c
@@ -160,6 +160,14 @@ json_object * dap_db_tx_history_to_json(json_object* a_json_arr_reply,
                             ? dap_enc_base58_encode_hash_to_str_static(l_atom_hash)
                             : dap_chain_hash_fast_to_str_static(l_atom_hash);
         json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str));
+        dap_chain_atom_iter_t *l_iter = a_chain->callback_atom_iter_create(a_chain, a_chain->active_cell_id, l_atom_hash);
+        size_t l_size = 0;
+        if(a_chain->callback_atom_find_by_hash(l_iter, l_atom_hash, &l_size) != NULL){
+            uint64_t l_block_count = a_chain->callback_count_atom(a_chain);
+            uint64_t l_confirmations = l_block_count - l_iter->cur_num;
+            json_object_object_add(json_obj_datum, "confirmations", json_object_new_uint64(l_confirmations));
+        }
+        a_chain->callback_atom_iter_delete(l_iter);
     }
 
     const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index cb08ddd68d1102e3c122018cf7245b9a8715ad42..3536a202c22e12892f535def1cb3cf7b4ba8fcd5 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -76,6 +76,7 @@ typedef struct xchange_tx_cache {
             uint256_t value;
             uint256_t value_ammount;
             dap_hash_fast_t next_hash;
+            uint64_t percent_completed;
         } order_info;
         struct {
             dap_hash_fast_t order_hash;
@@ -121,10 +122,8 @@ static bool s_string_append_tx_cond_info_json( json_object * a_json_out, dap_cha
 
 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(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in,  
-                                        dap_hash_fast_t *a_tx_in_hash,  dap_chain_tx_out_cond_t *a_prev_cond);
-static void s_ledger_tx_remove_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in,  
-                                        dap_hash_fast_t *a_tx_in_hash,  dap_chain_tx_out_cond_t *a_prev_cond);
+static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chain_tx_out_cond_t *a_prev_cond);
+static void s_ledger_tx_remove_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,  dap_chain_tx_out_cond_t *a_prev_cond);
 
 static bool s_debug_more = false;
 
@@ -239,7 +238,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 [-time_from <From_time>] [-time_to <To_time>]\n"
+    "srv_xchange token_pair -net <net_name> rate average -token_from <token_ticker> -token_to <token_ticker> [-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"
@@ -971,7 +970,15 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_
         DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
         MULT_256_COIN(l_percent_completed, dap_chain_balance_coins_scan("100.0"), &l_percent_completed);
     } else {
+        dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
+        xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, l_last_tx, NULL, NULL, &l_out_prev_cond_item);
+        if (tx_type == TX_TYPE_EXCHANGE){
+            l_percent_completed = dap_chain_balance_coins_scan("100.0");
+        } else if (tx_type == TX_TYPE_INVALIDATE){
+            SUBTRACT_256_256(l_out_cond->header.value, l_out_prev_cond_item->header.value, &l_percent_completed);
+            DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
             MULT_256_COIN(l_percent_completed, dap_chain_balance_coins_scan("100.0"), &l_percent_completed);
+        }
     }
 
     return dap_chain_balance_to_coins_uint64(l_percent_completed);
@@ -1560,21 +1567,20 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                             if(l_rc == XCHANGE_ORDER_STATUS_UNKNOWN){
                                 json_object_object_add(l_json_obj_order, "WRONG TX", json_object_new_string(l_tx_hash));
                             }else{
-                                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;
-                                json_object* l_json_order_arr = json_object_new_array();
+                                json_object* l_json_obj_tx_arr = json_object_new_array();
                                 while(l_tx_list_temp ){
-                                    json_object* l_json_order = json_object_new_object();
+                                    json_object* l_json_obj_cur_tx = json_object_new_object();
                                     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);
-                                    s_string_append_tx_cond_info_json(l_json_order, l_net, NULL, NULL, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                                    s_string_append_tx_cond_info_json(l_json_obj_cur_tx, l_net, NULL, NULL, l_tx_cur, TX_STATUS_ALL, true, true, false);
+                                    json_object_array_add(l_json_obj_tx_arr, l_json_obj_cur_tx);
                                     l_tx_list_temp = l_tx_list_temp->next;
-                                    json_object_array_add(l_json_order_arr, l_json_order);
                                 }
+                                json_object_object_add(l_json_obj_order, "history for order", l_json_obj_tx_arr);
                                 dap_list_free(l_tx_list);
-                                json_object_object_add(l_json_obj_order, "orders", l_json_order_arr);
                             }
                         }
                     }else
@@ -1591,13 +1597,13 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                         dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NO_HISTORY_ERR, "No history");
                         return -DAP_CHAIN_NODE_CLI_COM_NET_SRV_XCNGE_ORDRS_HIST_DOES_NO_HISTORY_ERR;
                     }
-                    json_object* l_json_order_arr = json_object_new_array();
+                    json_object* l_json_obj_tx_arr = json_object_new_array();
                     while(l_item){
-                                json_object* l_json_order = json_object_new_object();
-                                s_string_append_tx_cond_info_json(l_json_order, l_net, &l_item->seller_addr,
+                        json_object* l_json_obj_cur_tx = json_object_new_object();
+                        s_string_append_tx_cond_info_json(l_json_obj_cur_tx, l_net, &l_item->seller_addr, 
                                 l_item->tx_type == TX_TYPE_EXCHANGE ?  &l_item->tx_info.exchange_info.buyer_addr : NULL, 
                                 l_item->tx, TX_STATUS_ALL, true, true, false);
-                                json_object_array_add(l_json_order_arr, l_json_order);
+                        json_object_array_add(l_json_obj_tx_arr, l_json_obj_cur_tx);
                         switch(l_item->tx_type){
                             case TX_TYPE_ORDER:{
                                 l_cur_hash = l_item->tx_info.order_info.next_hash;
@@ -1614,7 +1620,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                             break;
                         HASH_FIND(hh, l_cache->cache, &l_cur_hash, sizeof(dap_hash_fast_t), l_item);
                     }
-                    json_object_object_add(l_json_obj_order, "orders", l_json_order_arr);
+                    json_object_object_add(l_json_obj_order, "history for order", l_json_obj_tx_arr);
                 }
             }
             json_object_array_add(*a_json_arr_reply, l_json_obj_order);
@@ -1769,12 +1775,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, j
                 l_token_buy = l_item->buy_token;
                 l_proposed = l_item->tx_info.order_info.value;
 
-                uint256_t l_completed = {};
-                SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed);
-                DIV_256_COIN(l_completed, l_item->tx_info.order_info.value, &l_completed);
-                MULT_256_COIN(l_completed, dap_uint256_scan_decimal("100.0"), &l_completed);
-
-                l_percent_completed = dap_chain_balance_to_coins_uint64(l_completed);
+                l_percent_completed = l_item->tx_info.order_info.percent_completed;
 
                 l_amount_datoshi_str = dap_uint256_to_char(l_item->tx_info.order_info.value_ammount, &l_amount_coins_str);
                 l_owner_addr = dap_chain_addr_to_str_static(&l_item->seller_addr);
@@ -2700,12 +2701,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     l_amount = l_item->tx_info.order_info.value_ammount;
                     l_proposed = l_item->tx_info.order_info.value;
 
-                    uint256_t l_completed = {};
-                    SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed);
-                    DIV_256_COIN(l_completed, l_item->tx_info.order_info.value, &l_completed);
-                    MULT_256_COIN(l_completed, dap_chain_balance_coins_scan("100.0"), &l_completed);
-
-                    l_percent_completed = dap_chain_balance_to_coins_uint64(l_completed);
+                    l_percent_completed = l_item->tx_info.order_info.percent_completed;
                 } else {
                     xchange_tx_list_t *l_tx_item = (xchange_tx_list_t*)it->data;
                     l_tx = l_tx_item->tx;
@@ -2785,37 +2781,32 @@ 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_tx->header.ts_created);
-                char *l_cp_rate;
-                l_cp_rate = dap_uint256_decimal_to_char(l_rate);
-                l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount);
-                l_amount_coins_str = dap_uint256_decimal_to_char(l_amount);
-                l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); 
-                l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed);
-
-                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_str));
-                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_sell_token));
-                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_buy_token));
-                json_object_object_add(json_obj_orders, "token sell", json_object_new_string(l_sell_token));
-                json_object_object_add(json_obj_orders, "balance rate", json_object_new_string(l_cp_rate));
-                json_object_object_add(json_obj_orders, "net name", json_object_new_string(l_net->pub.name));
-                json_object_object_add(json_obj_orders, "owner addr", json_object_new_string(l_owner_addr ? l_owner_addr : "unknown"));
-                json_object_array_add(json_arr_orders_out, json_obj_orders);
+
+                json_object* json_obj_order = json_object_new_object();
+                json_object_object_add(json_obj_order, "order_hash", 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_str));
+
+                l_proposed_datoshi_str = dap_uint256_to_char(l_proposed, &l_proposed_coins_str);
+                json_object_object_add(json_obj_order, "proposed_coins", json_object_new_string(*l_proposed_coins_str ? l_proposed_coins_str : "0.0"));
+                json_object_object_add(json_obj_order, "proposed_datoshi", json_object_new_string(*l_proposed_datoshi_str ? l_proposed_datoshi_str : "0"));
+                
+                l_amount_datoshi_str = dap_uint256_to_char(l_amount, &l_amount_coins_str);
+                json_object_object_add(json_obj_order, "amount_coins", json_object_new_string(*l_amount_coins_str ? l_amount_coins_str : "0.0")); 
+                json_object_object_add(json_obj_order, "amount_datoshi", json_object_new_string(*l_amount_datoshi_str ? l_amount_datoshi_str : "0")); 
+                json_object_object_add(json_obj_order, "filled_percent", json_object_new_uint64(l_percent_completed));
+                json_object_object_add(json_obj_order, "token_buy", json_object_new_string(l_buy_token));
+                json_object_object_add(json_obj_order, "token_sell", json_object_new_string(l_sell_token));
+
+                const char *l_cp_rate;
+                dap_uint256_to_char(l_rate, &l_cp_rate);
+                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_net->pub.name));
+                json_object_object_add(json_obj_order, "owner_addr", json_object_new_string(l_owner_addr));
+                json_object_array_add(*json_arr_reply, json_obj_order);
+                DAP_DELETE(l_owner_addr);
                 l_printed_orders_count++;
-                DAP_DEL_Z(l_cp_rate);
-                DAP_DEL_Z(l_amount_datoshi_str);
-                DAP_DEL_Z(l_amount_coins_str);
-                DAP_DEL_Z(l_proposed_coins_str);
-                DAP_DEL_Z(l_proposed_datoshi_str);
             }
             json_object_object_add(json_obj_order, "ORDERS", json_arr_orders_out);
             json_object_array_add(*json_arr_reply, json_obj_order);
@@ -3659,29 +3650,22 @@ static dap_hash_fast_t s_get_order_from_cache(xchange_tx_cache_t *a_cache_head,
 }
 
 
-static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_hash_fast_t *a_tx_hash,  dap_chain_tx_out_cond_t *a_prev_cond)
+static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chain_tx_out_cond_t *a_prev_cond)
 {
     // check and add tx into cache
     dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
     int l_item_idx = 0;
     dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
     dap_hash_fast_t l_prev_tx_hash = {};
+    xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_ledger, a_tx, &l_out_cond_item, &l_item_idx, &l_out_prev_cond_item);
+    if (l_tx_type == TX_TYPE_UNDEFINED)
+        return;
 
     xchange_orders_cache_net_t* l_cache_net = s_get_xchange_cache_by_net_id(a_ledger->net->pub.id);
     if(!l_cache_net)
         return;
-    
-    xchange_tx_cache_t* l_tx_cache = NULL;
-    HASH_FIND(hh, l_cache_net->cache, a_tx_hash, sizeof(dap_hash_fast_t), l_tx_cache);
-    if(l_tx_cache)
-        return;
 
-    xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_ledger, a_tx, &l_out_cond_item, &l_item_idx, &l_out_prev_cond_item);
-    if (l_tx_type == TX_TYPE_UNDEFINED)
-        return;
-    
     xchange_tx_cache_t* l_cache = DAP_NEW_Z_RET_IF_FAIL(xchange_tx_cache_t);
-
     l_cache->hash = *a_tx_hash;
     l_cache->tx = a_tx;
     l_cache->tx_type = l_tx_type;
@@ -3702,6 +3686,7 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         l_cache->tx_info.order_info.order_status = XCHANGE_ORDER_STATUS_OPENED;
         l_cache->tx_info.order_info.value = l_out_cond_item->header.value;
         l_cache->tx_info.order_info.value_ammount = l_cache->tx_info.order_info.value;
+        l_cache->tx_info.order_info.percent_completed = 0;
     } else if (l_tx_type == TX_TYPE_EXCHANGE){
         l_cache->rate = l_out_prev_cond_item->subtype.srv_xchange.rate;
         dap_strncpy(l_cache->buy_token, l_out_prev_cond_item->subtype.srv_xchange.buy_token, sizeof(l_cache->buy_token));
@@ -3715,6 +3700,7 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         
         l_cache->tx_info.exchange_info.order_hash = s_get_order_from_cache(l_cache_net->cache, &l_cache->tx_info.exchange_info.prev_hash);
         dap_hash_fast_is_blank(&l_cache->tx_info.exchange_info.order_hash);
+
         dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
         dap_sign_t *l_sign = dap_chain_datum_tx_item_sig_get_sign((dap_chain_tx_sig_t *)l_tx_sig);
         dap_enc_key_t *l_key_buyer = dap_sign_to_enc_key(l_sign);
@@ -3726,6 +3712,15 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         if(l_cache_order){
             if (l_cache_order->tx_type == TX_TYPE_ORDER){
                 l_cache_order->tx_info.order_info.value_ammount = l_out_cond_item && !IS_ZERO_256(l_out_cond_item->header.value) ? l_out_cond_item->header.value : uint256_0;
+                if (l_out_cond_item && !IS_ZERO_256(l_out_cond_item->header.value)){
+                    uint256_t l_percent_completed = {};
+                    SUBTRACT_256_256(l_cache_order->tx_info.order_info.value, l_cache_order->tx_info.order_info.value_ammount, &l_percent_completed);
+                    DIV_256_COIN(l_percent_completed, l_cache_order->tx_info.order_info.value, &l_percent_completed);
+                    MULT_256_COIN(l_percent_completed, dap_chain_balance_coins_scan("100.0"), &l_percent_completed);
+                    l_cache_order->tx_info.order_info.percent_completed = dap_chain_balance_to_coins_uint64(l_percent_completed);
+                } else {
+                    l_cache_order->tx_info.order_info.percent_completed = dap_chain_balance_to_coins_uint64(dap_chain_balance_coins_scan("100.0"));
+                }
                 l_cache_order->tx_info.order_info.order_status = IS_ZERO_256(l_cache_order->tx_info.order_info.value_ammount) ? XCHANGE_ORDER_STATUS_CLOSED : XCHANGE_ORDER_STATUS_OPENED;
                 if (dap_hash_fast_is_blank(&l_cache_order->tx_info.order_info.next_hash))
                     l_cache_order->tx_info.order_info.next_hash = *a_tx_hash;
@@ -3776,8 +3771,9 @@ static void s_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
 }
 
 
+
 static void s_ledger_tx_remove_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  
-                                        dap_hash_fast_t *a_tx_hash,  dap_chain_tx_out_cond_t *a_prev_cond)
+    dap_hash_fast_t *a_tx_hash,  dap_chain_tx_out_cond_t *a_prev_cond)
 {
     // delete tx from cache if present
     xchange_orders_cache_net_t* l_cache = s_get_xchange_cache_by_net_id(a_ledger->net->pub.id);
@@ -3795,9 +3791,15 @@ static void s_ledger_tx_remove_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx
                         HASH_FIND(hh, l_cache->cache, &l_cache_found->tx_info.exchange_info.order_hash, sizeof(dap_hash_fast_t), l_cache_order);
                         l_cache_prev_tx->tx_info.exchange_info.next_hash = (dap_hash_fast_t){0};
                         SUM_256_256(l_cache_order->tx_info.order_info.value_ammount, l_cache_found->tx_info.exchange_info.buy_value, &l_cache_order->tx_info.order_info.value_ammount);
+                        uint256_t l_percent_completed = {};
+                        SUBTRACT_256_256(l_cache_order->tx_info.order_info.value, l_cache_order->tx_info.order_info.value_ammount, &l_percent_completed);
+                        DIV_256_COIN(l_percent_completed, l_cache_order->tx_info.order_info.value, &l_percent_completed);
+                        MULT_256_COIN(l_percent_completed, dap_chain_balance_coins_scan("100.0"), &l_percent_completed);
+                        l_cache_order->tx_info.order_info.percent_completed = dap_chain_balance_to_coins_uint64(l_percent_completed);
                     } else if (l_cache_prev_tx->tx_type == TX_TYPE_ORDER){
                         l_cache_prev_tx->tx_info.order_info.next_hash = (dap_hash_fast_t){0};
                         l_cache_prev_tx->tx_info.order_info.value_ammount = l_cache_prev_tx->tx_info.order_info.value;
+                        l_cache_prev_tx->tx_info.order_info.percent_completed = 0;
                     }
                 }
             } else if (l_tx_type == TX_TYPE_INVALIDATE){
@@ -3820,4 +3822,4 @@ static void s_ledger_tx_remove_notify(dap_ledger_t *a_ledger, dap_chain_datum_tx
             DAP_DELETE(l_cache_found);
         }
     }
-}
+}
\ No newline at end of file