diff --git a/dap-sdk b/dap-sdk
index 59705ae76ca20b8ac1b8269ae67aa847ec73dfa9..dffb76d321e837c98157a691e7e9e352bb921511 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 59705ae76ca20b8ac1b8269ae67aa847ec73dfa9
+Subproject commit dffb76d321e837c98157a691e7e9e352bb921511
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index 6bfea9e5fa17c1a824136d9f5d2dd5a534b0a63b..3ce92f9fed3887be3fa0f05976779b3383e9a2c4 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -680,14 +680,19 @@ void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_not
  * @param a_atom_hash
  * @return
  */
-bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_hash_fast_t *a_atom_hash, dap_chain_cell_id_t a_cell_id)
+bool dap_chain_get_atom_last_hash_num(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash, uint64_t *a_atom_num)
 {
-    dap_chain_atom_iter_t *l_iter = a_chain->callback_atom_iter_create(a_chain, a_cell_id, false);
+    dap_return_val_if_fail(a_atom_hash || a_atom_num, false);
+    dap_chain_atom_iter_t *l_iter = a_chain->callback_atom_iter_create(a_chain, a_cell_id, NULL);
+    if (!l_iter)
+        return false;
     a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_LAST, NULL);
-    *a_atom_hash = l_iter->cur_hash ? *l_iter->cur_hash : (dap_hash_fast_t){0};
-    bool l_ret = l_iter->cur_hash;
+    if (a_atom_hash)
+        *a_atom_hash = l_iter->cur_hash ? *l_iter->cur_hash : (dap_hash_fast_t){0};
+    if (a_atom_num)
+        *a_atom_num = l_iter->cur_num;
     a_chain->callback_atom_iter_delete(l_iter);
-    return l_ret;
+    return true;
 }
 
 struct chain_thread_notifier {
diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index f4cfcde1a2827ff901fbc04e8be46a45a69a452d..7d1cb75fb9b2895cebcc35912696860b1a31c8fa 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -74,7 +74,7 @@ struct sync_request
 {
     dap_worker_t * worker;
     dap_stream_ch_uuid_t ch_uuid;
-    dap_chain_ch_sync_request_t request;
+    dap_chain_ch_sync_request_old_t request;
     dap_chain_ch_pkt_hdr_t request_hdr;
     dap_chain_pkt_item_t pkt;
 
@@ -119,10 +119,9 @@ static inline bool s_ch_chain_get_idle(dap_chain_ch_t *a_ch_chain) { return a_ch
 
 static void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg);
 static void s_stream_ch_delete(dap_stream_ch_t* a_ch, void* a_arg);
-static void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg);
+static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg);
 static bool s_stream_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg);
 static void s_stream_ch_io_complete(dap_events_socket_t *a_es, void *a_arg);
-static void s_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error);
 
 static bool s_sync_out_chains_proc_callback(void *a_arg);
 static void s_sync_out_chains_last_worker_callback(dap_worker_t *a_worker, void *a_arg);
@@ -183,6 +182,12 @@ static const char *s_error_type_to_string(dap_chain_ch_error_type_t a_error)
         return "UNKNOWN_CHAIN_PACKET_TYPE";
     case DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED:
         return "GLOBAL_DB_INTERNAL_SAVING_ERROR";
+    case DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE:
+        return "NET_IS_OFFLINE";
+    case DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY:
+        return "OUT_OF_MEMORY";
+    case DAP_CHAIN_CH_ERROR_INTERNAL:
+        return "INTERNAL_ERROR";
     default:
         return "UNKNOWN_ERROR";
     }
@@ -194,7 +199,7 @@ static const char *s_error_type_to_string(dap_chain_ch_error_type_t a_error)
  */
 int dap_chain_ch_init()
 {
-    log_it(L_NOTICE, "Chains and global db exchange channel initialized");
+    log_it(L_NOTICE, "Chains exchange channel initialized");
     dap_stream_ch_proc_add(DAP_CHAIN_CH_ID, s_stream_ch_new, s_stream_ch_delete, s_stream_ch_packet_in,
             s_stream_ch_packet_out);
     s_sync_timeout = dap_config_get_item_uint32_default(g_config, "chain", "sync_timeout", s_sync_timeout);
@@ -205,8 +210,7 @@ int dap_chain_ch_init()
     for (int i = 0; i < MEMSTAT$K_NR; i++)
         dap_memstat_reg(&s_memstat[i]);
 #endif
-    assert(!dap_stream_ch_gossip_callback_add(DAP_CHAIN_CH_ID, s_gossip_payload_callback));
-    return 0;
+    return dap_stream_ch_gossip_callback_add(DAP_CHAIN_CH_ID, s_gossip_payload_callback);
 }
 
 /**
@@ -248,9 +252,6 @@ static void s_stream_ch_delete(dap_stream_ch_t *a_ch, void *a_arg)
 {
     UNUSED(a_arg);
     dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch);
-    if (l_ch_chain->callback_notify_packet_out)
-        l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_DELETE, NULL, 0,
-                                               l_ch_chain->callback_notify_arg);
     s_ch_chain_go_idle(l_ch_chain);
     debug_if(s_debug_more, L_DEBUG, "[stm_ch_chain:%p] --- deleted chain:%p", a_ch, l_ch_chain);
     DAP_DEL_Z(a_ch->internal);
@@ -260,13 +261,6 @@ static void s_stream_ch_delete(dap_stream_ch_t *a_ch, void *a_arg)
 #endif
 }
 
-void dap_chain_ch_reset_unsafe(dap_chain_ch_t *a_ch_chain)
-{
-    if (!a_ch_chain)
-        return;
-    s_ch_chain_go_idle(a_ch_chain);
-}
-
 /**
  * @brief s_stream_ch_chain_delete
  * @param a_ch_chain
@@ -352,16 +346,13 @@ static void s_sync_out_chains_last_worker_callback(dap_worker_t *a_worker, void
     }
     l_ch_chain->request_atom_iter = l_sync_request->chain.request_atom_iter;
     // last packet
-    dap_chain_ch_sync_request_t l_request = {};
+    dap_chain_ch_sync_request_old_t l_request = {};
     if (s_debug_more )
         log_it(L_INFO,"Out: DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS");
     dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS,
             l_sync_request->request_hdr.net_id.uint64, l_sync_request->request_hdr.chain_id.uint64,
             l_sync_request->request_hdr.cell_id.uint64, &l_request, sizeof(l_request));
     s_ch_chain_go_idle(l_ch_chain);
-    if (l_ch_chain->callback_notify_packet_out)
-        l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS,
-                                                NULL, 0, l_ch_chain->callback_notify_arg);
     DAP_DELETE(l_sync_request);
 }
 /**
@@ -431,9 +422,6 @@ static void s_sync_out_gdb_first_worker_callback(dap_worker_t *a_worker, void *a
     dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB,
             l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64,
             l_ch_chain->request_hdr.cell_id.uint64, &g_node_addr, sizeof(dap_chain_node_addr_t));
-    if(l_ch_chain->callback_notify_packet_out)
-        l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB,
-                                                NULL, 0, l_ch_chain->callback_notify_arg);
 
     if( a_worker){ // We send NULL to prevent delete
         s_sync_request_delete(l_sync_request);
@@ -469,9 +457,6 @@ static void s_sync_out_gdb_last_worker_callback(dap_worker_t *a_worker, void *a_
                                          l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64,
                                          l_ch_chain->request_hdr.cell_id.uint64, NULL, 0);
     s_ch_chain_go_idle(l_ch_chain);
-    if(l_ch_chain->callback_notify_packet_out)
-        l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB,
-                                                NULL, 0, l_ch_chain->callback_notify_arg);
     s_sync_request_delete(l_sync_request);
 }
 
@@ -616,10 +601,12 @@ static bool s_sync_in_chains_callback(void *a_arg)
     if (s_debug_more)
         dap_get_data_hash_str_static(l_atom, l_atom_size, l_atom_hash_str);
     dap_chain_atom_verify_res_t l_atom_add_res = l_chain->callback_atom_add(l_chain, l_atom, l_atom_size);
+    bool l_ack_send = false;
     switch (l_atom_add_res) {
     case ATOM_PASS:
         debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s not accepted (code ATOM_PASS, already present)",
                                                 l_atom_hash_str, l_chain->net_name, l_chain->name);
+        l_ack_send = true;
         break;
     case ATOM_MOVE_TO_THRESHOLD:
         debug_if(s_debug_more, L_INFO, "Thresholded atom with hash %s for %s:%s", l_atom_hash_str, l_chain->net_name, l_chain->name);
@@ -628,18 +615,8 @@ static bool s_sync_in_chains_callback(void *a_arg)
         debug_if(s_debug_more, L_INFO,"Accepted atom with hash %s for %s:%s", l_atom_hash_str, l_chain->net_name, l_chain->name);
         if (dap_chain_atom_save(l_chain->cells, l_atom, l_atom_size, NULL) < 0)
             log_it(L_ERROR, "Can't save atom %s to the file", l_atom_hash_str);
-        if (l_args->ack_req) {
-            uint64_t l_ack_num = (l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo;
-            dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
-                                                             &l_ack_num, sizeof(uint64_t));
-            dap_stream_ch_pkt_send_by_addr(&l_args->addr, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK, l_pkt, dap_chain_ch_pkt_get_size(l_pkt));
-            DAP_DELETE(l_pkt);
-            debug_if(s_debug_more, L_DEBUG, "Out: CHAIN_ACK %s for net %s to destination " NODE_ADDR_FP_STR " with num %" DAP_UINT64_FORMAT_U,
-                                    l_chain ? l_chain->name : "(null)",
-                                                l_chain ? l_chain->net_name : "(null)",
-                                                                NODE_ADDR_FP_ARGS_S(l_args->addr),
-                                    l_ack_num);
-        }
+        else
+            l_ack_send = true;
         break;
     case ATOM_REJECT: {
         debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s rejected", l_atom_hash_str, l_chain->net_name, l_chain->name);
@@ -649,6 +626,18 @@ static bool s_sync_in_chains_callback(void *a_arg)
         log_it(L_CRITICAL, "Wtf is this ret code? %d", l_atom_add_res);
         break;
     }
+    if (l_ack_send && l_args->ack_req) {
+        uint64_t l_ack_num = (l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo;
+        dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                                                         &l_ack_num, sizeof(uint64_t));
+        dap_stream_ch_pkt_send_by_addr(&l_args->addr, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK, l_pkt, dap_chain_ch_pkt_get_size(l_pkt));
+        DAP_DELETE(l_pkt);
+        debug_if(s_debug_more, L_DEBUG, "Out: CHAIN_ACK %s for net %s to destination " NODE_ADDR_FP_STR " with num %" DAP_UINT64_FORMAT_U,
+                                l_chain ? l_chain->name : "(null)",
+                                            l_chain ? l_chain->net_name : "(null)",
+                                                            NODE_ADDR_FP_ARGS_S(l_args->addr),
+                                l_ack_num);
+    }
     DAP_DELETE(l_args);
     return false;
 }
@@ -686,7 +675,7 @@ static void s_gdb_in_pkt_error_worker_callback(dap_worker_t *a_worker, void *a_a
     if (l_ch == NULL)
         log_it(L_INFO,"Client disconnected before we sent the reply");
     else
-        s_stream_ch_write_error_unsafe(l_ch, l_sync_request->request_hdr.net_id.uint64,
+        dap_stream_ch_write_error_unsafe(l_ch, l_sync_request->request_hdr.net_id.uint64,
                                            l_sync_request->request_hdr.chain_id.uint64,
                                            l_sync_request->request_hdr.cell_id.uint64,
                                            DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED);
@@ -720,7 +709,7 @@ struct sync_request *dap_chain_ch_create_sync_request(dap_chain_ch_pkt_t *a_chai
     return l_sync_request;
 }
 
-static void s_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error)
+void dap_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error)
 {
     dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch);
     if (!l_ch_chain) {
@@ -746,12 +735,8 @@ static bool s_chain_timer_callback(void *a_arg)
         return false;
     }
     if (l_ch_chain->timer_shots++ >= DAP_SYNC_TICKS_PER_SECOND * s_sync_timeout) {
-        if (!s_ch_chain_get_idle(l_ch_chain)) {
+        if (!s_ch_chain_get_idle(l_ch_chain))
             s_ch_chain_go_idle(l_ch_chain);
-            if (l_ch_chain->callback_notify_packet_out)
-                l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_TIMEOUT, NULL, 0,
-                                                      l_ch_chain->callback_notify_arg);
-        }
         DAP_DELETE(a_arg);
         l_ch_chain->activity_timer = NULL;
         return false;
@@ -794,18 +779,18 @@ void dap_chain_ch_timer_start(dap_chain_ch_t *a_ch_chain)
  * @param a_ch
  * @param a_arg
  */
-void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
+static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 {
     dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch);
     if (!l_ch_chain || l_ch_chain->_inheritor != a_ch) {
         log_it(L_ERROR, "No chain in channel, returning");
-        return;
+        return false;
     }
     dap_stream_ch_pkt_t * l_ch_pkt = (dap_stream_ch_pkt_t *) a_arg;
     if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_ch_pkt_t)) {
         log_it(L_ERROR, "Corrupted packet: too small size %u, smaller then header size %zu",
                                             l_ch_pkt->hdr.data_size, sizeof(dap_chain_ch_pkt_t));
-        return;
+        return false;
     }
 
     dap_chain_ch_pkt_t *l_chain_pkt = (dap_chain_ch_pkt_t *)l_ch_pkt->data;
@@ -814,13 +799,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
     if (l_chain_pkt->hdr.version > DAP_CHAIN_CH_PKT_VERSION) {
         debug_if(s_debug_more, L_ATT, "Unsupported protocol version %d, current version %d",
                  l_chain_pkt->hdr.version, DAP_CHAIN_CH_PKT_VERSION);
-        return;
+        return false;
     }
     if (l_chain_pkt->hdr.version >= 2 &&
                 l_chain_pkt_data_size != l_chain_pkt->hdr.data_size) {
         log_it(L_WARNING, "Incorrect chain packet size %zu, expected %u",
                             l_chain_pkt_data_size, l_chain_pkt->hdr.data_size);
-        return;
+        return false;
     }
 
     s_chain_timer_reset(l_ch_chain);
@@ -843,21 +828,21 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         dap_cluster_t *l_cluster = dap_cluster_find(dap_guuid_compose(l_chain_pkt->hdr.net_id.uint64, 0));
         if (!l_cluster) {
             log_it(L_WARNING, "Can't find cluster with ID 0x%" DAP_UINT64_FORMAT_X, l_chain_pkt->hdr.net_id.uint64);
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND);
-            break;
+            return false;
         }
         dap_cluster_member_t *l_check = dap_cluster_member_find_unsafe(l_cluster, &a_ch->stream->node);
         if (!l_check) {
             log_it(L_WARNING, "Node with addr "NODE_ADDR_FP_STR" isn't a member of cluster %s",
                                         NODE_ADDR_FP_ARGS_S(a_ch->stream->node), l_cluster->mnemonim);
-            break;
+            return false;
         }
         struct atom_processing_args *l_args = DAP_NEW_SIZE(struct atom_processing_args, l_ch_pkt->hdr.data_size + sizeof(struct atom_processing_args));
         if (!l_args) {
             log_it(L_CRITICAL, g_error_memory_alloc);
-            return;
+            break;
         }
         l_args->addr = a_ch->stream->node;
         l_args->ack_req = true;
@@ -873,49 +858,61 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
     } break;
 
     case DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ: {
-        if (l_chain_pkt_data_size != sizeof(dap_hash_fast_t)) {
+        if (l_chain_pkt_data_size != sizeof(dap_chain_ch_sync_request_t)) {
             log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ: Wrong chain packet size %zd when expected %zd",
-                                                                            l_chain_pkt_data_size, sizeof(dap_hash_fast_t));
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                                                                            l_chain_pkt_data_size, sizeof(dap_chain_ch_sync_request_t));
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
-            break;
+            return false;
         }
+        dap_chain_ch_sync_request_t *l_request = (dap_chain_ch_sync_request_t *)l_chain_pkt->data;
         if (s_debug_more)
-            log_it(L_INFO, "In: CHAIN_REQ pkt: net 0x%016" DAP_UINT64_FORMAT_x " chain 0x%016" DAP_UINT64_FORMAT_x " cell 0x%016" DAP_UINT64_FORMAT_x,
-                            l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64);
+            log_it(L_INFO, "In: CHAIN_REQ pkt: net 0x%016" DAP_UINT64_FORMAT_x " chain 0x%016" DAP_UINT64_FORMAT_x
+                            " cell 0x%016" DAP_UINT64_FORMAT_x ", hash from %s, num from %" DAP_UINT64_FORMAT_U,
+                            l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                            dap_hash_fast_to_str_static(&l_request->hash_from), l_request->num_from);
         if (l_ch_chain->sync_context) {
             log_it(L_WARNING, "Can't process CHAIN_REQ request cause already busy with syncronization");
             dap_chain_ch_pkt_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS);
-            break;
+            return false;
         }
         dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
         if (!l_chain) {
             log_it(L_WARNING, "Not found chain id 0x%016" DAP_UINT64_FORMAT_x " with net id 0x%016" DAP_UINT64_FORMAT_x,
                                                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.net_id.uint64);
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND);
-            break;
+            return false;
         }
         if (!dap_link_manager_get_net_condition(l_chain_pkt->hdr.net_id.uint64)) {
             log_it(L_WARNING, "Net id 0x%016" DAP_UINT64_FORMAT_x " is offline", l_chain_pkt->hdr.net_id.uint64);
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE);
+            return false;
+        }
+        bool l_sync_from_begin = dap_hash_fast_is_blank(&l_request->hash_from);
+        dap_chain_atom_iter_t *l_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, l_sync_from_begin
+                                                                           ? NULL : &l_request->hash_from);
+        if (!l_iter) {
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                    DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY);
             break;
         }
-        dap_hash_fast_t *l_requested_hash = (dap_hash_fast_t *)l_chain_pkt->data;
-        if (dap_hash_fast_is_blank(l_requested_hash))
-            l_requested_hash = NULL;
-        dap_chain_atom_iter_t *l_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, l_requested_hash);
-        if (!l_requested_hash)
+        if (l_sync_from_begin)
             l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, NULL);
+        bool l_missed_hash = false;
         if (l_iter->cur) {
-            dap_chain_ch_summary_t l_sum = { .num_cur = l_requested_hash ? l_iter->cur_num : 0, .num_last = l_chain->callback_count_atom(l_chain) };
-            if (l_sum.num_last - l_sum.num_cur) {
+            uint64_t l_last_num = l_chain->callback_count_atom(l_chain);
+            if (l_sync_from_begin ||
+                    (l_request->num_from == l_iter->cur_num &&
+                    l_last_num > l_iter->cur_num)) {
+                dap_chain_ch_summary_t l_sum = { .num_cur = l_iter->cur_num, .num_last = l_last_num };
                 dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY,
                                                 l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
                                                 l_chain_pkt->hdr.cell_id.uint64, &l_sum, sizeof(l_sum));
@@ -938,15 +935,41 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                 l_ch_chain->sync_timer = dap_timerfd_start_on_worker(a_ch->stream_worker->worker, 1000, s_sync_timer_callback, l_ch_chain);
                 break;
             }
-        } else
-            debug_if(s_debug_more, L_DEBUG, "Requested atom with hash %s not found", dap_hash_fast_to_str_static(l_requested_hash));
-        dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN,
-                                      l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
-                                      l_chain_pkt->hdr.cell_id.uint64, NULL, 0);
-        debug_if(s_debug_more, L_DEBUG, "Out: SYNCED_CHAIN %s for net %s to destination " NODE_ADDR_FP_STR,
-                                l_chain ? l_chain->name : "(null)",
-                                            l_chain ? l_chain->net_name : "(null)",
-                                                            NODE_ADDR_FP_ARGS_S(a_ch->stream->node));
+            if (l_request->num_from < l_iter->cur_num || l_last_num > l_iter->cur_num)
+                l_missed_hash = true;
+        } else if (!l_sync_from_begin) {
+            l_missed_hash = true;
+            debug_if(s_debug_more, L_DEBUG, "Requested atom with hash %s not found", dap_hash_fast_to_str_static(&l_request->hash_from));
+        }
+        if (l_missed_hash) {
+            l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_LAST, NULL);
+            dap_chain_ch_miss_info_t l_miss_info = { .missed_hash = l_request->hash_from,
+                                                     .last_hash = *l_iter->cur_hash,
+                                                     .last_num = l_iter->cur_num };
+            dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS,
+                                          l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
+                                          l_chain_pkt->hdr.cell_id.uint64, &l_miss_info, sizeof(l_miss_info));
+            if (s_debug_more) {
+                char l_last_hash_str[DAP_HASH_FAST_STR_SIZE];
+                dap_hash_fast_to_str(&l_miss_info.last_hash, l_last_hash_str, DAP_HASH_FAST_STR_SIZE);
+                log_it(L_INFO, "Out: CHAIN_MISS %s for net %s to source " NODE_ADDR_FP_STR
+                                             " with hash missed %s, hash last %s and num last %" DAP_UINT64_FORMAT_U,
+                        l_chain ? l_chain->name : "(null)",
+                                    l_chain ? l_chain->net_name : "(null)",
+                                                    NODE_ADDR_FP_ARGS_S(a_ch->stream->node),
+                        dap_hash_fast_to_str_static(&l_miss_info.missed_hash),
+                        l_last_hash_str,
+                        l_miss_info.last_num);
+            }
+        } else {
+            dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN,
+                                          l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
+                                          l_chain_pkt->hdr.cell_id.uint64, NULL, 0);
+            debug_if(s_debug_more, L_DEBUG, "Out: SYNCED_CHAIN %s for net %s to destination " NODE_ADDR_FP_STR,
+                                    l_chain ? l_chain->name : "(null)",
+                                                l_chain ? l_chain->net_name : "(null)",
+                                                                NODE_ADDR_FP_ARGS_S(a_ch->stream->node));
+        }
         l_chain->callback_atom_iter_delete(l_iter);
     } break;
 
