diff --git a/dap-sdk b/dap-sdk
index 90e987710ed420a624be5619dc0d813b25947d9b..628e8fd05782d701bb1be115d3b5ba8268ee8fa6 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 90e987710ed420a624be5619dc0d813b25947d9b
+Subproject commit 628e8fd05782d701bb1be115d3b5ba8268ee8fa6
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index f59f10a6367fe6975a46a575e2b2b9a2f6d3f070..ee066d615550300e37807300dc263aad7a5a68cd 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -54,6 +54,7 @@ typedef struct dap_chain_atom_iter {
     size_t cur_size;
     dap_chain_hash_fast_t *cur_hash;
     uint64_t cur_num;
+    dap_time_t cur_ts;
 } dap_chain_atom_iter_t;
 
 typedef struct dap_chain_datum_iter {
@@ -96,6 +97,7 @@ typedef void (*dap_chain_callback_ptr_t)(dap_chain_t *, void * );
 
 typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_t)(dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, dap_hash_fast_t *a_atom_hash, bool a_atom_new);
 typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_form_treshold_t)(dap_chain_t *, size_t *);
+typedef json_object *(*dap_chain_callback_atom_to_json)(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hex_out_type);
 typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_verify_t)(dap_chain_t *, dap_chain_atom_ptr_t , size_t, dap_hash_fast_t*);
 typedef size_t (*dap_chain_callback_atom_get_hdr_size_t)(void);
 
@@ -200,6 +202,7 @@ typedef struct dap_chain {
     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_atom_to_json callback_atom_dump_json;
 
     dap_chain_callback_block_find_by_hash_t callback_block_find_by_tx_hash;
 
diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h
index 1d6722f12c9e351a1f1f06788ae4d0dd81959c4a..70ef4f65bd0effd30b298a3ff4bd8ac65925e9c0 100644
--- a/modules/common/include/dap_chain_datum_decree.h
+++ b/modules/common/include/dap_chain_datum_decree.h
@@ -128,6 +128,38 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d
     }
 }
 
+DAP_STATIC_INLINE uint16_t dap_chain_datum_decree_type_from_str(const char *a_decree_type) {
+    if (!dap_strcmp(a_decree_type, "fee")){
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_FEE;
+    } else if (!dap_strcmp(a_decree_type, "owners")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS;
+    } else if (!dap_strcmp(a_decree_type, "owners_min")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN;
+    } else if (!dap_strcmp(a_decree_type, "stake_approve")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE;
+    } else if (!dap_strcmp(a_decree_type, "stake_invalidate")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE;
+    } else if (!dap_strcmp(a_decree_type, "min_value")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE;
+    } else if (!dap_strcmp(a_decree_type, "min_validators_count")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT;
+    } else if (!dap_strcmp(a_decree_type, "ban")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN;
+    } else if (!dap_strcmp(a_decree_type, "unban")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN;
+    } else if (!dap_strcmp(a_decree_type, "reward")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD;
+    } else if (!dap_strcmp(a_decree_type, "validator_max_weight")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT;
+    } else if (!dap_strcmp(a_decree_type, "emergency_validators")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS;
+    } else if (!dap_strcmp(a_decree_type, "check_signs_structure")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE;
+    } else {
+        return 0;
+    }
+}
+
 DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_decree_tsd_type) {
     switch (a_decree_tsd_type) {
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 80b293580fb91af5c88f0a4455208fe27031fa1e..653f59ec2e54591e6e0ecf315809cb8a74115085 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -130,7 +130,6 @@ struct precached_key {
     uint64_t frequency;
     dap_hash_fast_t pkey_hash;
     size_t pkey_size;
-    struct precached_key *prev, *next;
     byte_t sign_pkey[];
 };
 
@@ -162,7 +161,7 @@ typedef struct dap_chain_esbocs_pvt {
     uint16_t min_validators_count;
     bool check_signs_structure;
     // Internal cache
-    struct precached_key *precached_keys;
+    dap_list_t *precached_keys;
 } dap_chain_esbocs_pvt_t;
 
 #define PVT(a) ((dap_chain_esbocs_pvt_t *)a->_pvt)
@@ -2769,11 +2768,13 @@ static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_b
     return dap_chain_block_sign_add(a_block_ptr, a_block_size, l_esbocs_pvt->blocks_sign_key);
 }
 
-static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys_list, dap_sign_t *a_source_sign, dap_hash_fast_t *a_result)
+static uint64_t s_get_precached_key_hash(dap_list_t **a_precached_keys_list, dap_sign_t *a_source_sign, dap_hash_fast_t *a_result)
 {
     bool l_found = false;
     struct precached_key *l_key = NULL;
-    DL_FOREACH(*a_precached_keys_list, l_key) {
+    dap_list_t *l_cur;
+    for (l_cur = *a_precached_keys_list; l_cur; l_cur = l_cur->next) {
+        l_key = (struct precached_key*)l_cur->data;
         if (l_key->pkey_size == a_source_sign->header.sign_pkey_size &&
                 !memcmp(l_key->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key->pkey_size)) {
             l_found = true;
@@ -2782,31 +2783,28 @@ static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys
         }
     }
     if (l_found) {
-        struct precached_key *l_key_swap = NULL;
-        DL_FOREACH(*a_precached_keys_list, l_key_swap) {
-            if (l_key_swap == l_key)
-                break;
-            if (l_key_swap->frequency < l_key->frequency) {
-                struct precached_key *l_swapper = l_key->next;
-                l_key->next = l_key_swap->next;
-                l_key_swap->next = l_swapper;
-                l_swapper = l_key->prev;
-                l_key->prev = l_key_swap->prev;
-                l_key_swap->prev = l_swapper;
-                break;
-            }
-        }
         if (a_result)
             *a_result = l_key->pkey_hash;
-        return l_key->frequency;
+        uint64_t l_freq = l_key->frequency;
+        while (l_cur != *a_precached_keys_list) {
+            struct precached_key* l_prev_key = (struct precached_key*)l_cur->prev->data;
+            if (l_key->frequency > l_prev_key->frequency) {
+                l_cur->prev->data = l_cur->data;
+                l_cur->data = l_prev_key;
+                l_key = l_prev_key;
+                l_cur = l_cur->prev;
+            } else
+                break;
+        }
+        return l_freq;
     }
-    struct precached_key *l_key_new = DAP_NEW_SIZE(struct precached_key,
+    struct precached_key *l_key_new = DAP_NEW_Z_SIZE(struct precached_key,
                                                    sizeof(struct precached_key) + a_source_sign->header.sign_pkey_size);
     l_key_new->pkey_size = a_source_sign->header.sign_pkey_size;
     l_key_new->frequency = 0;
     memcpy(l_key_new->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key_new->pkey_size);
     dap_sign_get_pkey_hash(a_source_sign, &l_key_new->pkey_hash);
-    DL_APPEND(*a_precached_keys_list, l_key_new);
+    *a_precached_keys_list = dap_list_append(*a_precached_keys_list, l_key_new);
     if (a_result)
         *a_result = l_key_new->pkey_hash;
     return 0;
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 144b69959c5047e5a094f0ae115207ce73ad769b..383f3ec95e042098793f7e05932e31d5cf296163 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -625,14 +625,14 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         l_tsd = (dap_tsd_t *)((byte_t *)l_tsd + l_tsd_size);
         l_tsd_size = dap_tsd_size(l_tsd);
         if (l_offset + l_tsd_size > a_tsd_total_size || l_offset + l_tsd_size < l_offset) {
-            log_it(L_WARNING, "Wrong TSD size %zu, exiting TSD parse", l_tsd_size);
+            log_it(L_WARNING, "Wrong TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
             return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
         }
         switch (l_tsd->type) {
         // set flags
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: {
             if (l_tsd->size != sizeof(uint16_t)) {
-                log_it(L_WARNING, "Wrong SET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong SET_FLAGS TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
@@ -643,7 +643,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // unset flags
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: {
             if (l_tsd->size != sizeof(uint16_t)) {
-                log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong UNSET_FLAGS TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
@@ -654,7 +654,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // set total supply
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256
             if (l_tsd->size != sizeof(uint256_t)) {
-                log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TOTAL_SUPPLY TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_item_apply_to) {
@@ -675,7 +675,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // Allowed tx receiver addres list add, remove or clear
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -714,7 +714,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -757,7 +757,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_CLEAR: {
             if (l_tsd->size != 0) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_ALLOWED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_recv_allow);
@@ -768,7 +768,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // Blocked tx receiver addres list add, remove or clear
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -807,7 +807,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -850,7 +850,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_CLEAR: {
             if (l_tsd->size != 0) {
-                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_RECEIVER_BLOCKED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_recv_block);
@@ -861,7 +861,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // Blocked tx sender addres list add, remove or clear
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -900,7 +900,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -944,7 +944,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_CLEAR: {
             if (l_tsd->size != 0) {
-                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_ALLOWED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_send_allow);
@@ -955,7 +955,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // Blocked tx sender addres list add, remove or clear
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -996,7 +996,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: {
             if (l_tsd->size != sizeof(dap_chain_addr_t)) {
-                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             // Check if its correct
@@ -1039,7 +1039,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR: {
             if (l_tsd->size != 0) {
-                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TX_SENDER_BLOCKED_CLEAR TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             DAP_DEL_Z(l_new_tx_send_block);
@@ -1049,7 +1049,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: {
             if (l_tsd->size == 0 || l_tsd->data[l_tsd->size - 1] != 0) {
-                log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_ERROR, "Wrong TOKEN_DESCRIPTION TSD format or size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!a_apply)
@@ -1061,7 +1061,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
         // Set signs count value need to emission be valid
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: {
             if (l_tsd->size != sizeof(uint16_t)) {
-                log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong SIGNS_VALID TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             l_new_signs_valid = dap_tsd_get_scalar(l_tsd, uint16_t);
@@ -1069,7 +1069,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: {
             if (l_tsd->size < sizeof(dap_pkey_t) || l_tsd->size != dap_pkey_get_size((dap_pkey_t *)l_tsd->data)) {
-                log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TOTAL_PKEYS_ADD TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) {
@@ -1142,7 +1142,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
 
         case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: {
             if (l_tsd->size != sizeof(dap_hash_t)) {
-                log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong TOTAL_PKEYS_REMOVE TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             if (!l_new_pkeys && l_new_signs_total && !l_was_pkeys_copied) {
@@ -1201,7 +1201,7 @@ static int s_token_tsd_parse(dap_ledger_token_item_t *a_item_apply_to, dap_chain
             }
             if (l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) &&
                     l_tsd->size != sizeof(dap_chain_datum_token_tsd_delegate_from_stake_lock_t) + 256 /* Legacy size */) {
-                log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %zu, exiting TSD parse", l_tsd_size);
+                log_it(L_WARNING, "Wrong DELEGATE_EMISSION_FROM_STAKE_LOCK TSD size %"DAP_UINT64_FORMAT_U", exiting TSD parse", l_tsd_size);
                 return m_ret_cleanup(DAP_LEDGER_CHECK_INVALID_SIZE);
             }
             dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_delegate = dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
@@ -1410,21 +1410,21 @@ int s_token_add_check(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_si
         dap_sign_t *l_sign = (dap_sign_t *)(l_signs_ptr + l_signs_size);
         if (l_signs_offset + l_signs_size + sizeof(dap_sign_t) > l_token_size ||
                 l_signs_offset + l_signs_size + sizeof(dap_sign_t) < l_signs_offset) {
-            log_it(L_WARNING, "Incorrect size %zu of datum token, expected at least %zu", l_token_size,
+            log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token, expected at least %zu", l_token_size,
                                                     l_signs_offset + l_signs_size + sizeof(dap_sign_t));
             DAP_DELETE(l_token);
             return DAP_LEDGER_CHECK_INVALID_SIZE;
         }
         uint64_t l_sign_size = dap_sign_get_size(l_sign);
         if (!l_sign_size || l_sign_size + l_signs_size < l_signs_size) {
-            log_it(L_WARNING, "Incorrect size %zu of datum token sign", l_sign_size);
+            log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token sign", l_sign_size);
             DAP_DELETE(l_token);
             return DAP_LEDGER_CHECK_INVALID_SIZE;
         }
         l_signs_size += l_sign_size;
     }
     if (l_token_size != l_signs_offset + l_signs_size) {
-        log_it(L_WARNING, "Incorrect size %zu of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size);
+        log_it(L_WARNING, "Incorrect size %"DAP_UINT64_FORMAT_U" of datum token, expected %zu", l_token_size, l_signs_offset + l_signs_size);
         DAP_DELETE(l_token);
         return DAP_LEDGER_CHECK_INVALID_SIZE;
     }
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index f96876ca0c123643f522706371c5c3aef96b8354..da8ffae15f4b4d66f531bfdead3345f396a8e072 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -107,6 +107,7 @@
 #include "dap_stream_cluster.h"
 #include "dap_http_ban_list_client.h"
 #include "dap_net.h"
+#include "dap_context.h"
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -154,16 +155,18 @@ typedef struct dap_chain_net_pvt{
     dap_chain_node_info_t *node_info;  // Current node's info
 
     dap_balancer_type_t balancer_type;
-    bool load_mode;
 
-    uint16_t permanent_links_count;
-    dap_link_info_t **permanent_links;
+    uint16_t permanent_links_addrs_count;
+    dap_stream_node_addr_t *permanent_links_addrs;
 
+    uint16_t permanent_links_hosts_count;
+    struct request_link_info **permanent_links_hosts;
+    
     uint16_t authorized_nodes_count;
     dap_stream_node_addr_t *authorized_nodes_addrs;
 
     uint16_t seed_nodes_count;
-    struct request_link_info **seed_nodes_info;
+    struct request_link_info **seed_nodes_hosts;
 
     struct chain_sync_context sync_context;
 
@@ -188,11 +191,9 @@ typedef struct dap_chain_net_pvt{
 #define PVT_S(a) ((dap_chain_net_pvt_t *)a.pvt)
 
 static dap_chain_net_t *s_nets_by_name = NULL, *s_nets_by_id = NULL;
-static pthread_mutex_t s_net_cond_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t s_net_cond = PTHREAD_COND_INITIALIZER;
-static uint16_t s_net_loading_count = 0;
 
 static const char *c_net_states[] = {
+    [NET_STATE_LOADING]             = "NET_STATE_LOADING",
     [NET_STATE_OFFLINE]             = "NET_STATE_OFFLINE",
     [NET_STATE_LINKS_PREPARE ]      = "NET_STATE_LINKS_PREPARE",
     [NET_STATE_LINKS_CONNECTING]    = "NET_STATE_LINKS_CONNECTING",
@@ -202,7 +203,7 @@ static const char *c_net_states[] = {
 };
 
 static inline const char * dap_chain_net_state_to_str(dap_chain_net_state_t a_state) {
-    return a_state < NET_STATE_OFFLINE || a_state > NET_STATE_ONLINE ? "NET_STATE_INVALID" : c_net_states[a_state];
+    return a_state < NET_STATE_LOADING || a_state > NET_STATE_ONLINE ? "NET_STATE_INVALID" : c_net_states[a_state];
 }
 
 // Node link callbacks
@@ -226,7 +227,7 @@ static void s_net_states_notify(dap_chain_net_t * l_net);
 static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg);
 //static void s_net_proc_kill( dap_chain_net_t * a_net );
 static int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx);
-static bool s_net_load(void *a_arg);
+static void *s_net_load(void *a_arg);
 static int s_net_try_online(dap_chain_net_t *a_net);
 static int s_cli_net(int argc, char ** argv, void **a_str_reply);
 static uint8_t *s_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash);
@@ -353,12 +354,12 @@ static struct request_link_info *s_balancer_link_from_cfg(dap_chain_net_t *a_net
         l_idx = dap_random_uint16() % PVT(a_net)->seed_nodes_count;
     break;
     }
-    if ( !PVT(a_net)->seed_nodes_info[l_idx] ) {
+    if ( !PVT(a_net)->seed_nodes_hosts[l_idx] ) {
         // Unresolved before? Let's try again
         const char **l_seed_nodes_hosts = dap_config_get_array_str(a_net->pub.config, "general", "seed_nodes_hosts", NULL);
-        PVT(a_net)->seed_nodes_info[l_idx] = s_net_resolve_host(l_seed_nodes_hosts[l_idx]);
+        PVT(a_net)->seed_nodes_hosts[l_idx] = s_net_resolve_host(l_seed_nodes_hosts[l_idx]);
     }
-    return PVT(a_net)->seed_nodes_info[l_idx];
+    return PVT(a_net)->seed_nodes_hosts[l_idx];
 }
 
 dap_chain_node_info_t *dap_chain_net_get_my_node_info(dap_chain_net_t *a_net)
@@ -435,8 +436,8 @@ static void s_link_manager_callback_connected(dap_link_t *a_link, uint64_t a_net
 static bool s_net_check_link_is_permanent(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr)
 {
     dap_chain_net_pvt_t *l_net_pvt = PVT(a_net);
-    for (uint16_t i = 0; i < l_net_pvt->permanent_links_count; i++) {
-        if (l_net_pvt->permanent_links[i]->node_addr.uint64 == a_addr.uint64)
+    for (uint16_t i = 0; i < l_net_pvt->permanent_links_addrs_count; i++) {
+        if (l_net_pvt->permanent_links_addrs[i].uint64 == a_addr.uint64)
             return true;
     }
     return false;
@@ -521,23 +522,47 @@ int s_link_manager_link_request(uint64_t a_net_id)
     return dap_worker_exec_callback_on(dap_worker_get_auto(), dap_chain_net_balancer_request, l_arg), 0;
 }
 
+struct request_link_info *s_get_permanent_link_info(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_address)
+{
+    dap_chain_net_pvt_t *l_net_pvt = PVT(a_net);
+    for (uint16_t i = 0; i < l_net_pvt->permanent_links_addrs_count; ++i) {
+        if (l_net_pvt->permanent_links_addrs[i].uint64 == a_address->uint64 &&
+            i < l_net_pvt->permanent_links_hosts_count &&
+            i < l_net_pvt->permanent_links_hosts[i]->addr[0] && 
+            i < l_net_pvt->permanent_links_hosts[i]->port)
+            return l_net_pvt->permanent_links_hosts[i];
+    }
+    return NULL;
+}
+
 int s_link_manager_fill_net_info(dap_link_t *a_link)
 {
 // sanity check
     dap_return_val_if_pass(!a_link, -1);
 // func work
-    dap_chain_node_info_t *l_node_info = NULL;
-    for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) {
-        if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) ))
+    const char *l_host = NULL;
+    uint16_t l_port = 0;
+    struct request_link_info *l_permanent_link = NULL;
+    for (dap_chain_net_t *l_net = s_nets_by_name; l_net; l_net = l_net->hh.next) {
+        if ( dap_chain_net_get_state(l_net) > NET_STATE_OFFLINE && ( l_permanent_link = s_get_permanent_link_info(l_net, &a_link->addr) )) {
+            l_host = l_permanent_link->addr;
+            l_port = l_permanent_link->port;
             break;
+        }
     }
-    if (!l_node_info)
-        return -3;
-    a_link->uplink.ready = true;
-    if ( dap_link_manager_link_update(&a_link->addr, l_node_info->ext_host, l_node_info->ext_port) )
-        a_link->uplink.ready = true;
-    DAP_DELETE(l_node_info);
-    return 0;
+    dap_chain_node_info_t *l_node_info = NULL;
+    if (!l_host || !l_host[0] || !l_port) {
+        for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) {
+            if (( l_node_info = dap_chain_node_info_read(net, &a_link->addr) ))
+                break;
+        }
+        if (!l_node_info)
+            return -3;
+        l_host = l_node_info->ext_host;
+        l_port = l_node_info->ext_port;
+    }
+    a_link->uplink.ready = !dap_link_manager_link_update(&a_link->addr, l_host, l_port);
+    return DAP_DELETE(l_node_info), 0;
 }
 
 json_object *s_net_sync_status(dap_chain_net_t *a_net)
@@ -569,7 +594,11 @@ json_object *s_net_sync_status(dap_chain_net_t *a_net)
                 l_jobj_chain_status = json_object_new_string("unknown");
                 break;
         }
-        if (l_chain->state == CHAIN_SYNC_STATE_IDLE) {
+        if (dap_chain_net_get_load_mode(a_net)) {
+            char *l_percent_str = dap_strdup_printf("%d %c", l_chain->load_progress, '%');
+            l_jobj_percent = json_object_new_string(l_percent_str);
+            DAP_DELETE(l_percent_str);
+        } else if (l_chain->state == CHAIN_SYNC_STATE_IDLE) {
             l_jobj_percent = json_object_new_string(" - %");
         } else {
             double l_percent = dap_min((double)l_chain->callback_count_atom(l_chain) * 100 / l_chain->atom_num_last, 100.0);
@@ -647,6 +676,9 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg)
                 *a_native_ticker= dap_config_get_item_str(a_cfg, "general", "native_ticker");
     dap_chain_net_id_t l_net_id;
 
+    if(!a_node_role)
+        return log_it(L_ERROR, "Can't create l_net, can't read node role config"), NULL;
+
     if(!l_net_name_str || !l_net_id_str || dap_chain_net_id_parse(l_net_id_str, &l_net_id))
         return log_it(L_ERROR, "Can't create l_net, can't read name or ID config"), NULL;
 
@@ -730,30 +762,28 @@ bool s_net_disk_load_notify_callback(UNUSED_ARG void *a_arg) {
  */
 void dap_chain_net_load_all()
 {
-    pthread_mutex_lock(&s_net_cond_lock);
-    s_net_loading_count = HASH_COUNT(s_nets_by_name);
-    if (!s_net_loading_count) {
-        log_it(L_ERROR, "Can't find any nets");
-        pthread_mutex_unlock(&s_net_cond_lock);
-        return;
-    }
+    uint16_t l_nets_count = HASH_COUNT(s_nets_by_name);
+    if (!l_nets_count)
+        return log_it(L_ERROR, "No networks initialized!");
+    pthread_t l_tids[l_nets_count];
+    dap_chain_net_t *l_net = s_nets_by_name;
     dap_timerfd_t *l_load_notify_timer = dap_timerfd_start(5000, (dap_timerfd_callback_t)s_net_disk_load_notify_callback, NULL);
-    for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next)
-        dap_proc_thread_callback_add(NULL, s_net_load, net);
-    while (s_net_loading_count)
-        pthread_cond_wait(&s_net_cond, &s_net_cond_lock);
-    pthread_mutex_unlock(&s_net_cond_lock);
+    for (int i = 0; i < l_nets_count; ++i) {
+        pthread_create(&l_tids[i], NULL, s_net_load, l_net);
+        l_net = l_net->hh.next;
+    }
+    for (int i = 0; i < l_nets_count; ++i) {
+        pthread_join(l_tids[i], NULL);
+    }
     dap_timerfd_delete_mt(l_load_notify_timer->worker, l_load_notify_timer->esocket_uuid);
 }
 
 dap_string_t* dap_cli_list_net()
 {
     dap_string_t *l_string_ret = dap_string_new("");
-    unsigned l_net_i = 0;
     dap_string_append(l_string_ret, "Available networks and chains:\n");
     for (dap_chain_net_t *net = s_nets_by_name; net; net = net->hh.next) {
         dap_string_append_printf(l_string_ret, "\t%s:\n", net->pub.name);
-        ++l_net_i;
         dap_chain_t *l_chain = net->pub.chains;
         while (l_chain) {
             dap_string_append_printf( l_string_ret, "\t\t%s\n", l_chain->name );
@@ -815,8 +845,7 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){
     char* l_sync_current_link_text_block = NULL;
     if (PVT(a_net)->state != NET_STATE_OFFLINE)
         l_sync_current_link_text_block = dap_strdup_printf(", active links %zu from %u",
-                                                           dap_link_manager_links_count(a_net->pub.id.uint64),
-                                                           0 /*HASH_COUNT(PVT(a_net)->net_links)*/);
+                                                           dap_link_manager_links_count(a_net->pub.id.uint64), 0);
     dap_cli_server_cmd_set_reply_text(a_str_reply,
                                       "Network \"%s\" has state %s (target state %s)%s%s",
                                       a_net->pub.name, c_net_states[PVT(a_net)->state],
@@ -1236,7 +1265,12 @@ static int s_cli_net(int argc, char **argv, void **reply)
                     return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
                 }
                 json_object_object_add(l_jobj_return, "to", l_jobj_to);
-                dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE);
+                if (dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE)) {
+                    json_object_put(l_jobj_return);
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s",
+                                            "Can't change state of loading network\n");
+                    return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START;
+                }
                 l_ret = DAP_CHAIN_NET_JSON_RPC_OK;
             } else if ( strcmp(l_go_str,"offline") == 0 ) {
                 json_object *l_jobj_to = json_object_new_string(c_net_states[NET_STATE_OFFLINE]);
@@ -1246,7 +1280,12 @@ static int s_cli_net(int argc, char **argv, void **reply)
                     return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
                 }
                 json_object_object_add(l_jobj_return, "to", l_jobj_to);
-                dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE);
+                if ( dap_chain_net_state_go_to(l_net, NET_STATE_OFFLINE) ) {
+                    json_object_put(l_jobj_return);
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s",
+                                            "Can't change state of loading network\n");
+                    return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START;
+                }
                 l_ret = DAP_CHAIN_NET_JSON_RPC_OK;
             } else if (strcmp(l_go_str, "sync") == 0) {
                 json_object *l_jobj_to = json_object_new_string("resynchronizing");
@@ -1257,9 +1296,15 @@ static int s_cli_net(int argc, char **argv, void **reply)
                 }
                 json_object_object_add(l_jobj_return, "start", l_jobj_to);
                 if (PVT(l_net)->state_target == NET_STATE_ONLINE)
-                    dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE);
+                    l_ret = dap_chain_net_state_go_to(l_net, NET_STATE_ONLINE);
                 else
-                    dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS);
+                    l_ret = dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS);
+                if (l_ret) {
+                    json_object_put(l_jobj_return);
+                    dap_json_rpc_error_add(*a_json_arr_reply, DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, "%s",
+                                            "Can't change state of loading network\n");
+                    return DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START;
+                }
                 l_ret = DAP_CHAIN_NET_JSON_RPC_OK;
             } else {
                 json_object_put(l_jobj_return);
@@ -1723,6 +1768,56 @@ int dap_chain_net_test_init()
 #endif
 
 
+int s_nodes_addrs_init(dap_config_t *a_cfg, const char *a_addrs_type, dap_stream_node_addr_t **a_addrs, uint16_t *a_addrs_count)
+{
+    dap_return_val_if_pass(!a_cfg || !a_addrs_type || !a_addrs || !a_addrs_count, -1);
+    const char **l_nodes_addrs = dap_config_get_array_str(a_cfg, "general", a_addrs_type, a_addrs_count);
+    if (*a_addrs_count) {
+        *a_addrs = DAP_NEW_Z_COUNT(dap_chain_node_addr_t, *a_addrs_count);
+        if (!*a_addrs) {
+            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
+            return -1;
+        }
+        for (uint16_t i = 0; i < *a_addrs_count; ++i) {
+            dap_chain_node_addr_t l_addr;
+            if (dap_stream_node_addr_from_str(&l_addr, l_nodes_addrs[i])) {
+                log_it(L_ERROR, "Incorrect format of %s address \"%s\", fix net config and restart node", a_addrs_type, l_nodes_addrs[i]);
+                return -2;
+            }
+            (*a_addrs)[i].uint64 = l_addr.uint64;
+        }
+    }
+    return 0;
+}
+
+int s_nodes_hosts_init(dap_chain_net_t *a_net, dap_config_t *a_cfg, const char *a_hosts_type, struct request_link_info ***a_hosts, uint16_t *a_hosts_count)
+{
+    dap_return_val_if_pass(!a_cfg || !a_hosts_type || !a_hosts || !a_hosts_count, -1);
+    const char **l_nodes_addrs = dap_config_get_array_str(a_cfg, "general", a_hosts_type, a_hosts_count);
+    if (*a_hosts_count) {
+        *a_hosts = DAP_NEW_Z_COUNT(struct request_link_info *, *a_hosts_count);
+        if (!*a_hosts) {
+            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
+            return -1;
+        }
+        uint16_t i = 0, e = 0;
+        for (; i < *a_hosts_count; ++i) {
+            if (!( (*a_hosts)[i] = s_net_resolve_host(l_nodes_addrs[i]) )) {
+                log_it(L_ERROR, "Incorrect address [ %s : %u ], fix \"%s\" network config"
+                                "or check internet connection and restart node",
+                                (*a_hosts)[i]->addr, (*a_hosts)[i]->port,  a_net->pub.name);
+                ++e;
+                continue;
+            }
+        }
+        debug_if(e, L_ERROR, "%d / %d %s links are invalid or can't be accessed, fix \"%s\""
+                        "network config or check internet connection and restart node",
+                        e, i, a_hosts_type, a_net->pub.name);
+
+    }
+    return 0;
+}
+
 /**
  * @brief load network config settings from cellframe-node.cfg file
  *
@@ -1741,7 +1836,6 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx)
         return log_it(L_ERROR,"Can't create net \"%s\"", a_net_name), dap_config_close(l_cfg), -1;
 
     dap_chain_net_pvt_t *l_net_pvt = PVT(l_net);
-    l_net_pvt->load_mode = true;
     l_net_pvt->acl_idx = a_acl_idx;
     // Transaction can be sent to bridged networks
     uint16_t l_net_ids_count = 0;
@@ -1762,88 +1856,21 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx)
             l_net->pub.bridged_networks = DAP_REALLOC_COUNT(l_net->pub.bridged_networks, j); // Can be NULL, it's ok
     }
 
-    const char **l_permanent_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_addrs", &l_net_pvt->permanent_links_count);
-    if (l_net_pvt->permanent_links_count) {
-        l_net_pvt->permanent_links = DAP_NEW_Z_COUNT(dap_link_info_t *, l_net_pvt->permanent_links_count);
-        if (!l_net_pvt->permanent_links) {
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            dap_chain_net_delete(l_net);
-            dap_config_close(l_cfg);
-            return -4;
-        }
-    }
-    for (uint16_t i = 0; i < l_net_pvt->permanent_links_count; ++i) {
-        l_net_pvt->permanent_links[i] = DAP_NEW_Z(dap_link_info_t);
-        if (!l_net_pvt->permanent_links[i]) {
-            log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-            dap_chain_net_delete(l_net);
-            dap_config_close(l_cfg);
-            return -4;
-        }
-        if (dap_stream_node_addr_from_str(&l_net_pvt->permanent_links[i]->node_addr, l_permanent_nodes_addrs[i])) {
-            log_it(L_ERROR, "Incorrect format of node address \"%s\", fix net config and restart node", l_permanent_nodes_addrs[i]);
-            dap_chain_net_delete(l_net);
-            dap_config_close(l_cfg);
-            return -16;
-        }
-    }
-    uint16_t l_permalink_hosts_count = 0, i, e;
-    const char **l_permanent_links_hosts = dap_config_get_array_str(l_cfg, "general", "permanent_nodes_hosts", &l_permalink_hosts_count);
-    for (i = 0, e = 0; i < dap_min(l_permalink_hosts_count, l_net_pvt->permanent_links_count); ++i) {
-        struct request_link_info *l_tmp = s_net_resolve_host( l_permanent_links_hosts[i] );
-        if ( !l_tmp ) {
-            log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config"
-                            "or check internet connection and restart node",
-                            a_net_name, l_permanent_links_hosts[i]);
-            ++e;
-            continue;
-        }
-        l_net_pvt->permanent_links[i]->uplink_port = l_tmp->port;
-        dap_strncpy(l_net_pvt->permanent_links[i]->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN);
-        DAP_DELETE(l_tmp);
-    }
-    debug_if(e, L_ERROR, "%d / %d permanent links are invalid or can't be accessed, fix \"%s\""
-                    "network config or check internet connection and restart node",
-                    e, i, a_net_name);
-
-    const char **l_authorized_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "authorized_nodes_addrs", &l_net_pvt->authorized_nodes_count);
-    if (!l_net_pvt->authorized_nodes_count)
-        log_it(L_WARNING, "Can't read PoA nodes addresses");
-    else
-        l_net_pvt->authorized_nodes_addrs = DAP_NEW_Z_COUNT(dap_chain_node_addr_t, l_net_pvt->authorized_nodes_count);
-    for (i = 0; i < l_net_pvt->authorized_nodes_count; ++i) {
-        dap_chain_node_addr_t l_addr;
-        if (dap_stream_node_addr_from_str(&l_addr, l_authorized_nodes_addrs[i])) {
-            log_it(L_ERROR, "Incorrect format of node address \"%s\", fix net config and restart node", l_authorized_nodes_addrs[i]);
-            dap_chain_net_delete(l_net);
-            dap_config_close(l_cfg);
-            return -17;
-        }
-        l_net_pvt->authorized_nodes_addrs[i].uint64 = l_addr.uint64;
-    }
-    const char **l_seed_nodes_hosts = dap_config_get_array_str(l_cfg, "general", "seed_nodes_hosts", &l_net_pvt->seed_nodes_count);
-    if (!l_net_pvt->seed_nodes_count)
-         l_seed_nodes_hosts  = dap_config_get_array_str(l_cfg, "general", "bootstrap_hosts", &l_net_pvt->seed_nodes_count);
-    if (!l_net_pvt->seed_nodes_count)
-        log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only");
-    else if (!( l_net_pvt->seed_nodes_info = DAP_NEW_Z_COUNT(struct request_link_info*, l_net_pvt->seed_nodes_count) )) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
+    // read permanent and authorized nodes addrs
+    if (
+        s_nodes_addrs_init(l_cfg, "permanent_nodes_addrs", &l_net_pvt->permanent_links_addrs, &l_net_pvt->permanent_links_addrs_count) ||
+        s_nodes_addrs_init(l_cfg, "authorized_nodes_addrs", &l_net_pvt->authorized_nodes_addrs, &l_net_pvt->authorized_nodes_count) ||
+        s_nodes_hosts_init(l_net, l_cfg, "permanent_nodes_hosts", &l_net_pvt->permanent_links_hosts, &l_net_pvt->permanent_links_hosts_count) ||
+        s_nodes_hosts_init(l_net, l_cfg, "seed_nodes_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) || 
+        (!l_net_pvt->seed_nodes_count && s_nodes_hosts_init(l_net, l_cfg, "bootstrap_hosts", &l_net_pvt->seed_nodes_hosts, &l_net_pvt->seed_nodes_count) )
+    ) {
         dap_chain_net_delete(l_net);
         dap_config_close(l_cfg);
         return -4;
     }
-    for (i = 0, e = 0; i < l_net_pvt->seed_nodes_count; ++i) {
-        if (!( l_net_pvt->seed_nodes_info[i] = s_net_resolve_host(l_seed_nodes_hosts[i]) )) {
-            log_it(L_ERROR, "Incorrect address \"%s\", fix \"%s\" network config"
-                            "or check internet connection and restart node",
-                            a_net_name, l_seed_nodes_hosts[i]);
-            ++e;
-            continue;
-        }
-    }
-    debug_if(e, L_ERROR, "%d / %d seed links are invalid or can't be accessed, fix \"%s\""
-                    "network config or check internet connection and restart node",
-                    e, i, a_net_name);
+    debug_if(!l_net_pvt->authorized_nodes_count, L_WARNING, "Can't read PoA nodes addresses");
+    if (!l_net_pvt->seed_nodes_count)
+        log_it(L_WARNING, "Can't read seed nodes addresses, work with local balancer only");
 
     /* *** Chains init by configs *** */
     DIR *l_chains_dir = opendir(a_path);
@@ -1875,12 +1902,14 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx)
     dap_chain_t *l_chain;
     dap_chain_type_t *l_types_arr;
     char l_occupied_default_types[CHAIN_TYPE_MAX] = { 0 };
-    uint16_t k;
     HASH_ITER(hh, l_all_chain_configs, l_chain_config, l_tmp_cfg) {
         if (( l_chain = dap_chain_load_from_cfg(l_net->pub.name, l_net->pub.id, l_chain_config) )) {
             DL_APPEND(l_net->pub.chains, l_chain);
             l_types_arr = l_chain->default_datum_types;
-            for (i = 0, k = l_chain->default_datum_types_count; i < k; ++i) {
+            uint16_t
+                i = 0,
+                k = l_chain->default_datum_types_count;
+            for ( ; i < k; ++i) {
                 if ( l_occupied_default_types[l_types_arr[i]] ) {
                     if ( i < k - 1 )
                         l_types_arr[i] =
@@ -1937,7 +1966,7 @@ int s_net_init(const char *a_net_name, const char *a_path, uint16_t a_acl_idx)
     return 0;
 }
 
-bool s_net_load(void *a_arg)
+static void *s_net_load(void *a_arg)
 {
     dap_chain_net_t *l_net = a_arg;
     int l_err_code = 0;
@@ -1951,12 +1980,12 @@ bool s_net_load(void *a_arg)
     dap_chain_net_pvt_t *l_net_pvt = PVT(l_net);
 
     // reload ledger cache at once
-    if (s_chain_net_reload_ledger_cache_once(l_net)) {
+    /*if (s_chain_net_reload_ledger_cache_once(l_net)) {
         log_it(L_WARNING,"Start one time ledger cache reloading");
         dap_ledger_purge(l_net->pub.ledger, false);
         dap_chain_net_srv_stake_purge(l_net);
     } else
-        dap_chain_net_srv_stake_load_cache(l_net);
+        dap_chain_net_srv_stake_load_cache(l_net);*/
 
     // load chains
     dap_chain_t *l_chain = l_net->pub.chains;
@@ -2001,7 +2030,6 @@ bool s_net_load(void *a_arg)
         log_it(L_NOTICE, "[%s] Chain [%s] processing took %f seconds", l_chain->net_name, l_chain->name, time_taken);
         l_chain = l_chain->next;
     }
-    l_net_pvt->load_mode = false;
     dap_ledger_load_end(l_net->pub.ledger);
 
     // Do specific role actions post-chain created
@@ -2173,14 +2201,11 @@ bool s_net_load(void *a_arg)
     dap_proc_thread_timer_add(NULL, s_sync_timer_callback, l_net, c_sync_timer_period);
 
     log_it(L_INFO, "Chain network \"%s\" initialized", l_net->pub.name);
+    l_net_pvt->state = NET_STATE_OFFLINE;
 ret:
     if (l_err_code)
         log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net->pub.name, l_err_code);
-    pthread_mutex_lock(&s_net_cond_lock);
-    s_net_loading_count--;
-    pthread_cond_signal(&s_net_cond);
-    pthread_mutex_unlock(&s_net_cond_lock);
-    return false;
+    return NULL;
 }
 
 dap_global_db_cluster_t *dap_chain_net_get_mempool_cluster(dap_chain_t *a_chain)
@@ -2433,14 +2458,14 @@ char * dap_chain_net_get_gdb_group_mempool_by_chain_type(dap_chain_net_t *a_net,
  * @param l_net
  * @return
  */
-dap_chain_net_state_t dap_chain_net_get_state (dap_chain_net_t * l_net)
+dap_chain_net_state_t dap_chain_net_get_state (dap_chain_net_t *a_net)
 {
-    return PVT(l_net)->state;
+    return PVT(a_net)->state;
 }
 
-dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net)
+dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t *a_net)
 {
-    return  PVT(l_net)->node_info ? &PVT(l_net)->node_info->cell_id: 0;
+    return  PVT(a_net)->node_info ? &PVT(a_net)->node_info->cell_id: 0;
 }
 
 /**
@@ -2794,7 +2819,7 @@ int dap_chain_datum_remove(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, siz
 
 bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net)
 {
-    return PVT(a_net)->load_mode;
+    return PVT(a_net)->state == NET_STATE_LOADING;
 }
 
 int dap_chain_net_add_reward(dap_chain_net_t *a_net, uint256_t a_reward, uint64_t a_block_num)
@@ -3245,7 +3270,7 @@ static bool s_net_states_proc(void *a_arg)
  */
 int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_new_state)
 {
-    if (PVT(a_net)->load_mode) {
+    if (dap_chain_net_get_load_mode(a_net)) {
         log_it(L_ERROR, "Can't change state of loading network '%s'", a_net->pub.name);
         return -1;
     }
@@ -3272,25 +3297,12 @@ int dap_chain_net_state_go_to(dap_chain_net_t *a_net, dap_chain_net_state_t a_ne
         dap_link_manager_set_net_condition(a_net->pub.id.uint64, true);
         uint16_t l_permalink_hosts_count = 0;
         dap_config_get_array_str(a_net->pub.config, "general", "permanent_nodes_hosts", &l_permalink_hosts_count);
-        l_permalink_hosts_count = dap_min(l_permalink_hosts_count, PVT(a_net)->permanent_links_count);
-        for (uint16_t i = 0; i < l_permalink_hosts_count; ++i) {
-            dap_link_info_t *l_permalink_info = PVT(a_net)->permanent_links[i];
-            if ( !*l_permalink_info->uplink_addr ) {
-                // Unresolved before? Let's try again
-                const char **l_permanent_links_hosts = dap_config_get_array_str(a_net->pub.config, "general", "permanent_nodes_hosts", NULL);
-                struct request_link_info *l_tmp = s_net_resolve_host(l_permanent_links_hosts[i]);
-                if (l_tmp) {
-                    l_permalink_info->uplink_port = l_tmp->port;
-                    dap_strncpy(l_permalink_info->uplink_addr, l_tmp->addr, DAP_HOSTADDR_STRLEN);
-                    DAP_DELETE(l_tmp);
-                } else {
-                    log_it(L_ERROR, "Can't resolve permanent link address %s for net %s, possibly an internet connection issue",
-                                    l_permanent_links_hosts[i], a_net->pub.name);
-                    continue;
-                }
-            }
-            if (dap_chain_net_link_add(a_net, &l_permalink_info->node_addr, l_permalink_info->uplink_addr, l_permalink_info->uplink_port)) {
-                log_it(L_ERROR, "Can't create permanent link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_permalink_info->node_addr));
+        for (uint16_t i = 0; i < PVT(a_net)->permanent_links_addrs_count; ++i) {
+            if (dap_chain_net_link_add(a_net, PVT(a_net)->permanent_links_addrs + i, 
+                i < PVT(a_net)->permanent_links_hosts_count ? (PVT(a_net)->permanent_links_hosts[i])->addr : NULL,
+                i < PVT(a_net)->permanent_links_hosts_count ? (PVT(a_net)->permanent_links_hosts[i])->port : 0)
+             ) {
+                log_it(L_ERROR, "Can't create permanent link to addr " NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(PVT(a_net)->permanent_links_addrs + i));
                 continue;
             }
             PVT(a_net)->state = NET_STATE_LINKS_CONNECTING;
diff --git a/modules/net/dap_chain_net_node_list.c b/modules/net/dap_chain_net_node_list.c
index a4d6cb70db35f5732cd880609480a4fded514e3c..ba669e0342d7570a5d3380c723caf212e45ceb68 100644
--- a/modules/net/dap_chain_net_node_list.c
+++ b/modules/net/dap_chain_net_node_list.c
@@ -107,7 +107,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
     }
     const char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} );
     if (!l_key) {
-        log_it(L_ERROR, "Bad node address %zu", addr);
+        log_it(L_ERROR, "Bad node address %"DAP_UINT64_FORMAT_U, addr);
         *l_return_code = Http_Status_BadRequest;
         return;
     }
@@ -287,7 +287,7 @@ int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, boo
     if (!l_link_node_request)
         return log_it(L_CRITICAL, "%s", c_error_memory_alloc), -4;
 
-    char *l_request = dap_strdup_printf( "%s/%s?version=1,method=%c,addr=%zu,port=%hu,net=%s",
+    char *l_request = dap_strdup_printf( "%s/%s?version=1,method=%c,addr=%"DAP_UINT64_FORMAT_U",port=%hu,net=%s",
                                          DAP_UPLINK_PATH_NODE_LIST, DAP_NODE_LIST_URI_HASH, a_cmd,
                                          g_node_addr.uint64, a_port, a_net->pub.name );
     int l_ret = -1;
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index 73de66e80ec091a5214b5a0cb1e7f1ec278d5372..68391bb0f3da610c60eba83fc4d4999e2e33700f 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -342,6 +342,17 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
             "decree info -net <net_name>\n"
             "Displays information about the parameters of the decrees in the network.\n");
 
+    //Find command
+    dap_cli_server_cmd_add("find", cmd_find, "The command searches for the specified elements by the specified attributes",
+                           "find datum -net <net_name> [-chain <chain_name>] -hash <datum_hash>\n"
+                           "\tSearches for datum by hash in the specified network in chains and mempool.\n"
+                           "find atom -net <net_name> [-chain <chain_name>] -hash <atom_hash>\n"
+                           "\tSearches for an atom by hash in a specified network in chains.\n"
+                           "find decree -net <net_name> [-chain <chain_name>] -type <type_decree> [-where <chains|mempool>]\n"
+                           "\tSearches for decrees by hash in the specified decree type in the specified network in its chains.\n"
+                           "\tTypes decree: fee, owners, owners_min, stake_approve, stake_invalidate, min_value, "
+                           "min_validators_count, ban, unban, reward, validator_max_weight, emergency_validators, check_signs_structure\n");
+
     // Exit - always last!
     dap_cli_server_cmd_add ("exit", com_exit, "Stop application and exit",
                 "exit\n" );
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index f4d5bbff06446efa04b4038a84dccf8ce57eda75..644a40e19fc7cd937f1269010b179eb61a837275 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2258,9 +2258,6 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                         return  DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INTERNAL_ERR;
                     }
 
-                    l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL;
-
-                    const char *l_addr_str = dap_chain_addr_to_str_static(l_addr);
                     json_object * json_obj_wall = json_object_new_object();
                     json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet->name));
                     if (l_sign_count > 1) {
@@ -2274,8 +2271,10 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                     } else
                         json_object_object_add(json_obj_wall, "Sign type", json_object_new_string(l_sign_type_str));
                     json_object_object_add(json_obj_wall, "Status", json_object_new_string("successfully created"));
-                    if ( l_addr_str ) {
-                        json_object_object_add(json_obj_wall, "new address", json_object_new_string(l_addr_str));
+
+                    const char *l_addr_str = NULL;
+                    if ( l_net && (l_addr_str = dap_chain_addr_to_str_static(dap_chain_wallet_get_addr(l_wallet,l_net->pub.id))) ) {
+                        json_object_object_add(json_obj_wall, "new address", json_object_new_string(l_addr_str) );
                     }
                     json_object_array_add(json_arr_out, json_obj_wall);
                     dap_chain_wallet_close(l_wallet);
@@ -3359,20 +3358,9 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
     bool l_found_in_chains = false;
     int l_ret_code = 0;
     dap_hash_fast_t l_atom_hash = {};
-    if (a_chain)
-        l_datum = s_com_mempool_check_datum_in_chain(a_chain, a_datum_hash);
-    else {
-        dap_chain_t *it = NULL;
-        DL_FOREACH(a_net->pub.chains, it) {
-            l_datum = s_com_mempool_check_datum_in_chain(it, a_datum_hash);
-            if (l_datum) {
-                l_chain_name = it->name;
-                break;
-            }
-        }
-    }
-    if (!l_datum) {
-        l_found_in_chains = true;
+    // FIND in chain
+    {
+        //
         dap_hash_fast_t l_datum_hash;
         if (dap_chain_hash_fast_from_hex_str(a_datum_hash, &l_datum_hash)) {
             dap_json_rpc_error_add(*a_json_arr_reply, COM_MEMPOOL_CHECK_ERR_INCORRECT_HASH_STR,
@@ -3391,6 +3379,23 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
                 }
             }
         }
+        if (l_datum)
+            l_found_in_chains = true;
+    }
+    //  FIND in mempool
+    if (!l_found_in_chains) {
+        if (a_chain)
+            l_datum = s_com_mempool_check_datum_in_chain(a_chain, a_datum_hash);
+        else {
+            dap_chain_t *it = NULL;
+            DL_FOREACH(a_net->pub.chains, it) {
+                l_datum = s_com_mempool_check_datum_in_chain(it, a_datum_hash);
+                if (l_datum) {
+                    l_chain_name = it->name;
+                    break;
+                }
+            }
+        }
     }
     json_object *l_jobj_datum = json_object_new_object();
     json_object *l_datum_hash = json_object_new_string(a_datum_hash);
@@ -4002,6 +4007,217 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply)
     return ret;
 }
 
+typedef enum _s_where_search{
+    ALL,
+    CHAINS,
+    MEMPOOL
+}_s_where_search_t;
+
+void _cmd_find_type_decree_in_chain(json_object *a_out, dap_chain_t *a_chain, uint16_t a_decree_type, _s_where_search_t a_where, const char *a_hash_out_type) {
+    json_object *l_common_decree_arr = json_object_new_array();
+    json_object *l_service_decree_arr = json_object_new_array();
+    if (a_where == ALL || a_where == CHAINS) {
+        dap_chain_cell_t *l_cell, *l_iter_tmp;
+        HASH_ITER(hh, a_chain->cells, l_cell, l_iter_tmp) {
+            dap_chain_atom_iter_t *l_atom_iter = l_cell->chain->callback_atom_iter_create(l_cell->chain, l_cell->id,
+                                                                                          NULL);
+            dap_chain_atom_ptr_t l_atom;
+            uint64_t l_atom_size = 0;
+            for (l_atom = l_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size);
+                 l_atom && l_atom_size;
+                 l_atom = l_cell->chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_NEXT, &l_atom_size)) {
+                size_t l_datum_count = 0;
+                dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_atom, l_atom_size,
+                                                                                       &l_datum_count);
+                json_object *l_obj_atom = json_object_new_object();
+                char l_buff_ts[50] = {'\0'};
+                dap_time_to_str_rfc822(l_buff_ts, 50, l_atom_iter->cur_ts);
+                for (size_t i = 0; i < l_datum_count; i++) {
+                    dap_chain_datum_t *l_datum = l_datums[i];
+                    if (l_datum[i].header.type_id != DAP_CHAIN_DATUM_DECREE) continue;
+                    dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *) l_datum[i].data;
+                    if (l_decree->header.sub_type == a_decree_type) {
+                        json_object *l_jobj_atom = json_object_new_object();
+                        json_object *l_jobj_atom_create = json_object_new_string(l_buff_ts);
+                        json_object *l_jobj_atom_hash = json_object_new_string(
+                                !dap_strcmp(a_hash_out_type, "base58") ?
+                                dap_enc_base58_encode_hash_to_str_static(l_atom_iter->cur_hash) :
+                                dap_hash_fast_to_str_static(l_atom_iter->cur_hash));
+                        json_object_object_add(l_jobj_atom, "hash", l_jobj_atom_hash);
+                        json_object_object_add(l_jobj_atom, "created", l_jobj_atom_create);
+                        json_object *l_jobj_decree = json_object_new_object();
+                        size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree);
+                        dap_chain_datum_decree_dump_json(l_jobj_decree, l_decree, l_decree_size, a_hash_out_type);
+                        json_object *l_obj_source = json_object_new_object();
+                        json_object_object_add(l_obj_source, "atom", l_jobj_atom);
+                        json_object_object_add(l_jobj_decree, "source", l_obj_source);
+                        (l_decree->header.type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON) ?
+                            json_object_array_add(l_common_decree_arr, l_jobj_decree) :
+                            json_object_array_add(l_service_decree_arr, l_jobj_decree);
+                    }
+                }
+            }
+            l_cell->chain->callback_atom_iter_delete(l_atom_iter);
+        }
+    }
+    if (a_where == ALL || a_where == MEMPOOL) {
+        char *l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(a_chain);
+        size_t l_mempool_count = 0;
+        dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_mempool_count);
+        for (size_t i = 0; i < l_mempool_count; i++) {
+            dap_chain_datum_t *l_datum = (dap_chain_datum_t *) (l_objs[i].value);
+            if (l_datum->header.type_id != DAP_CHAIN_DATUM_DECREE) continue;
+            dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *) l_datum->data;
+            if (l_decree->header.sub_type == a_decree_type) {
+                json_object *l_jobj_decree = json_object_new_object();
+                size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree);
+                dap_chain_datum_decree_dump_json(l_jobj_decree, l_decree, l_decree_size, a_hash_out_type);
+                json_object_object_add(l_jobj_decree, "source", json_object_new_string("mempool"));
+                (l_decree->header.type == DAP_CHAIN_DATUM_DECREE_TYPE_COMMON) ?
+                json_object_array_add(l_common_decree_arr, l_jobj_decree) :
+                json_object_array_add(l_service_decree_arr, l_jobj_decree);
+            }
+        }
+        dap_global_db_objs_delete(l_objs, l_mempool_count);
+    }
+    json_object_object_add(a_out, "common", l_common_decree_arr);
+    json_object_object_add(a_out, "service", l_service_decree_arr);
+}
+
+int cmd_find(int a_argc, char **a_argv, void **a_reply) {
+    json_object **a_json_reply = (json_object **)a_reply;
+    int arg_index = 1;
+    dap_chain_net_t *l_net = NULL;
+    dap_chain_t *l_chain = NULL;
+    enum _subcmd {SUBCMD_DATUM, SUBCMD_ATOM, SUBCMD_DECREE};
+    enum _subcmd l_cmd = 0;
+    if (a_argv[1]) {
+        if (!dap_strcmp(a_argv[1], "datum")) {
+            l_cmd = SUBCMD_DATUM;
+        } else if (!dap_strcmp(a_argv[1], "atom")) {
+            l_cmd = SUBCMD_ATOM;
+        } else if (!dap_strcmp(a_argv[1], "decree")) {
+            l_cmd = SUBCMD_DECREE;
+        } else {
+            dap_json_rpc_error_add(*a_json_reply,DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD,"Invalid sub command specified. Sub command %s "
+                                                "is not supported.", a_argv[1]);
+            return DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD;
+        }
+    }
+    int cmd_parse_status = dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*a_json_reply, &arg_index, a_argc, a_argv, &l_chain, &l_net, CHAIN_TYPE_INVALID);
+    if (cmd_parse_status != 0){
+        dap_json_rpc_error_add(*a_json_reply, cmd_parse_status, "Request parsing error (code: %d)", cmd_parse_status);
+            return cmd_parse_status;
+    }
+    const char *l_hash_out_type = "hex";
+    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
+    switch (l_cmd) {
+        case SUBCMD_DATUM: {
+            const char *l_datum_hash = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_datum_hash);
+            if (!l_datum_hash) {
+                dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-datum", &l_datum_hash);
+                if (!l_datum_hash) {
+                    dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED,
+                                           "The hash of the datum is not specified.");
+                    return DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED;
+                }
+            }
+            return _cmd_mempool_check(l_net, l_chain, l_datum_hash, l_hash_out_type, a_reply);
+        } break;
+        case SUBCMD_ATOM: {
+            const char *l_atom_hash_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_atom_hash_str);
+            dap_hash_fast_t l_atom_hash = {0};
+            if (!l_atom_hash_str) {
+                dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, "The hash of the atom is not specified.");
+                return DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED;
+            }
+            if (dap_chain_hash_fast_from_str(l_atom_hash_str, &l_atom_hash)) {
+                dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH, "Failed to convert the value '%s' to a hash.", l_atom_hash_str);
+                return DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH;
+            }
+            json_object *l_obj_atom = json_object_new_object();
+            json_object *l_obj_atom_hash = json_object_new_string(l_atom_hash_str);
+            json_object_object_add(l_obj_atom, "hash", l_obj_atom_hash);
+            dap_chain_atom_ptr_t l_atom_ptr = NULL;
+            size_t l_atom_size = 0;
+            if (l_chain) {
+                l_atom_ptr = dap_chain_get_atom_by_hash(l_chain, &l_atom_hash, &l_atom_size);
+            } else {
+                for (l_chain = l_net->pub.chains ; l_chain; l_chain = l_chain->next){
+                    l_atom_ptr = dap_chain_get_atom_by_hash(l_chain, &l_atom_hash, &l_atom_size);
+                    if (l_atom_ptr) break;
+                }
+            }
+            json_object *l_obj_source = NULL;
+            json_object *l_jobj_find = NULL;
+            if (l_atom_ptr) {
+                l_obj_source = json_object_new_object();
+                json_object *l_obj_net = json_object_new_string(l_net->pub.name);
+                json_object *l_obj_chain = json_object_new_string(l_chain->name);
+                json_object_object_add(l_obj_source, "net", l_obj_net);
+                json_object_object_add(l_obj_source, "chain", l_obj_chain);
+                l_jobj_find = json_object_new_boolean(TRUE);
+                json_object_object_add(l_obj_atom, "source", l_obj_source);
+                json_object_object_add(l_obj_atom, "dump", l_chain->callback_atom_dump_json(a_json_reply, l_chain, l_atom_ptr, l_atom_size, l_hash_out_type));
+            } else {
+                l_jobj_find = json_object_new_boolean(FALSE);
+            }
+            json_object_object_add(l_obj_atom, "find", l_jobj_find);
+            json_object_array_add(*a_json_reply, l_obj_atom);
+        } break;
+        case SUBCMD_DECREE: {
+            const char* l_type_decre_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-type", &l_type_decre_str);
+            if (!l_type_decre_str){
+                dap_json_rpc_error_add(*a_json_reply, DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED,
+                                       "The type of decree you are looking for is not specified.");
+                return DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED;
+            }
+            uint16_t l_subtype_decree = dap_chain_datum_decree_type_from_str(l_type_decre_str);
+            if (!l_subtype_decree) {
+                dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE,
+                                       "There is no decree of type '%s'.", l_type_decre_str);
+                return DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE;
+            }
+            const char *l_with_type_str = NULL;
+            const char *l_where_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-where", &l_where_str);
+            _s_where_search_t l_where = ALL;
+            if (l_where_str) {
+                if (!dap_strcmp(l_where_str, "chains")) {
+                    l_where = CHAINS;
+                } else if (!dap_strcmp(l_where_str, "mempool")) {
+                    l_where = MEMPOOL;
+                } else {
+                    dap_json_rpc_error_add(*a_json_reply, DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE,
+                                       "'%s' is not a valid place to look. Use mempool or chains.",
+                                           l_where_str);
+                    return DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE;
+                }
+            }
+            json_object *l_obj = json_object_new_object();
+            json_object_object_add(l_obj, "type", json_object_new_string(l_type_decre_str));
+            json_object *l_jobj_chains = json_object_new_object();
+            if (l_chain) {
+                json_object *l_jobj_data = json_object_new_object();
+                _cmd_find_type_decree_in_chain(l_jobj_data, l_chain, l_subtype_decree, l_where, l_hash_out_type);
+                json_object_object_add(l_jobj_chains, l_chain->name, l_jobj_data);
+            } else {
+                for (l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) {
+                    json_object *l_jobj_data = json_object_new_object();
+                    _cmd_find_type_decree_in_chain(l_jobj_data, l_chain, l_subtype_decree, l_where, l_hash_out_type);
+                    json_object_object_add(l_jobj_chains, l_chain->name, l_jobj_data);
+                }
+            }
+            json_object_object_add(l_obj, "chains", l_jobj_chains);
+            json_object_array_add(*a_json_reply, l_obj);
+        } break;
+    }
+    return DAP_CHAIN_NODE_CLI_FIND_OK;
+}
+
 /**
  * @brief
  *
@@ -5435,7 +5651,7 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_json_arr_reply)
 
     uint256_t l_cond_value_sum = {};
     size_t l_num_of_hashes = dap_list_length(l_hashes_list);
-    log_it(L_INFO, "Found %"DAP_UINT64_FORMAT_U" hashes. Start returning funds from transactions.", l_num_of_hashes);
+    log_it(L_INFO, "Found %zu hashes. Start returning funds from transactions.", l_num_of_hashes);
     for (dap_list_t * l_tmp = l_hashes_list; l_tmp; l_tmp=l_tmp->next){
         dap_hash_fast_t *l_hash = (dap_hash_fast_t*)l_tmp->data;
         // get tx by hash
@@ -8462,7 +8678,7 @@ static dap_tsd_t *s_alloc_metadata (const char *a_file, const int a_meta)
                 struct stat l_st;
                 stat (a_file, &l_st);
                 char l_size[513];
-                snprintf(l_size, 513, "%ld", l_st.st_size);
+                snprintf(l_size, 513, "%lld", l_st.st_size);
                 return dap_tsd_create_string(SIGNER_FILESIZE, l_size);
             }
             break;
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index e08164a47dc01ee669a7bec7dc74788c25339631..d417ca03cfb801e528b3335c74884e1b28569853 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -400,7 +400,7 @@ int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_s
         // prepare for signal waiting
         struct timespec l_cond_timeout;
         clock_gettime(CLOCK_REALTIME, &l_cond_timeout);
-        l_cond_timeout.tv_sec += a_timeout_ms;
+        l_cond_timeout.tv_sec += a_timeout_ms/1000;
         int l_ret_wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &l_cond_timeout);
         if (l_ret_wait == 0) {
             if (a_client->state != a_waited_state) {
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 304a9037505539a26d3b511d569940396d014976..052ffb7b6d94407e588b3cc6917c3af842b61d8b 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -48,7 +48,8 @@ typedef struct dap_chain_net_decree dap_chain_net_decree_t;
 typedef struct decree_table decree_table_t;
 typedef struct anchor_table anchor_table_t;
 typedef enum dap_chain_net_state {
-    NET_STATE_OFFLINE = 0,
+    NET_STATE_LOADING = 0,
+    NET_STATE_OFFLINE,
     NET_STATE_LINKS_PREPARE,
     NET_STATE_LINKS_CONNECTING,
     NET_STATE_LINKS_ESTABLISHED,
diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h
index 253a0bf8b9aa920b0120d201fe57c87c928e8b27..a76937af3b861d0ee346f0e740bbb77a72d1f892 100644
--- a/modules/net/include/dap_chain_node_cli_cmd.h
+++ b/modules/net/include/dap_chain_node_cli_cmd.h
@@ -363,4 +363,22 @@ 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);
 
+typedef enum cmd_find_list_err {
+    DAP_CHAIN_NODE_CLI_FIND_OK = 0,
+    DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD,
+    DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED,
+    DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE,
+    DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED,
+    DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE,
+}cmd_find_list_err_t;
+/**
+ * Handler coomand find
+ * @param a_argc
+ * @param a_argv
+ * @param a_str_reply
+ * @return
+ */
+int cmd_find(int a_argc, char **a_argv, void **a_str_reply);
+
 void dap_notify_new_client_send_info(dap_events_socket_t *a_es, void *a_arg);
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 283f78856f8622a16833a82f823d5e8b57d281d1..6c26497597eb3194f7309b5f61cc350a35495d67 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
@@ -137,14 +137,12 @@ int dap_chain_net_srv_stake_pos_delegate_init()
     "srv_stake order create staker -net <net_name> -w <wallet_with_m_tokens> -value <stake_value> -fee <value> -tax <percent>"
                         " [-addr <for_tax_collecting>]  [-cert <for_order_signing>] [-H {hex(default) | base58}]\n"
         "\tCreates an order allowing the validator to delegate it's key with specified params\n"
-    "srv_stake order update -net <net_name> -order <order_hash> [-params]\n"
-        "\tUpdates an order with specified hash\n"
     "srv_stake order list [fee | validator | staker] -net <net_name>\n"
         "\tGet orders list of specified type within specified net name\n"
     "srv_stake order remove -net <net_name> -order <order_hash>\n"
         "\tRemove order with specified hash\n"
             "\t\t === Commands for work with stake delegate ===\n"
-    "srv_stake delegate {-cert <pub_cert_name> -value <datoshi> | "
+    "srv_stake delegate {[-cert <pub_cert_name> | -pkey <pkey> -sign_type <sign_type>] -value <datoshi> | "
                                 "-order <order_hash> {[-tax_addr <wallet_addr_for_tax_collecting>] | "
                                         "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}"
                         " -net <net_name> -w <wallet_name> -fee <value>\n"
@@ -1529,7 +1527,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
 {
     json_object **a_json_arr_reply = (json_object **)a_str_reply;
     enum {
-        CMD_NONE, CMD_CREATE_FEE, CMD_CREATE_VALIDATOR, CMD_CREATE_STAKER, CMD_UPDATE, CMD_LIST,
+        CMD_NONE, CMD_CREATE_FEE, CMD_CREATE_VALIDATOR, CMD_CREATE_STAKER, CMD_LIST,
         CMD_LIST_STAKER, CMD_LIST_VALIDATOR, CMD_LIST_FEE, CMD_REMOVE
     };
     int l_cmd_num = CMD_NONE;
@@ -1542,8 +1540,6 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         else
             l_cmd_num = CMD_CREATE_FEE;
     }
-    else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "update") >= 0)
-        l_cmd_num = CMD_UPDATE;
     else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "list") >= 0)
         l_cmd_num = CMD_LIST;
     else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "remove") >= 0)