@@ -954,10 +977,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         if (l_chain_pkt_data_size != sizeof(dap_chain_ch_summary_t)) {
             log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY: Wrong chain packet size %zd when expected %zd",
                                                                             l_chain_pkt_data_size, sizeof(dap_chain_ch_summary_t));
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
-            break;
+            return false;
         }
         dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
         dap_chain_ch_summary_t *l_sum = (dap_chain_ch_summary_t *)l_chain_pkt->data;
@@ -973,10 +996,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         if (l_chain_pkt_data_size != sizeof(uint64_t)) {
             log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK: Wrong chain packet size %zd when expected %zd",
                                                                             l_chain_pkt_data_size, sizeof(uint64_t));
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
-            break;
+            return false;
         }
         uint64_t l_ack_num = *(uint64_t *)l_chain_pkt->data;
         dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
@@ -988,7 +1011,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         struct sync_context *l_context = l_ch_chain->sync_context;
         if (!l_context) {
             log_it(L_WARNING, "CHAIN_ACK: No active sync context");
-            s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                     DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE);
             break;
@@ -1018,10 +1041,37 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                                                 NODE_ADDR_FP_ARGS_S(a_ch->stream->node));
     } break;
 
+    case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: {
+        if (l_chain_pkt_data_size != sizeof(dap_chain_ch_miss_info_t)) {
+            log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: Wrong chain packet size %zd when expected %zd",
+                                                                            l_chain_pkt_data_size, sizeof(dap_chain_ch_miss_info_t));
+            dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                    DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
+            return false;
+        }
+        dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
+        dap_chain_ch_miss_info_t *l_miss_info = (dap_chain_ch_miss_info_t *)l_chain_pkt->data;
+        if (s_debug_more) {
+            char l_last_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_miss_info->last_hash, l_last_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_INFO, "In: CHAIN_MISS %s for net %s from source " NODE_ADDR_FP_STR
+                                         " with hash missed %s, hash last %s and num last %" DAP_UINT64_FORMAT_U,
+                    l_chain ? l_chain->name : "(null)",
+                                l_chain ? l_chain->net_name : "(null)",
+                                                NODE_ADDR_FP_ARGS_S(a_ch->stream->node),
+                    dap_hash_fast_to_str_static(&l_miss_info->missed_hash),
+                    l_last_hash_str,
+                    l_miss_info->last_num);
+        }
+        // Will be processed upper in net packet notifier callback
+    } break;
+
     default:
-        s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+        dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                                             l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                                             DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE);
+        return false;
 
 //    }
 //}
@@ -1040,8 +1090,8 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
             }
             log_it(L_INFO, "In:  UPDATE_GLOBAL_DB_REQ pkt: net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x,
                             l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64);
-            if (l_chain_pkt_data_size == (size_t)sizeof(dap_chain_ch_sync_request_t))
-                l_ch_chain->request = *(dap_chain_ch_sync_request_t*)l_chain_pkt->data;
+            if (l_chain_pkt_data_size == (size_t)sizeof(dap_chain_ch_sync_request_old_t))
+                l_ch_chain->request = *(dap_chain_ch_sync_request_old_t*)l_chain_pkt->data;
             struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch);
             l_ch_chain->stats_request_gdb_processed = 0;
             l_ch_chain->request_hdr = l_chain_pkt->hdr;
@@ -1077,7 +1127,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                     memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id,
                            sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) {
                 log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB request because its already busy with syncronization");
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS);
                 break;
@@ -1094,7 +1144,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                     l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t);
                     if (!l_hash_item) {
                         log_it(L_CRITICAL, "Memory allocation error");
-                        return;
+                        break;
                     }
                     l_hash_item->hash = l_element->hash;
                     l_hash_item->size = l_element->size;
@@ -1110,25 +1160,25 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         } break;
         // End of response with starting of DB sync
         case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: {
-            if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t)) {
+            if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t)) {
                 if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE ||
                         memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id,
                                sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) {
                     log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_END request because its already busy with syncronization");
-                    s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                             l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                             DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS);
                     break;
                 }
                 debug_if(s_debug_more, L_INFO, "In: UPDATE_GLOBAL_DB_END pkt with total count %d hashes",
                                         HASH_COUNT(l_ch_chain->remote_gdbs));
-                if (l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t))
-                    l_ch_chain->request = *(dap_chain_ch_sync_request_t*)l_chain_pkt->data;
+                if (l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t))
+                    l_ch_chain->request = *(dap_chain_ch_sync_request_old_t*)l_chain_pkt->data;
                 struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch);
                 dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_gdb_proc_callback, l_sync_request);
             } else {
                 log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: Wrong chain packet size %zd when expected %zd", l_chain_pkt_data_size, sizeof(l_ch_chain->request));
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
             }
@@ -1143,7 +1193,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                               l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, NODE_ADDR_FP_ARGS_S(l_ch_chain->request.node_addr) );
             }else {
                log_it(L_WARNING,"Incorrect data size %zu in packet DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB", l_chain_pkt_data_size);
-               s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+               dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                        l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                        DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
             }
@@ -1161,7 +1211,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                 dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_gdb_in_pkt_proc_callback, l_sync_request);
             } else {
                 log_it(L_WARNING, "Packet with GLOBAL_DB atom has zero body size");
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
             }
@@ -1170,12 +1220,11 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         case DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB: {
                 log_it(L_INFO, "In:  SYNCED_GLOBAL_DB: net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x,
                                 l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64);
-                if (!l_ch_chain->callback_notify_packet_in) { // we haven't node client waitng, so reply to other side
-                    dap_chain_ch_sync_request_t l_sync_gdb = {};
-                    l_sync_gdb.node_addr.uint64 = g_node_addr.uint64;
-                    dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ, l_chain_pkt->hdr.net_id.uint64,
-                                                  l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_sync_gdb, sizeof(l_sync_gdb));
-                }
+                // we haven't node client waitng, so reply to other side
+                dap_chain_ch_sync_request_old_t l_sync_gdb = {};
+                l_sync_gdb.node_addr.uint64 = g_node_addr.uint64;
+                dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ, l_chain_pkt->hdr.net_id.uint64,
+                                              l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_sync_gdb, sizeof(l_sync_gdb));
         } break;
 
         /// --- Chains update ---
@@ -1183,7 +1232,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ:{
             if (l_ch_chain->state != DAP_CHAIN_CH_STATE_IDLE) {
                 log_it(L_WARNING, "Can't process UPDATE_CHAINS_REQ request because its already busy with syncronization");
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS);
                 break;
@@ -1226,7 +1275,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                                 " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet",
                                 a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
                                 l_chain_pkt->hdr.cell_id.uint64);
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                                                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                                                     DAP_CHAIN_CH_ERROR_NET_INVALID_ID);
                 // Who are you? I don't know you! go away!
@@ -1250,7 +1299,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                                 a_ch->stream->esocket->remote_addr_str,
                                 l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
                                 l_chain_pkt->hdr.cell_id.uint64);
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                                                     l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                                                     DAP_CHAIN_CH_ERROR_NET_INVALID_ID);
                 // Who are you? I don't know you! go away!
@@ -1269,7 +1318,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                     l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t);
                     if (!l_hash_item) {
                         log_it(L_CRITICAL, "Memory allocation error");
-                        return;
+                        break;
                     }
                     l_hash_item->hash = l_element->hash;
                     l_hash_item->size = l_element->size;
@@ -1290,12 +1339,12 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         } break;
 
         case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: {
-            if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t)) {
+            if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t)) {
                 if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE ||
                         memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id,
                                sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) {
                     log_it(L_WARNING, "Can't process UPDATE_CHAINS_END request because its already busy with syncronization");
-                    s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                             l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                             DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS);
                     break;
@@ -1306,7 +1355,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                                     " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet",
                                     a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64,
                                     l_chain_pkt->hdr.cell_id.uint64);
-                    s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                    dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                                                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                                                         DAP_CHAIN_CH_ERROR_NET_INVALID_ID);
                     break;
@@ -1320,7 +1369,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
             } else {
                 log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: Wrong chain packet size %zd when expected %zd",
                        l_chain_pkt_data_size, sizeof(l_ch_chain->request));
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
             }
@@ -1336,7 +1385,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                                l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64);
             }else{
                 log_it(L_WARNING,"Incorrect data size %zd in packet DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN", l_chain_pkt_data_size);
-                s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
                         l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
                         DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE);
             }
@@ -1357,30 +1406,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                 dap_timerfd_delete_unsafe(l_ch_chain->activity_timer);
                 l_ch_chain->activity_timer = NULL;
             }
-            if (!l_ch_chain->callback_notify_packet_in) { // we haven't node client waitng, so reply to other side
-                dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
-                if (!l_chain) {
-                    log_it(L_ERROR, "Invalid SYNCED_CHAINS packet from %s with net id 0x%016"DAP_UINT64_FORMAT_x
-                                    " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet",
-                                    a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64,
-                                    l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64);
-                    s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
-                                                        l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
-                                                        DAP_CHAIN_CH_ERROR_NET_INVALID_ID);
-                    break;
-                }
-                if (s_debug_more) {
-                    log_it(L_INFO, "Out: UPDATE_CHAINS_REQ pkt");
-                }
-                dap_chain_ch_sync_request_t l_request= {};
-                dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ, l_chain_pkt->hdr.net_id.uint64,
-                                              l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_request, sizeof(l_request));
+            // we haven't node client waitng, so reply to other side
+            dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id);
+            if (!l_chain) {
+                log_it(L_ERROR, "Invalid SYNCED_CHAINS packet from %s with net id 0x%016"DAP_UINT64_FORMAT_x
+                                " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet",
+                                a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64,
+                                l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64);
+                dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
+                                                    l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
+                                                    DAP_CHAIN_CH_ERROR_NET_INVALID_ID);
+                break;
+            }
+            if (s_debug_more) {
+                log_it(L_INFO, "Out: UPDATE_CHAINS_REQ pkt");
             }
+            dap_chain_ch_sync_request_old_t l_request= {};
+            dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ, l_chain_pkt->hdr.net_id.uint64,
+                                          l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_request, sizeof(l_request));
         } break;
     }
-    if(l_ch_chain->callback_notify_packet_in)
-        l_ch_chain->callback_notify_packet_in(l_ch_chain, l_ch_pkt->hdr.type, l_chain_pkt,
-                                              l_chain_pkt_data_size, l_ch_chain->callback_notify_arg);
+    return true;
 }
 
 static bool s_sync_timer_callback(void *a_arg)
@@ -1388,6 +1434,13 @@ static bool s_sync_timer_callback(void *a_arg)
     dap_chain_ch_t *l_ch_chain = a_arg;
     struct sync_context *l_context = l_ch_chain->sync_context;
     if (l_context->last_activity + s_sync_timeout <= dap_time_now()) {
+        log_it(L_ERROR, "Sync timeout for node " NODE_ADDR_FP_STR " with net 0x%016" DAP_UINT64_FORMAT_x
+                            " chain 0x%016" DAP_UINT64_FORMAT_x " cell 0x%016" DAP_UINT64_FORMAT_x,
+                                        NODE_ADDR_FP_ARGS_S(l_context->addr), l_context->net_id.uint64,
+                                        l_context->chain_id.uint64, l_context->cell_id.uint64);
+        dap_stream_ch_write_error_unsafe(DAP_STREAM_CH(l_ch_chain), l_context->net_id.uint64,
+                                         l_context->chain_id.uint64, l_context->cell_id.uint64,
+                                         DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT);
         l_ch_chain->sync_timer = NULL;
         s_ch_chain_go_idle(l_ch_chain);
         return false;
@@ -1617,7 +1670,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                                                  l_ch_chain->request_hdr.net_id.uint64,
                                                  l_ch_chain->request_hdr.chain_id.uint64,
                                                  l_ch_chain->request_hdr.cell_id.uint64,
-                                                 &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_t));
+                                                 &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_old_t));
             debug_if(s_debug_more, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END");
             l_go_idle = true;
         }
@@ -1650,7 +1703,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                                                      l_ch_chain->request_hdr.net_id.uint64,
                                                      l_ch_chain->request_hdr.chain_id.uint64,
                                                      l_ch_chain->request_hdr.cell_id.uint64,
-                                                     &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_t));
+                                                     &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_old_t));
                 if (s_debug_more )
                     log_it(L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END");
                 l_go_idle = true;
@@ -1700,7 +1753,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
         } else if (!l_objs) {
             l_was_sent_smth = true;
             // last message
-            dap_chain_ch_sync_request_t l_request = { };
+            dap_chain_ch_sync_request_old_t l_request = { };
             s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB,
                                         l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64,
                                         l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request));
@@ -1769,7 +1822,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                 log_it( L_INFO,"Syncronized database: items syncronyzed %"DAP_UINT64_FORMAT_U" from %zu",
                         l_ch_chain->stats_request_gdb_processed, dap_db_log_list_get_count(l_ch_chain->request_db_log));
                 // last message
-                dap_chain_ch_sync_request_t l_request = {};
+                dap_chain_ch_sync_request_old_t l_request = {};
                 s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB,
                                                      l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64,
                                                      l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request));
@@ -1807,12 +1860,12 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                 l_was_sent_smth = true;
                 if(s_debug_more)
                     log_it(L_INFO,"Out: UPDATE_CHAINS_END sent ");
-                dap_chain_ch_sync_request_t l_request = {};
+                dap_chain_ch_sync_request_old_t l_request = {};
                 s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END,
                                                      l_ch_chain->request_hdr.net_id.uint64,
                                                      l_ch_chain->request_hdr.chain_id.uint64,
                                                      l_ch_chain->request_hdr.cell_id.uint64,
-                                                     &l_request, sizeof(dap_chain_ch_sync_request_t));
+                                                     &l_request, sizeof(dap_chain_ch_sync_request_old_t));
                 l_go_idle = true;
                 dap_stream_ch_set_ready_to_write_unsafe(a_ch, false);
             }
@@ -1868,7 +1921,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                     break;
             }
             if(!l_ch_chain->request_atom_iter || !l_ch_chain->request_atom_iter->cur)  { // All chains synced
-                dap_chain_ch_sync_request_t l_request = {};
+                dap_chain_ch_sync_request_old_t l_request = {};
                 // last message
                 l_was_sent_smth = true;
                 s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS,
@@ -1876,9 +1929,6 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg)
                                                      l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request));
                 log_it( L_INFO,"Synced: %"DAP_UINT64_FORMAT_U" atoms processed", l_ch_chain->stats_request_atoms_processed);
                 l_go_idle = true;
-                if (l_ch_chain->callback_notify_packet_out)
-                    l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS, NULL,
-                                                           0, l_ch_chain->callback_notify_arg);
             }
         } break;
 
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 59237d96057b64a84641848127359a4bd9ca3712..a0b865f378f72e2441265157b2eaa427e0e052f6 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -95,6 +95,7 @@ typedef size_t (*dap_chain_callback_atom_get_hdr_size_t)(void);
 typedef dap_chain_atom_iter_t * (*dap_chain_callback_atom_iter_create_t)(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash_from);
 typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_t)(dap_chain_atom_iter_t *a_iter, dap_chain_iter_op_t a_operation, size_t *a_atom_size);
 typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_find_by_hash_t)(dap_chain_atom_iter_t *a_iter, dap_hash_fast_t *a_atom_hash, size_t *a_atom_size);
+typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_by_num_t)(dap_chain_atom_iter_t *a_iter, uint64_t a_atom_num);
 typedef void (*dap_chain_callback_atom_iter_delete_t)(dap_chain_atom_iter_t *);
 
 typedef dap_chain_datum_iter_t * (*dap_chain_datum_callback_iter_create_t)(dap_chain_t *);
@@ -178,6 +179,7 @@ typedef struct dap_chain {
     dap_chain_callback_atom_get_timestamp_t callback_atom_get_timestamp;
 
     dap_chain_callback_atom_iter_find_by_hash_t callback_atom_find_by_hash;
+    dap_chain_callback_atom_iter_get_by_num_t callback_atom_get_by_num;
     dap_chain_callback_datum_find_by_hash_t callback_datum_find_by_hash;
 
     dap_chain_callback_block_find_by_hash_t callback_block_find_by_tx_hash;
@@ -258,7 +260,11 @@ dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net
 void dap_chain_delete(dap_chain_t * a_chain);
 void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_arg);
 dap_chain_atom_ptr_t dap_chain_get_atom_by_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
-bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_hash_fast_t *a_atom_hash, dap_chain_cell_id_t a_cell_id);
+bool dap_chain_get_atom_last_hash_num(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash, uint64_t *a_atom_num);
+DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash)
+{
+    return dap_chain_get_atom_last_hash_num(a_chain, a_cell_id, a_atom_hash, NULL);
+}
 ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash);
 int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name);
 const char* dap_chain_get_path(dap_chain_t *a_chain);