@@ -1792,13 +1788,11 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
         DAP_DELETE(l_tx_hash_str);
     } break;
 
-    case CMD_REMOVE:
-    case CMD_UPDATE: {
+    case CMD_REMOVE: {
         const char *l_order_hash_str = NULL;
         dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
         if (!l_order_hash_str) {
-            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR, "Command 'srv_stake order %s' requires prameter -order\n",
-                                                l_cmd_num  == CMD_REMOVE ? "remove" : "update");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR, "Command 'srv_stake order remove' requires prameter -order\n");
             return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_PARAM_ERR;
         }
         char *l_order_hash_hex_str;
@@ -1819,47 +1813,14 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi
             DAP_DELETE(l_order_hash_hex_str);
             return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_ORDER_ERR;
         }
-        if (l_cmd_num == CMD_REMOVE) {
-            if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str)) {
-                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR, "Can't remove order %s\n", l_order_hash_str);
-                return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR;
-            }
-            json_object * l_json_obj_create_val = json_object_new_object();
-            json_object_object_add(l_json_obj_create_val, "status", json_object_new_string("success"));
-            json_object_array_add(*a_json_arr_reply, l_json_obj_create_val);
-            DAP_DELETE(l_order_hash_hex_str);
-        } else { // l_cmd_num == CMD_UPDATE
-            const char *l_cert_str = NULL, *l_value_str = NULL;
-            // TODO make orders updatable
-            /*uint256_t l_value = {0};
-            if (l_value_str) {
-                l_value = dap_chain_balance_scan(l_value_str);
-                if (IS_ZERO_256(l_value)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <uint256_t>");
-                    return -8;
-                }
-            }
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
-            if (!l_cert_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order update' requires parameter -cert");
-                return -7;
-            }
-            dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
-            if (!l_cert) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str);
-                return -9;
-            }
-            l_key = l_cert->enc_key;
-            // Remove old order and create the order & put it to GDB
-            dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str);
-            DAP_DELETE(l_order_hash_hex_str);
-            DAP_DELETE(l_order_hash_base58_str);
-            l_order_hash_hex_str = s_fee_order_create(l_net, &l_value, l_key);
-            if(!l_order_hash_hex_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create new order");
-                return -15;
-            }*/
+        if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str)) {
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR, "Can't remove order %s\n", l_order_hash_str);
+            return DAP_CHAIN_NODE_CLI_SRV_STAKE_ORDER_REMOVE_ERR;
         }
+        json_object * l_json_obj_create_val = json_object_new_object();
+        json_object_object_add(l_json_obj_create_val, "status", json_object_new_string("success"));
+        json_object_array_add(*a_json_arr_reply, l_json_obj_create_val);
+        DAP_DELETE(l_order_hash_hex_str);
     } break;
 
     case CMD_LIST: {
@@ -1997,6 +1958,8 @@ typedef enum s_cli_srv_stake_delegate_err{
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WALLET_ERR,
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NO_CERT_ERR,
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_CERT_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR,
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_UNRECOGNIZED_ADDR_ERR,
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NO_ORDER_ERR,
     DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_ORDER_ERR,
@@ -2026,6 +1989,8 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
     const char *l_net_str = NULL,
                *l_wallet_str = NULL,
                *l_cert_str = NULL,
+               *l_pkey_str = NULL,
+               *l_sign_type_str = NULL,
                *l_value_str = NULL,
                *l_fee_str = NULL,
                *l_node_addr_str = NULL,
@@ -2057,9 +2022,16 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
     dap_chain_addr_t l_signing_addr, l_sovereign_addr = {};
     uint256_t l_sovereign_tax = uint256_0;
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str);
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-pkey", &l_pkey_str);
+    dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-sign_type", &l_sign_type_str);
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-order", &l_order_hash_str);
-    if (!l_cert_str && !l_order_hash_str) {
-        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -cert and/or -order");
+    if (!l_cert_str && !l_order_hash_str && !l_pkey_str) {
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -cert and/or -order and/or -pkey");
+        dap_enc_key_delete(l_enc_key);
+        return -13;
+    }
+    if (l_pkey_str && !l_sign_type_str) {
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -sign_type for pkey");
         dap_enc_key_delete(l_enc_key);
         return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR;
     }
@@ -2093,6 +2065,21 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
             return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_CERT_ERR;
         }
         dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str);