diff --git a/modules/chain/include/dap_chain_ch.h b/modules/chain/include/dap_chain_ch.h
index 13554e358f8f4f068057fad9cce83fe85eefd9a1..9d51f6319edd336118b3ef1e375a0cf6171dbc1c 100644
--- a/modules/chain/include/dap_chain_ch.h
+++ b/modules/chain/include/dap_chain_ch.h
@@ -50,13 +50,16 @@ typedef enum dap_chain_ch_state {
 typedef enum dap_chain_ch_error_type {
     DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS,
     DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE,
+    DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT,
     DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE,
     DAP_CHAIN_CH_ERROR_NET_INVALID_ID,
     DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND,
     DAP_CHAIN_CH_ERROR_ATOM_NOT_FOUND,
     DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE,
     DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED,
-    DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE
+    DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE,
+    DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY,
+    DAP_CHAIN_CH_ERROR_INTERNAL
 } dap_chain_ch_error_type_t;
 
 typedef struct dap_chain_ch dap_chain_ch_t;
@@ -68,7 +71,7 @@ typedef struct dap_chain_pkt_item {
     byte_t *pkt_data;
 } dap_chain_pkt_item_t;
 
-typedef struct dap_chain_ch_hash_item{
+typedef struct dap_chain_ch_hash_item {
     dap_hash_fast_t hash;
     uint32_t size;
     UT_hash_handle hh;
@@ -92,17 +95,13 @@ typedef struct dap_chain_ch {
     // request section
     dap_chain_atom_iter_t *request_atom_iter;
     //dap_db_log_list_t *request_db_log; // list of global db records
-    dap_chain_ch_sync_request_t request;
+    dap_chain_ch_sync_request_old_t request;
     dap_chain_ch_pkt_hdr_t request_hdr;
     dap_list_t *request_db_iter;
 
     uint32_t timer_shots;
     dap_timerfd_t *activity_timer;
     int sent_breaks;
-
-    dap_chain_ch_callback_packet_t callback_notify_packet_out;
-    dap_chain_ch_callback_packet_t callback_notify_packet_in;
-    void *callback_notify_arg;
 } dap_chain_ch_t;
 
 #define DAP_CHAIN_CH(a) ((dap_chain_ch_t *) ((a)->internal) )
@@ -114,4 +113,5 @@ int dap_chain_ch_init(void);
 void dap_chain_ch_deinit(void);
 
 void dap_chain_ch_timer_start(dap_chain_ch_t *a_ch_chain);
-void dap_chain_ch_reset_unsafe(dap_chain_ch_t *a_ch_chain);
+
+void dap_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error);
diff --git a/modules/chain/include/dap_chain_ch_pkt.h b/modules/chain/include/dap_chain_ch_pkt.h
index 68046ededd862aa238032d327b81a5e2cedd47fb..0c721f1408379a5972fdf7138514607b9574cacc 100644
--- a/modules/chain/include/dap_chain_ch_pkt.h
+++ b/modules/chain/include/dap_chain_ch_pkt.h
@@ -60,6 +60,7 @@
 
 // Stable
 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ                 0x80
+#define DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS                0x69
 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN                     0x01
 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY             0x81
 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK                 0x82
@@ -75,15 +76,33 @@
 #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_HASH_FIRST   0x0004   // Hash of first(s) item
 #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_LAST_ID      0x0100   // Last ID of GDB synced group
 
+// *** Legacy *** //
+
 typedef struct dap_chain_ch_update_element{
     dap_hash_fast_t hash;
     uint32_t size;
 } DAP_ALIGN_PACKED dap_chain_ch_update_element_t;
 
-typedef struct dap_chain_ch_sync_request{
+typedef struct dap_chain_ch_sync_request_old {
     dap_chain_node_addr_t node_addr; // Requesting node's address
     dap_chain_hash_fast_t hash_from;
     byte_t unused[96];
+} DAP_ALIGN_PACKED dap_chain_ch_sync_request_old_t;
+
+static const char* c_dap_chain_ch_pkt_type_str[]={
+    [DAP_CHAIN_CH_PKT_TYPE_CHAIN] = "DAP_CHAIN_CH_PKT_TYPE_CHAIN",
+    [DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB",
+    [DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS",
+    [DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB",
+    [DAP_CHAIN_CH_PKT_TYPE_ERROR] = "DAP_CHAIN_CH_PKT_TYPE_ERROR"
+
+};
+
+// *** Active *** //
+
+typedef struct dap_chain_ch_sync_request {
+    dap_chain_hash_fast_t hash_from;
+    uint64_t num_from;
 } DAP_ALIGN_PACKED dap_chain_ch_sync_request_t;
 
 typedef struct dap_chain_ch_summary {
@@ -92,6 +111,12 @@ typedef struct dap_chain_ch_summary {
     byte_t reserved[128];
 } DAP_ALIGN_PACKED dap_chain_ch_summary_t;
 
+typedef struct dap_chain_ch_miss_info {
+    dap_hash_fast_t missed_hash;
+    dap_hash_fast_t last_hash;
+    uint64_t last_num;
+} DAP_ALIGN_PACKED dap_chain_ch_miss_info_t;
+
 typedef struct dap_chain_ch_pkt_hdr {
     uint8_t version;
     uint8_t num_hi;
@@ -107,15 +132,6 @@ typedef struct dap_chain_ch_pkt {
     uint8_t data[];
 } DAP_ALIGN_PACKED dap_chain_ch_pkt_t;
 
-static const char* c_dap_chain_ch_pkt_type_str[]={
-    [DAP_CHAIN_CH_PKT_TYPE_CHAIN] = "DAP_CHAIN_CH_PKT_TYPE_CHAIN",
-    [DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB",
-    [DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS",
-    [DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB",
-    [DAP_CHAIN_CH_PKT_TYPE_ERROR] = "DAP_CHAIN_CH_PKT_TYPE_ERROR"
-
-};
-
 DAP_STATIC_INLINE size_t dap_chain_ch_pkt_get_size(dap_chain_ch_pkt_t *a_pkt) { return sizeof(dap_chain_ch_pkt_hdr_t) + a_pkt->hdr.data_size; }
 
 dap_chain_ch_pkt_t *dap_chain_ch_pkt_new(uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id,
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c
index 2ec116819d111324e8b84e310fdc29ce0aae1385..23d3aaac5a2808a68dec9aac455be73aba851857 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -59,7 +59,7 @@
 
 static void s_stream_ch_new(dap_stream_ch_t* ch, void* arg);
 static void s_stream_ch_delete(dap_stream_ch_t* ch, void* arg);
-static void s_stream_ch_packet_in(dap_stream_ch_t* ch, void* arg);
+static bool s_stream_ch_packet_in(dap_stream_ch_t* ch, void* arg);
 
 /**
  * @brief dap_stream_ch_chain_net_init
@@ -110,7 +110,7 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch, void* a_arg)
  * @param ch
  * @param arg
  */
-void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
+static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
 {
     dap_stream_ch_chain_net_t * l_ch_chain_net = DAP_STREAM_CH_CHAIN_NET(a_ch);
     if(l_ch_chain_net) {
@@ -119,18 +119,18 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
             char *l_data_hash_str;
             dap_get_data_hash_str_static(l_ch_pkt->data, l_ch_pkt->hdr.data_size, l_data_hash_str);
             log_it(L_ATT, "Receive test data packet with hash %s", l_data_hash_str);
-            return;
+            return false;
         }
         if (l_ch_pkt->hdr.data_size < sizeof(dap_stream_ch_chain_net_pkt_t)) {
             log_it(L_WARNING, "Too small stream channel N packet size %u (header size %zu)",
                                     l_ch_pkt->hdr.data_size, sizeof(dap_stream_ch_chain_net_pkt_t));
-            return;
+            return false;
         }
         dap_stream_ch_chain_net_pkt_t *l_ch_chain_net_pkt = (dap_stream_ch_chain_net_pkt_t *)l_ch_pkt->data;
         if (l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t) > l_ch_pkt->hdr.data_size) {
             log_it(L_WARNING, "Too small stream channel N packet size %u (expected at least %zu)",
                                     l_ch_pkt->hdr.data_size, l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t));
-            return;
+            return false;
         }
         dap_chain_net_t *l_net = dap_chain_net_by_id(l_ch_chain_net_pkt->hdr.net_id);
         if (!l_net) {
@@ -138,7 +138,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
             char l_err_str[] = "ERROR_NET_INVALID_ID";
             dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR ,
                                               l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str));
-            return;
+            return false;
         }
         if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR) {
             char *l_err_str = (char *)l_ch_chain_net_pkt->data;
@@ -147,7 +147,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
                 assert(!dap_stream_node_addr_is_blank(&a_ch->stream->node));
                 dap_link_manager_accounting_link_in_net(l_net->pub.id.uint64, &a_ch->stream->node, false);
             }
-            return;
+            return false;
         }
         uint16_t l_acl_idx = dap_chain_net_get_acl_idx(l_net);
         uint8_t l_acl = a_ch->stream->session->acl ? a_ch->stream->session->acl[l_acl_idx] : 1;
@@ -157,13 +157,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
             char l_err_str[] = "ERROR_NET_NOT_AUTHORIZED";
             dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR ,
                                               l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str));
-            return;
+            return false;
         }
         if (dap_chain_net_get_state(l_net) == NET_STATE_OFFLINE) {
             char l_err_str[] = "ERROR_NET_IS_OFFLINE";
             dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR,
                                               l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str));
-            return;
+            return false;
         }
         switch (l_ch_pkt->hdr.type) {
 
@@ -174,7 +174,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
                 char l_err_str[] = "ERROR_STREAM_NOT_AUTHORIZED";
                 dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR ,
                                                   l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str));
-                return;
+                break;
             }
             assert(!dap_stream_node_addr_is_blank(&a_ch->stream->node));
             dap_link_manager_accounting_link_in_net(l_net->pub.id.uint64, &a_ch->stream->node, true);
@@ -293,7 +293,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
 
         default:
             log_it(L_ERROR, "Unknown paket type %hhu", l_ch_pkt->hdr.type);
-            break;
+            return false;
         }
 
         if(l_ch_chain_net->notify_callback)
@@ -301,4 +301,5 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg)
                                             l_ch_chain_net_pkt->hdr.data_size, l_ch_chain_net->notify_callback_arg);
 
     }
+    return true;
 }
diff --git a/modules/common/CMakeLists.txt b/modules/common/CMakeLists.txt
index 79ce7eb3e44dfc280d9600754d066fef587185de..e1d05ec18bae2fba2e5b7e24102ca9107db03580 100644
--- a/modules/common/CMakeLists.txt
+++ b/modules/common/CMakeLists.txt
@@ -10,7 +10,7 @@ if(BUILD_CELLFRAME_SDK_TESTS)
     add_subdirectory(tests)
 endif()
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain_net)
 target_include_directories(${PROJECT_NAME} PUBLIC include/ )
 target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../dap-sdk/3rdparty/json-c)
 
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index 1dbb358441dd3dc4ba98c5ece3568677b21329fa..341f52c739b33fab85bbff206568e33d3635d0b8 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -134,7 +134,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok
         }
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD:
             if(l_tsd->size >= sizeof(dap_pkey_t)) {
-                char *l_hash_str;
+                const char *l_hash_str;
                 dap_pkey_t *l_pkey = (dap_pkey_t*)l_tsd->data;
                 dap_hash_fast_t l_hf = { };
                 if (!dap_pkey_get_hash(l_pkey, &l_hf)) {
@@ -152,7 +152,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE:
                 if(l_tsd->size == sizeof(dap_chain_hash_fast_t) ){
-                    char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash"))
+                    const char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash"))
                             ? dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*) l_tsd->data)
                             : dap_enc_base58_encode_hash_to_str_static((dap_chain_hash_fast_t*) l_tsd->data);
                     dap_string_append_printf(a_str_out,"total_pkeys_remove: %s\n", l_hash_str);
@@ -400,7 +400,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
     if (l_in_item && dap_hash_fast_is_blank(&l_in_item->header.tx_prev_hash))
         l_is_first = true;
     char l_tmp_buf[DAP_TIME_STR_SIZE];
-    char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+    const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
             ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash)
             : dap_chain_hash_fast_to_str_static(a_tx_hash);
     dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_datum->header.ts_created);
@@ -677,7 +677,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
         } break;
         case TX_ITEM_TYPE_VOTE:{
             dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item;
-            char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash);
+            const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash);
             dap_string_append_printf(a_str_out, "\t VOTE: \n"
                                                 "\t Voting hash: %s\n"
                                                 "\t Vote answer idx: %"DAP_UINT64_FORMAT_U"\n", l_hash_str, l_vote_item->answer_idx);
@@ -715,7 +715,7 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c
     }
     dap_hash_fast_t l_datum_hash;
     dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash);
-    char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+    const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
             ? dap_enc_base58_encode_hash_to_str_static(&l_datum_hash)
             : dap_chain_hash_fast_to_str_static(&l_datum_hash);
     switch (a_datum->header.type_id) {
diff --git a/modules/common/dap_chain_datum_anchor.c b/modules/common/dap_chain_datum_anchor.c
index a6110889698dd5828769a9797221dddd2d475805..58cdc378b7257a7476c41a29d617a1df3a635b9d 100644
--- a/modules/common/dap_chain_datum_anchor.c
+++ b/modules/common/dap_chain_datum_anchor.c
@@ -83,7 +83,7 @@ void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
             dap_string_append_printf(a_str_out, "<CORRUPTED - can't calc hash>\n");
             continue;
         }