+    } else if (l_pkey_str) {
+        dap_chain_hash_fast_t l_hash_public_key = {0};
+        dap_sign_type_t l_type = dap_sign_type_from_str(l_sign_type_str);
+        if (l_type.type == SIG_TYPE_NULL) {
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR, "Wrong sign type");
+            dap_enc_key_delete(l_enc_key);
+            return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR;
+        }
+        if (dap_chain_hash_fast_from_str(l_pkey_str, &l_hash_public_key)) {
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "Invalid pkey hash format");
+            dap_enc_key_delete(l_enc_key);
+            return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR;
+        }
+        dap_chain_addr_fill(&l_signing_addr, l_type, &l_hash_public_key, l_net->pub.id);
+        dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str);
     }
     dap_chain_node_addr_t l_node_addr = g_node_addr;
     if (l_node_addr_str) {
@@ -2294,15 +2281,36 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index,
     DAP_DELETE(l_tx);
     json_object* l_json_obj_deligate = json_object_new_object();
     json_object_object_add(l_json_obj_deligate, "status", json_object_new_string("success"));
-    json_object_object_add(l_json_obj_deligate, "sign", json_object_new_string(l_sign_str));
+    if (dap_strcmp(l_sign_str, ""))
+        json_object_object_add(l_json_obj_deligate, "sign", json_object_new_string(l_sign_str));  // deprecated signs error
     json_object_object_add(l_json_obj_deligate, "tx_hash", json_object_new_string(l_tx_hash_str));
     json_object_array_add(*a_json_arr_reply, l_json_obj_deligate);
     DAP_DELETE(l_tx_hash_str);
     return 0;
 }
 
+
+typedef enum s_cli_srv_stake_update_err{
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_OK = 0,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_MEMORY_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NET_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_FEE_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_CERT_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_WRONG_CERT_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PKEY_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_STAKE_IN_NET_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NOT_DELGATED_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_TX_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_INVALID_TX_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_TX_SPENT_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_WALLET_ERR,
+    DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_CANT_COMPOSE_ERR,
+} s_cli_srv_stake_update_err_t;
 static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply, const char *a_hash_out_type)
 {
+    json_object **a_json_arr_reply = (json_object **)a_str_reply;
     const char *l_net_str = NULL,
                *l_wallet_str = NULL,
                *l_value_str,
@@ -2311,45 +2319,45 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo
                *l_cert_str = NULL;
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str);
     if (!l_net_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -net");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -net");
         return -3;
     }
     dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
     if (!l_net) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NET_ERR, "Network %s not found", l_net_str);
         return -4;
     }
     uint256_t l_fee = {};
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str);
     if (!l_wallet_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -w");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -w");
         return -17;
     }
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str);
     if (!l_fee_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -fee");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -fee");
         return -5;
     }
     l_fee = dap_chain_balance_scan(l_fee_str);
     if (IS_ZERO_256(l_fee)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-fee' param");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_FEE_ERR, "Unrecognized number in '-fee' param");
         return -6;
     }
     uint256_t l_value = {};
     dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str);
     if (!l_value_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -value");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -value");
         return -7;
     }
     l_value = dap_chain_balance_scan(l_value_str);
     if (IS_ZERO_256(l_value)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-value' param");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR, "Unrecognized number in '-value' param");
         return -8;
     }
     uint256_t l_value_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id);
     if (compare256(l_value, l_value_min) == -1) {
         const char *l_value_min_str; dap_uint256_to_char(l_value_min, &l_value_min_str);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "New delegation value should be not less than service required minimum %s", l_value_min_str);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_FORMAT_ERR, "New delegation value should be not less than service required minimum %s", l_value_min_str);
         return -25;
     }
 
@@ -2357,7 +2365,7 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo
     if (!l_tx_hash_str) {
         dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str);
         if (!l_cert_str) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'update' requires parameter -tx or -cert");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PARAM_ERR, "Command 'update' requires parameter -tx or -cert");
             return -13;
         }
     }
@@ -2368,26 +2376,26 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo
         dap_chain_addr_t l_signing_addr;
         dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
         if (!l_cert) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_CERT_ERR, "Specified certificate not found");
             return -18;
         }
         if (!l_cert->enc_key->priv_key_data || l_cert->enc_key->priv_key_data_size == 0) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "It is not possible to update a stake using a public key.");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_PKEY_ERR, "It is not possible to update a stake using a public key.");
             return -31;
         }
         if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_WRONG_CERT_ERR, "Specified certificate is wrong");
             return -22;
         }
         dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id);
         if (!l_srv_stake) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated");
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_STAKE_IN_NET_ERR, "Specified net have no stake service activated");
             return -25;
         }
         dap_chain_net_srv_stake_item_t *l_stake = NULL;
         HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake);
         if (!l_stake) {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate/pkey hash is not delegated nor this delegating is approved."
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NOT_DELGATED_ERR, "Specified certificate/pkey hash is not delegated nor this delegating is approved."
                                                            " Try to update with tx hash instead");
             return -24;
         }
@@ -2397,24 +2405,24 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo
     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);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_TX_ERR, "Transaction %s not found", l_tx_hash_str_tmp);
         return -21;
     }
     int l_out_num = 0;
     if (!dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, &l_out_num)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is invalid", l_tx_hash_str_tmp);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_INVALID_TX_ERR, "Transaction %s is invalid", l_tx_hash_str_tmp);
         return -22;
     }
     dap_hash_fast_t l_spender_hash = {};
     if (dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, &l_tx_hash, l_out_num, &l_spender_hash)) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is spent", l_tx_hash_str_tmp);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_TX_SPENT_ERR, "Transaction %s is spent", l_tx_hash_str_tmp);
         return -23;
     }
 
     const char* l_sign_str = "";
     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL);
     if (!l_wallet) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet %s not found", l_wallet_str);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_NO_WALLET_ERR, "Specified wallet %s not found", l_wallet_str);
         return -18;
     } else {
         l_sign_str = dap_chain_wallet_check_sign(l_wallet);
@@ -2425,12 +2433,17 @@ static int s_cli_srv_stake_update(int a_argc, char **a_argv, int a_arg_index, vo
     dap_enc_key_delete(l_enc_key);
     char *l_out_hash_str = NULL;
     if (l_tx_new && (l_out_hash_str = s_stake_tx_put(l_tx_new, l_net, a_hash_out_type))) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%sDelegated m-tokens value will change. Updating tx hash is %s.", l_sign_str, l_out_hash_str);
+        json_object* l_json_object_ret = json_object_new_object();
+        if (l_sign_str)
+            json_object_object_add(l_json_object_ret, "sign", json_object_new_string(l_sign_str));
+        json_object_object_add(l_json_object_ret, "hash", json_object_new_string(l_out_hash_str));
+        json_object_object_add(l_json_object_ret, "message", json_object_new_string("Delegated m-tokens value will change"));
+        json_object_array_add(*a_json_arr_reply, l_json_object_ret);
         DAP_DELETE(l_out_hash_str);
         DAP_DELETE(l_tx_new);
     } else {
         l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose updating transaction %s, examine log files for details", l_tx_hash_str);
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_CANT_COMPOSE_ERR, "Can't compose updating transaction %s, examine log files for details", l_tx_hash_str);
         DAP_DEL_Z(l_tx_new);
         return -21;
     }