-        char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+        const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
                 ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash)
                 : dap_chain_hash_fast_to_str_static(&l_pkey_hash);
         dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str,
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 38758a133ae949afc47c62ef1859caf438ae719f..6920023a493e992d1188653a5ccb0a2d7affe229 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -245,7 +245,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 }
                 dap_hash_fast_t *l_stake_tx = /*{ };
                 _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
-                char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
+                const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
                         ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
                         : dap_chain_hash_fast_to_str_static(l_stake_tx);
                 dap_string_append_printf(a_str_out, "\tStake tx: %s\n", l_stake_tx_hash);
@@ -269,7 +269,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
                 dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", dap_chain_addr_to_str(l_stake_addr_signing));
                 dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
-                char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
+                const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
                         ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
                         : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
                 dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
@@ -341,7 +341,7 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
             continue;
         }
 
-        char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+        const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
                 ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash)
                 : dap_chain_hash_fast_to_str_static(&l_pkey_hash);
         dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str,
diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c
index 8d1c75fc617429cffe57ae481bf78ad6378b54a7..bd1f2d3f8504e3ae369b4748bbc7fcae6040452e 100644
--- a/modules/common/dap_chain_datum_token.c
+++ b/modules/common/dap_chain_datum_token.c
@@ -282,7 +282,7 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_
             continue;
         }
 
-        char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+        const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
                 ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash)
                 : dap_chain_hash_fast_to_str_static(&l_pkey_hash);
 
diff --git a/modules/common/dap_chain_datum_tx_voting.c b/modules/common/dap_chain_datum_tx_voting.c
index 658407e446ac81dcd1d84ffaa63686e2d0559ef3..bfd0043bc51872f97be902aee48f32a7769ec948 100644
--- a/modules/common/dap_chain_datum_tx_voting.c
+++ b/modules/common/dap_chain_datum_tx_voting.c
@@ -150,6 +150,32 @@ dap_chain_tx_voting_t *dap_chain_datum_tx_item_voting_create(void)
     return l_item;
 }
 
+const char *s_tx_voting_get_answer_text_by_idx(dap_chain_datum_tx_t *a_tx, uint64_t a_idx) {
+    dap_list_t *l_answers_list = NULL;
+    size_t l_anwers_count = 0;
+    dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TSD, NULL);
+    dap_list_t* l_temp = l_tsd_list;
+    while (l_temp){
+        dap_tsd_t* l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)l_temp->data)->tsd;
+        if (l_tsd->type == VOTING_TSD_TYPE_ANSWER) {
+            char *l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
+            memcpy(l_buf_string, l_tsd->data, l_tsd->size);
+            l_buf_string[l_tsd->size] = '\0';
+            l_answers_list = dap_list_append(l_answers_list, l_buf_string);
+            l_anwers_count++;
+        }
+        l_temp = l_temp->next;
+    }
+    dap_list_free(l_tsd_list);
+    if (l_anwers_count < a_idx) {
+        dap_list_free_full(l_answers_list, NULL);
+        return NULL;
+    }
+    char *l_ret = dap_strdup(dap_list_nth_data(l_answers_list, a_idx));
+    dap_list_free_full(l_answers_list, NULL);
+    return l_ret;
+}
+
 json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_tx)
 {
     if (!a_tx)
@@ -210,14 +236,31 @@ dap_chain_tx_vote_t *dap_chain_datum_tx_item_vote_create(dap_chain_hash_fast_t *
     return l_item;
 }
 
-json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote)
+const char *s_get_vote_answer_text(dap_hash_fast_t *a_vote, uint64_t a_idx, dap_ledger_t *a_ledger) {
+    dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_ledger, a_vote);
+    if (!l_tx || !a_ledger) {
+        return NULL;
+    }
+    return s_tx_voting_get_answer_text_by_idx(l_tx, a_idx);
+}
+
+json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote, dap_ledger_t *a_ledger)
 {
     json_object *l_object = json_object_new_object();
     char *l_voting_hash_str = dap_hash_fast_to_str_new(&a_vote->voting_hash);
     json_object *l_voting_hash = json_object_new_string(l_voting_hash_str);
     DAP_DELETE(l_voting_hash_str);
     json_object *l_answer_idx = json_object_new_uint64(a_vote->answer_idx);
+    char *l_answer_text_str = s_get_vote_answer_text(&a_vote->voting_hash, a_vote->answer_idx, a_ledger);
+    json_object *l_answer_text = NULL;
+    if (!l_answer_text_str) {
+        l_answer_text = json_object_new_string("{UNDEFINED}");
+    } else {
+        l_answer_text = json_object_new_string(l_answer_text_str);
+        DAP_DELETE(l_answer_text_str);
+    }
     json_object_object_add(l_object, "votingHash", l_voting_hash);
     json_object_object_add(l_object, "answer_idx", l_answer_idx);
+    json_object_object_add(l_object, "answer_text", l_answer_text);
     return l_object;
 }
diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h
index 1eaf8b5b42d4aab79b8e7075af757a2deea77263..331cb806f80f929b7b33af509b38b3e8117bfafa 100644
--- a/modules/common/include/dap_chain_datum_tx_voting.h
+++ b/modules/common/include/dap_chain_datum_tx_voting.h
@@ -25,6 +25,7 @@
 #include "dap_chain_common.h"
 #include "dap_chain_datum_tx.h"
 #include "dap_chain_datum_tx_items.h"
+#include "dap_chain_ledger.h"
 #include "dap_time.h"
 #include "dap_list.h"
 #include "dap_tsd.h"
@@ -87,4 +88,4 @@ json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_
 
 
 dap_chain_tx_vote_t *dap_chain_datum_tx_item_vote_create(dap_chain_hash_fast_t *a_voting_hash, uint64_t *a_answer_idx);
-json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote);
+json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote, dap_ledger_t *a_ledger);
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 5233bd3581116838137e90c01a1f0da09c0b94ae..02cd42e366e87c8c60962a4b5cc1ad88b1a9f7d9 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -51,7 +51,7 @@ enum s_esbocs_session_state {
 
 static dap_list_t *s_validator_check(dap_chain_addr_t *a_addr, dap_list_t *a_validators);
 static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s_esbocs_session_state a_new_state, dap_time_t a_time);
-static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg);
+static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg);
 static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain_node_addr_t *a_sender_node_addr, uint8_t *a_data, size_t a_data_size);
 static void s_session_round_clear(dap_chain_esbocs_session_t *a_session);
 static void s_session_round_new(dap_chain_esbocs_session_t *a_session);
@@ -267,7 +267,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg)
         l_validator->node_addr = l_signer_node_addr;
         l_validator->weight = uint256_1;
         l_esbocs_pvt->poa_validators = dap_list_append(l_esbocs_pvt->poa_validators, l_validator);
-        char *l_signer_addr = dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast);
+        const char *l_signer_addr = dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast);
         log_it(L_MSG, "add validator addr "NODE_ADDR_FP_STR", signing addr %s", NODE_ADDR_FP_ARGS_S(l_signer_node_addr), l_signer_addr);
 
         if (!l_esbocs_pvt->poa_mode) { // auth certs in PoA mode will be first PoS validators keys
@@ -356,7 +356,7 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel
     assert(l_session->chain == a_chain);
     pthread_mutex_lock(&l_session->mutex);
     dap_chain_hash_fast_t l_last_block_hash;
-    dap_chain_get_atom_last_hash(l_session->chain, &l_last_block_hash, a_id);
+    dap_chain_get_atom_last_hash(l_session->chain, a_id, &l_last_block_hash);
     if (!dap_hash_fast_compare(&l_last_block_hash, &l_session->cur_round.last_block_hash))
         s_session_round_new(l_session);
     pthread_mutex_unlock(&l_session->mutex);
@@ -828,7 +828,7 @@ static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session)
     if (a_session->cur_round.sync_sent)
         return;     // Sync message already was sent
     dap_chain_hash_fast_t l_last_block_hash;
-    dap_chain_get_atom_last_hash(a_session->chain, &l_last_block_hash, c_dap_chain_cell_id_null);
+    dap_chain_get_atom_last_hash(a_session->chain, c_dap_chain_cell_id_null, &l_last_block_hash);
     a_session->ts_round_sync_start = dap_time_now();
     if (!dap_hash_fast_compare(&l_last_block_hash, &a_session->cur_round.last_block_hash))
         return;     // My last block hash has changed, skip sync message
@@ -877,7 +877,7 @@ static void s_session_update_penalty(dap_chain_esbocs_session_t *a_session)
         }
         if (l_item->miss_count < DAP_CHAIN_ESBOCS_PENALTY_KICK) {
             if (PVT(a_session->esbocs)->debug) {
-                char *l_addr_str = dap_chain_hash_fast_to_str_static(&l_signing_addr->data.hash_fast);
+                const char *l_addr_str = dap_chain_hash_fast_to_str_static(&l_signing_addr->data.hash_fast);
                 log_it(L_DEBUG, "Increment miss count %d for addr %s. Miss count for kick is %d",
                                         l_item->miss_count, l_addr_str, DAP_CHAIN_ESBOCS_PENALTY_KICK);
             }
@@ -929,7 +929,7 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session)
     a_session->ts_stage_entry = 0;
 
     dap_hash_fast_t l_last_block_hash;
-    dap_chain_get_atom_last_hash(a_session->chain, &l_last_block_hash, c_dap_chain_cell_id_null);
+    dap_chain_get_atom_last_hash(a_session->chain, c_dap_chain_cell_id_null, &l_last_block_hash);
     if (!dap_hash_fast_compare(&l_last_block_hash, &a_session->cur_round.last_block_hash) ||
             (!dap_hash_fast_is_blank(&l_last_block_hash) &&
                 dap_hash_fast_is_blank(&a_session->cur_round.last_block_hash))) {
@@ -1036,7 +1036,7 @@ static uint64_t s_session_calc_current_round_id(dap_chain_esbocs_session_t *a_se
             }
         }
         if (l_id_candidate == 0) {
-            char *l_signing_addr_str = dap_chain_hash_fast_to_str_static(&l_validator->signing_addr.data.hash_fast);
+            const char *l_signing_addr_str = dap_chain_hash_fast_to_str_static(&l_validator->signing_addr.data.hash_fast);
             log_it(L_ERROR, "Can't find sync message of synced validator %s", l_signing_addr_str);
             continue;
         }
@@ -1164,7 +1164,7 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s
                 dap_hash_fast_t l_directive_hash;
                 dap_hash_fast(l_directive, l_directive->size, &l_directive_hash);
                 if (PVT(a_session->esbocs)->debug) {
-                    char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_directive_hash);
+                    const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_directive_hash);
                     log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Put on the vote my directive:%s",
                             a_session->chain->net_name, a_session->chain->name,
                                 a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str);
@@ -1205,7 +1205,7 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s
                         );
             dap_chain_esbocs_validator_t *l_validator = l_list ? l_list->data : NULL;
             if (!l_validator || !l_validator->is_chosen) {
-                char *l_addr = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_submit_validator.data.hash_fast);
+                const char *l_addr = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_submit_validator.data.hash_fast);
                 log_it(L_MSG, "Error: can't find current attmempt submit validator %s in signers list", l_addr);
             }
             l_validator->is_chosen = false;
@@ -1332,7 +1332,7 @@ static void s_session_proc_state(dap_chain_esbocs_session_t *a_session)
             }
             if (dap_list_length(l_store->candidate_signs) >= PVT(a_session->esbocs)->min_validators_count) {
                 if(l_cs_debug) {
-                    char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_candidate_hash);
+                    const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_candidate_hash);
                     log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu"
                                             " Candidate %s collected sings of minimum number of validators, so to sent PRE_COMMIT",
                                                 a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id,
@@ -1418,7 +1418,7 @@ static void s_session_candidate_submit(dap_chain_esbocs_session_t *a_session)
     if (l_candidate_size) {
         dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash);
         if (PVT(a_session->esbocs)->debug) {
-            char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash);
+            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Submit my candidate %s",
                     a_session->chain->net_name, a_session->chain->name,
                         a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str);
@@ -1462,7 +1462,7 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da
         s_message_send(a_session, DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE, a_candidate_hash,
                        NULL, 0, a_session->cur_round.validators_list);
         if (PVT(a_session->esbocs)->debug) {
-            char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
+            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Sent APPROVE candidate %s",
                                 a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id,
                                         a_session->cur_round.attempt_num, l_candidate_hash_str);
@@ -1472,7 +1472,7 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da
         s_message_send(a_session, DAP_CHAIN_ESBOCS_MSG_TYPE_REJECT, a_candidate_hash,
                        NULL, 0, a_session->cur_round.validators_list);
         if (PVT(a_session->esbocs)->debug) {
-            char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
+            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Sent REJECT candidate %s",
                                 a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id,
                                         a_session->cur_round.attempt_num, l_candidate_hash_str);
@@ -1492,7 +1492,7 @@ static void s_session_candidate_precommit(dap_chain_esbocs_session_t *a_session,
     byte_t *l_message_data = a_message->msg_n_sign;
     dap_chain_hash_fast_t *l_candidate_hash = &a_message->hdr.candidate_hash;
     dap_chain_esbocs_store_t *l_store;
-    char *l_candidate_hash_str = NULL;
+    const char *l_candidate_hash_str = NULL;
     HASH_FIND(hh, a_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store);
     if (!l_store) {
         l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
@@ -1552,7 +1552,7 @@ static bool s_session_candidate_to_chain(dap_chain_esbocs_session_t *a_session,
     }
     bool res = false;
     dap_chain_atom_verify_res_t l_res = a_session->chain->callback_atom_add(a_session->chain, a_candidate, a_candidate_size);
-    char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
+    const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash);
     switch (l_res) {
     case ATOM_ACCEPT:
         // block save to chain
@@ -1594,25 +1594,25 @@ static void s_session_round_finish(dap_chain_esbocs_session_t *a_session, dap_ch
     }
 
     if (l_store->reject_count >= l_cs_level) {
-        char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
+        const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
         debug_if(l_cs_debug, L_WARNING, "Trying to finish rejected candidate %s", l_finish_candidate_hash_str);
         return;
     }
 
     if (l_store->approve_count < l_cs_level) {
-        char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
+        const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
         debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly approved candidate %s", l_finish_candidate_hash_str);
         return;
     }
 
     if (dap_list_length(l_store->candidate_signs) < l_cs_level) {
-        char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
+        const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
         debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly signed candidate %s", l_finish_candidate_hash_str);
         return;
     }
 
     if (l_store->precommit_count < l_cs_level) {
-        char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
+        const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash);
         debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly precommited candidate %s", l_finish_candidate_hash_str);
         return;
     }
@@ -1751,7 +1751,7 @@ static void s_session_directive_process(dap_chain_esbocs_session_t *a_session, d
     }
 
     if (PVT(a_session->esbocs)->debug) {
-        char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(a_directive_hash);
+        const char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(a_directive_hash);
         log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Send VOTE %s directive %s",
                             a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id,
                                     a_session->cur_round.attempt_num, l_vote_for ? "FOR" : "AGAINST",
@@ -1862,32 +1862,32 @@ static bool s_process_incoming_message(void *a_arg)
     return false;
 }
 
-static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
+static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
 {
     dap_stream_ch_pkt_t *l_ch_pkt = (dap_stream_ch_pkt_t *)a_arg;
     if (!l_ch_pkt)
-        return;
+        return false;
     dap_chain_esbocs_message_t *l_message = (dap_chain_esbocs_message_t *)l_ch_pkt->data;
     size_t l_message_size = l_ch_pkt->hdr.data_size;
     if (l_message_size < sizeof(dap_chain_esbocs_message_t) ||
             l_message_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE + PKT_SIGN_N_HDR_OVERHEAD ||
             l_message_size != sizeof(*l_message) + l_message->hdr.sign_size + l_message->hdr.message_size) {
         log_it(L_WARNING, "Invalid message size %zu, drop this packet", l_message_size);
-        return;
+        return false;
     }
     dap_chain_net_t *l_net = dap_chain_net_by_id(l_message->hdr.net_id);
     if (!l_net) {
         log_it(L_WARNING, "Can't find net with ID 0x%" DAP_UINT64_FORMAT_x, l_message->hdr.net_id.uint64);
-        return;
+        return false;
     }
     if (dap_chain_net_get_state(l_net) == NET_STATE_OFFLINE) {
         log_it(L_MSG, "Reject packet because net %s is offline", l_net->pub.name);
         a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
-        return;
+        return false;
     }
     if (l_message->hdr.recv_addr.uint64 != g_node_addr.uint64) {
         log_it(L_WARNING, "Wrong packet destination address" NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_message->hdr.recv_addr));
-        return;
+        return false;
     }
     dap_chain_esbocs_session_t *l_session;
     DL_FOREACH(s_session_items, l_session)
@@ -1896,14 +1896,14 @@ static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
     if (!l_session) {
         log_it(L_WARNING, "Session for net %s not found", l_net->pub.name);
         a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
-        return;
+        return false;
     }
     if (l_message->hdr.version != DAP_CHAIN_ESBOCS_PROTOCOL_VERSION) {
         debug_if(PVT(l_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U
                             " Message is rejected - different protocol version %hu (need %u)",
                                 l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
                                     l_message->hdr.version, DAP_CHAIN_ESBOCS_PROTOCOL_VERSION);
-        return;
+        return false;
     }
     debug_if(PVT(l_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                             " Receive pkt type:0x%x from addr:"NODE_ADDR_FP_STR", my_addr:"NODE_ADDR_FP_STR"",
@@ -1913,13 +1913,14 @@ static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
     struct esbocs_msg_args *l_args = DAP_NEW_SIZE(struct esbocs_msg_args, sizeof(struct esbocs_msg_args) + l_message_size);
     if (!l_args) {
         log_it(L_CRITICAL, g_error_memory_alloc);
-        return;
+        return false;
     }
     l_args->addr_from = a_ch->stream->node;
     l_args->session = l_session;
     l_args->message_size = l_message_size;
     memcpy(l_args->message, l_message, l_message_size);
     dap_proc_thread_callback_add(NULL, s_process_incoming_message, l_args);
+    return true;
 }
 
 /**
@@ -2152,7 +2153,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         }
 
         if (l_cs_debug) {
-            char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
+            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                             " Receive SUBMIT candidate %s, size %zu",
                                 l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
@@ -2162,7 +2163,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         dap_chain_esbocs_store_t *l_store;
         HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store);
         if (l_store) {
-            char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
+            const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_WARNING, "Duplicate candidate: %s", l_candidate_hash_str);
             break;
         }
@@ -2190,7 +2191,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
     case DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE:
     case DAP_CHAIN_ESBOCS_MSG_TYPE_REJECT: {
         dap_chain_esbocs_store_t *l_store;
-        char *l_candidate_hash_str = NULL;
+        const char *l_candidate_hash_str = NULL;
         bool l_approve = l_message->hdr.type == DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE;
         HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store);
         if (!l_store) {
@@ -2257,7 +2258,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
         }
 
         dap_chain_esbocs_store_t *l_store;
-        char *l_candidate_hash_str = NULL;
+        const char *l_candidate_hash_str = NULL;
         HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store);
         if (!l_store) {
             l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
@@ -2325,7 +2326,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
             break;
         }
         if (l_cs_debug) {
-            char *l_dirtective_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
+            const char *l_dirtective_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                             " Receive DIRECTIVE hash %s, size %zu",
                                 l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
@@ -2356,7 +2357,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain
             break;
         }
         if (l_cs_debug) {
-            char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
+            const char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash);
             log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu."
                             " Receive VOTE %s directive %s",
                                 l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id,
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
index 572d2606365a9dd04e3a70ea90c903a146005722..95d2cedcc88c33ec686dcacca946a23101dd593e 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
@@ -399,7 +399,7 @@ json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){
                 _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);
 //                dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", l_stake_addr_signing_str);
                 dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing.data.hash_fast;
-                char *l_pkey_signing_str = dap_chain_hash_fast_to_str_static(&l_pkey_signing);
+                const char *l_pkey_signing_str = dap_chain_hash_fast_to_str_static(&l_pkey_signing);
                 json_object *l_jobj_stake_addr_signing = dap_chain_addr_to_json(&l_stake_addr_signing);
                 json_object *l_jobj_pkey_signing = json_object_new_string(l_pkey_signing_str);
                 json_object_object_add(l_jobj_tsd, "addr", l_jobj_stake_addr_signing);
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
index 51974801211a61428a4392d0d34c77deb4b995ed..9b3d6404058a8390a7fa1e23551fe00964d9cea6 100644
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
+++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
@@ -10,6 +10,7 @@
 #include "dap_json_rpc_chain_datum_tx_receipt.h"
 #include "json.h"
 #include "dap_chain_datum_tx_voting.h"
+#include "dap_chain_net.h"
 
 #define LOG_TAG "dap_json_rpc_chain_datum_tx"
 
@@ -110,7 +111,8 @@ json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx,dap_chain_net
                 break;
             case TX_ITEM_TYPE_VOTE:
                 l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTE");
-                l_obj_item_data = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)item);
+                dap_chain_net_t *l_net = dap_chain_net_by_id(*a_net_id);
+                l_obj_item_data = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)item, l_net->pub.ledger);
             break;
             case TX_ITEM_TYPE_VOTING:
                 l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTING");
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 41639e23b430d3845416bda33ecaee24f13d7d29..73d98c1ba859dbab66dacf4185996b407c66b2f8 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -95,7 +95,7 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t
 
     dap_chain_hash_fast_t l_key_hash;
     dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_key_hash);
-    char *l_key_str = dap_strcmp(a_hash_out_type, "hex")
+    const char *l_key_str = dap_strcmp(a_hash_out_type, "hex")
             ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash)
             : dap_chain_hash_fast_to_str_static(&l_key_hash);
 
@@ -1484,8 +1484,8 @@ void dap_chain_mempool_filter(dap_chain_t *a_chain, int *a_removed){
     char * l_gdb_group = dap_chain_net_get_gdb_group_mempool_new(a_chain);
     size_t l_objs_size = 0;
     dap_time_t l_cut_off_time = dap_time_now() - 3 * 24 * 3600; // 3 days
-    char l_cut_off_time_str[80] = {'\0'};
-    dap_time_to_str_rfc822(l_cut_off_time_str, 80, l_cut_off_time);
+    char l_cut_off_time_str[DAP_TIME_STR_SIZE] = {'\0'};
+    dap_time_to_str_rfc822(l_cut_off_time_str, DAP_TIME_STR_SIZE, l_cut_off_time);
     dap_global_db_obj_t * l_objs = dap_global_db_get_all_sync(l_gdb_group, &l_objs_size);
     for (size_t i = 0; i < l_objs_size; i++) {
         dap_chain_datum_t *l_datum = (dap_chain_datum_t*)l_objs[i].value;
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index b8424b1e8664e9bd17ee14520775fd82c2c4dcbc..b83d20a05457e0d3d8f670b3d2d18febea6b9033 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -819,7 +819,7 @@ static void s_tx_header_print(json_object *a_json_out, dap_chain_datum_tx_t *a_t
     char l_time_str[DAP_TIME_STR_SIZE] = "unknown";
     if (a_tx->header.ts_created)
         dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, a_tx->header.ts_created);
-    char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex")
+    const char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex")
             ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash)
             : dap_chain_hash_fast_to_str_static(a_tx_hash);
     json_object_object_add(a_json_out, "TX hash ", json_object_new_string(l_tx_hash_str));
@@ -5726,7 +5726,7 @@ dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_
 {
     dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger);
     pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
-    a_iter->cur_ledger_tx_item = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next;
+    a_iter->cur_ledger_tx_item = a_iter->cur_ledger_tx_item ? ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next : NULL;
     if (a_iter->cur_ledger_tx_item){
         a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx;
         a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast;
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index b362c7cf2e5f75981b3f8ca1fde89e7db680b252..5d256ba44edf9caebfaa6f39c7d8f349bcf9b3b9 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -165,6 +165,8 @@ struct chain_sync_context {
     dap_stream_node_addr_t current_link;
     dap_chain_t *cur_chain;
     dap_chain_cell_t *cur_cell;
+    dap_hash_fast_t requested_atom_hash;
+    uint64_t requested_atom_num;
 };
 
 /**
@@ -2482,6 +2484,8 @@ int s_net_load(dap_chain_net_t *a_net)
     return 0;
 }
 
+static const uint64_t s_fork_sync_step = 20; // TODO get it from config
+
 static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const void *a_data, size_t a_data_size, void *a_arg)
 {
     debug_if(s_debug_more, L_DEBUG, "Got IN sync packet type %hhu size %zu from addr " NODE_ADDR_FP_STR,
@@ -2491,10 +2495,76 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo
     switch (a_type) {
     case DAP_CHAIN_CH_PKT_TYPE_ERROR:
         l_net_pvt->sync_context.state = SYNC_STATE_ERROR;
-        break;
+        return;
+
     case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN:
         l_net_pvt->sync_context.state = SYNC_STATE_SYNCED;
-        break;
+        return;
+
+    case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: {
+        dap_chain_ch_miss_info_t *l_miss_info = (dap_chain_ch_miss_info_t *)(((dap_chain_ch_pkt_t *)(a_data))->data);
+        if (!dap_hash_fast_compare(&l_miss_info->missed_hash, &l_net_pvt->sync_context.requested_atom_hash)) {
+            char l_missed_hash_str[DAP_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_miss_info->missed_hash, l_missed_hash_str, DAP_HASH_FAST_STR_SIZE);
+            log_it(L_WARNING, "Get irrelevant chain sync MISSED packet with missed hash %s, but requested hash is %s",
+                                                                        l_missed_hash_str,
+                                                                        dap_hash_fast_to_str_static(&l_net_pvt->sync_context.requested_atom_hash));
+            dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id.uint64,
+                                             l_net_pvt->sync_context.cur_chain->id.uint64,
+                                             l_net_pvt->sync_context.cur_cell
+                                             ? l_net_pvt->sync_context.cur_cell->id.uint64
+                                             : 0,
+                                             DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE);
+            return;
+        }
+        dap_chain_atom_iter_t *l_iter = l_net_pvt->sync_context.cur_chain->callback_atom_iter_create(
+                                                                            l_net_pvt->sync_context.cur_chain,
+                                                                            l_net_pvt->sync_context.cur_cell
+                                                                            ? l_net_pvt->sync_context.cur_cell->id
+                                                                            : c_dap_chain_cell_id_null,
+                                                                            NULL);
+        if (!l_iter) {
+            log_it(L_CRITICAL, g_error_memory_alloc);
+            dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id.uint64,
+                                             l_net_pvt->sync_context.cur_chain->id.uint64,
+                                             l_net_pvt->sync_context.cur_cell
+                                             ? l_net_pvt->sync_context.cur_cell->id.uint64
+                                             : 0,
+                                             DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY);
+            return;
+        }
+        dap_chain_atom_ptr_t l_atom = l_net_pvt->sync_context.cur_chain->callback_atom_find_by_hash(l_iter, &l_miss_info->last_hash, NULL);
+        if (l_atom && l_iter->cur_num == l_miss_info->last_num) {       // We already have this subchain in our chain
+            l_net_pvt->sync_context.state = SYNC_STATE_SYNCED;
+            return;
+        }
+        dap_chain_ch_sync_request_t l_request = {};
+        l_request.num_from = l_net_pvt->sync_context.requested_atom_num > s_fork_sync_step
+                            ? l_net_pvt->sync_context.requested_atom_num - s_fork_sync_step
+                            : 0;
+        if (l_request.num_from) {
+            l_atom = l_net_pvt->sync_context.cur_chain->callback_atom_get_by_num(l_iter, l_request.num_from);
+            assert(l_atom);
+            l_request.hash_from = *l_iter->cur_hash;
+        }
+        l_net_pvt->sync_context.cur_chain->callback_atom_iter_delete(l_iter);
+        debug_if(s_debug_more, L_INFO, "Send sync request to node " NODE_ADDR_FP_STR
+                                        " for net %s and chain %s, hash from %s, num from %" DAP_UINT64_FORMAT_U,
+                                                        NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link),
+                                                        l_net->pub.name, l_net_pvt->sync_context.cur_chain->name,
+                                                        dap_hash_fast_to_str_static(&l_request.hash_from), l_request.num_from);
+        dap_chain_ch_pkt_write_unsafe(a_ch,
+                                      DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ,
+                                      l_net->pub.id.uint64,
+                                      l_net_pvt->sync_context.cur_chain->id.uint64,
+                                      l_net_pvt->sync_context.cur_cell
+                                      ? l_net_pvt->sync_context.cur_cell->id.uint64
+                                      : 0,
+                                      &l_request,
+                                      sizeof(l_request));
+        l_net_pvt->sync_context.requested_atom_hash = l_request.hash_from;
+        l_net_pvt->sync_context.requested_atom_num = l_request.num_from;
+    }
     default:
         break;
     }
@@ -2563,19 +2633,37 @@ static void s_sync_timer_callback(void *a_arg)
         // TODO make correct working with cells
         assert(l_net_pvt->sync_context.cur_chain);
         l_net_pvt->sync_context.cur_cell = l_net_pvt->sync_context.cur_chain->cells;
-        log_it(L_INFO, "Start synchronization process with " NODE_ADDR_FP_STR " for net %s and chain %s",
-                                                        NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link),
-                                                        l_net->pub.name, l_net_pvt->sync_context.cur_chain->name);
         l_net_pvt->sync_context.state = l_net_pvt->sync_context.last_state = SYNC_STATE_WAITING;
-        dap_hash_fast_t l_last_hash;
-        dap_chain_get_atom_last_hash(l_net_pvt->sync_context.cur_chain, &l_last_hash, l_net_pvt->sync_context.cur_cell
-                                                                                        ? l_net_pvt->sync_context.cur_cell->id : c_dap_chain_cell_id_null);
+        dap_chain_ch_sync_request_t l_request = {};
+        uint64_t l_last_num = 0;
+        if (!dap_chain_get_atom_last_hash_num(l_net_pvt->sync_context.cur_chain,
+                                              l_net_pvt->sync_context.cur_cell
+                                              ? l_net_pvt->sync_context.cur_cell->id
+                                              : c_dap_chain_cell_id_null,
+                                              &l_request.hash_from,
+                                              &l_last_num)) {
+            log_it(L_ERROR, "Can't get last atom hash and number for chain %s with net %s", l_net_pvt->sync_context.cur_chain->name,
+                                                                                            l_net->pub.name);
+            return;
+        }
+        l_request.num_from = l_last_num;
         dap_chain_ch_pkt_t *l_chain_pkt = dap_chain_ch_pkt_new(l_net->pub.id.uint64, l_net_pvt->sync_context.cur_chain->id.uint64,
                                                                l_net_pvt->sync_context.cur_cell ? l_net_pvt->sync_context.cur_cell->id.uint64 : 0,
-                                                               &l_last_hash, sizeof(l_last_hash));
+                                                               &l_request, sizeof(l_request));
+        if (!l_chain_pkt) {
+            log_it(L_CRITICAL, g_error_memory_alloc);
+            return;
+        }
+        log_it(L_INFO, "Start synchronization process with " NODE_ADDR_FP_STR
+                        " for net %s and chain %s, last hash %s, last num %" DAP_UINT64_FORMAT_U,
+                                                        NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link),
+                                                        l_net->pub.name, l_net_pvt->sync_context.cur_chain->name,
+                                                        dap_hash_fast_to_str_static(&l_request.hash_from), l_last_num);
         dap_stream_ch_pkt_send_by_addr(&l_net_pvt->sync_context.current_link, DAP_CHAIN_CH_ID,
                                        DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ, l_chain_pkt,
                                        dap_chain_ch_pkt_get_size(l_chain_pkt));
+        l_net_pvt->sync_context.requested_atom_hash = l_request.hash_from;
+        l_net_pvt->sync_context.requested_atom_num = l_request.num_from;
         DAP_DELETE(l_chain_pkt);
     }
     if (l_net_pvt->sync_context.last_state != SYNC_STATE_IDLE &&
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index b6e8c1195c010d9df8be5755af4441465ff8ae31..5f664784d2b18bd40072f487f486d18c239f7244 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -152,7 +152,7 @@ dap_chain_net_links_t *dap_chain_net_balancer_get_node(const char *a_net_name, u
     size_t l_node_num_prep = a_links_need;
     dap_link_info_t *l_links_info = s_get_links_info_list(l_net, &l_node_num_prep, true);
     if (!l_links_info || !l_node_num_prep){        
-        log_it(L_ERROR, "Active node list in net %s is empty", a_net_name);
+        log_it(L_WARNING, "Active node list in net %s is empty", a_net_name);
         return NULL;
     }
     size_t l_node_num_send = dap_min(s_max_links_response_count, l_node_num_prep);
@@ -187,7 +187,7 @@ dap_chain_net_links_t *dap_chain_net_balancer_get_node_old(const char *a_net_nam
     size_t l_node_num_prep = a_links_need;
     dap_link_info_t *l_links_info = s_get_links_info_list(l_net, &l_node_num_prep, true);
     if (!l_links_info || !l_node_num_prep){        
-        log_it(L_ERROR, "Active node list in net %s is empty", a_net_name);
+        log_it(L_WARNING, "Active node list in net %s is empty", a_net_name);
         return NULL;
     }
     size_t l_node_num_send = dap_min(s_max_links_response_count, l_node_num_prep);
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index fd0f78e13f826b1d2d37224760bdefa72d7378c1..f0019c1b7f4db2402dde52dc4d3a868ef4d57295 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -417,13 +417,12 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 log_it(L_WARNING,"Can't get signer node address from decree.");
                 return -105;
             }
-            // Check it directly before applying
+            if (!a_apply)
+                break;
             if (dap_chain_net_srv_stake_verify_key_and_node(&l_addr, &l_node_addr)) {
                 log_it(L_WARNING, "Key and node verification error");
                 return -105;
             }
-            if (!a_apply)
-                break;
             dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr);
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE:
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index c0d081d6bffa6b9c42ebd034112591fabf34f8f9..078e5076fd4c15c529786c7a9d465bef593a8bb0 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -315,9 +315,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
             "ledger list coins -net <net_name> [-limit] [-offset]\n"
             "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name> [-limit] [-offset]\n"
             "ledger list balance -net <net_name> [-limit] [-offset]\n"
-            "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n"
-            "ledger tx -all -net <net_name> [-unspent]\n"
-            "ledger tx {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} -net <net_name>\n");
+            "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n");
 
     // Token info
     dap_cli_server_cmd_add("token", com_token, "Token info",
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 85db305dd0e41e8054156dc24b0227813922b3a8..c0faca96be5c64b81e846e1f4cba411dabdb30e5 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -1180,7 +1180,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
         }
         log_it(L_NOTICE, "Stream connection established");
 
-        dap_chain_ch_sync_request_t l_sync_request = {};
+        dap_chain_ch_sync_request_old_t l_sync_request = {};
         dap_stream_ch_t *l_ch_chain = dap_client_get_stream_ch_unsafe(l_node_client->client, DAP_CHAIN_CH_ID);
         // fill begin id
         l_sync_request.id_start = 1;
@@ -1223,7 +1223,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
             // reset state NODE_CLIENT_STATE_SYNCED
             dap_chain_node_client_reset(l_node_client);
             // send request
-            dap_chain_ch_sync_request_t l_sync_request = {};
+            dap_chain_ch_sync_request_old_t l_sync_request = {};
             if(0 == dap_chain_ch_pkt_write_unsafe(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNC_CHAINS,
                     l_net->pub.id.uint64, l_chain->id.uint64, l_remote_node_info->hdr.cell_id.uint64, &l_sync_request,
                     sizeof(l_sync_request))) {
@@ -1269,6 +1269,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
                 return -4;
             }
         }
+        l_node_addr = l_node_info->address;
         if(!l_node_addr.uint64) {
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Addr not found");
             return -5;
@@ -1875,6 +1876,8 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 struct dirent * l_dir_entry = NULL;
 
                 while( (l_dir_entry = readdir(l_dir)) ) {
+                    if (dap_strcmp(l_dir_entry->d_name, "..") == 0 || dap_strcmp(l_dir_entry->d_name, ".") == 0)
+                        continue;
                     json_object * json_obj_wall = json_object_new_object();
                     if (!json_obj_wall) {
                         json_object_put(json_arr_out);
@@ -1969,7 +1972,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                 json_object_object_add(json_obj_wall, "sign", json_object_new_string(
                                                                   strlen(dap_chain_wallet_check_sign(l_wallet))!=0 ?
                                                                   dap_chain_wallet_check_sign(l_wallet) : "correct"));
-                json_object_object_add(json_obj_wall, "nwallet", json_object_new_string(l_wallet->name));
+                json_object_object_add(json_obj_wall, "wallet", json_object_new_string(l_wallet->name));
             }
             json_object_object_add(json_obj_wall, "addr", l_l_addr_str ? json_object_new_string(l_l_addr_str) : json_object_new_string("-"));
             json_object_object_add(json_obj_wall, "network", l_net_name? json_object_new_string(l_net_name) : json_object_new_string("-"));
@@ -2035,7 +2038,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                     switch (l_rc) {
                     case 0:
                         json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet_name));
-                        json_object_object_add(json_obj_wall, "protection", CMD_WALLET_ACTIVATE ?
+                        json_object_object_add(json_obj_wall, "protection", cmd_num == CMD_WALLET_ACTIVATE ?
                         json_object_new_string("is activated") : json_object_new_string("is deactivated"));
                         break;
                     case -EBUSY:
@@ -2568,8 +2571,8 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply)
                 l_datum_size = dap_chain_datum_size(l_datum);
                 dap_chain_hash_fast_t l_key_hash = { };
                 dap_hash_fast(l_datum->data, l_token_size, &l_key_hash);
-                char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash);
-                char *l_key_str_base58 = dap_enc_base58_encode_hash_to_str_static(&l_key_hash);
+                const char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash);
+                const char *l_key_str_base58 = dap_enc_base58_encode_hash_to_str_static(&l_key_hash);
                 const char *l_key_out_str = dap_strcmp(l_hash_out_type, "hex")
                         ? l_key_str_base58 : l_key_str;
                 // Add datum to mempool with datum_token hash as a key
@@ -2711,8 +2714,8 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
             dap_hash_fast_t l_datum_hash_from_key = {0};
             dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_real_hash);
             dap_chain_hash_fast_from_str(l_objs[i].key, &l_datum_hash_from_key);
-            char buff_time[50];
-            dap_time_to_str_rfc822(buff_time, 50, l_datum->header.ts_create);
+            char buff_time[DAP_TIME_STR_SIZE];
+            dap_time_to_str_rfc822(buff_time, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
             json_object *l_jobj_type = json_object_new_string(l_datum_type);
             json_object *l_jobj_hash = json_object_new_string(l_objs[i].key);
             json_object *l_jobj_ts_created = json_object_new_object();
@@ -3096,7 +3099,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                         }
                         for (dap_list_t *it = l_vote_list; it; it = it->next) {
                             json_object *l_jobj_vote = dap_chain_datum_tx_item_vote_to_json(
-                                    (dap_chain_tx_vote_t *) it->data);
+                                    (dap_chain_tx_vote_t *) it->data, a_net->pub.ledger);
                             json_object_array_add(l_jobj_tx_vote, l_jobj_vote);
                         }
                         for (dap_list_t *it = l_voting_list; it; it = it->next) {
@@ -3404,7 +3407,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
         json_object_array_add(*a_json_reply, l_jobj_datum);
         return 0;
     } else {
-        l_find_bool = json_object_new_boolean(TRUE);
+        l_find_bool = json_object_new_boolean(FALSE);
         if (!l_find_bool) {
             json_object_put(l_jobj_datum);
             dap_json_rpc_allocation_error;
@@ -4534,7 +4537,7 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply)
     // Calc datum's hash
     dap_chain_hash_fast_t l_key_hash;
     dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash);
-    char * l_key_str = !dap_strcmp(l_hash_out_type, "hex") ?
+    const char *l_key_str = !dap_strcmp(l_hash_out_type, "hex") ?
                 dap_chain_hash_fast_to_str_static(&l_key_hash) :
                 dap_enc_base58_encode_hash_to_str_static(&l_key_hash);
 
@@ -4737,8 +4740,8 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply)
     // Calc datum's hash
     dap_chain_hash_fast_t l_key_hash;
     dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash);
-    char * l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash);
-    char * l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ?
+    const char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash);
+    const char *l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ?
                            dap_enc_base58_encode_hash_to_str_static(&l_key_hash) : l_key_str;
 
     // Add datum to mempool with datum_token hash as a key
@@ -4964,7 +4967,7 @@ int com_token_emit(int a_argc, char **a_argv, void **a_str_reply)
  * @param a_str_reply
  * @return int
  */