@@ -2686,6 +2699,7 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t
     snprintf(l_node_addr, 32, ""NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(a_stake->node_addr));
     json_object_object_add(l_json_obj_stake, "pkey_hash", json_object_new_string(l_pkey_hash_str));
     json_object_object_add(l_json_obj_stake, "stake_value", json_object_new_string(l_balance));
+    json_object_object_add(l_json_obj_stake, "effective_value", json_object_new_string(l_effective_weight));
     json_object_object_add(l_json_obj_stake, "related_weight", json_object_new_string(l_rel_weight_str));
     json_object_object_add(l_json_obj_stake, "tx_hash", json_object_new_string(l_tx_hash_str));
     json_object_object_add(l_json_obj_stake, "node_addr", json_object_new_string(l_node_addr));
@@ -2774,6 +2788,7 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa
     l_remote_node_info = (dap_chain_node_info_t*) dap_global_db_get_sync(a_net->pub.gdb_nodes,
         dap_stream_node_addr_to_str_static(l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr),
         &l_node_info_size, NULL, NULL);
+    
 
     if(!l_remote_node_info) {
         return -6;
@@ -2984,7 +2999,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
             }
 
             json_object* json_obj_order = json_object_new_object();
-            json_object_object_add(json_obj_order, "VERSION", json_object_new_int(*(int*)l_out.header.version));
+            json_object_object_add(json_obj_order, "VERSION", json_object_new_string((char*)l_out.header.version));
             json_object_object_add(json_obj_order, "AUTO_PROC", json_object_new_string((l_out.header.flags & A_PROC)?"true":"false"));
             json_object_object_add(json_obj_order, "ORDER", json_object_new_string((l_out.header.flags & F_ORDR)?"true":"false"));
             json_object_object_add(json_obj_order, "AUTO_ONLINE", json_object_new_string((l_out.header.flags & A_ONLN)?"true":"false"));
@@ -3123,10 +3138,14 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                         json_object_object_add(l_json_obj_keys_count, "total_keys", json_object_new_int(l_total_count));
                     if (dap_chain_esbocs_started(l_net->pub.id))
                         json_object_object_add(l_json_obj_keys_count, "inactive_keys", json_object_new_int(l_inactive_count));
-                    const char *l_total_weight_coins, *l_total_weight_str =
-                            dap_uint256_to_char(l_total_weight, &l_total_weight_coins);
+
+
+                    const char *l_total_weight_coins, *l_total_weight_str = dap_uint256_to_char(l_total_locked_weight, &l_total_weight_coins);
                     json_object_object_add(l_json_obj_keys_count, "total_weight_coins", json_object_new_string(l_total_weight_coins));
                     json_object_object_add(l_json_obj_keys_count, "total_weight_str", json_object_new_string(l_total_weight_str));
+                    l_total_weight_str = dap_uint256_to_char(l_total_weight, &l_total_weight_coins);
+                    json_object_object_add(l_json_obj_keys_count, "total_effective_weight_coins", json_object_new_string(l_total_weight_coins));
+                    json_object_object_add(l_json_obj_keys_count, "total_effective_weight", json_object_new_string(l_total_weight_str));
                 }
 
                 const char *l_delegate_min_str; dap_uint256_to_char(dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id),
diff --git a/modules/service/voting/dap_chain_net_srv_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c
index c0d207af700b1eab185ee8bca2b4e6a513504744..8196ec0549881ee61f9e62addb59583a8dea75c6 100644
--- a/modules/service/voting/dap_chain_net_srv_voting.c
+++ b/modules/service/voting/dap_chain_net_srv_voting.c
@@ -1043,6 +1043,7 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
         l_val = dap_strdup_printf("%s (%s) %s\n\n", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker);
         json_object_object_add(json_vote_out, "Total weight", json_object_new_string(l_val));
         DAP_DELETE(l_val);
+        json_object_array_add(*json_arr_reply, json_vote_out);
     }break;
     default:{
 
diff --git a/modules/type/blocks/CMakeLists.txt b/modules/type/blocks/CMakeLists.txt
index 3770f285fde25cf498200ae5b8af9f18757fcdd1..67e7ef053890c1eaad0126e5f8d15707ba1e8eb0 100644
--- a/modules/type/blocks/CMakeLists.txt
+++ b/modules/type/blocks/CMakeLists.txt
@@ -10,7 +10,7 @@ if(BUILD_CELLFRAME_SDK_TESTS)
     add_subdirectory(tests)
 endif()
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_cli_server dap_chain_net)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_common dap_cli_server dap_chain_net)
 target_include_directories(${PROJECT_NAME} INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
 
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 66b3817e868833d54a6b530c449de491fa5b7d8e..85b25313f3d4a20faddae904c2a758d4c4eccf2d 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -33,6 +33,8 @@
 #include "dap_chain_mempool.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_cs_esbocs.h"
+#include "dap_chain_datum.h"
+#include "dap_enc_base58.h"
 
 #define LOG_TAG "dap_chain_cs_blocks"
 
@@ -95,7 +97,7 @@ typedef struct dap_chain_cs_blocks_pvt {
         log_it(L_DEBUG, "Unlocked rwqlock, %s, %d, thread_id=%u", __FUNCTION__, __LINE__, dap_gettid());
 
 static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, void **a_str_reply,const char * a_param, dap_chain_hash_fast_t * a_datum_hash);
-static void s_cli_meta_hash_print(  json_object* a_json_obj_out, const char * a_meta_title, dap_chain_block_meta_t * a_meta);
+static void s_cli_meta_hash_print(  json_object* a_json_obj_out, const char * a_meta_title, dap_chain_block_meta_t * a_meta, const char *a_hash_out_type);
 static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply);
 
 // Setup BFT consensus and select the longest chunk
@@ -116,6 +118,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 json_object *s_callback_atom_dump_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom_ptr, size_t a_atom_size, const char *a_hash_out_type);
 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);
@@ -287,8 +290,10 @@ static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_con
     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_dump_json = s_callback_atom_dump_json;
     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_atom_dump_json =
 
     a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash;
     a_chain->callback_calc_reward = s_callback_calc_reward;
@@ -454,13 +459,22 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, voi
  * @param a_str_tmp
  * @param a_meta_title
  * @param a_meta
+ * @param a_hash_out_type
  */
-static void s_cli_meta_hash_print(json_object* a_json_obj_out, const char *a_meta_title, dap_chain_block_meta_t *a_meta)
+static void s_cli_meta_hash_print(json_object* a_json_obj_out, const char *a_meta_title, dap_chain_block_meta_t *a_meta, const char *a_hash_out_type)
 {
     if (a_meta->hdr.data_size == sizeof (dap_chain_hash_fast_t)) {
-        char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-        dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *)a_meta->data, l_hash_str, sizeof(l_hash_str));
+        const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ?
+                dap_enc_base58_encode_hash_to_str_static((dap_chain_hash_fast_t*)a_meta->data) :
+                dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*)a_meta->data);
         json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string(l_hash_str));
+//        if (dap_strcmp(a_hash_out_type, "base58")) {
+//            const char *l_hash_str = dap_enc_base58_encode_hash_to_str_static(a_meta->data);
+            //
+//        } else {
+//            char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+//            dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *) a_meta->data, l_hash_str, sizeof(l_hash_str));
+//        }
     } else
         json_object_object_add(a_json_obj_out, a_meta_title, json_object_new_string("Error, hash size is incorrect"));
 }
@@ -754,13 +768,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     json_object_object_add(json_obj_meta, "GENESIS", json_object_new_string("GENESIS"));
                     break;
                 case DAP_CHAIN_BLOCK_META_PREV:
-                    s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta, l_hash_out_type);
                     break;
                 case DAP_CHAIN_BLOCK_META_ANCHOR:
-                    s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta, l_hash_out_type);
                     break;
                 case DAP_CHAIN_BLOCK_META_LINK:
-                    s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta, l_hash_out_type);
                     break;
                 case DAP_CHAIN_BLOCK_META_NONCE:
                     s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta);
@@ -820,11 +834,12 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 size_t l_sign_size = dap_sign_get_size(l_sign);
                 dap_chain_hash_fast_t l_pkey_hash;
                 dap_sign_get_pkey_hash(l_sign, &l_pkey_hash);
-                char l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-                dap_chain_hash_fast_to_str(&l_pkey_hash, l_pkey_hash_str, sizeof(l_pkey_hash_str));
+                const char *l_hash_str = !dap_strcmp(l_hash_out_type, "base58") ?
+                        dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) :
+                        dap_chain_hash_fast_to_str_static(&l_pkey_hash);
                 json_object_object_add(json_obj_sign, "type",json_object_new_string(dap_sign_type_to_str( l_sign->header.type )));
                 json_object_object_add(json_obj_sign, "size",json_object_new_uint64(l_sign_size));
-                json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_pkey_hash_str));
+                json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_hash_str));
                 json_object_array_add(json_arr_sign_out, json_obj_sign);
             }
             json_object_array_add(*a_json_arr_reply, json_arr_sign_out);
@@ -2093,6 +2108,104 @@ static dap_chain_atom_ptr_t s_callback_block_find_by_tx_hash(dap_chain_t * a_cha
     return l_datum_index->block_cache->block;
 }
 
+static json_object *s_callback_atom_dump_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom_ptr, size_t a_atom_size, const char *a_hash_out_type) {
+   dap_chain_block_t *l_block = (dap_chain_block_t *) a_atom_ptr;
+    json_object *l_obj_ret = json_object_new_object();
+    char l_time_buf[DAP_TIME_STR_SIZE], l_hexbuf[32] = { '\0' };
+    sprintf(l_hexbuf, "0x%04X", l_block->hdr.version);
+
+    json_object_object_add(l_obj_ret, "version", json_object_new_string(l_hexbuf));
+    sprintf(l_hexbuf, "0x%016"DAP_UINT64_FORMAT_X"", l_block->hdr.cell_id.uint64);
+    json_object_object_add(l_obj_ret, "cell_id", json_object_new_string(l_hexbuf));
+    sprintf(l_hexbuf, "0x%016"DAP_UINT64_FORMAT_X"", l_block->hdr.chain_id.uint64);
+    json_object_object_add(l_obj_ret, "chain_id", json_object_new_string(l_hexbuf));
+    dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
+    json_object_object_add(l_obj_ret, "ts_created", json_object_new_string(l_time_buf));
+
+    // Dump Metadata
+    size_t l_offset = 0;
+    json_object *l_jobj_metadata = json_object_new_array();
+    for (uint32_t i = 0; i < l_block->hdr.meta_count; i++) {
+        json_object *json_obj_meta = json_object_new_object();
+        dap_chain_block_meta_t *l_meta = (dap_chain_block_meta_t *) (l_block->meta_n_datum_n_sign + l_offset);
+        switch (l_meta->hdr.type) {
+            case DAP_CHAIN_BLOCK_META_GENESIS:
+                json_object_object_add(json_obj_meta, "GENESIS", json_object_new_string("GENESIS"));
+                break;
+            case DAP_CHAIN_BLOCK_META_PREV:
+                s_cli_meta_hash_print(json_obj_meta, "PREV", l_meta, a_hash_out_type);
+                break;
+            case DAP_CHAIN_BLOCK_META_ANCHOR:
+                s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta, a_hash_out_type);
+                break;
+            case DAP_CHAIN_BLOCK_META_LINK:
+                s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta, a_hash_out_type);
+                break;
+            case DAP_CHAIN_BLOCK_META_NONCE:
+                s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta);
+                break;
+            case DAP_CHAIN_BLOCK_META_NONCE2:
+                s_cli_meta_hex_print(json_obj_meta, "NONCE2", l_meta);
+                break;
+            default: {
+                sprintf(l_hexbuf, "0x%0X", i);
+                json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_hexbuf));
+                int l_len = l_meta->hdr.data_size * 2 + 5;
+                char *l_data_hex = DAP_NEW_STACK_SIZE(char, l_len);
+                snprintf(l_data_hex, 2, "0x");
+                dap_bin2hex(l_data_hex + 2, l_meta->data, l_meta->hdr.data_size);
+                json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_data_hex));
+            }
+        }
+        json_object_array_add(l_jobj_metadata, json_obj_meta);
+        l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size;
+    }
+    json_object_object_add(l_obj_ret, "metadata", l_jobj_metadata);
+    json_object *l_jobj_datums = json_object_new_array();
+    for (uint16_t i = 0; i < l_block->hdr.datum_count; i++) {
+        dap_chain_datum_t *l_datum = (dap_chain_datum_t*)(l_block->meta_n_datum_n_sign + l_offset);
+        json_object *l_jobj_datum = json_object_new_object();
+        size_t l_datum_size =  dap_chain_datum_size(l_datum);
+        json_object_object_add(l_jobj_datum, "datum size ",json_object_new_uint64(l_datum_size));
+        if (l_datum_size < sizeof (l_datum->header) ){
+            dap_json_rpc_error_add(*a_arr_out, DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu",l_datum_size,
+                                    sizeof (l_datum->header));
+            break;
+        }
+        // Nested datums
+        sprintf(l_hexbuf,"0x%02X",l_datum->header.version_id);
+        json_object_object_add(l_jobj_datum, "version",json_object_new_string(l_hexbuf));
+        const char * l_datum_type_str = "UNKNOWN";
+        DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str);
+        json_object_object_add(l_jobj_datum, "type_id",json_object_new_string(l_datum_type_str));
+        dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
+        json_object_object_add(l_jobj_datum, "ts_create",json_object_new_string(l_time_buf));
+        json_object_object_add(l_jobj_datum, "data_size",json_object_new_int(l_datum->header.data_size));
+        dap_chain_datum_dump_json(*a_arr_out, l_jobj_datum,l_datum, a_hash_out_type, a_chain->net_id);
+        json_object_array_add(l_jobj_datums, l_jobj_datum);
+        l_offset += l_datum_size;
+    }
+    json_object_object_add(l_obj_ret, "datums", l_jobj_datums);
+    json_object *l_jobj_signatures = json_object_new_array();
+    size_t l_block_signs = dap_chain_block_get_signs_count(l_block, a_atom_size);
+    for (uint32_t i = 0; i < l_block_signs; i++) {
+        json_object* json_obj_sign = json_object_new_object();
+        dap_sign_t * l_sign = dap_chain_block_sign_get(l_block, dap_chain_block_get_size(l_block), i);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        dap_chain_hash_fast_t l_pkey_hash;
+        dap_sign_get_pkey_hash(l_sign, &l_pkey_hash);
+        const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ?
+                dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) :
+                dap_chain_hash_fast_to_str_static(&l_pkey_hash);
+        json_object_object_add(json_obj_sign, "type",json_object_new_string(dap_sign_type_to_str( l_sign->header.type )));
+        json_object_object_add(json_obj_sign, "size",json_object_new_uint64(l_sign_size));
+        json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_hash_str));
+        json_object_array_add(l_jobj_signatures, json_obj_sign);
+    }
+    json_object_object_add(l_obj_ret, "signatures", l_jobj_signatures);
+    return l_obj_ret;
+}
+
 /**
  * @brief s_callback_atom_get_datum
  * @param a_event
@@ -2165,6 +2278,7 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_get(dap_chain_atom_iter_t *a_at
         a_atom_iter->cur_size   = l_item->block_size;
         a_atom_iter->cur_hash   = &l_item->block_hash;
         a_atom_iter->cur_num    = l_item->block_number;
+        a_atom_iter->cur_ts     = l_item->ts_created;
     } else 
         *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain,
                                                  .cell_id = a_atom_iter->cell_id };
@@ -2492,10 +2606,10 @@ static uint256_t s_callback_calc_reward(dap_chain_t *a_chain, dap_hash_fast_t *a
     }
     assert(l_block);
     dap_time_t l_cur_time = dap_max(l_block->hdr.ts_created, DAP_REWARD_INIT_TIMESTAMP);
-    dap_time_t l_time_diff = l_block_time > l_cur_time ? l_block_time - l_cur_time : 1;
-    if (MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret)) {
-        log_it(L_ERROR, "Integer overflow while multiplication execution to calculate final reward");
-        return uint256_0;
+    if ( l_block_time > l_cur_time ) {
+        dap_time_t l_time_diff = l_block_time - l_cur_time;
+        if (MULT_256_256(l_ret, GET_256_FROM_64(l_time_diff), &l_ret))
+            return log_it(L_ERROR, "Integer overflow while multiplication execution to calculate final reward"), uint256_0;
     }
     DIV_256(l_ret, GET_256_FROM_64(s_block_timediff_unit_size * l_signs_count), &l_ret);
     return l_ret;
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 45e5125c520478c01697efbd28a8b959b8db99ee..6263a75ab810841623091b007b14949efcba917a 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -135,6 +135,7 @@ static uint64_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain);
 static dap_list_t *s_dap_chain_callback_get_txs(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse);
 
 static uint64_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain);
+static json_object *s_dap_chain_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type);
 static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse);
 
 static bool s_seed_mode = false, s_debug_more = false, s_threshold_enabled = false;
@@ -246,6 +247,7 @@ static int s_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     a_chain->callback_count_atom = s_dap_chain_callback_get_count_atom;
     // Get atom list in chain
     a_chain->callback_get_atoms = s_callback_get_atoms;
+    a_chain->callback_atom_dump_json = s_dap_chain_callback_atom_to_json;
 
     // Others
     a_chain->_inheritor = l_dag;
@@ -1117,6 +1119,7 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get(dap_chain_atom_iter_t
         a_atom_iter->cur_size = l_item->event_size;
         a_atom_iter->cur_hash = &l_item->hash;
         a_atom_iter->cur_num = l_item->event_number;
+        a_atom_iter->cur_ts = l_item->ts_created;
     } else
         *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain,
                                                  .cell_id = a_atom_iter->cell_id };
@@ -2004,3 +2007,60 @@ static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, si
     pthread_mutex_unlock(&PVT(l_dag)->events_mutex);
     return l_list;
 }
+
+
+static json_object *s_dap_chain_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type){
+    json_object *l_jobj = json_object_new_object();
+    dap_chain_cs_dag_event_t *l_event = (dap_chain_cs_dag_event_t*)a_atom;
+    char l_buf[150] = {'\0'};
+    // Header
+    sprintf(l_buf,"%hu",l_event->header.version);
+    json_object_object_add(l_jobj,"version", json_object_new_string(l_buf));
+    json_object_object_add(l_jobj,"round ID", json_object_new_uint64(l_event->header.round_id));
+    sprintf(l_buf,"0x%016"DAP_UINT64_FORMAT_x"",l_event->header.cell_id.uint64);
+    json_object_object_add(l_jobj,"cell_id", json_object_new_string(l_buf));
+    sprintf(l_buf,"0x%016"DAP_UINT64_FORMAT_x"",l_event->header.chain_id.uint64);
+    json_object_object_add(l_jobj,"chain_id", json_object_new_string(l_buf));
+    dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_event->header.ts_created);
+    json_object_object_add(l_jobj,"ts_created", json_object_new_string(l_buf));
+    // Hash links
+    json_object *l_jobj_hash_links = json_object_new_array();
+    for (uint16_t i=0; i < l_event->header.hash_count; i++){
+        dap_chain_hash_fast_t * l_hash = (dap_chain_hash_fast_t *) (l_event->hashes_n_datum_n_signs + i*sizeof (dap_chain_hash_fast_t));
+        const char *l_hash_str = !dap_strcmp(a_hash_out_type, "base58") ?
+                                 dap_enc_base58_encode_hash_to_str_static(l_hash) :
+                                 dap_hash_fast_to_str_static(l_hash);
+        json_object_array_add(l_jobj_hash_links, json_object_new_string(l_hash_str));
+    }
+    json_object_object_add(l_jobj, "hash_links", l_jobj_hash_links);
+    size_t l_offset =  l_event->header.hash_count*sizeof (dap_chain_hash_fast_t);
+    // Nested datum
+    dap_chain_datum_t * l_datum = (dap_chain_datum_t*) (l_event->hashes_n_datum_n_signs + l_offset);
+    const char *l_datum_type = NULL;
+    DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type)
+    json_object_object_add(l_jobj, "datum_type", json_object_new_string(l_datum_type));
+    dap_chain_datum_dump_json(*a_arr_out, l_jobj, l_datum, a_hash_out_type, a_chain->net_id);
+    json_object *l_jobj_signatures = json_object_new_array();
+    l_offset += dap_chain_datum_size(l_datum);
+    // Signatures
+    while (l_offset + sizeof (l_event->header) < a_atom_size ){
+        json_object *l_jobj_signature = json_object_new_object();
+        dap_sign_t * l_sign =(dap_sign_t *) (l_event->hashes_n_datum_n_signs +l_offset);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
+        if (l_sign_size == 0 ){
+            dap_json_rpc_error_add(*a_arr_out, DAP_CHAIN_NODE_CLI_COM_DAG_SIGN_ERR," wrong sign size 0, stop parsing headers");
+            break;
+        }
+        dap_chain_hash_fast_t l_pkey_hash;
+        dap_sign_get_pkey_hash(l_sign, &l_pkey_hash);
+        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);
+        json_object_object_add(l_jobj_signature,"type", json_object_new_string(dap_sign_type_to_str( l_sign->header.type )));
+        json_object_object_add(l_jobj_signature,"pkey_hash", json_object_new_string(l_hash_str));
+        json_object_array_add(l_jobj_signatures, l_jobj_signature);
+        l_offset += l_sign_size;
+    }
+    json_object_object_add(l_jobj, "signatures", l_jobj_signatures);
+    return  l_jobj;
+}
diff --git a/modules/type/none/dap_chain_cs_none.c b/modules/type/none/dap_chain_cs_none.c
index 046eeef125ac5167411d904dd0247bb6f8d23145..fc3c037ecd583e850c94f6e44883d21e01e39947 100644
--- a/modules/type/none/dap_chain_cs_none.c
+++ b/modules/type/none/dap_chain_cs_none.c
@@ -72,6 +72,8 @@ static void s_nonconsensus_callback_atom_iter_delete(dap_chain_atom_iter_t * a_a
 static dap_chain_atom_ptr_t s_nonconsensus_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 json_object *s_nonconsensus_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type);
+
 // Get event(s) from gdb
 static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_get(dap_chain_atom_iter_t *a_atom_iter, dap_chain_iter_op_t a_operation, size_t *a_atom_size);
 static dap_chain_atom_ptr_t *s_nonconsensus_callback_atom_iter_get_links(dap_chain_atom_iter_t *a_atom_iter, size_t *a_links_size_ptr, size_t **a_lasts_sizes_ptr); //    Get list of linked events
@@ -190,6 +192,7 @@ static int s_cs_callback_new(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_ch
     a_chain->callback_atom_iter_delete = s_nonconsensus_callback_atom_iter_delete;
     a_chain->callback_atom_iter_get = s_nonconsensus_callback_atom_iter_get; // Linear pass through
     a_chain->callback_atom_find_by_hash = s_nonconsensus_callback_atom_iter_find_by_hash;
+    a_chain->callback_atom_dump_json = s_nonconsensus_callback_atom_to_json;
 
     a_chain->callback_atom_iter_get_links = s_nonconsensus_callback_atom_iter_get_links; // Get the next element from chain from the current one
 
@@ -428,6 +431,23 @@ static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_find_by_hash(dap_c
     return l_ret;
 }
 
+
+/**
+ * @brief Serializes dap_chain_atom_ptr in none consensus to JSON
+ * @param a_chain
+ * @param a_atom
+ * @param a_atom_size
+ * @param a_hash_out_type
+ * @return
+ */
+static json_object *s_nonconsensus_callback_atom_to_json(json_object **a_arr_out, dap_chain_t *a_chain, dap_chain_atom_ptr_t a_atom, size_t a_atom_size, const char *a_hash_out_type)
+{
+    json_object *obj_ret = json_object_new_object();
+    dap_chain_datum_t *l_datum = (dap_chain_datum_t*)a_atom;
+    dap_chain_datum_dump_json(*a_arr_out, obj_ret, l_datum, a_hash_out_type, a_chain->net_id);
+    return obj_ret;
+}
+
 /**
  * @brief Get the first dag event from database
  *