-int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply)
+int com_tx_cond_create(int a_argc, char ** a_argv, void **a_reply)
 {
     (void) a_argc;
     int arg_index = 1;
@@ -4984,8 +4987,9 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply)
     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(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX,
+                               "Invalid parameter -H, valid values: -H <hex | base58>");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX;
     }
 
     // Token ticker
@@ -5006,84 +5010,86 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply)
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str);
 
     if(!l_token_ticker) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-token'");
-        return -1;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN, "tx_cond_create requires parameter '-token'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN;
     }
     if (!l_wallet_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-w'");
-        return -2;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W, "tx_cond_create requires parameter '-w'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W;
     }
     if (!l_cert_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-cert'");
-        return -3;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT, "tx_cond_create requires parameter '-cert'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT;
     }
     if(!l_value_datoshi_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-value'");
-        return -4;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE, "tx_cond_create requires parameter '-value'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE;
     }
     if(!l_value_fee_str){
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-fee'");
-        return -15;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE, "tx_cond_create requires parameter '-fee'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE;
     }
     if(!l_net_name) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-net'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET, "tx_cond_create requires parameter '-net'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET;
     }
     if(!l_unit_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-unit'");
-        return -6;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT, "tx_cond_create requires parameter '-unit'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT;
     }
 
     if(!l_srv_uid_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-srv_uid'");
-        return -7;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID, "tx_cond_create requires parameter '-srv_uid'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID;
     }
     dap_chain_net_srv_uid_t l_srv_uid = {};
     l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10);
     if (!l_srv_uid.uint64) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find service UID %s ", l_srv_uid_str);
-        return -8;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID, "Can't find service UID %s ", l_srv_uid_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID;
     }
 
     dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = dap_chain_srv_str_to_unit_enum((char*)l_unit_str)};
 
     if(l_price_unit.enm == SERV_UNIT_UNDEFINED) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize unit '%s'. Unit must look like { B | SEC }",
-                l_unit_str);
-        return -9;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT,
+                               "Can't recognize unit '%s'. Unit must look like { B | SEC }", l_unit_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT;
     }
 
     l_value_datoshi = dap_chain_balance_scan(l_value_datoshi_str);
     if(IS_ZERO_256(l_value_datoshi)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize value '%s' as a number", l_value_datoshi_str);
-        return -10;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE,
+                               "Can't recognize value '%s' as a number", l_value_datoshi_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE;
     }
 
     l_value_fee = dap_chain_balance_scan(l_value_fee_str);
     if(IS_ZERO_256(l_value_fee)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize value '%s' as a number", l_value_fee_str);
-        return -16;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE,
+                               "Can't recognize value '%s' as a number", l_value_fee_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE;
     }
 
     dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL;
     if(!l_net) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find net '%s'", l_net_name);
-        return -11;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET, "Can't find net '%s'", l_net_name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET;
     }
     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path);
-    const char* l_sign_str = "";
+//    const char* l_sign_str = "";
     if(!l_wallet) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't open wallet '%s'", l_wallet_str);
-        return -12;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET;
     } else {
-        l_sign_str = dap_chain_wallet_check_sign(l_wallet);
+//        l_sign_str = dap_chain_wallet_check_sign(l_wallet);
     }
 
     dap_cert_t *l_cert_cond = dap_cert_find_by_name(l_cert_str);
     if(!l_cert_cond) {
         dap_chain_wallet_close(l_wallet);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find cert '%s'", l_cert_str);
-        return -13;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT, "Can't find cert '%s'", l_cert_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT;
     }
 
     dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0);
@@ -5091,8 +5097,9 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply)
     if (!l_key_cond) {
         dap_chain_wallet_close(l_wallet);
         dap_enc_key_delete(l_key_from);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Cert '%s' doesn't contain a valid public key", l_cert_str);
-        return -14;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY,
+                               "Cert '%s' doesn't contain a valid public key", l_cert_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY;
     }
 
     uint256_t l_value_per_unit_max = {};
@@ -5104,12 +5111,20 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply)
     DAP_DELETE(l_key_cond);
 
     if (l_hash_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%sConditional 256bit TX created succefully, hash=%s\n", l_hash_str, l_sign_str);
+        json_object *l_jobj_ret = json_object_new_object();
+        json_object *l_jobj_tx_cond_transfer = json_object_new_boolean(true);
+        json_object *l_jobj_hash = json_object_new_string(l_hash_str);
+        json_object_object_add(l_jobj_ret, "create_tx_cond", l_jobj_tx_cond_transfer);
+        json_object_object_add(l_jobj_ret, "hash", l_jobj_hash);
+        json_object_array_add(*a_reply, l_jobj_ret);
         DAP_DELETE(l_hash_str);
-        return 0;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK;
     }
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create conditional 256bit TX\n");
-    return -1;
+    json_object *l_jobj_ret = json_object_new_object();
+    json_object *l_jobj_tx_cond_transfer = json_object_new_boolean(false);
+    json_object_object_add(l_jobj_ret, "create_tx_cond", l_jobj_tx_cond_transfer);
+    json_object_array_add(*a_reply, l_jobj_ret);
+    return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_CONDITIONAL_TX_CREATE;
 }
 
 static dap_list_t* s_hashes_parse_str_list(const char * a_hashes_str)
@@ -5144,10 +5159,9 @@ static dap_list_t* s_hashes_parse_str_list(const char * a_hashes_str)
     return  l_ret_list;
 }
 
-int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
+int com_tx_cond_remove(int a_argc, char ** a_argv, void **reply)
 {
     (void) a_argc;
-    void** l_str_reply = a_str_reply;
     int arg_index = 1;
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
     const char * l_wallet_str = NULL;
@@ -5162,8 +5176,9 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     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(l_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>");
-        return -1;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX,
+                               "Invalid parameter -H, valid values: -H <hex | base58>");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX;
     }
 
     // Wallet name 
@@ -5178,43 +5193,43 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str);
 
     if (!l_wallet_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-w'");
-        return -2;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W, "com_txs_cond_remove requires parameter '-w'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W;
     }
     if(!l_value_fee_str){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-fee'");
-        return -15;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE, "com_txs_cond_remove requires parameter '-fee'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE;
     }
     if(!l_net_name) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-net'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET, "com_txs_cond_remove requires parameter '-net'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET;
     }
     if(!l_hashes_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-hashes'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES, "com_txs_cond_remove requires parameter '-hashes'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES;
     }
     if(!l_srv_uid_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-srv_uid'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID, "com_txs_cond_remove requires parameter '-srv_uid'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID;
     }
 
     dap_chain_net_srv_uid_t l_srv_uid = {};
     l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10);
     if (!l_srv_uid.uint64) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find service UID %s ", l_srv_uid_str);
-        return -8;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID, "Can't find service UID %s ", l_srv_uid_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID;
     }
 
     dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL;
     if(!l_net) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find net '%s'", l_net_name);
-        return -11;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET, "Can't find net '%s'", l_net_name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET;
     }
     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path);
-    const char* l_sign_str = "";
+//    const char* l_sign_str = "";
     if(!l_wallet) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't open wallet '%s'", l_wallet_str);
-        return -12;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET;
     } 
 
     dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0);
@@ -5222,32 +5237,32 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
 
     l_value_fee = dap_chain_balance_scan(l_value_fee_str);
     if(IS_ZERO_256(l_value_fee)) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't recognize value '%s' as a number", l_value_fee_str);
-        return -16;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE, "Can't recognize value '%s' as a number", l_value_fee_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE;
     }
 
     const char *l_native_ticker = l_net->pub.native_ticker;
     if (!l_native_ticker){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find native ticker for net %s", l_net->pub.name);
-        return -16;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, "Can't find native ticker for net %s", l_net->pub.name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET;
     }
     dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net->pub.name);
     if (!l_ledger){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find ledger for net %s", l_net->pub.name);
-        return -17;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET, "Can't find ledger for net %s", l_net->pub.name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET;
     }
     // create empty transaction
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
     if (!l_ledger){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new tx");
-        return -18;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX, "Can't create new tx");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX;
     }
 
     dap_list_t *l_hashes_list = s_hashes_parse_str_list(l_hashes_str);
     if (!l_hashes_list){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Requested conditional transaction with hash not found");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND, "Requested conditional transaction with hash not found");
         dap_chain_datum_tx_delete(l_tx);
-        return -19;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND;
     }
 
     uint256_t l_cond_value_sum = {};
@@ -5335,11 +5350,12 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     dap_list_free_full(l_hashes_list, NULL);
 
     if (IS_ZERO_256(l_cond_value_sum)){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "No unspent conditional transactions in hashes list for wallet %s. Check input parameters.", l_wallet_str);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET,
+                               "No unspent conditional transactions in hashes list for wallet %s. Check input parameters.", l_wallet_str);
         dap_chain_datum_tx_delete(l_tx);
         dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_wallet_pkey);
-        return -20;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET;
     }
 
     uint256_t l_net_fee = {};
@@ -5350,11 +5366,12 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
         SUM_256_256(l_total_fee, l_net_fee, &l_total_fee);
 
     if (compare256(l_total_fee, l_cond_value_sum) >= 0 ){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Sum of conditional outputs must be greater than fees sum.");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM,
+                               "Sum of conditional outputs must be greater than fees sum.");
         dap_chain_datum_tx_delete(l_tx);
         dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_wallet_pkey);
-        return -21;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM;
     }
 
     uint256_t l_coin_back = {};
@@ -5363,12 +5380,13 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     // return coins to owner
     if (dap_chain_datum_tx_add_out_item(&l_tx, l_wallet_addr, l_coin_back) == -1) {
         dap_chain_datum_tx_delete(l_tx);
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT,
+                               "Can't create new TX. Something went wrong.\n");
         log_it(L_ERROR, "Can't add returning coins output");
         DAP_DELETE(l_wallet_addr);
         dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_wallet_pkey);
-        return -22;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT-22;
     }
      DAP_DELETE(l_wallet_addr);
     // Network fee
@@ -5377,18 +5395,18 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
         dap_chain_datum_tx_delete(l_tx);
         dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_wallet_pkey);
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT, "Can't create new TX. Something went wrong.\n");
         log_it(L_ERROR, "Cant add network fee output");
-        return -23;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT;
     }
     // Validator's fee
     if (dap_chain_datum_tx_add_fee_item(&l_tx, l_value_fee) == -1) {
         dap_chain_datum_tx_delete(l_tx);
         dap_chain_wallet_close(l_wallet);
         DAP_DEL_Z(l_wallet_pkey);
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT, "Can't create new TX. Something went wrong.\n");
         log_it(L_ERROR, "Cant add validator's fee output");
-        return -24;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT;
     }
 
     // add 'sign' items
@@ -5396,9 +5414,9 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     if(dap_chain_datum_tx_add_sign_item(&l_tx, l_owner_key) != 1) {
         dap_chain_datum_tx_delete(l_tx);
         dap_enc_key_delete(l_owner_key);
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT, "Can't create new TX. Something went wrong.\n");
         log_it( L_ERROR, "Can't add sign output");
-        return -25;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT;
     }
 
     dap_chain_wallet_close(l_wallet);
@@ -5409,21 +5427,27 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply)
     dap_chain_datum_tx_delete(l_tx);
     dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_TX);
     if (!l_chain) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET,
+                               "Can't create new TX. Something went wrong.\n");
         DAP_DELETE(l_datum);
-        return -26;
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET;
     }
     // Processing will be made according to autoprocess policy
     char *l_hash_str = dap_chain_mempool_datum_add(l_datum, l_chain, "hex");
     DAP_DELETE(l_datum);
 
     if (l_hash_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Successfuly created transaction with hash %s\n", l_hash_str);
+        json_object *l_jobj_ret = json_object_new_object();
+        json_object *l_jobj_tx_status = json_object_new_boolean(true);
+        json_object *l_jobj_tx_hash = json_object_new_string(l_hash_str);
+        json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_status);
+        json_object_object_add(l_jobj_ret, "hash", l_jobj_tx_hash);
         DAP_DELETE(l_hash_str);
-        return 0;
+        json_object_array_add(*reply, l_jobj_ret);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OK;
     }
-    dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n");
-    return -1;
+    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR, "Can't create new TX. Something went wrong.");
+    return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR;
 }
 
 typedef struct tx_check_args {
@@ -5444,10 +5468,9 @@ void s_tx_is_srv_pay_check (dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx,
        
 }
 
-int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply)
+int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply)
 {
     (void) a_argc;
-    void** l_str_reply = a_str_reply;
     int arg_index = 1;
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
     const char * l_wallet_str = NULL;
@@ -5459,8 +5482,9 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply)
     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(l_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>");
-        return -1;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX,
+                               "Invalid parameter -H, valid values: -H <hex | base58>");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX;
     }
 
     // Public certifiacte of condition owner
@@ -5471,36 +5495,41 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply)
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str);
 
     if (!l_wallet_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-w'");
-        return -3;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W,
+                               "com_txs_cond_remove requires parameter '-w'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W;
     }
     if(!l_net_name) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-net'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET,
+                               "com_txs_cond_remove requires parameter '-net'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET;
     }
     if(!l_srv_uid_str) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-srv_uid'");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID,
+                               "com_txs_cond_remove requires parameter '-srv_uid'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID;
     }
 
     dap_chain_net_srv_uid_t l_srv_uid = {};
     l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10);
     if (!l_srv_uid.uint64) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find service UID %s ", l_srv_uid_str);
-        return -8;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID,
+                               "Can't find service UID %s ", l_srv_uid_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID;
     }
 
     dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL;
     if(!l_net) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find net '%s'", l_net_name);
-        return -11;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET,
+                               "Can't find net '%s'", l_net_name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET;
     }
 
     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path);
     const char* l_sign_str = "";
     if(!l_wallet) {
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't open wallet '%s'", l_wallet_str);
-        return -12;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET;
     } 
 
     dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0);
@@ -5508,16 +5537,18 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply)
 
     const char *l_native_ticker = l_net->pub.native_ticker;
     if (!l_native_ticker){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find native ticker for net %s", l_net->pub.name);
-        return -16;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET,
+                               "Can't find native ticker for net %s", l_net->pub.name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET;
     }
     dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net->pub.name);
     if (!l_ledger){
-        dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find ledger for net %s", l_net->pub.name);
-        return -17;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET, "Can't find ledger for net %s", l_net->pub.name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET;
     }
 
-    dap_string_t *l_reply_str = dap_string_new("");
+//    dap_string_t *l_reply_str = dap_string_new("");
+    json_object *l_jobj_tx_list_cond_outs = json_object_new_array();
     dap_list_t *l_tx_list = NULL;
 
     dap_chain_net_get_tx_all(l_net, TX_SEARCH_TYPE_NET, s_tx_is_srv_pay_check, &l_tx_list);
@@ -5570,19 +5601,38 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply)
         dap_chain_hash_fast_to_str(&l_data_tx->tx_hash, l_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
         l_remain_coins_str = dap_chain_balance_to_coins(l_out_cond->header.value);
         l_remain_datoshi_str = dap_chain_balance_print(l_out_cond->header.value);
-
-        dap_string_append_printf(l_reply_str, "Tx %s has %s (%s) %s remaining in cond out\n", l_hash_str, l_remain_coins_str, l_remain_datoshi_str, l_native_ticker);
+        json_object *l_jobj_hash = json_object_new_string(l_hash_str);
+        json_object *l_jobj_remain = json_object_new_object();
+        json_object *l_jobj_remain_coins = json_object_new_string(l_remain_coins_str);
+        json_object *l_jobj_remain_datoshi = json_object_new_string(l_remain_datoshi_str);
+        json_object_object_add(l_jobj_remain, "coins", l_jobj_remain_coins);
+        json_object_object_add(l_jobj_remain, "datoshi", l_jobj_remain_datoshi);
+        json_object *l_jobj_native_ticker = json_object_new_string(l_native_ticker);
+        json_object *l_jobj_tx = json_object_new_object();
+        json_object_object_add(l_jobj_tx, "hash", l_jobj_hash);
+        json_object_object_add(l_jobj_tx, "remain", l_jobj_remain);
+        json_object_object_add(l_jobj_tx, "ticker", l_jobj_native_ticker);
+        json_object_array_add(l_jobj_tx_list_cond_outs, l_jobj_tx);
         l_tx_count++;
         SUM_256_256(l_total_value, l_out_cond->header.value, &l_total_value);
     }
     char *l_total_datoshi_str = dap_chain_balance_to_coins(l_total_value);
-    char *l_total_coins_str = dap_chain_balance_print(l_total_value); 
-    dap_string_append_printf(l_reply_str, "\n\nFound %"DAP_UINT64_FORMAT_U" transactions with total value %s (%s) %s", l_tx_count, l_total_datoshi_str, l_total_coins_str, l_native_ticker);
+    char *l_total_coins_str = dap_chain_balance_print(l_total_value);
+    json_object *l_jobj_total = json_object_new_object();
+    json_object *l_jobj_total_datoshi = json_object_new_string(l_total_datoshi_str);
+    json_object *l_jobj_total_coins = json_object_new_string(l_total_coins_str);
+    json_object *l_jobj_native_ticker = json_object_new_string(l_native_ticker);
+    json_object_object_add(l_jobj_total, "datoshi", l_jobj_total_datoshi);
+    json_object_object_add(l_jobj_total, "coins", l_jobj_total_coins);
+    json_object_object_add(l_jobj_total, "ticker", l_jobj_native_ticker);
+    json_object *l_jobj_ret = json_object_new_object();
+    json_object_object_add(l_jobj_ret, "transactions_out_cond", l_jobj_tx_list_cond_outs);
+    json_object_object_add(l_jobj_ret, "total", l_jobj_total);
     dap_list_free_full(l_tx_list, NULL);
-    *l_str_reply = dap_string_free(l_reply_str, false);
+    json_object_array_add(*reply, l_jobj_ret);
     DAP_DEL_Z(l_wallet_pkey);
     dap_chain_wallet_close(l_wallet);
-    return 0;
+    return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_OK;
 }
 typedef enum cmd_mempool_add_ca_error_list{
     COM_MEMPOOL_ADD_CA_ERROR_NET_NOT_FOUND = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
@@ -5927,10 +5977,9 @@ static dap_pkey_t* s_json_get_pkey(struct json_object *a_json)
  * @param str_reply
  * @return int
  */
-int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
+int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
 {
     int l_arg_index = 1;
-    int l_err_code = 0;
     const char *l_net_name = NULL; // optional parameter
     const char *l_chain_name = NULL; // optional parameter
     const char *l_json_file_path = NULL;
@@ -5942,19 +5991,21 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json", &l_json_file_path);
 
     if(!l_json_file_path) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command requires one of parameters '-json <json file path>'");
-        return -1;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON,
+                               "Command requires one of parameters '-json <json file path>'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON;
     }
     // Open json file
     struct json_object *l_json = json_object_from_file(l_json_file_path);
     if(!l_json) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't open json file: %s", json_util_get_last_err());
-        return -2;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+                               "Can't open json file: %s", json_util_get_last_err());
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE;
     }
     if(!json_object_is_type(l_json, json_type_object)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong json format");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format");
         json_object_put(l_json);
-        return -3;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT;
     }
 
     
@@ -5965,17 +6016,18 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
             l_net_name = json_object_get_string(l_json_net);
         }
         if(!l_net_name) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command requires parameter '-net' or set net in the json file");
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
+                                   "Command requires parameter '-net' or set net in the json file");
             json_object_put(l_json);
-            return -11;
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET;
         }
     }
     dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_name);
     l_native_token = l_net->pub.native_ticker;
     if(!l_net) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Not found net by name '%s'", l_net_name);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, "Not found net by name '%s'", l_net_name);
         json_object_put(l_json);
-        return -12;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME;
     }
 
     // Read chain from json file
@@ -5990,9 +6042,10 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
         l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX);
     }
     if(!l_chain) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
+                               "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name);
         json_object_put(l_json);
-        return -13;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME;
     }
 
 
@@ -6001,17 +6054,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
     size_t l_items_count = json_object_array_length(l_json_items);
     bool a = (l_items_count = json_object_array_length(l_json_items));
     if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong json format: not found array 'items' or array is empty");
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS,
+                               "Wrong json format: not found array 'items' or array is empty");
         json_object_put(l_json);
-        return -15;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS;
     }
 
     log_it(L_ERROR, "Json TX: found %lu items", l_items_count);
     // Create transaction
     dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t));
     if(!l_tx) {
-        log_it(L_CRITICAL, "Memory allocation error");
-        return -16;
+        json_object_put(l_json);
+        dap_json_rpc_allocation_error;
+        return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
     }
     l_tx->header.ts_created = time(NULL);
     size_t l_items_ready = 0;
@@ -6021,7 +6076,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
     dap_list_t *l_tsd_list = NULL;// list tsd sections
     uint256_t l_value_need = { };// how many tokens are needed in the 'out' item
     uint256_t l_value_need_fee = {};
-    dap_string_t *l_err_str = dap_string_new("Errors: \n");
+    json_object *l_jobj_errors = json_object_new_array();
+//    dap_string_t *l_err_str = dap_string_new("Errors: \n");
     // Creating and adding items to the transaction
     for(size_t i = 0; i < l_items_count; ++i) {
         struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i);
@@ -6063,8 +6119,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                         // Create OUT item
                         dap_chain_tx_out_t *l_out_item = dap_chain_datum_tx_item_out_create(l_addr, l_value);
                         if (!l_out_item) {
-                            dap_string_append_printf(l_err_str, "Failed to create transaction out. "
-                                                                "There may not be enough funds in the wallet.\n");
+                            json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. "
+                                                                             "There may not be enough funds in the wallet.");
+                            json_object_array_add(l_jobj_errors, l_jobj_err);
                         }
                         l_item = (const uint8_t*) l_out_item;
                     }
@@ -6076,10 +6133,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                             // Create OUT_EXT item
                             dap_chain_tx_out_ext_t *l_out_ext_item = dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token);
                             if (!l_out_ext_item) {
-                                dap_string_append_printf(l_err_str, "Failed to create a out ext"
+                                json_object *l_jobj_err = json_object_new_string("Failed to create a out ext"
                                                                     "for a transaction. There may not be enough funds "
                                                                     "on the wallet or the wrong ticker token "
-                                                                    "is indicated.\n");
+                                                                    "is indicated.");
+                                json_object_array_add(l_jobj_errors, l_jobj_err);
                             }
                             l_item = (const uint8_t*) l_out_ext_item;
                         }
@@ -6099,9 +6157,12 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                     else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) {
                         log_it(L_WARNING, "Invalid 'out_ext' item %zu", i);
                     }
-                    dap_string_append_printf(l_err_str, "For item %zu of type 'out' or 'out_ext' the "
+                    char *l_str_err = dap_strdup_printf("For item %zu of type 'out' or 'out_ext' the "
                                                         "string representation of the address could not be converted, "
-                                                        "or the size of the output sum is 0.\n", i);
+                                                        "or the size of the output sum is 0.", i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                     continue;
                 }
             }
@@ -6152,8 +6213,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 if(l_item) {
                     SUM_256_256(l_value_need, l_value, &l_value_need);
                 } else {
-                    dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction "
+                    char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
                                                         "can of type %s described in item %zu.\n", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                 }
                 DAP_DELETE(l_pkey);
             }
@@ -6188,8 +6252,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 if(l_item) {
                     SUM_256_256(l_value_need, l_value, &l_value_need);
                 } else {
-                    dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction "
-                                                        "can of type %s described in item %zu.\n", l_subtype_str, i);
+                    char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                         "can of type %s described in item %zu.", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                 }
             }
                 break;
@@ -6229,8 +6296,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 if(l_item) {
                     SUM_256_256(l_value_need, l_value, &l_value_need);
                 } else {
-                    dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction "
-                                                        "can of type %s described in item %zu.\n", l_subtype_str, i);
+                    char *l_err_str = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                        "can of type %s described in item %zu.", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_err_str);
+                    DAP_DELETE(l_err_str);
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                 }
                 }
             }
@@ -6245,8 +6315,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                     if(l_item) {
                         SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee);
                     } else {
-                        dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction "
-                                                            "can of type %s described in item %zu.\n", l_subtype_str, i);
+                        char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                            "can of type %s described in item %zu.", l_subtype_str, i);
+                        json_object *l_jobj_err = json_object_new_string(l_str_err);
+                        json_object_array_add(l_jobj_errors, l_jobj_err);
+                        DAP_DELETE(l_str_err);
                     }
                 }
                 else
@@ -6255,8 +6328,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 break;
             case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED:
                 log_it(L_WARNING, "Undefined subtype: '%s' of 'out_cond' item %zu ", l_subtype_str, i);
-                    dap_string_append_printf(l_err_str, "Specified unknown sub type %s of conditional out "
-                                                        "on item %zu.\n", l_subtype_str, i);
+                char *l_str_err = dap_strdup_printf("Specified unknown sub type %s of conditional out on item %zu.",
+                                                    l_subtype_str, i);
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                json_object_array_add(l_jobj_errors, l_jobj_err);
                 break;
             }
         }
@@ -6295,8 +6371,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
             if(l_item)
                 l_receipt_count++;
             else {
-                dap_string_append_printf(l_err_str, "Unable to create receipt out for transaction "
-                                                    "described by item %zu.\n", i);
+                char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction "
+                                                    "described by item %zu.", i);
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                json_object_array_add(l_jobj_errors, l_jobj_err);
             }
         }
             break;
@@ -6347,12 +6426,13 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 // Create IN item
                 dap_chain_tx_in_t *l_in_item = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, (uint32_t) l_out_prev_idx);
                 if (!l_in_item) {
-                    dap_string_append_printf(l_err_str, "Unable to create in for transaction.\n");
+                    json_object *l_jobj_err = json_object_new_string("Unable to create in for transaction.");
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                 }
             } else {
                 log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str);
-                dap_string_append_printf(l_err_str, "Unable to create in for transaction. Invalid 'in' item, "
-                                                    "bad prev_hash %s\n", l_prev_hash_str);
+                char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, "
+                                                    "bad prev_hash %s", l_prev_hash_str);
                 // Go to the next item
                 l_list = dap_list_next(l_list);
                 continue;
@@ -6369,8 +6449,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                 if (!l_addr_from) {
                     log_it(L_WARNING, "Invalid element 'in', unable to convert string representation of addr_from: '%s' "
                                       "to binary.", l_json_item_addr_str);
-                    dap_string_append_printf(l_err_str, "Invalid element 'to', unable to convert string representation "
-                                                        "of addr_from: '%s' to binary.\n", l_json_item_addr_str);
+                    char *l_str_err = dap_strdup_printf("Invalid element 'to', unable to convert string representation "
+                                                        "of addr_from: '%s' to binary.", l_json_item_addr_str);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
                     // Go to the next item
                     l_list = dap_list_next(l_list);
                     continue;
@@ -6378,22 +6461,27 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
             }
             else {
                 log_it(L_WARNING, "Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]");
-                dap_string_append_printf(l_err_str, "Invalid 'in' item, incorrect addr_from: '%s'\n",
+                char *l_str_err = dap_strdup_printf("Invalid 'in' item, incorrect addr_from: '%s'",
                                          l_json_item_addr_str ? l_json_item_addr_str : "[null]");
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                json_object_array_add(l_jobj_errors, l_jobj_err);
                 // Go to the next item
                 l_list = dap_list_next(l_list);
                 continue;
             }
             if(!l_json_item_token) {
                 log_it(L_WARNING, "Invalid 'in' item, not found token name");
-                dap_string_append_printf(l_err_str, "Invalid 'in' item, not found token name\n");
+                json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found token name");
+                json_object_array_add(l_jobj_errors, l_jobj_err);
                 // Go to the next item
                 l_list = dap_list_next(l_list);
                 continue;
             }
             if(IS_ZERO_256(l_value_need)) {
                 log_it(L_WARNING, "Invalid 'in' item, not found value in out items");
-                dap_string_append_printf(l_err_str, "Invalid 'in' item, not found value in out items\n");
+                json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found value in out items");
+                json_object_array_add(l_jobj_errors, l_jobj_err);
                 // Go to the next item
                 l_list = dap_list_next(l_list);
                 continue;
@@ -6414,8 +6502,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                                                                                              l_addr_from, l_value_need_check, &l_value_transfer);
                     if(!l_list_used_out) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
-                        dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx "
-                                                            "to transfer\n");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds in previous tx "
+                                                            "to transfer");
+                        json_object_array_add(l_jobj_errors, l_jobj_err);
                         // Go to the next item
                         l_list = dap_list_next(l_list);
                         continue;
@@ -6426,8 +6515,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                                                                                              l_addr_from, l_value_need, &l_value_transfer);
                     if(!l_list_used_out) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
-                        dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx "
-                                                            "to transfer\n");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds "
+                                                                         "in previous tx to transfer");
+                        json_object_array_add(l_jobj_errors, l_jobj_err);
                         // Go to the next item
                         l_list = dap_list_next(l_list);
                         continue;
@@ -6437,8 +6527,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
                                                                                      l_addr_from, l_value_need_fee, &l_value_transfer_fee);
                     if(!l_list_used_out_fee) {
                         log_it(L_WARNING, "Not enough funds in previous tx to transfer");
-                        dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx "
-                                                            "to transfer\n");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds "
+                                                                         "in previous tx to transfer");
+                        json_object_array_add(l_jobj_errors, l_jobj_err);
                         // Go to the next item
                         l_list = dap_list_next(l_list);
                         continue;
@@ -6510,7 +6601,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
             l_enc_key = l_cert->enc_key; 
         }
         else{
-		dap_string_append_printf(l_err_str, "Can't create sign for transactions.\n");
+            json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions.");
+            json_object_array_add(l_jobj_errors, l_jobj_err);
             log_it(L_ERROR, "Json TX: Item sign has no wallet or cert of they are invalid ");
             l_list = dap_list_next(l_list);
             continue;
@@ -6536,14 +6628,21 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
     dap_list_free(l_sign_list);
     json_object_put(l_json);
 
+    json_object *l_jobj_ret = json_object_new_object();
+
     if(l_items_ready<l_items_count) {
-        if(!l_items_ready)
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "No valid items found to create a transaction");
-        else
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create transaction, because only %zu items out of %zu are valid",l_items_ready,l_items_count);
+        json_object *l_tx_create = json_object_new_boolean(false);
+        json_object *l_jobj_valid_items = json_object_new_uint64(l_items_ready);
+        json_object *l_jobj_total_items = json_object_new_uint64(l_items_count);
+        json_object_object_add(l_jobj_ret, "tx_create", l_tx_create);
+        json_object_object_add(l_jobj_ret, "valid_items", l_jobj_valid_items);
+        json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items);
+        json_object_object_add(l_jobj_ret, "errors", l_jobj_errors);
+        json_object_array_add(*reply, l_jobj_ret);
         DAP_DELETE(l_tx);
-        return -30;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS;
     }
+    json_object_put(l_jobj_errors);
 
     // Pack transaction into the datum
     dap_chain_datum_t *l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, dap_chain_datum_tx_get_size(l_tx));
@@ -6559,12 +6658,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
     DAP_DEL_Z(l_datum_tx);
     DAP_DELETE(l_gdb_group_mempool_base_tx);
     if(!l_placed) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't add transaction to mempool");
-        return -90;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
+                               "Can't add transaction to mempool");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL;
     }
     // Completed successfully
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s with %zu items created and added to mempool successfully", l_tx_hash_str, l_items_ready);
-    return l_err_code;
+    json_object *l_jobj_tx_create = json_object_new_boolean(true);
+    json_object *l_jobj_hash = json_object_new_string(l_tx_hash_str);
+    json_object *l_jobj_total_items = json_object_new_uint64(l_items_ready);
+    json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_create);
+    json_object_object_add(l_jobj_ret, "hash", l_jobj_hash);
+    json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items);
+    json_object_array_add(*reply, l_jobj_ret);
+    return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK;
 }
 
 /**
@@ -6576,7 +6682,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply)
  * @param str_reply
  * @return int
  */
-int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
+int com_tx_create(int a_argc, char **a_argv, void **reply)
 {
     int arg_index = 1;
 //    int cmd_num = 1;
@@ -6603,15 +6709,15 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
     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(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID, "Invalid parameter -H, valid values: -H <hex | base58>");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID;
     }
 
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_name);
     dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name);
     if (l_net == NULL) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "not found net by name '%s'", l_net_name);
-        return -7;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND, "not found net by name '%s'", l_net_name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND;
     }
 
     uint256_t l_value = {};
@@ -6632,19 +6738,13 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
     if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp))
         l_value_fee = dap_chain_balance_scan(str_tmp);
     if (IS_ZERO_256(l_value_fee) && (!l_emission_hash_str || (str_tmp && strcmp(str_tmp, "0")))) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply,
-                "tx_create requires parameter '-fee' to be valid uint256");
-        return -5;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256, "tx_create requires parameter '-fee' to be valid uint256");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256;
     }
 
     if((!l_from_wallet_name && !l_emission_hash_str)||(l_from_wallet_name && l_emission_hash_str)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires one of parameters '-from_wallet' or '-from_emission'");
-        return -1;
-    }
-
-    if(!l_net_name) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-net'");
-        return -6;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION, "tx_create requires one of parameters '-from_wallet' or '-from_emission'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION;
     }
 
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
@@ -6652,9 +6752,10 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
     dap_chain_t *l_emission_chain = NULL;
     if (l_emission_hash_str) {
         if (dap_chain_hash_fast_from_str(l_emission_hash_str, &l_emission_hash)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-from_emission' "
-                                                         "to be valid string containing hash in hex or base58 format");
-            return -3;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION,
+                                   "tx_create requires parameter '-from_emission' "
+                                   "to be valid string containing hash in hex or base58 format");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION;
         }
         if (l_emission_chain_name) {
             l_emission_chain = dap_chain_net_get_chain_by_name(l_net, l_emission_chain_name);
@@ -6662,56 +6763,58 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
             l_emission_chain = dap_chain_net_get_default_chain_by_chain_type(l_net,CHAIN_TYPE_EMISSION);
         }
         if (!l_emission_chain) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-chain_emission' "
-                                                         "to be a valid chain name or set default datum type in chain configuration file");
-            return -9;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION,
+                                   "tx_create requires parameter '-chain_emission' "
+                                   "to be a valid chain name or set default datum type in chain configuration file");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION;
         }
 
         if (l_wallet_fee_name){
             l_wallet_fee = dap_chain_wallet_open(l_wallet_fee_name, c_wallets_path);
             if (!l_wallet_fee) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Wallet %s does not exist", l_wallet_fee_name);
-                return -12;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE,
+                                       "Wallet %s does not exist", l_wallet_fee_name);
+                return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE;
             }
             l_priv_key = dap_chain_wallet_get_key(l_wallet_fee, 0);
         } else if (l_cert_str) {
             l_cert = dap_cert_find_by_name(l_cert_str);
             if (!l_cert) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Certificate %s is invalid", l_cert_str);
-                return -5;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID, "Certificate %s is invalid", l_cert_str);
+                return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID;
             }
             l_priv_key = l_cert->enc_key;
         } else {
-            dap_cli_server_cmd_set_reply_text(a_str_reply,
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE,
                                               "tx_create requires parameter '-cert' or '-wallet_fee' for create base tx for emission");
-            return -10;
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE;
         }
     } else {
         dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-token", &l_token_ticker);
         if (!l_token_ticker) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-token'");
-            return -3;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN, "tx_create requires parameter '-token'");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN;
         }
         if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_ticker)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Ticker '%s' is not declared on network '%s'.",
-                                              l_token_ticker, l_net_name);
-            return -16;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET,
+                                   "Ticker '%s' is not declared on network '%s'.", l_token_ticker, l_net_name);
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET;
         }
         dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &addr_base58_to);
         if (!addr_base58_to) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-to_addr'");
-            return -2;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR, "tx_create requires parameter '-to_addr'");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR;
         }
         l_addr_to = dap_chain_addr_from_str(addr_base58_to);
         if(!l_addr_to) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "destination address is invalid");
-            return -11;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, "destination address is invalid");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID;
         }
         if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &str_tmp))
             l_value = dap_chain_balance_scan(str_tmp);
         if (IS_ZERO_256(l_value)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-value' to be valid uint256 value");
-            return -4;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, "tx_create requires parameter '-value' to be valid uint256 value");
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE;
         }
     }
 
@@ -6723,32 +6826,40 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
     }
 
     if(!l_chain) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file",
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN,
+                               "not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file",
                 l_chain_name);
-        return -8;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN;
     }
 
-    dap_string_t *l_string_ret = dap_string_new(NULL);
-    int l_ret = 0;
+    int l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_OK;
     if (l_emission_hash_str) {
         char *l_tx_hash_str = NULL;
         if (!l_priv_key) {
-            dap_string_append_printf(l_string_ret, "No private key defined for creating the underlying "
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED, "No private key defined for creating the underlying "
                                                    "transaction no '-wallet_fee' or '-cert' parameter specified.");
-            l_ret = -10;
+            l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED;
         }
         l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id,
                                                          uint256_0, NULL, NULL, // Get this params from emission itself
                                                          l_priv_key, l_hash_out_type, l_value_fee);
+        json_object *l_jobj_emission = json_object_new_object();
+        json_object *l_jobj_emi_status = NULL;
+        json_object *l_jobj_emi_hash = NULL;
         if (l_tx_hash_str) {
-            dap_string_append_printf(l_string_ret, "\nDatum %s with 256bit TX is placed in datum pool\n", l_tx_hash_str);
+            l_jobj_emi_status = json_object_new_string("Ok");
+            l_jobj_emi_hash = json_object_new_string(l_tx_hash_str);
             DAP_DELETE(l_tx_hash_str);
+            json_object_object_add(l_jobj_emission, "emission", l_jobj_emi_status);
+            json_object_object_add(l_jobj_emission, "hash", l_jobj_emi_hash);
         } else {
-            dap_string_append_printf(l_string_ret, "\nCan't place TX datum in mempool, examine log files\n");
-            l_ret = -15;
+            l_jobj_emi_status = json_object_new_string("False");
+            json_object_object_add(l_jobj_emission, "emission", l_jobj_emi_status);
+            json_object *l_jobj_msg = json_object_new_string("Can't place TX datum in mempool, examine log files\n");
+            json_object_object_add(l_jobj_emission, "message", l_jobj_msg);
+            l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL;
         }
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_string_ret->str);
-        dap_string_free(l_string_ret, true);
+        json_object_array_add(*reply, l_jobj_emission);
         DAP_DELETE(l_addr_to);
         if (l_wallet_fee) {
             dap_chain_wallet_close(l_wallet_fee);
@@ -6760,16 +6871,17 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
     dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_from_wallet_name, c_wallets_path);
 
     if(!l_wallet) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "wallet %s does not exist", l_from_wallet_name);
-        return -9;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST,
+                               "wallet %s does not exist", l_from_wallet_name);
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST;
     } else {
-        dap_string_append(l_string_ret, dap_chain_wallet_check_sign(l_wallet));
+        json_object *l_jobj_check_wallet = json_object_new_string(dap_chain_wallet_check_sign(l_wallet));
     }
     const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
 
     if(!addr_from) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "source address is invalid");
-        return -10;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID, "source address is invalid");
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID;
     }
 
     if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) {
@@ -6785,35 +6897,42 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
             dap_string_append_printf(l_allowed_list, "0x%016"DAP_UINT64_FORMAT_X, l_net->pub.id.uint64);
             for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next)
                 dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, ((dap_chain_net_id_t *)it->data)->uint64);
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Destination network ID=0x%"DAP_UINT64_FORMAT_x
-                                                           " is unreachable. List of available network IDs:\n%s"
-                                                           " Please, change network name or wallet address",
-                                              l_addr_to->net_id.uint64, l_allowed_list->str);
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE,
+                                   "Destination network ID=0x%"DAP_UINT64_FORMAT_x
+                                   " is unreachable. List of available network IDs:\n%s"
+                                   " Please, change network name or wallet address",
+                                   l_addr_to->net_id.uint64, l_allowed_list->str);
             dap_string_free(l_allowed_list, true);
-            return -13;
+            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE;
         }
     }
 
+    json_object *l_jobj_transfer_status = NULL;
+    json_object *l_jobj_tx_hash = NULL;
+    json_object *l_jobj_result = json_object_new_object();
+
     l_priv_key = dap_chain_wallet_get_key(l_wallet, 0);
     if(l_tx_num){
         l_ret = dap_chain_mempool_tx_create_massive(l_chain, l_priv_key, addr_from,
                                                   l_addr_to, l_token_ticker, l_value, l_value_fee, l_tx_num);
-
-        dap_string_append_printf(l_string_ret, "transfer=%s\n",
-                (l_ret == 0) ? "Ok" : (l_ret == -2) ? "False, not enough funds for transfer" : "False");
+        l_jobj_transfer_status = json_object_new_string((l_ret == 0) ? "Ok" : (l_ret == -2) ? "False, not enough funds for transfer" : "False");
+        json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status);
     } else {
         char *l_tx_hash_str = dap_chain_mempool_tx_create(l_chain, l_priv_key, addr_from, l_addr_to,
                                                                   l_token_ticker, l_value, l_value_fee, l_hash_out_type);
         if (l_tx_hash_str) {
-            dap_string_append_printf(l_string_ret, "transfer=Ok\ntx_hash=%s\n",l_tx_hash_str);
+            l_jobj_transfer_status = json_object_new_string("Ok");
+            l_jobj_tx_hash = json_object_new_string(l_tx_hash_str);
+            json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status);
+            json_object_object_add(l_jobj_result, "hash", l_jobj_tx_hash);
             DAP_DELETE(l_tx_hash_str);
         } else {
-            dap_string_append_printf(l_string_ret, "transfer=False\n");
-            l_ret = -14;
+            l_jobj_transfer_status = json_object_new_string("False");
+            json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status);
+            l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION;
         }
     }
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_string_ret->str);
-    dap_string_free(l_string_ret, true);
+    json_object_array_add(*reply, l_jobj_result);
 
     DAP_DELETE(l_addr_to);
     dap_chain_wallet_close(l_wallet);
@@ -6832,7 +6951,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply)
  * @param str_reply
  * @return int
  */
-int com_tx_verify(int a_argc, char **a_argv, void **a_str_reply)
+int com_tx_verify(int a_argc, char **a_argv, void **reply)
 {
     const char * l_tx_hash_str = NULL;
     dap_chain_net_t * l_net = NULL;
@@ -6841,41 +6960,63 @@ int com_tx_verify(int a_argc, char **a_argv, void **a_str_reply)
 
     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tx", &l_tx_hash_str);
     if(!l_tx_hash_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_verify requires parameter '-tx'");
-        return -1;
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX, "tx_verify requires parameter '-tx'");
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX;
     }
-    dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net);
+    dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&l_arg_index, a_argc, a_argv, &l_chain, &l_net);
     if (!l_net || !l_chain) {
-        return -2;
-    } else if (a_str_reply && *a_str_reply) {
-        DAP_DELETE(*a_str_reply);
-        *a_str_reply = NULL;
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_NET_CHAIN_UNDEFINED;
     }
     dap_hash_fast_t l_tx_hash;
     char *l_hex_str_from58 = NULL;
     if (dap_chain_hash_fast_from_hex_str(l_tx_hash_str, &l_tx_hash)) {
         l_hex_str_from58 = dap_enc_base58_to_hex_str_from_str(l_tx_hash_str);
         if (dap_chain_hash_fast_from_hex_str(l_hex_str_from58, &l_tx_hash)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58");
-            return -3;
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH, "Invalid tx hash format, need hex or base58");
+            return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH;
         }
     }
-    size_t l_tx_size = 0;
+    size_t l_datum_size = 0;
     char *l_gdb_group = dap_chain_net_get_gdb_group_mempool_new(l_chain);
-    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)
-            dap_global_db_get_sync(l_gdb_group, l_hex_str_from58 ? l_hex_str_from58 : l_tx_hash_str, &l_tx_size, NULL, NULL );
+    dap_chain_datum_t *l_datum = (dap_chain_datum_t*)dap_global_db_get_sync(l_gdb_group, l_hex_str_from58 ? l_hex_str_from58 : l_tx_hash_str, &l_datum_size, NULL, NULL);
     DAP_DEL_Z(l_hex_str_from58);
-    if (!l_tx) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx not found");
-        return -3;
-    }
-    int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash);
+    if (!l_datum) {
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND, "Specified tx not found");
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND;
+    }
+    if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX){
+        char *l_str_err = dap_strdup_printf("Based on the specified hash, the type %s was found and not a transaction.",
+                                            dap_chain_datum_type_id_to_str(l_datum->header.type_id));
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH, l_str_err);
+        DAP_DELETE(l_str_err);
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH;
+    }
+    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data;
+    int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_datum->header.data_size, &l_tx_hash);
+    json_object *l_obj_ret = json_object_new_object();
+    json_object *l_obj_hash = json_object_new_string(l_tx_hash_str);
+    json_object_object_add(l_obj_ret, "hash", l_obj_hash);
+    json_object *l_jobj_verfiy = NULL;
+    json_object *l_jobj_error = NULL;
     if (l_ret) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verify fail with return code=%d", l_ret);
-        return -4;
+        l_jobj_verfiy = json_object_new_boolean(false);
+        l_jobj_error = json_object_new_object();
+        json_object *l_jobj_err_str = json_object_new_string(dap_ledger_tx_check_err_str(l_ret));
+        json_object *l_jobj_err_code = json_object_new_int64(l_ret);
+        json_object_object_add(l_jobj_error, "code", l_jobj_err_code);
+        json_object_object_add(l_jobj_error, "message", l_jobj_err_str);
+        json_object_object_add(l_obj_ret, "verify", l_jobj_verfiy);
+        json_object_object_add(l_obj_ret, "error", l_jobj_error);
+        json_object_array_add(*reply, l_obj_ret);
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_TX_NOT_VERIFY;
+    } else {
+        l_jobj_verfiy = json_object_new_boolean(true);
+        l_jobj_error = json_object_new_null();
+        json_object_object_add(l_obj_ret, "verify", l_jobj_verfiy);
+        json_object_object_add(l_obj_ret, "error", l_jobj_error);
+        json_object_array_add(*reply, l_obj_ret);
+        return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_OK;
     }
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verified successfully");
-    return 0;
 }
 
 
@@ -7562,7 +7703,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply)
        dap_cli_server_cmd_set_reply_text(a_str_reply, "Error when deleting, because:\n%s", return_message);
     }
     else if (successful) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Successful removal: %s %s", successful & REMOVED_GDB ? "gdb" : "-", successful & REMOVED_CHAINS ? "chains" : "-");
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Successful removal: %s", successful & REMOVED_GDB && successful & REMOVED_CHAINS ? "gdb, chains" : successful & REMOVED_GDB ? "gdb" : successful & REMOVED_CHAINS ? "chains" : "");
     } else {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Nothing to delete. Check if the command is correct.\nUse flags: -gdb or/and -chains [-net <net_name> | -all]\n"
                                                        "Be careful, the '-all' option will delete ALL CHAINS and won't ask you for permission!");
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index db41574ba2cde3307cca679dd221c8c3f671d60b..d4a9b1ab4a87b876668d5f90acac870a0ed0ea9f 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -172,13 +172,13 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
     }
 
     if (l_atom_hash) {
-        char *l_atom_hash_str = dap_strcmp(a_hash_out_type, "hex")
+        const char *l_atom_hash_str = dap_strcmp(a_hash_out_type, "hex")
                             ? 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));
     }
 
-    char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+    const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
                         ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash)
                         : dap_chain_hash_fast_to_str_static(a_tx_hash);
     json_object_object_add(json_obj_datum, "hash", json_object_new_string(l_hash_str));
@@ -228,7 +228,7 @@ json_object * dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash,
     if (l_tx) {
         return dap_db_tx_history_to_json(a_tx_hash, &l_atom_hash,l_tx, a_chain, a_hash_out_type, l_net, l_ret_code, &accepted_tx, false);
     } else {
-        char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex")
+        const char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex")
                 ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash)
                 : dap_chain_hash_fast_to_str_static(a_tx_hash);
         dap_json_rpc_error_add(-1, "TX hash %s not founds in chains", l_tx_hash_str);
@@ -803,9 +803,9 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger
                 dap_chain_datum_t *l_datum = l_datums[l_datum_n];
                 if(!l_datum)
                     continue;
-                char l_time_str[70];
+                char l_time_str[DAP_TIME_STR_SIZE];
                 // get time of create datum
-                if(dap_time_to_str_rfc822(l_time_str, 71, l_datum->header.ts_create) < 1)
+                if(dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_datum->header.ts_create) < 1)
                     l_time_str[0] = '\0';
                 switch (l_datum->header.type_id) {
                 // token
@@ -925,7 +925,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger
 int com_ledger(int a_argc, char ** a_argv, void **reply)
 {
     json_object ** json_arr_reply = (json_object **) reply;
-    enum { CMD_NONE, CMD_LIST, CMD_LEDGER_HISTORY, CMD_TX_INFO };
+    enum { CMD_NONE, CMD_LIST, CMD_TX_INFO };
     int arg_index = 1;
     const char *l_addr_base58 = NULL;
     const char *l_wallet_name = NULL;
@@ -946,8 +946,6 @@ int com_ledger(int a_argc, char ** a_argv, void **reply)
     int l_cmd = CMD_NONE;
     if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "list", NULL)){
         l_cmd = CMD_LIST;
-    } else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "tx", NULL)){
-        l_cmd = CMD_LEDGER_HISTORY;
     } else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "info", NULL))
         l_cmd = CMD_TX_INFO;
 
@@ -955,119 +953,7 @@ int com_ledger(int a_argc, char ** a_argv, void **reply)
 
     arg_index++;
 
-    if(l_cmd == CMD_LEDGER_HISTORY) {
-        dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-addr", &l_addr_base58);
-        dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-w", &l_wallet_name);
-        dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str);
-        dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-tx", &l_tx_hash_str);
-        bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL);
-        dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL;
-
-        if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) {
-            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "command 'tx' requires parameter '-all' or '-addr' or '-w' or '-tx'");
-            return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR;
-        }
-        // Select chain network
-        if(!l_net_str) {
-            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net'");
-            return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR;
-        } else {
-            if((l_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net' to be valid chain network name");
-                return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR;
-            }
-        }
-
-        dap_chain_hash_fast_t l_tx_hash;
-        if(l_tx_hash_str) {
-            if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) {
-                l_tx_hash_str = NULL;
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR, "tx hash not recognized");
-                return DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR;
-            }
-        }
-        
-        dap_chain_addr_t *l_addr = NULL;
-        // if need addr
-        const char* l_sign_str = "";
-        if(l_wallet_name || l_addr_base58) {
-            if(l_wallet_name) {
-                const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
-                dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path);
-                if(l_wallet) {
-                    l_sign_str = dap_chain_wallet_check_sign(l_wallet);
-                    l_addr = dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
-                    dap_chain_wallet_close(l_wallet);
-                }
-            }
-            if(!l_addr && l_addr_base58) {
-                l_addr = dap_chain_addr_from_str(l_addr_base58);
-            }
-            if(!l_addr && !l_tx_hash_str) {
-                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR, "wallet address not recognized");
-                return DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR;
-            }
-        }
-        json_object* json_obj_out = json_object_new_object();
-        json_object_object_add(json_obj_out, "sign ", json_object_new_string(l_sign_str));
-        char *l_str_out = NULL;
-        dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str);
-        if(l_is_all) {
-            size_t l_tx_count = dap_ledger_count(l_ledger), l_tx_count_spent_count = 0;
-            if (!l_tx_count) {
-                json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name));
-                json_object_object_add(json_obj_out, "info", json_object_new_string("Contains no transactions."));
-            } else {
-                json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name));
-                json_object_object_add(json_obj_out, "count tx", json_object_new_int(l_tx_count));
-                json_object* json_arr_tx = json_object_new_array();
-                dap_list_t *l_txs_list = dap_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag);
-                for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) {
-                    dap_chain_datum_tx_t *l_tx = iter->data;
-                    dap_hash_fast_t l_tx_hash = { };
-                    dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
-                    json_object * l_json_obj_datum = json_object_new_object();
-                    s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_json_obj_datum, l_hash_out_type, &l_tx_hash);
-                    json_object_array_add(json_arr_tx, l_json_obj_datum);
-                }
-                json_object_object_add(json_obj_out, "data", json_arr_tx);
-                dap_list_free(l_txs_list);
-            }
-        } else {
-            if(l_addr)
-            {
-                json_object* json_obj_array = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag);
-                json_object_object_add(json_obj_out, "Datum_tx", json_obj_array);
-                json_object_object_add(json_obj_out, "history for addr ", json_object_new_string(dap_chain_addr_to_str(l_addr)));
-            } else if(l_tx_hash_str) {
-                dap_chain_datum_tx_t *l_tx = NULL;
-                if (l_unspent_flag) {
-                    l_tx = dap_ledger_tx_unspent_find_by_hash(l_ledger, &l_tx_hash);
-                } else {
-                    l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash);
-                }
-                if(l_tx) {
-                    size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
-                    dap_hash_fast_t l_tx_hash = { };
-                    dap_hash_fast(l_tx, l_tx_size, &l_tx_hash);
-                    s_dap_chain_datum_tx_out_data(l_tx, l_ledger, json_obj_out, l_hash_out_type, &l_tx_hash);
-                    json_object_object_add(json_obj_out, "history for tx hash ", json_object_new_string(l_tx_hash_str));
-                    json_object_object_add(json_obj_out, "ticker ", json_object_new_string(l_tx_hash_str));
-                } else {
-                    json_object_object_add(json_obj_out, "status", json_object_new_string("There is not transaction in the network ledger"));
-                    json_object_object_add(json_obj_out, "hash", json_object_new_string(l_tx_hash_str));
-                }
-            }            
-        }
-        DAP_DELETE(l_str_out);
-        DAP_DELETE(l_addr);
-        s_dap_chain_tx_hash_processed_ht_free(&l_list_tx_hash_processd);
-        if (json_obj_out) {
-            json_object_array_add(*json_arr_reply, json_obj_out);
-        }
-        return 0;       
-    }
-    else if(l_cmd == CMD_LIST){
+    if(l_cmd == CMD_LIST){
         enum {SUBCMD_NONE, SUBCMD_LIST_COIN, SUB_CMD_LIST_LEDGER_THRESHOLD, SUB_CMD_LIST_LEDGER_BALANCE, SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH};
         int l_sub_cmd = SUBCMD_NONE;
         dap_chain_hash_fast_t l_tx_threshold_hash;
@@ -1182,7 +1068,7 @@ int com_ledger(int a_argc, char ** a_argv, void **reply)
         }        
     }
     else{
-        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'", l_tx_hash_str);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'ledger' requires parameter 'list' or 'info'", l_tx_hash_str);
         return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR;
     }
     return 0;
diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h
index 4ded811acf2331c546f00b2a6f537f88856ead65..a20814b648b5d3162caf984e0b69cce16eb58862 100644
--- a/modules/net/include/dap_chain_node_cli_cmd.h
+++ b/modules/net/include/dap_chain_node_cli_cmd.h
@@ -137,17 +137,121 @@ int com_tx_wallet(int a_argc, char **a_argv, void **a_str_reply);
  *
  * Create transaction
  */
+typedef enum s_com_tx_create_err{
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION
+}s_com_tx_create_err_t;
 int com_tx_create(int a_argc, char **a_argv, void **a_str_reply);
-int com_tx_create_json(int a_argc, char **a_argv, void **a_str_reply);
-int com_tx_cond_create(int a_argc, char **a_argv, void **a_str_reply);
-int com_tx_cond_remove(int a_argc, char **a_argv, void **a_str_reply);
-int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply);
-
+typedef enum s_com_tx_create_json_err {
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL
+}s_com_tx_create_json_err_t;
+int com_tx_create_json(int a_argc, char **a_argv, void **reply);
+typedef enum s_com_tx_cond_create{
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_CONDITIONAL_TX_CREATE
+}s_com_tx_cond_create_t;
+int com_tx_cond_create(int a_argc, char **a_argv, void **reply);
+typedef enum s_com_tx_cond_remove{
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR
+}s_com_tx_cond_remove_t;
+int com_tx_cond_remove(int a_argc, char **a_argv, void **reply);
+typedef enum s_com_tx_cond_unspent_find{
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET,
+}s_com_tx_cond_unspent_find_t;
+int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply);
+
+typedef enum s_com_tx_verify{
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_NET_CHAIN_UNDEFINED,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH,
+    DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_TX_NOT_VERIFY
+}s_com_tx_verify_t;
 /**
  * tx_verify command
  *
  * Verifing transaction
  */
+
 int com_tx_verify(int a_argc, char ** a_argv, void **a_str_reply);
 
 typedef enum s_com_tx_history_err{
@@ -210,5 +314,4 @@ int com_chain_ca_pub( int a_argc,  char **a_argv, void **a_str_reply);
 int com_chain_ca_copy( int a_argc,  char **a_argv, void **a_str_reply);
 int com_signer(int a_argc, char **a_argv, void **a_str_reply);
 //remove func
-int cmd_remove(int a_argc, char **a_argv, void **a_str_reply);
-
+int cmd_remove(int a_argc, char **a_argv, void **a_str_reply);
\ No newline at end of file
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index 1141d2584c23b119c141e775ba7d05ba45adc991..c1a954203a269d81271f21cb03367cdf621207ea 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -350,7 +350,7 @@ char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_ord
     dap_chain_hash_fast_t l_order_hash;
     size_t l_order_size = dap_chain_net_srv_order_get_size(a_order);
     dap_hash_fast(a_order, l_order_size, &l_order_hash);
-    char *l_order_hash_str = dap_chain_hash_fast_to_str_static(&l_order_hash);
+    const char *l_order_hash_str = dap_chain_hash_fast_to_str_static(&l_order_hash);
     char *l_gdb_group_str = a_common ? dap_chain_net_srv_order_get_common_group(a_net)
                                      : dap_chain_net_srv_order_get_gdb_group(a_net);
     if (!l_gdb_group_str)
@@ -541,7 +541,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
     if (a_order && a_str_out ){
         dap_chain_hash_fast_t l_hash;
         dap_hash_fast(a_order, dap_chain_net_srv_order_get_size(a_order), &l_hash);
-        char *l_hash_str = dap_strcmp(a_hash_out_type,"hex")
+        const char *l_hash_str = dap_strcmp(a_hash_out_type,"hex")
                 ? dap_enc_base58_encode_hash_to_str_static(&l_hash)
                 : dap_chain_hash_fast_to_str_static(&l_hash);
 
@@ -553,8 +553,8 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         case SERV_DIR_SELL:         dap_string_append_printf(a_str_out, "  direction:        SERV_DIR_SELL\n" );        break;
         case SERV_DIR_BUY:          dap_string_append_printf(a_str_out, "  direction:        SERV_DIR_BUY\n" );         break;
         }
-        char buf_time[50];
-        dap_time_to_str_rfc822(buf_time, 50, a_order->ts_created);
+        char buf_time[DAP_TIME_STR_SIZE];
+        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 );
         
@@ -589,7 +589,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d
         dap_sign_t *l_sign = (dap_sign_t*)((byte_t*)a_order->ext_n_sign + a_order->ext_size);
         dap_hash_fast_t l_sign_pkey = {0};
         dap_sign_get_pkey_hash(l_sign, &l_sign_pkey);
-        char *l_sign_pkey_hash_str = dap_hash_fast_to_str_static(&l_sign_pkey);
+        const char *l_sign_pkey_hash_str = dap_hash_fast_to_str_static(&l_sign_pkey);
         dap_string_append_printf(a_str_out, "  pkey:             %s\n", l_sign_pkey_hash_str);
         DAP_DELETE(l_ext_out);
     }
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 6287d6a0582666f8df5782ea0fe42162a54813ee..00a8f1eec0cf188133bda08c6b1c2097089ff901 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
@@ -87,7 +87,7 @@ int dap_chain_net_srv_stake_pos_delegate_init()
                                         "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}"
                         " -net <net_name> -w <wallet_name> -fee <value>\n"
          "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n"
-    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -cert_pkey_hash <pkey_hash>}"
+    "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -siging_pkey_hash <pkey_hash> -signing_pkey_type <pkey_type>}"
                             " {-w <wallet_name> -fee <value> | -poa_cert <cert_name>}\n"
          "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and"
          " return m-tokens to specified wallet (if any)\n"
@@ -1931,7 +1931,7 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index
         l_tx_hash = l_stake->tx_hash;
     }
 
-    char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash);
+    const char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash);
     dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
     if (!l_tx) {
         dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s not found", l_tx_hash_str_tmp);
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index f207fb10adf0b4256ecc0f81e1e69f9f0557d1c6..22abf697ed0316fd2c8f728b2505822f1ee9b31f 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -200,7 +200,7 @@ static char* s_ch_vpn_get_my_pkey_str(dap_chain_net_srv_usage_t* a_usage);
 // Stream callbacks
 static void s_ch_vpn_new(dap_stream_ch_t* ch, void* arg);
 static void s_ch_vpn_delete(dap_stream_ch_t* ch, void* arg);
-static void s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg);
+static bool s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg);
 static bool s_ch_packet_out(dap_stream_ch_t* ch, void* arg);
 
 static void s_ch_vpn_esocket_assigned(dap_events_socket_t* a_es, dap_worker_t * l_worker);
@@ -1687,7 +1687,7 @@ static void s_ch_packet_in_vpn_address_request(dap_stream_ch_t* a_ch, dap_chain_
  * @param ch
  * @param arg
  */
-void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
+static bool s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 {
     dap_stream_ch_pkt_t * l_pkt = (dap_stream_ch_pkt_t *) a_arg;
     dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION (a_ch->stream->session );
@@ -1698,7 +1698,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothing on this channel");
         dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
         dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
-        return;
+        return false;
     }
 
     if ( ! l_usage->is_active ){
@@ -1707,7 +1707,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
             dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
         dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
         dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
-        return;
+        return false;
     }
     // check role
     if (dap_chain_net_get_role(l_usage->net).enums > NODE_ROLE_MASTER) {
@@ -1720,7 +1720,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
             dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
         dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
         dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
-        return;
+        return false;
     }
 
     // TODO move address leasing to this structure
@@ -1808,6 +1808,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                 log_it(L_WARNING, "Can't process SF type 0x%02x", l_vpn_pkt->header.op_code);
         }
     }
+    return true;
 }
 
 /**
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
index 8fb7670106aa0d22cee24df42f54ae58a818a904..695fb53faab302c846a7b4e92dfdd4daaed08ae1 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
@@ -46,7 +46,7 @@ int com_vpn_statistics(int a_argc, char ** a_argv, void **a_str_reply)
             l_conn++;
             // time start/length
             uint32_t l_time_len_sec = time(NULL) - l_session->time_created;
-            char l_buf[70] = { '\0' };
+            char l_buf[DAP_TIME_STR_SIZE] = { '\0' };
             if(dap_time_to_str_rfc822(l_buf, sizeof(l_buf), l_session->time_created) > 0)
                 dap_string_append_printf(l_str, "  start at %s (length %02u:%02u:%02u)\n", l_buf,
                         l_time_len_sec / 3600, (l_time_len_sec % 3600) / 60, l_time_len_sec % 60);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index dcdafae8ffeaaf1663cfff95d36609b4c6951294..9e0d51900c4f54bb0245156e825ad593dc424bc5 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1420,7 +1420,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 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);
-                    char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_price->tx_hash);
+                    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_DELETE(l_price);
                 } break;
@@ -1689,7 +1689,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
     dap_hash_fast_t l_tx_hash = {0};
 
     dap_hash_fast(a_tx, l_tx_size, &l_tx_hash);
-    char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&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(
@@ -2025,7 +2025,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                 dap_hash_fast_t l_tx_hash = {};
                 dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
-                char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
+                const char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
 
                 uint64_t l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_tx_hash);
 
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index cac044c804aa681a8edac5d41f7c5713bca52ab4..98ed880f12811494fe83edeaded80a2daa8bfdf0 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -102,6 +102,7 @@ static size_t s_callback_atom_get_static_hdr_size(void);
 static dap_chain_atom_iter_t *s_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash_from);
 static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter ,
                                                                        dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
+static dap_chain_atom_ptr_t s_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num);
 static dap_chain_datum_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash,
                                                         dap_chain_hash_fast_t *a_block_hash, int *a_ret_code);
 
@@ -253,6 +254,7 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c
     a_chain->callback_atom_get_timestamp = s_chain_callback_atom_get_timestamp;
 
     a_chain->callback_atom_find_by_hash = s_callback_atom_iter_find_by_hash;
+    a_chain->callback_atom_get_by_num = s_callback_atom_iter_get_by_num;
     a_chain->callback_datum_find_by_hash = s_callback_datum_find_by_hash;
 
     a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash;
@@ -446,8 +448,9 @@ static void s_cli_meta_hex_print(  dap_string_t * a_str_tmp, const char * a_meta
 static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_reply_str, const char *a_table_name)
 {
     bool l_status = dap_chain_esbocs_get_autocollect_status(a_net->pub.id);
-    dap_string_append_printf(a_reply_str, "\nAutocollect status for network %s is %s\n", a_net->pub.name,
-                                        l_status ? "active" : "inactive, cause the network config or consensus starting problems");
+    dap_string_append_printf(a_reply_str, "\nAutocollect status for %s in network %s is %s\n",
+                                         dap_strdown(a_table_name, -1), a_net->pub.name,
+                                         l_status ? "active" : "inactive, cause the network config or consensus starting problems");
     if (!l_status)
         return;
     dap_string_append_printf(a_reply_str, "\nAutocollect tables content for:\n=== %s ===\n", a_table_name);
@@ -662,8 +665,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_string_append_printf(l_str_tmp, "\t\t\tversion: 0x%04X\n", l_block->hdr.version);
             dap_string_append_printf(l_str_tmp, "\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.cell_id.uint64);
             dap_string_append_printf(l_str_tmp, "\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.chain_id.uint64);
-            char buf[50];
-            dap_time_to_str_rfc822(buf, 50, l_block->hdr.ts_created);
+            char buf[DAP_TIME_STR_SIZE];
+            dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
             dap_string_append_printf(l_str_tmp, "\t\t\tts_created: %s\n", buf);
 
             // Dump Metadata
@@ -714,7 +717,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 const char * l_datum_type_str="UNKNOWN";
                 DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str);
                 dap_string_append_printf(l_str_tmp,"\t\t\t\ttype_id:=%s\n", l_datum_type_str);
-                dap_time_to_str_rfc822(buf, 50, l_datum->header.ts_create);
+                dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
                 dap_string_append_printf(l_str_tmp,"\t\t\t\tts_create=%s\n", buf);
                 dap_string_append_printf(l_str_tmp,"\t\t\t\tdata_size=%u\n", l_datum->header.data_size);
                 dap_chain_datum_dump(l_str_tmp, l_datum, "hex", l_net->pub.id);
@@ -901,8 +904,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                             continue;
                     }
                 }
-                char l_buf[50];
-                dap_time_to_str_rfc822(l_buf, 50, l_ts);
+                char l_buf[DAP_TIME_STR_SIZE];
+                dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
                 dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
                 l_block_count++;
                 if (l_to_hash_str && dap_hash_fast_compare(&l_to_hash, &l_block_cache->block_hash))
@@ -1467,6 +1470,28 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_ite
     return a_atom_iter->cur;
 }
 
+static dap_chain_atom_ptr_t s_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num)
+{
+    assert(a_atom_iter);
+    dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain);
+    dap_chain_block_cache_t *l_block_cache = NULL;
+    pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock);
+    for (l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next)
+        if (l_block_cache->block_number == a_atom_num)
+            break;
+    a_atom_iter->cur_item = l_block_cache;
+    if (l_block_cache) {
+        a_atom_iter->cur        = l_block_cache->block;
+        a_atom_iter->cur_size   = l_block_cache->block_size;
+        a_atom_iter->cur_hash   = &l_block_cache->block_hash;
+        a_atom_iter->cur_num    = l_block_cache->block_number;
+    } else
+        *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain,
+                                                 .cell_id = a_atom_iter->cell_id };
+    pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
+    return a_atom_iter->cur;
+}
+
 /**
  * @brief s_callback_atom_iter_find_by_tx_hash
  * @param a_chain
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index b96a079e1fb1a84ce927556e34169561cae7949d..5a9cc40d795ac213e7be2a8a5c9c719349e74d5e 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -104,6 +104,7 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_
 
 static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter ,
                                                                        dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size);
+static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num);
 static dap_chain_datum_t *s_chain_callback_atom_find_by_datum_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash,
                                                                    dap_chain_hash_fast_t *a_event_hash, int *a_ret_code);
 static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count);
@@ -218,6 +219,7 @@ static int s_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     a_chain->callback_atom_iter_delete = s_chain_callback_atom_iter_delete;
     a_chain->callback_atom_iter_get = s_chain_callback_atom_iter_get;               // Linear pass through
     a_chain->callback_atom_find_by_hash = s_chain_callback_atom_iter_find_by_hash;  // Get element by hash
+    a_chain->callback_atom_get_by_num = s_chain_callback_atom_iter_get_by_num;
     a_chain->callback_atom_iter_get_links = s_chain_callback_atom_iter_get_links;
 
     a_chain->callback_atom_get_datums = s_chain_callback_atom_get_datum;
@@ -515,16 +517,15 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha
             debug_if(s_debug_more, L_WARNING, "... added with ledger code %d", l_consensus_check);
             break;
         }
-        dap_chain_cs_dag_event_item_t *l_tail = PVT(l_dag)->events ? PVT(l_dag)->events->hh.tbl->tail->prev : NULL;
-        if (!l_tail)
-            l_tail = PVT(l_dag)->events;
-        else
-            l_tail = l_tail->hh.next;
-        if (l_tail && l_tail->event->header.ts_created > l_event->header.ts_created)
+        dap_chain_cs_dag_event_item_t *l_tail;
+        HASH_LAST(PVT(l_dag)->events, l_tail);
+        if (l_tail && l_tail->event->header.ts_created > l_event->header.ts_created) {
             DAP_CHAIN_PVT(a_chain)->need_reorder = true;
-        if (DAP_CHAIN_PVT(a_chain)->need_reorder)
             HASH_ADD_INORDER(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item, s_sort_event_item);
-        else
+            dap_chain_cs_dag_event_item_t *it = PVT(l_dag)->events;
+            for (uint64_t i = 0; it; it = it->hh.next)  // renumber chain events
+                it->event_number = ++i;
+        } else
             HASH_ADD(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item);
         s_dag_events_lasts_process_new_last_event(l_dag, l_event_item);
     } break;
@@ -1143,17 +1144,40 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at
     dap_chain_cs_dag_event_item_t *l_event_item = NULL;
     pthread_mutex_lock(&PVT(l_dag)->events_mutex);
     HASH_FIND(hh, PVT(l_dag)->events, a_atom_hash, sizeof(*a_atom_hash), l_event_item);
-    pthread_mutex_unlock(&PVT(l_dag)->events_mutex);
-    if (!l_event_item)
-        return NULL;
-    a_atom_iter->cur_item = l_event_item;
-    a_atom_iter->cur = l_event_item->event;
-    a_atom_iter->cur_size= l_event_item->event_size;
-    a_atom_iter->cur_hash = &l_event_item->hash;
-    a_atom_iter->cur_num = l_event_item->event_number;
+    if (l_event_item) {
+        a_atom_iter->cur_item = l_event_item;
+        a_atom_iter->cur = l_event_item->event;
+        a_atom_iter->cur_size = l_event_item->event_size;
+        a_atom_iter->cur_hash = &l_event_item->hash;
+        a_atom_iter->cur_num = l_event_item->event_number;
+    } else
+        *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain,
+                                                 .cell_id = a_atom_iter->cell_id };
     if (a_atom_size)
-        *a_atom_size = l_event_item->event_size;
-    return l_event_item->event;
+        *a_atom_size = a_atom_iter->cur_size;
+    pthread_mutex_unlock(&PVT(l_dag)->events_mutex);
+    return a_atom_iter->cur;
+}
+
+static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num)
+{
+    dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_atom_iter->chain);
+    dap_chain_cs_dag_event_item_t *l_event_item = NULL;
+    pthread_mutex_lock(&PVT(l_dag)->events_mutex);
+    for (l_event_item = PVT(l_dag)->events; l_event_item; l_event_item = l_event_item->hh.next)
+        if (l_event_item->event_number == a_atom_num)
+            break;
+    if (l_event_item) {
+        a_atom_iter->cur_item = l_event_item;
+        a_atom_iter->cur = l_event_item->event;
+        a_atom_iter->cur_size = l_event_item->event_size;
+        a_atom_iter->cur_hash = &l_event_item->hash;
+        a_atom_iter->cur_num = l_event_item->event_number;
+    } else
+        *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain,
+                                                 .cell_id = a_atom_iter->cell_id };
+    pthread_mutex_unlock(&PVT(l_dag)->events_mutex);
+    return a_atom_iter->cur;
 }
 
 /**
@@ -1644,7 +1668,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                 }
                 if ( l_event ){
                     dap_string_t * l_str_tmp = dap_string_new(NULL);
-                    char buf[50];
+                    char buf[DAP_TIME_STR_SIZE];
 
                     dap_string_append_printf(l_str_tmp,"\nEvent %s:\n", l_event_hash_str);
 
@@ -1653,7 +1677,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                         dap_string_append_printf(l_str_tmp,
                             "\tRound info:\n\t\tsigns reject: %d\n",
                             l_round_item->round_info.reject_count);
-                        dap_time_to_str_rfc822(buf, 50, l_round_item->round_info.ts_update);
+                        dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_round_item->round_info.ts_update);
                         dap_string_append_printf(l_str_tmp, "\t\tdatum_hash: %s\n\t\tts_update: %s\n",
                             dap_chain_hash_fast_to_str_static(&l_round_item->round_info.datum_hash), buf);
                     }
@@ -1664,7 +1688,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                     dap_string_append_printf(l_str_tmp,"\t\t\tround ID: %"DAP_UINT64_FORMAT_U"\n",l_event->header.round_id);
                     dap_string_append_printf(l_str_tmp,"\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_x"\n",l_event->header.cell_id.uint64);
                     dap_string_append_printf(l_str_tmp,"\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n",l_event->header.chain_id.uint64);
-                    dap_time_to_str_rfc822(buf, 50, l_event->header.ts_created);
+                    dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event->header.ts_created);
                     dap_string_append_printf(l_str_tmp,"\t\t\tts_created: %s\n", buf );
 
                     // Hash links
@@ -1685,7 +1709,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                     dap_string_append_printf(l_str_tmp,"\t\tdatum:\tdatum_size: %zu\n",l_datum_size);
                     dap_string_append_printf(l_str_tmp,"\t\t\tversion:=0x%02hhX\n", l_datum->header.version_id);
                     dap_string_append_printf(l_str_tmp,"\t\t\ttype_id:=%s\n", l_datum_type);
-                    dap_time_to_str_rfc822(buf, 50, l_datum->header.ts_create);
+                    dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
                     dap_string_append_printf(l_str_tmp,"\t\t\tts_create=%s\n", buf);
                     dap_string_append_printf(l_str_tmp,"\t\t\tdata_size=%u\n", l_datum->header.data_size);
 
@@ -1701,7 +1725,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                         }
                         dap_chain_hash_fast_t l_pkey_hash;
                         dap_sign_get_pkey_hash(l_sign, &l_pkey_hash);
-                        char *l_hash_str = dap_strcmp(l_hash_out_type, "hex")
+                        const char *l_hash_str = dap_strcmp(l_hash_out_type, "hex")
                             ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash)
                             : dap_chain_hash_fast_to_str_static(&l_pkey_hash);
 
@@ -1797,8 +1821,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                             i_tmp++;
                         } else {
                             i_tmp++;
-                            char buf[50];
-                            dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created);
+                            char buf[DAP_TIME_STR_SIZE];
+                            dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created);
                             dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n",
                                                      dap_chain_hash_fast_to_str_static(&l_event_item->hash),
                                                      buf);
@@ -1835,8 +1859,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                             continue;
                         }
                         i_tmp++;
-                        char buf[50];
-                        dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created);
+                        char buf[DAP_TIME_STR_SIZE];
+                        dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created);
                         dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s\n",
                                                  dap_chain_hash_fast_to_str_static( &l_event_item->hash),
                                                  buf);
@@ -1886,8 +1910,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                         if ( l_event_size_new ) {
                             dap_chain_hash_fast_t l_event_new_hash;
                             dap_chain_cs_dag_event_calc_hash(l_event, l_event_size_new, &l_event_new_hash);
-                            char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_static(&l_event_new_hash);
-                            char * l_event_new_hash_base58_str = NULL;
+                            const char *l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_static(&l_event_new_hash);
+                            const char *l_event_new_hash_base58_str = NULL;
                             if (dap_strcmp(l_hash_out_type, "hex"))
                                 l_event_new_hash_base58_str = dap_enc_base58_encode_hash_to_str_static(&l_event_new_hash);
 
diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c
index 0e081e629d9a6ea4d279e3329ffc24d00bf00397..c08185192ccac440d147a2c4723813b900eea1d7 100644
--- a/modules/type/dag/dap_chain_cs_dag_event.c
+++ b/modules/type/dag/dap_chain_cs_dag_event.c
@@ -221,7 +221,7 @@ size_t dap_chain_cs_dag_event_round_sign_add(dap_chain_cs_dag_event_round_item_t
  * @param a_group
  * @return
  */
-bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event,
+bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, const char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event,
                                     size_t a_event_size, dap_chain_cs_dag_event_round_item_t *a_round_item)
 {
     size_t l_signs_size = (size_t)(a_round_item->data_size-a_round_item->event_size);
diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h
index cef68bfeee9e31e4839ff6fb15715d38eea48b26..bbe4f5b064044e7bc25f1b59e601f50fbaebab05 100644
--- a/modules/type/dag/include/dap_chain_cs_dag_event.h
+++ b/modules/type/dag/include/dap_chain_cs_dag_event.h
@@ -149,7 +149,7 @@ static inline size_t dap_chain_cs_dag_event_round_item_get_size(dap_chain_cs_dag
 
 void dap_chain_cs_dag_event_broadcast(dap_chain_cs_dag_t *a_dag, dap_store_obj_t *a_obj, dap_global_db_instance_t *a_dbi);
 
-bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event,
+bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, const char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event,
                                     size_t a_event_size, dap_chain_cs_dag_event_round_item_t *a_round_item);
 
 dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size,