From f7ad393c21d4263401552d3828f26ccfdc34e283 Mon Sep 17 00:00:00 2001
From: "roman.padenkov" <roman.padenkov@demlabs.net>
Date: Tue, 28 May 2024 09:20:53 +0000
Subject: [PATCH] feature-11409_d

---
 CMakeLists.txt                                |  15 +-
 dap-sdk                                       |   2 +-
 modules/CMakeLists.txt                        |  12 +-
 modules/chain/tests/dap_chain_ledger_tests.c  |   4 +-
 .../dap_stream_ch_chain_net_srv.c             |   2 +-
 modules/common/dap_chain_common.c             |   9 +-
 modules/common/dap_chain_datum.c              | 526 ++++++++++++-
 modules/common/dap_chain_datum_anchor.c       |  38 +
 modules/common/dap_chain_datum_decree.c       | 221 +++++-
 modules/common/dap_chain_datum_tx_items.c     | 150 ++++
 modules/common/include/dap_chain_datum.h      |   7 +
 .../common/include/dap_chain_datum_anchor.h   |   2 +
 .../common/include/dap_chain_datum_decree.h   |  23 +-
 .../common/include/dap_chain_datum_token.h    |  16 +
 modules/common/include/dap_chain_datum_tx.h   |   1 -
 .../common/include/dap_chain_datum_tx_items.h |  36 +
 .../block-poa/dap_chain_cs_block_poa.c        |   4 +-
 .../consensus/dag-poa/dap_chain_cs_dag_poa.c  |   4 +-
 .../consensus/esbocs/dap_chain_cs_esbocs.c    |  82 +-
 .../esbocs/include/dap_chain_cs_esbocs.h      |  11 +-
 modules/json_rpc/CMakeLists.txt               |   3 -
 modules/json_rpc/common/CMakeLists.txt        |  10 -
 .../common/dap_json_rpc_chain_common.c        |  13 -
 .../common/dap_json_rpc_chain_datum.c         | 744 ------------------
 .../common/dap_json_rpc_chain_datum_anchor.c  | 169 ----
 .../common/dap_json_rpc_chain_datum_decree.c  | 583 --------------
 .../common/dap_json_rpc_chain_datum_token.c   | 379 ---------
 .../common/dap_json_rpc_chain_datum_tx.c      | 149 ----
 .../dap_json_rpc_chain_datum_tx_items.c       | 302 -------
 .../dap_json_rpc_chain_datum_tx_receipt.c     |  78 --
 .../include/dap_json_rpc_chain_common.h       |  35 -
 .../common/include/dap_json_rpc_chain_datum.h |  31 -
 .../include/dap_json_rpc_chain_datum_anchor.h |  33 -
 .../include/dap_json_rpc_chain_datum_decree.h |  35 -
 .../include/dap_json_rpc_chain_datum_token.h  |  33 -
 .../include/dap_json_rpc_chain_datum_tx.h     |  31 -
 .../dap_json_rpc_chain_datum_tx_items.h       |  43 -
 .../dap_json_rpc_chain_datum_tx_receipt.h     |  31 -
 modules/json_rpc/mempool/CMakeLists.txt       |  11 -
 .../json_rpc/mempool/dap_chain_mempool_rpc.c  | 149 ----
 .../mempool/include/dap_chain_mempool_rpc.h   |  37 -
 modules/mempool/dap_chain_mempool.c           |   2 +-
 .../mempool/include/dap_chain_mempool_rpc.h   |   2 +
 modules/net/CMakeLists.txt                    |   4 +-
 modules/net/dap_chain_ledger.c                | 344 +++++++-
 modules/net/dap_chain_net.c                   |   8 +-
 modules/net/dap_chain_net_balancer.c          |   2 +-
 modules/net/dap_chain_net_decree.c            |   6 +-
 modules/net/dap_chain_node_cli_cmd.c          | 158 +++-
 modules/net/dap_chain_node_cli_cmd_tx.c       | 220 ++++--
 modules/net/include/dap_chain_ledger.h        |  53 +-
 modules/net/include/dap_chain_node_cli_cmd.h  |  17 +-
 .../net/include/dap_chain_node_cli_cmd_tx.h   |  19 +-
 modules/net/srv/dap_chain_net_srv.c           |   2 +-
 modules/service/bridge/CMakeLists.txt         |  22 +
 .../service/bridge/dap_chain_net_srv_bridge.c | 161 ++++
 .../bridge/include/dap_chain_net_srv_bridge.h |   5 +
 .../service/datum/dap_chain_net_srv_datum.c   |  10 +
 .../stake/dap_chain_net_srv_stake_lock.c      | 138 ++++
 .../dap_chain_net_srv_stake_pos_delegate.c    |  30 +-
 modules/service/voting/CMakeLists.txt         |  22 +
 .../voting/dap_chain_net_srv_voting.c}        |  31 +-
 .../include/dap_chain_net_srv_voting.h}       |  22 +-
 modules/service/vpn/CMakeLists.txt            |  12 +-
 .../vpn/dap_chain_net_srv_vpn_common.c        |  44 ++
 .../vpn/include/dap_chain_net_srv_vpn.h       |   4 +-
 .../include/dap_chain_net_srv_vpn_common.h    |   4 +
 .../xchange/dap_chain_net_srv_xchange.c       | 139 +++-
 .../include/dap_chain_net_srv_xchange.h       |  18 +-
 modules/type/blocks/dap_chain_cs_blocks.c     | 403 ++++++----
 .../type/blocks/include/dap_chain_cs_blocks.h |  21 +
 modules/type/dag/dap_chain_cs_dag.c           |  12 +-
 72 files changed, 2670 insertions(+), 3329 deletions(-)
 delete mode 100644 modules/json_rpc/CMakeLists.txt
 delete mode 100644 modules/json_rpc/common/CMakeLists.txt
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_common.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_token.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
 delete mode 100644 modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_common.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h
 delete mode 100644 modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h
 delete mode 100644 modules/json_rpc/mempool/CMakeLists.txt
 delete mode 100644 modules/json_rpc/mempool/dap_chain_mempool_rpc.c
 delete mode 100644 modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h
 create mode 100644 modules/service/bridge/CMakeLists.txt
 create mode 100644 modules/service/bridge/dap_chain_net_srv_bridge.c
 create mode 100644 modules/service/bridge/include/dap_chain_net_srv_bridge.h
 create mode 100644 modules/service/voting/CMakeLists.txt
 rename modules/{net/dap_chain_net_voting.c => service/voting/dap_chain_net_srv_voting.c} (99%)
 rename modules/{net/include/dap_chain_net_voting.h => service/voting/include/dap_chain_net_srv_voting.h} (89%)
 create mode 100644 modules/service/vpn/dap_chain_net_srv_vpn_common.c
 create mode 100644 modules/service/vpn/include/dap_chain_net_srv_vpn_common.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 14bcb0d0ff..cb475b591e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ endif()
 if(NOT DEFINED CELLFRAME_MODULES)
     include (dap-sdk/cmake/OS_Detection.cmake)
 
-    set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-esbocs cs-none srv-app srv-app-db srv-datum srv-stake srv-xchange")
+    set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-esbocs cs-none srv-app srv-app-db srv-datum srv-stake srv-voting srv-bridge srv-xchange")
 
     if(LINUX OR DARWIN)
         set(CELLFRAME_MODULES "${CELLFRAME_MODULES} srv-vpn")
@@ -182,6 +182,19 @@ if (CELLFRAME_MODULES MATCHES "srv-stake")
     set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_stake)
 endif()
 
+
+# Enable service bridge
+if (CELLFRAME_MODULES MATCHES "srv-bridge")
+    message("[+] Module 'srv-bridge'")
+    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_bridge)
+endif()
+
+# Enable service voting
+if (CELLFRAME_MODULES MATCHES "srv-voting")
+    message("[+] Module 'srv-voting'")
+    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_voting)
+endif()
+
 # Enable service for dynamic modules
 if (CELLFRAME_MODULES MATCHES "modules-dynamic")
     message("[+] Module 'dap_modules_dynamic_cdb'")
diff --git a/dap-sdk b/dap-sdk
index 952c219fe0..72796e25f1 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 952c219fe0a702543bdf24728bc43aca288ee047
+Subproject commit 72796e25f1a7e792200c24e109b50d94ee7f5fd5
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index 1aca3bdd4b..3b4079665a 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -20,7 +20,6 @@ if (CELLFRAME_MODULES MATCHES "network")
     add_subdirectory(mempool)
     add_subdirectory(net)
     add_subdirectory(net/srv)
-    add_subdirectory(json_rpc)
     # Stream channels
     add_subdirectory(channel/chain-net)
 endif()
@@ -110,7 +109,12 @@ if (CELLFRAME_MODULES MATCHES "srv-stake")
     add_subdirectory(service/stake)
 endif()
 
-# Unit tests
-if( BUILD_TESTS)
-    add_subdirectory(test)
+# Service for polls and voting
+if (CELLFRAME_MODULES MATCHES "srv-voting")
+    add_subdirectory(service/voting)
+endif()
+
+# Service for bridge
+if (CELLFRAME_MODULES MATCHES "srv-bridge")
+    add_subdirectory(service/bridge)
 endif()
diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c
index 0de1b65491..81246a5e86 100644
--- a/modules/chain/tests/dap_chain_ledger_tests.c
+++ b/modules/chain/tests/dap_chain_ledger_tests.c
@@ -18,7 +18,7 @@ dap_chain_datum_token_t  *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert,
     l_token->version = 2;
     l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL;
     l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE;
-    dap_snprintf(l_token->ticker, sizeof(l_token->ticker), "%s", a_token_ticker);
+    snprintf(l_token->ticker, sizeof(l_token->ticker), "%s", a_token_ticker);
     l_token->signs_valid = 1;
     l_token->total_supply = a_total_supply;
     l_token->header_native_decl.decimals = 18;
@@ -368,7 +368,7 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert,
 void dap_ledger_test_run(void){
     dap_chain_net_srv_stake_pos_delegate_init();
     dap_chain_net_id_t l_iddn = {0};
-    dap_sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64);
+    sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64);
     dap_print_module_name("dap_ledger");
     uint16_t l_flags = 0;
     l_flags |= DAP_LEDGER_CHECK_TOKEN_EMISSION;
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index a199d448f9..4bcb099019 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -823,7 +823,7 @@ void s_set_usage_data_to_gdb(const dap_chain_net_srv_usage_t *a_usage)
     client_statistic_value_t l_bin_value_new = {0};
     size_t l_value_size = 0;
     // forming key
-    dap_sprintf(l_bin_key.key, "0x%016"DAP_UINT64_FORMAT_X"", a_usage->service->uid.uint64);
+    sprintf(l_bin_key.key, "0x%016"DAP_UINT64_FORMAT_X"", a_usage->service->uid.uint64);
     dap_chain_hash_fast_to_str_do(&a_usage->client_pkey_hash, l_bin_key.key + 18);
     // check writed value
     client_statistic_value_t *l_bin_value = (client_statistic_value_t *)dap_global_db_get_sync(SRV_STATISTIC_GDB_GROUP, l_bin_key.key, &l_value_size, NULL, NULL);
diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c
index fe7747c579..d3351160e6 100644
--- a/modules/common/dap_chain_common.c
+++ b/modules/common/dap_chain_common.c
@@ -52,14 +52,15 @@ size_t dap_chain_hash_slow_to_str( dap_chain_hash_slow_t *a_hash, char *a_str, s
 {
     const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */;
 
-    if(a_str_max < c_hash_str_size) {
+    if (a_str_max < c_hash_str_size) {
         log_it(L_ERROR, "String for hash too small, need %zu but have only %zu", c_hash_str_size, a_str_max);
+        return 0;
     }
     size_t i;
-    snprintf(a_str, 3, "0x");
+    sprintf(a_str, "0x");
 
-    for(i = 0; i < sizeof(a_hash->raw); ++i)
-        snprintf( a_str + i * 2 + 2, 3, "%02x", a_hash->raw[i] );
+    for (i = 0; i < sizeof(a_hash->raw); ++i)
+        sprintf( a_str + i * 2 + 2, "%02x", a_hash->raw[i] );
 
     a_str[c_hash_str_size] = '\0';
 
diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c
index b991151950..54d06bfa03 100644
--- a/modules/common/dap_chain_datum.c
+++ b/modules/common/dap_chain_datum.c
@@ -34,6 +34,7 @@
 #include "dap_chain_datum_tx_voting.h"
 #include "dap_chain_datum_hashtree_roots.h"
 #include "dap_enc_base58.h"
+#include "dap_sign.h"
 
 #define LOG_TAG "dap_chain_datum"
 
@@ -369,7 +370,7 @@ void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datu
             continue;
         default: {
                 char l_tsd_type_char[50] = {};
-                dap_snprintf(l_tsd_type_char, 50, "<0x%04hX>", l_tsd->type);
+                snprintf(l_tsd_type_char, 50, "<0x%04hX>", l_tsd->type);
                 json_object_object_add(json_obj_out, "tsd_type", json_object_new_string(l_tsd_type_char));
                 json_object_object_add(json_obj_out, "tsd_size", json_object_new_int(l_tsd->size));
             }
@@ -698,6 +699,320 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
     return true;
 }
 
+/**
+ * @brief _dap_chain_datum_tx_out_data
+ *
+ * @param a_datum
+ * @param a_ledger
+ * @param a_str_out
+ * @param a_hash_out_type
+ * @param save_processed_tx
+ * @param a_tx_hash_processed
+ * @param l_tx_num
+ */
+bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
+                             const char *a_ticker,
+                             json_object* json_obj_out,
+                             const char *a_hash_out_type,
+                             dap_hash_fast_t *a_tx_hash,
+                             dap_chain_net_id_t a_net_id)
+{
+    bool l_is_first = false;
+    dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, TX_ITEM_TYPE_IN, NULL);
+    if (l_in_item && dap_hash_fast_is_blank(&l_in_item->header.tx_prev_hash))
+        l_is_first = true;
+    char l_tmp_buf[DAP_TIME_STR_SIZE];
+    const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+            ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash)
+            : dap_chain_hash_fast_to_str_static(a_tx_hash);
+    json_object* json_arr_items = json_object_new_array();
+    dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_datum->header.ts_created);
+    l_is_first ? 
+    json_object_object_add(json_obj_out, "first transaction", json_object_new_string("emit")):
+    json_object_object_add(json_obj_out, "first transaction", json_object_new_string(""));
+    json_object_object_add(json_obj_out, "hash", json_object_new_string(l_hash_str));
+    json_object_object_add(json_obj_out, "TS Created", json_object_new_string(l_tmp_buf));
+    json_object_object_add(json_obj_out, "Token ticker", a_ticker ? json_object_new_string(a_ticker) : json_object_new_string(""));
+    //json_object_array_add(json_arr_items, json_obj_tx);
+    
+    uint32_t l_tx_items_count = 0;
+    uint32_t l_tx_items_size = a_datum->header.tx_items_size;
+    dap_hash_fast_t *l_hash_tmp = NULL;
+    while (l_tx_items_count < l_tx_items_size) {
+        json_object* json_obj_item = json_object_new_object();
+        uint8_t *item = a_datum->tx_items + l_tx_items_count;
+        size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item);
+        switch(dap_chain_datum_tx_item_get_type(item)){
+        case TX_ITEM_TYPE_IN:
+            l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
+            if (dap_hash_fast_is_blank(l_hash_tmp)) {
+                l_hash_str = "BLANK";
+            } else {
+                l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                        ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                        : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+            }
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("IN"));
+            json_object_object_add(json_obj_item,"Tx prev hash", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_item,"Tx out prev idx", json_object_new_uint64(((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx));
+            break;
+        case TX_ITEM_TYPE_OUT_OLD: {
+            const char *l_value_str = dap_uint256_to_char(
+                dap_chain_uint256_from(((dap_chain_tx_out_old_t*)item)->header.value), NULL );
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT OLD"));
+            json_object_object_add(json_obj_item,"Value", json_object_new_uint64(((dap_chain_tx_out_old_t*)item)->header.value));
+            json_object_object_add(json_obj_item,"Address", json_object_new_string(dap_chain_addr_to_str(&((dap_chain_tx_out_old_t*)item)->addr)));
+        } break;
+        case TX_ITEM_TYPE_OUT: { // 256
+            const char *l_coins_str,
+                    *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str),
+                    *l_addr_str = dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT"));
+            json_object_object_add(json_obj_item,"Coins", json_object_new_string(l_coins_str));
+            json_object_object_add(json_obj_item,"Value", json_object_new_string(l_value_str));
+            json_object_object_add(json_obj_item,"Address", json_object_new_string(l_addr_str));            
+        } break;
+        case TX_ITEM_TYPE_IN_EMS: {
+            char l_tmp_buff[70]={0};
+            l_hash_tmp = &((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash;
+            l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_EMS"));
+            json_object_object_add(json_obj_item,"ticker", json_object_new_string(((dap_chain_tx_in_ems_t*)item)->header.ticker));
+            json_object_object_add(json_obj_item,"token_emission_hash", json_object_new_string(l_hash_str));
+            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_in_ems_t*)item)->header.token_emission_chain_id.uint64);
+            json_object_object_add(json_obj_item,"token_emission_chain_id", json_object_new_string(l_tmp_buff));
+        } break;
+            /*
+        case TX_ITEM_TYPE_IN_EMS_EXT: {
+            l_hash_tmp = &((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_hash;
+            l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str(l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_new(l_hash_tmp);
+            dap_string_append_printf(a_str_out, "\t IN_EMS EXT:\n"
+                                         "\t\t Version: %u\n"
+                                         "\t\t Ticker: %s\n"
+                                         "\t\t Ext chain id: 0x%016"DAP_UINT64_FORMAT_x"\n"
+                                         "\t\t Ext net id: 0x%016"DAP_UINT64_FORMAT_x"\n"
+                                         "\t\t Ext tx hash: %s\n"
+                                         "\t\t Ext tx out idx: %u\n",
+                                     ((dap_chain_tx_in_ems_ext_t*)item)->header.version,
+                                     ((dap_chain_tx_in_ems_ext_t*)item)->header.ticker,
+                                     ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_chain_id.uint64,
+                                     ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_net_id.uint64,
+                                     l_hash_str,
+                                     ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_out_idx);
+            DAP_DELETE(l_hash_str);
+        } break; */
+
+        case TX_ITEM_TYPE_IN_REWARD: {
+            l_hash_tmp = &((dap_chain_tx_in_reward_t *)item)->block_hash;
+            l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_REWARD"));
+            json_object_object_add(json_obj_item,"block_hash", json_object_new_string(l_hash_str));
+        } break;
+
+        case TX_ITEM_TYPE_SIG: {
+            dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("SIG"));
+            dap_sign_get_information_json(l_sign, json_obj_item, a_hash_out_type);
+            dap_chain_addr_t l_sender_addr;
+            dap_chain_addr_fill_from_sign(&l_sender_addr, l_sign, a_net_id);
+            json_object_object_add(json_obj_item,"Sender addr", json_object_new_string(dap_chain_addr_to_str(&l_sender_addr)));            
+        } break;
+        case TX_ITEM_TYPE_RECEIPT: {
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("RECEIPT"));
+            json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->size));
+            json_object_object_add(json_obj_item,"ext size", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->exts_size));
+            json_object_object_add(json_obj_item,"INFO", json_object_new_string(""));
+            json_object_object_add(json_obj_item,"units", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units));
+            json_object_object_add(json_obj_item,"uid", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.srv_uid.uint64));
+            json_object_object_add(json_obj_item,"units type", json_object_new_string(dap_chain_srv_unit_enum_to_str(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units_type.enm)));
+            json_object_object_add(json_obj_item,"coins", json_object_new_string(l_coins_str));
+            json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str));
+
+            json_object_object_add(json_obj_item,"Exts",json_object_new_string(""));                         
+            switch ( ((dap_chain_datum_tx_receipt_t*)item)->exts_size ) {
+            case (sizeof(dap_sign_t) * 2): {
+                dap_sign_t *l_client = DAP_CAST_PTR( dap_sign_t, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs + sizeof(dap_sign_t) );
+                json_object_object_add(json_obj_item,"Client", json_object_new_string(""));
+                dap_sign_get_information_json(l_client, json_obj_item, a_hash_out_type);                
+            }
+            case (sizeof(dap_sign_t)): {
+                dap_sign_t *l_provider = DAP_CAST_PTR( dap_sign_t, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs );
+                json_object_object_add(json_obj_item,"Provider", json_object_new_string(""));
+                dap_sign_get_information_json(l_provider,json_obj_item, a_hash_out_type);
+                break;
+            }
+            }
+        } break;
+        case TX_ITEM_TYPE_PKEY: {
+            dap_pkey_t *l_pkey = (dap_pkey_t*)((dap_chain_tx_pkey_t*)item)->pkey;
+            dap_chain_hash_fast_t l_pkey_hash;
+            dap_hash_fast(l_pkey->pkey, l_pkey->header.size, &l_pkey_hash);
+            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(json_obj_item,"item type", json_object_new_string("PKey"));
+            json_object_object_add(json_obj_item,"PKey", json_object_new_string(""));
+            json_object_object_add(json_obj_item,"SIG type", json_object_new_string(dap_sign_type_to_str(((dap_chain_tx_pkey_t*)item)->header.sig_type)));
+            json_object_object_add(json_obj_item,"SIG size", json_object_new_uint64(((dap_chain_tx_pkey_t*)item)->header.sig_size));
+            json_object_object_add(json_obj_item,"Sequence number", json_object_new_uint64(((dap_chain_tx_pkey_t*)item)->seq_no));
+            json_object_object_add(json_obj_item,"Key", json_object_new_string(""));
+            json_object_object_add(json_obj_item,"Type", json_object_new_string(dap_pkey_type_to_str(l_pkey->header.type)));
+            json_object_object_add(json_obj_item,"Size", json_object_new_uint64(l_pkey->header.size));
+            json_object_object_add(json_obj_item,"Hash", json_object_new_string(l_hash_str));
+
+        } break;
+        case TX_ITEM_TYPE_TSD: {
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("TSD data"));
+            json_object_object_add(json_obj_item,"type", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.type));
+            json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.size));            
+        } break;
+        case TX_ITEM_TYPE_IN_COND:
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("IN COND"));
+            l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
+            l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                    ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                    : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+            json_object_object_add(json_obj_item,"Receipt_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.receipt_idx));
+            json_object_object_add(json_obj_item,"Tx_prev_hash", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_item,"Tx_out_prev_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx));
+            break;
+        case TX_ITEM_TYPE_OUT_COND: {
+            char l_tmp_buff[70]={0};
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT COND"));
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str);
+            dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires;
+            dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp);
+            json_object_object_add(json_obj_item,"Header", json_object_new_string(""));
+            json_object_object_add(json_obj_item,"ts_expires", l_ts_exp ? json_object_new_string(l_tmp_buf) : json_object_new_string("never"));
+            json_object_object_add(json_obj_item,"coins", json_object_new_string(l_coins_str));
+            json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str));
+            json_object_object_add(json_obj_item,"subtype", json_object_new_string(dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype)));
+            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64);
+            json_object_object_add(json_obj_item,"uid", json_object_new_string(l_tmp_buff));
+            switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
+                    const char *l_coins_str, *l_value_str =
+                        dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str );
+                    l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
+                    l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    sprintf(l_tmp_buff,"0x%08x",((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32);
+                    json_object_object_add(json_obj_item,"unit", json_object_new_string(l_tmp_buff));
+                    json_object_object_add(json_obj_item,"pkey", json_object_new_string(l_hash_str));
+                    json_object_object_add(json_obj_item,"max price(coins)", json_object_new_string(l_coins_str));
+                    json_object_object_add(json_obj_item,"max price(value)", json_object_new_string(l_value_str));
+
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: {
+                    dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr;
+                    dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr;
+                    l_hash_tmp = &l_signing_addr->data.hash_fast;
+                    l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+                            ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp)
+                            : dap_chain_hash_fast_to_str_static(l_hash_tmp);
+                    json_object_object_add(json_obj_item,"signing_addr", json_object_new_string(dap_chain_addr_to_str(l_signing_addr)));
+                    json_object_object_add(json_obj_item,"with pkey hash", json_object_new_string(l_hash_str));                    
+                    sprintf(l_tmp_buff,""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS(l_signer_node_addr));
+                    json_object_object_add(json_obj_item,"signer_node_addr", json_object_new_string(l_tmp_buff));
+                    
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
+                    const char *l_rate_str, *l_tmp_str =
+                        dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str );
+                    sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64);
+                    json_object_object_add(json_obj_item,"net id", json_object_new_string(l_tmp_buff));
+                    json_object_object_add(json_obj_item,"buy_token", json_object_new_string(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token));
+                    json_object_object_add(json_obj_item,"rate", json_object_new_string(l_rate_str));
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: {
+                    dap_time_t l_ts_unlock = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_lock.time_unlock;
+                    dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_unlock);
+                    json_object_object_add(json_obj_item,"time_unlock", json_object_new_string(l_tmp_buf));
+                } break;
+                default: break;
+            }
+        } break;
+        case TX_ITEM_TYPE_OUT_EXT: {
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str );
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT EXT"));
+            json_object_object_add(json_obj_item,"Addr", json_object_new_string(dap_chain_addr_to_str(&((dap_chain_tx_out_ext_t*)item)->addr)));
+            json_object_object_add(json_obj_item,"Token", json_object_new_string(((dap_chain_tx_out_ext_t*)item)->token));
+            json_object_object_add(json_obj_item,"Coins", json_object_new_string(l_coins_str));
+            json_object_object_add(json_obj_item,"Value", json_object_new_string(l_value_str));
+            
+        } break;
+        case TX_ITEM_TYPE_VOTING:{
+            char l_tmp_buff[10]={0};
+            int l_tsd_size = 0;
+            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, 0, TX_ITEM_TYPE_TSD, &l_tsd_size);
+            if (!l_item || !l_tsd_size)
+                    break;
+            dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_voting_parse_tsd(a_datum);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("VOTING"));
+            json_object_object_add(json_obj_item,"Voting question", json_object_new_string(l_voting_params->voting_question));
+            json_object_object_add(json_obj_item,"Answer options", json_object_new_string(""));
+            
+            dap_list_t *l_temp = l_voting_params->answers_list;
+            uint8_t l_index = 0;
+            while (l_temp) {
+                sprintf(l_tmp_buff, "%i", l_index);
+                json_object_object_add(json_obj_item, l_tmp_buff, json_object_new_string((char *)l_temp->data));
+                l_index++;
+                l_temp = l_temp->next;
+            }
+            if (l_voting_params->voting_expire) {
+                dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting_params->voting_expire);
+                json_object_object_add(json_obj_item,"Voting expire", json_object_new_string(l_tmp_buf));                
+            }
+            if (l_voting_params->votes_max_count) {
+                sprintf(l_tmp_buff, "%"DAP_UINT64_FORMAT_U, l_voting_params->votes_max_count);
+                json_object_object_add(json_obj_item, "Votes max count", json_object_new_string(l_tmp_buff));
+            }
+            json_object_object_add(json_obj_item,"Changing vote is", l_voting_params->vote_changing_allowed ? json_object_new_string("available") : 
+                                    json_object_new_string("not available"));
+            l_voting_params->delegate_key_required ? 
+                json_object_object_add(json_obj_item,"Votes max count", json_object_new_string("A delegated key is required to participate in voting.")):
+                json_object_object_add(json_obj_item,"Votes max count", json_object_new_string("A delegated key is not required to participate in voting."));                 
+
+            dap_list_free_full(l_voting_params->answers_list, NULL);
+            DAP_DELETE(l_voting_params->voting_question);
+            DAP_DELETE(l_voting_params);
+        } break;
+        case TX_ITEM_TYPE_VOTE:{
+            char l_tmp_buff[10]={0};
+            dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item;
+            const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash);
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("VOTE"));
+            json_object_object_add(json_obj_item,"Voting hash", json_object_new_string(l_hash_str));
+            sprintf(l_tmp_buff,"%"DAP_UINT64_FORMAT_U"",l_vote_item->answer_idx);
+            json_object_object_add(json_obj_item,"Vote answer idx", json_object_new_string(l_tmp_buff));
+
+        } break;
+        default:
+            json_object_object_add(json_obj_item,"item type", json_object_new_string("This transaction have unknown item type"));
+            break;
+        }
+        json_object_array_add(json_arr_items, json_obj_item);
+        l_tx_items_count += l_item_tx_size;
+        // Freeze protection
+        if(!l_item_tx_size)
+        {
+            break;
+        }
+
+    }
+    json_object_object_add(json_obj_out, "ITEMS", json_arr_items);
+    return true;
+}
+
 /**
  * @brief dap_chain_net_dump_datum
  * process datum verification process. Can be:
@@ -889,3 +1204,212 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c
         } break;
     }    
 }
+
+
+
+/**
+ * @brief dap_chain_net_dump_datum
+ * process datum verification process. Can be:
+ * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check
+ * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check
+ * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check
+ * @param a_obj_out
+ * @param a_datum
+ */
+void dap_chain_datum_dump_json(json_object  *a_obj_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id)
+{
+    if( a_datum == NULL){
+        dap_json_rpc_error_add(-1,"==Datum is NULL");
+        return;
+    }
+    json_object * json_obj_datum = json_object_new_object();
+    dap_hash_fast_t l_datum_hash;
+    dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash);
+    const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex")
+            ? dap_enc_base58_encode_hash_to_str_static(&l_datum_hash)
+            : dap_chain_hash_fast_to_str_static(&l_datum_hash);
+    switch (a_datum->header.type_id) {
+        case DAP_CHAIN_DATUM_TOKEN_DECL: {
+            size_t l_token_size = a_datum->header.data_size;
+            dap_chain_datum_token_t * l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size);
+            if(l_token_size < sizeof(dap_chain_datum_token_t)){
+                dap_json_rpc_error_add(-2,"==Datum has incorrect size. Only %zu, while at least %zu is expected\n",
+                                         l_token_size, sizeof(dap_chain_datum_token_t));
+                DAP_DEL_Z(l_token);
+                return;
+            }
+            json_object_object_add(json_obj_datum,"=== Datum Token Declaration ===",json_object_new_string("empty"));
+            json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_datum,"ticker",json_object_new_string(l_token->ticker));
+            json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_token_size));
+            json_object_object_add(json_obj_datum,"version",json_object_new_int(l_token->version));
+            
+            switch (l_token->type) {
+                case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: {
+                    json_object_object_add(json_obj_datum,"type",json_object_new_string("DECL"));
+                    switch (l_token->subtype) {
+                        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:{
+                            json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PRIVATE"));
+                            json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_private_decl.decimals));
+                            json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid));
+                            json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total));
+                            json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL)));
+                            json_object_object_add(json_obj_datum,"Flags",json_object_new_string(""));
+
+                            dap_chain_datum_token_flags_dump_to_json(json_obj_datum,l_token->header_private_update.flags);
+                            dap_datum_token_dump_tsd_to_json(json_obj_datum,l_token, l_token_size, a_hash_out_type);               
+                            size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size;
+                            dap_chain_datum_token_certs_dump_to_json(json_obj_datum,l_token->data_n_tsd + l_token->header_private_update.tsd_total_size,
+                                                             l_certs_field_size, a_hash_out_type);                            
+                        } break;
+                        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: {
+                            json_object_object_add(json_obj_datum,"subtype",json_object_new_string("CF20"));
+                            json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_native_decl.decimals));
+                            json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid));
+                            json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total));
+                            json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL)));
+                            json_object_object_add(json_obj_datum,"Flags",json_object_new_string(""));
+
+                            dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_decl.flags);
+                            dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type);
+                            size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_decl.tsd_total_size;
+                            dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_decl.tsd_total_size,
+                                                             l_certs_field_size, a_hash_out_type);
+                        } break;
+                        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: {
+                            dap_chain_addr_t l_premine_addr = l_token->header_public.premine_address;
+                            json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PUBLIC"));
+                            json_object_object_add(json_obj_datum,"premine_supply", json_object_new_string(dap_uint256_to_char(l_token->header_public.premine_supply, NULL)));
+                            json_object_object_add(json_obj_datum,"premine_address", json_object_new_string(dap_chain_addr_to_str(&l_premine_addr)));
+
+                            json_object_object_add(json_obj_datum,"Flags",json_object_new_string(""));
+                            dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_public.flags);
+                        } break;
+                    }
+                } break;
+                case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: {
+                    json_object_object_add(json_obj_datum,"type",json_object_new_string("UPDATE"));
+                    switch (l_token->subtype) {
+                        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: {
+                            json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PRIVATE"));
+                            json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_private_decl.decimals));
+                            json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid));
+                            json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total));
+                            json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL)));
+                            
+                            json_object_object_add(json_obj_datum,"Flags",json_object_new_string(""));
+                            dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_private_update.flags);
+                            dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type);
+                            size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size;
+                            dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_private_update.tsd_total_size,
+                                                             l_certs_field_size, a_hash_out_type);
+                        } break;
+                        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: {
+                            json_object_object_add(json_obj_datum,"subtype", json_object_new_string("CF20"));
+                            json_object_object_add(json_obj_datum,"decimals", json_object_new_uint64(l_token->header_native_update.decimals));
+                            json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid));
+                            json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total));
+                            json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL)));
+                            
+                            json_object_object_add(json_obj_datum,"Flags",json_object_new_string(""));
+                            dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_update.flags);
+                            dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type);
+                            size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_update.tsd_total_size;
+                            dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_update.tsd_total_size,
+                                                             l_certs_field_size, a_hash_out_type);
+                        } break;
+                    }
+                } break;
+                default:
+                    json_object_object_add(json_obj_datum,"type", json_object_new_string("UNKNOWN"));
+                    break;
+            }
+            if (l_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE ) {
+                json_object_object_add(json_obj_datum,"subtype", json_object_new_string("SIMPLE"));
+                json_object_object_add(json_obj_datum,"decimals", json_object_new_uint64(l_token->header_simple.decimals));
+                json_object_object_add(json_obj_datum,"sign_total", json_object_new_uint64(l_token->signs_total));
+                json_object_object_add(json_obj_datum,"sign_valid", json_object_new_uint64(l_token->signs_valid));
+                json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL)));
+                
+                size_t l_certs_field_size = l_token_size - sizeof(*l_token);
+                dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd,
+                                                 l_certs_field_size, a_hash_out_type);
+            }
+            DAP_DELETE(l_token);
+        } break;
+        case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
+            size_t l_emission_size = a_datum->header.data_size;
+            dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size);
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str);
+            json_object_object_add(json_obj_datum,"emission hash", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_datum,"coins", json_object_new_string(l_coins_str));
+            json_object_object_add(json_obj_datum,"value", json_object_new_string(l_value_str));
+            json_object_object_add(json_obj_datum,"ticker", json_object_new_string(l_emission->hdr.ticker));
+            json_object_object_add(json_obj_datum,"type", json_object_new_string(c_dap_chain_datum_token_emission_type_str[l_emission->hdr.type]));
+            json_object_object_add(json_obj_datum,"version", json_object_new_uint64(l_emission->hdr.version));
+            json_object_object_add(json_obj_datum,"to addr", json_object_new_string(dap_chain_addr_to_str(&(l_emission->hdr.address))));
+
+            switch (l_emission->hdr.type) {
+            case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:
+                json_object_object_add(json_obj_datum,"signs_count", json_object_new_uint64(l_emission->data.type_auth.signs_count));
+                json_object_object_add(json_obj_datum,"tsd_total_size", json_object_new_uint64(l_emission->data.type_auth.tsd_total_size));
+
+                if (  ( (void *) l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size) >
+                      ((void *) l_emission + l_emission_size) )
+                {
+                    log_it(L_ERROR, "Illformed DATUM type %d, TSD section is out-of-buffer (%" DAP_UINT64_FORMAT_U " vs %zu)",
+                        l_emission->hdr.type, l_emission->data.type_auth.tsd_total_size, l_emission_size);
+                    dap_json_rpc_error_add(-3,"Skip incorrect or illformed DATUM");
+                    break;
+                }
+                dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size,
+                                                l_emission->data.type_auth.size - l_emission->data.type_auth.tsd_total_size, a_hash_out_type);
+                break;
+            case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO:
+                json_object_object_add(json_obj_datum,"codename",json_object_new_string(l_emission->data.type_algo.codename));
+                break;
+            case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: {
+                char l_time_str[32];
+                char l_flags[50] = {};
+                // get time of create datum
+                if(dap_time_to_str_rfc822(l_time_str, sizeof(l_time_str), l_emission->data.type_presale.lock_time) < 1)
+                        l_time_str[0] = '\0';                        
+                snprintf(l_flags, 50, "0x%x", l_emission->data.type_presale.flags);
+                json_object_object_add(json_obj_datum,"flags", json_object_new_string(l_flags));
+                json_object_object_add(json_obj_datum,"lock_time", json_object_new_string(l_time_str));
+                json_object_object_add(json_obj_datum,"addr", json_object_new_string(dap_chain_addr_to_str(&l_emission->data.type_presale.addr)));                
+            }
+            case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER:
+            case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED:
+            default:
+                break;
+            }
+            DAP_DELETE(l_emission);
+        } break;
+        case DAP_CHAIN_DATUM_TX: {
+            dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)a_datum->data;
+            dap_chain_datum_dump_tx_json(l_tx, NULL, json_obj_datum, a_hash_out_type, &l_datum_hash, a_net_id);
+        } break;
+        case DAP_CHAIN_DATUM_DECREE:{
+            dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data;
+            size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree);
+            json_object_object_add(json_obj_datum,"=== Datum decree ===",json_object_new_string("empty"));
+            json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_decree_size));
+            dap_chain_datum_decree_dump_json(json_obj_datum, l_decree, l_decree_size, a_hash_out_type);
+        } break;
+        case DAP_CHAIN_DATUM_ANCHOR:{
+            dap_chain_datum_anchor_t *l_anchor = (dap_chain_datum_anchor_t *)a_datum->data;
+            size_t l_anchor_size = sizeof(dap_chain_datum_anchor_t) + l_anchor->header.data_size + l_anchor->header.signs_size;
+            json_object_object_add(json_obj_datum,"=== Datum anchor ===",json_object_new_string("empty"));
+            json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_anchor_size));
+            dap_hash_fast_t l_decree_hash = { };
+            dap_chain_datum_anchor_get_hash_from_data(l_anchor, &l_decree_hash);
+            l_hash_str = dap_chain_hash_fast_to_str_static(&l_decree_hash);
+            json_object_object_add(json_obj_datum,"decree hash",json_object_new_string(l_hash_str));
+            dap_chain_datum_anchor_certs_dump_json(json_obj_datum,l_anchor->data_n_sign + l_anchor->header.data_size, l_anchor->header.signs_size, a_hash_out_type);
+        } break;
+    }  
+    json_object_object_add(a_obj_out,"Datum",json_obj_datum);  
+}
diff --git a/modules/common/dap_chain_datum_anchor.c b/modules/common/dap_chain_datum_anchor.c
index 58cdc378b7..a87618bb02 100644
--- a/modules/common/dap_chain_datum_anchor.c
+++ b/modules/common/dap_chain_datum_anchor.c
@@ -90,3 +90,41 @@ void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
                                  dap_sign_type_to_str(l_sign->header.type), l_sign->header.sign_size);
     }
 }
+
+void dap_chain_datum_anchor_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type)
+{
+    json_object_object_add(a_json_out, "signatures", json_object_new_string(""));
+    if (!a_certs_size) {
+        json_object_object_add(a_json_out, "Cert status", json_object_new_string("NONE"));
+        return;
+    }
+    json_object* json_arr_certs_out = json_object_new_array();    
+    size_t l_offset = 0;
+    for (int i = 1; l_offset < (a_certs_size); i++) {
+        json_object* json_obj_sign = json_object_new_object();
+        dap_sign_t *l_sign = (dap_sign_t*)(a_signs + l_offset);
+        l_offset += dap_sign_get_size(l_sign);
+        if (l_sign->header.sign_size == 0) {
+            json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - 0 size signature"));
+            json_object_array_add(json_arr_certs_out, json_obj_sign);
+            continue;
+        }
+
+        dap_chain_hash_fast_t l_pkey_hash = {0};
+        if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) {
+            json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - can't calc hash"));
+            json_object_array_add(json_arr_certs_out, json_obj_sign);
+            continue;
+        }
+        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(json_obj_sign, "sign #", json_object_new_uint64(i));
+        json_object_object_add(json_obj_sign, "hash", json_object_new_string(l_hash_str));
+        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, "sign size", json_object_new_uint64(l_sign->header.sign_size));
+        json_object_array_add(json_arr_certs_out, json_obj_sign); 
+    }
+    json_object_object_add(a_json_out,"SIGNS",json_arr_certs_out);
+}
+
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index d3c060befb..951b8d0474 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -113,7 +113,7 @@ int dap_chain_datum_decree_get_stake_signing_addr(dap_chain_datum_decree_t *a_de
 int dap_chain_datum_decree_get_stake_signer_node_addr(dap_chain_datum_decree_t *a_decree, dap_chain_node_addr_t *a_node_addr)
 {
     dap_return_val_if_fail(a_decree && a_node_addr, -1);
-    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR);
     return l_tsd && l_tsd->size == sizeof(dap_chain_node_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_node_addr); 0; }) : 1;
 }
 
@@ -150,7 +150,7 @@ int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, cons
     dap_return_val_if_fail(a_decree && a_addr, -1);
     dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST);
     if (!l_tsd)
-        l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR);
+        l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING);
     return l_tsd ? ({ *a_addr = dap_tsd_get_string_const(l_tsd); !dap_strcmp(*a_addr, DAP_TSD_CORRUPTED_STRING); }) : 1;
 }
 
@@ -264,7 +264,6 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                         : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
                 dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR:
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
                 if(l_tsd->size > sizeof(dap_chain_node_addr_t)){
                     dap_string_append_printf(a_str_out, "\tNode addr: <WRONG SIZE>\n");
@@ -294,9 +293,10 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
                 const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
                 dap_string_append_printf(a_str_out, "\tMin signers count: %s\n", l_min_signers_count_str);
                 break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: {
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
                 dap_string_append_printf(a_str_out, "\tHost address: %s\n", dap_tsd_get_string(l_tsd));
-            } break;
+                break;
             case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
                 if (l_tsd->size != sizeof(uint8_t)){
                     dap_string_append_printf(a_str_out, "\tAction: <WRONG SIZE>\n");
@@ -358,6 +358,217 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign
     }
 }
 
+void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type)
+{
+    char *l_type_str = "";
+    char l_tmp_buff[70]={0};
+    switch(a_decree->header.type)
+    {
+        case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:
+            l_type_str = "DECREE_TYPE_COMMON";
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:
+            l_type_str = "DECREE_TYPE_SERVICE";
+            break;
+        default:
+            l_type_str = "DECREE_TYPE_UNKNOWN";
+    }
+    json_object_object_add(a_json_out, "type", json_object_new_string(l_type_str));
+    const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type);
+    json_object_object_add(a_json_out, "subtype", json_object_new_string(l_subtype_str));
+    json_object_object_add(a_json_out, "TSD", json_object_new_string(""));
+    for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) {
+        dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset);
+        l_offset += dap_tsd_size(l_tsd);
+        switch(l_tsd->type) {
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE:
+                if (l_tsd->size > sizeof(uint256_t)){
+                    json_object_object_add(a_json_out, "Value", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_value = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_value);
+                const char *l_value_str = dap_uint256_to_char(l_value, NULL);
+                json_object_object_add(a_json_out, "Value", json_object_new_string(l_value_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN:
+            break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE:
+                if (l_tsd->size > sizeof(uint256_t)){
+                    json_object_object_add(a_json_out, "Fee", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_fee_value = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_fee_value);
+                const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL);
+                json_object_object_add(a_json_out, "Fee", json_object_new_string(l_fee_value_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER:
+                if (l_tsd->size < sizeof(dap_pkey_t)) {
+                    json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size);
+                memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t);
+                char *l_owner_pkey_str;
+                dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str);
+                json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(l_owner_pkey_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER:
+                if (l_tsd->size > sizeof(uint256_t)){
+                    json_object_object_add(a_json_out, "Owner min", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_owner_min = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_owner_min);
+                const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL);
+                json_object_object_add(a_json_out, "Owner min", json_object_new_string(l_owner_min_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET:
+                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
+                    json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                dap_chain_addr_t *l_addr_fee_wallet = /*{ };
+                _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+                json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string(dap_chain_addr_to_str(l_addr_fee_wallet)));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH:
+                if (l_tsd->size > sizeof(dap_hash_fast_t)) {
+                    json_object_object_add(a_json_out, "Stake tx", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                dap_hash_fast_t *l_stake_tx = /*{ };
+                _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t);
+                const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
+                        ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx)
+                        : dap_chain_hash_fast_to_str_static(l_stake_tx);
+                json_object_object_add(a_json_out, "Stake tx", json_object_new_string(l_stake_tx_hash));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE:
+                if (l_tsd->size > sizeof(uint256_t)){
+                    json_object_object_add(a_json_out, "Stake value", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_stake_value = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_stake_value);
+                const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL);
+                json_object_object_add(a_json_out, "Stake value", json_object_new_string(l_stake_value_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
+                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
+                    json_object_object_add(a_json_out, "Signing addr", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                dap_chain_addr_t *l_stake_addr_signing = /*{ };
+                _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t);
+                json_object_object_add(a_json_out, "Signing addr", json_object_new_string(dap_chain_addr_to_str(l_stake_addr_signing)));
+                dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast;
+                const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
+                        ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing)
+                        : dap_chain_hash_fast_to_str_static(&l_pkey_signing);
+                json_object_object_add(a_json_out, "Signing pkey fingerprint", json_object_new_string(l_pkey_signing_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
+                if(l_tsd->size > sizeof(dap_chain_node_addr_t)){
+                    json_object_object_add(a_json_out, "Node addr", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t);
+                sprintf(l_tmp_buff, NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(l_node_addr));
+                json_object_object_add(a_json_out, "Node addr", json_object_new_string(l_tmp_buff));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
+                if (l_tsd->size > sizeof(uint256_t)) {
+                    json_object_object_add(a_json_out, "Min value", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_min_value = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_min_value);
+                const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL);
+                json_object_object_add(a_json_out, "Min value", json_object_new_string(l_min_value_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
+                if (l_tsd->size > sizeof(uint256_t)) {
+                    json_object_object_add(a_json_out, "Min signers count", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint256_t l_min_signers_count = uint256_0;
+                _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
+                const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL);
+                json_object_object_add(a_json_out, "Min signers count", json_object_new_string(l_min_signers_count_str));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
+                json_object_object_add(a_json_out, "Host address", json_object_new_string(dap_tsd_get_string(l_tsd)));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
+                if (l_tsd->size != sizeof(uint8_t)) {
+                    json_object_object_add(a_json_out, "Action", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint8_t l_action = 0;
+                _dap_tsd_get_scalar(l_tsd, &l_action);
+                json_object_object_add(a_json_out, "tAction", l_action ?
+                                           json_object_new_string("add (enable)") : json_object_new_string("delete (disable)"));
+                break;
+            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
+                if (l_tsd->size != sizeof(uint32_t)) {
+                    json_object_object_add(a_json_out, "Signature type", json_object_new_string("WRONG SIZE"));
+                    break;
+                }
+                uint32_t l_type = 0;
+                _dap_tsd_get_scalar(l_tsd, &l_type);
+                dap_sign_type_t l_sign_type = { .type = l_type };
+                json_object_object_add(a_json_out, "Signature type", json_object_new_string(dap_sign_type_to_str(l_sign_type)));
+                break;
+            default:
+                json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string(""));
+                break;
+        }
+    }
+    dap_chain_datum_decree_certs_dump_json(a_json_out, a_decree->data_n_signs + a_decree->header.data_size,
+                                      a_decree->header.signs_size, a_hash_out_type);
+}
+
+void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type)
+{
+    json_object_object_add(a_json_out, "signatures", json_object_new_string(""));
+    if (!a_certs_size) {
+        json_object_object_add(a_json_out, "Cert status", json_object_new_string("NONE"));
+        return;
+    }
+    json_object* json_arr_certs_out = json_object_new_array();
+    size_t l_offset = 0;
+    for (int i = 1; l_offset < (a_certs_size); i++) {
+        json_object* json_obj_sign = json_object_new_object();
+        dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset);
+        l_offset += dap_sign_get_size(l_sign);
+        if (l_sign->header.sign_size == 0) {
+            json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - 0 size signature"));
+            json_object_array_add(json_arr_certs_out, json_obj_sign);
+            continue;
+        }
+
+        dap_chain_hash_fast_t l_pkey_hash = {0};
+        if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) {
+            json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - can't calc hash"));
+            json_object_array_add(json_arr_certs_out, json_obj_sign);
+            continue;
+        }
+
+        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(json_obj_sign, "sign #", json_object_new_uint64(i));
+        json_object_object_add(json_obj_sign, "hash", json_object_new_string(l_hash_str));
+        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, "sign size", json_object_new_uint64(l_sign->header.sign_size));
+        json_object_array_add(json_arr_certs_out, json_obj_sign);        
+    }
+    json_object_object_add(a_json_out,"SIGNS", json_arr_certs_out);
+}
+
 dap_chain_datum_decree_t *dap_chain_datum_decree_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id,
                                                      dap_chain_cell_id_t a_cell_id, size_t a_total_tsd_size)
 {
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 114a3c341a..8828011982 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -34,6 +34,7 @@
 #include "dap_chain_datum_tx_items.h"
 #include "dap_chain_datum_tx_voting.h"
 
+#define LOG_TAG "dap_chain_datum_tx_items"
 
 static size_t dap_chain_tx_in_get_size(const dap_chain_tx_in_t *a_item)
 {
@@ -696,3 +697,152 @@ uint8_t *dap_chain_datum_tx_out_get_by_out_idx(dap_chain_datum_tx_t *a_tx, int a
     return l_ret;
 
 }
+
+void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_items_groups)
+{   
+    if (a_items_groups->items_in) dap_list_free(a_items_groups->items_in);
+    if (a_items_groups->items_in_cond) dap_list_free(a_items_groups->items_in_cond);
+    if (a_items_groups->items_in_reward) dap_list_free(a_items_groups->items_in_reward);
+    if (a_items_groups->items_sig) dap_list_free(a_items_groups->items_sig);
+    if (a_items_groups->items_out) dap_list_free(a_items_groups->items_out);
+    if (a_items_groups->items_out_ext) dap_list_free(a_items_groups->items_out_ext);
+    if (a_items_groups->items_out_cond) dap_list_free(a_items_groups->items_out_cond);
+    if (a_items_groups->items_out_cond_srv_fee) dap_list_free(a_items_groups->items_out_cond_srv_fee);
+    if (a_items_groups->items_out_cond_srv_pay) dap_list_free(a_items_groups->items_out_cond_srv_pay);
+    if (a_items_groups->items_out_cond_srv_xchange) dap_list_free(a_items_groups->items_out_cond_srv_xchange);
+    if (a_items_groups->items_out_cond_srv_stake_pos_delegate) dap_list_free(a_items_groups->items_out_cond_srv_stake_pos_delegate);
+    if (a_items_groups->items_out_cond_srv_stake_lock) dap_list_free(a_items_groups->items_out_cond_srv_stake_lock);
+    if (a_items_groups->items_in_ems) dap_list_free(a_items_groups->items_in_ems);
+    if (a_items_groups->items_vote) dap_list_free(a_items_groups->items_vote);
+    if (a_items_groups->items_voting) dap_list_free(a_items_groups->items_voting);
+    if (a_items_groups->items_tsd) dap_list_free(a_items_groups->items_tsd);
+    if (a_items_groups->items_pkey) dap_list_free(a_items_groups->items_pkey);
+    if (a_items_groups->items_receipt) dap_list_free(a_items_groups->items_receipt);
+    if (a_items_groups->items_unknown) dap_list_free(a_items_groups->items_unknown);
+    if (a_items_groups->items_out_old) dap_list_free(a_items_groups->items_out_old);
+    if (a_items_groups->items_out_cond_unknonwn) dap_list_free(a_items_groups->items_out_cond_unknonwn);
+    if (a_items_groups->items_out_cond_undefined) dap_list_free(a_items_groups->items_out_cond_undefined);
+    if (a_items_groups->items_out_all) dap_list_free(a_items_groups->items_out_all);
+    if (a_items_groups->items_in_all) dap_list_free(a_items_groups->items_in_all);
+}
+
+#define DAP_LIST_SAPPEND(X, Y) X = dap_list_append(X,Y)
+bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_res_group)
+{   
+    
+    if(!a_tx || !a_res_group)
+        return NULL;
+    
+    uint32_t l_tx_items_pos = 0, l_tx_items_size = a_tx->header.tx_items_size;
+
+    int l_item_idx = 0;
+
+    while (l_tx_items_pos < l_tx_items_size) {
+
+        uint8_t *l_item = a_tx->tx_items + l_tx_items_pos;
+        int l_item_size = dap_chain_datum_item_tx_get_size(l_item);
+        
+        if(!l_item_size)
+            return false;
+        
+        dap_chain_tx_item_type_t l_type = dap_chain_datum_tx_item_get_type(l_item);
+        
+        switch (l_type)
+        {
+            case TX_ITEM_TYPE_IN:
+                DAP_LIST_SAPPEND(a_res_group->items_in, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_IN_COND:
+                DAP_LIST_SAPPEND(a_res_group->items_in_cond, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_IN_REWARD:
+                DAP_LIST_SAPPEND(a_res_group->items_in_reward, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_IN_EMS:
+                DAP_LIST_SAPPEND(a_res_group->items_in_ems, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_OUT_OLD:
+                DAP_LIST_SAPPEND(a_res_group->items_out_old, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_OUT_EXT:
+                DAP_LIST_SAPPEND(a_res_group->items_out_ext, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_OUT:
+                DAP_LIST_SAPPEND(a_res_group->items_out, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+                break;
+
+            case TX_ITEM_TYPE_OUT_COND: {
+                switch ( ((dap_chain_tx_out_cond_t *)l_item)->header.subtype )
+                {
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_undefined, l_item);
+                        break;
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_pay, l_item);
+                        break;
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_xchange, l_item);
+                        break;
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_pos_delegate, l_item);
+                        break;
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_fee, l_item);
+                        break;
+                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_lock, l_item);
+                        break;
+                    default:
+                        DAP_LIST_SAPPEND(a_res_group->items_out_cond_unknonwn, l_item);
+                        break;
+                }
+
+                DAP_LIST_SAPPEND(a_res_group->items_out_cond, l_item);
+                DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item);
+                }
+                break;
+
+            case TX_ITEM_TYPE_PKEY:
+                DAP_LIST_SAPPEND(a_res_group->items_pkey, l_item);
+                break;
+            case TX_ITEM_TYPE_SIG:
+                DAP_LIST_SAPPEND(a_res_group->items_sig, l_item);
+                break;
+            case TX_ITEM_TYPE_RECEIPT:
+                DAP_LIST_SAPPEND(a_res_group->items_receipt, l_item);
+                break;
+            case TX_ITEM_TYPE_TSD:
+                DAP_LIST_SAPPEND(a_res_group->items_tsd, l_item);
+                break;
+
+            case TX_ITEM_TYPE_VOTING:
+                DAP_LIST_SAPPEND(a_res_group->items_voting, l_item);
+                break;
+
+            case TX_ITEM_TYPE_VOTE:
+                DAP_LIST_SAPPEND(a_res_group->items_vote, l_item);
+                break;
+            default:
+                DAP_LIST_SAPPEND(a_res_group->items_unknown, l_item);
+        }
+        
+        l_tx_items_pos += l_item_size;
+        l_item_idx++;
+    }
+    
+    return true;
+
+}
diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h
index f7fc580471..d9df56a67e 100644
--- a/modules/common/include/dap_chain_datum.h
+++ b/modules/common/include/dap_chain_datum.h
@@ -160,4 +160,11 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum,
                              const char *a_hash_out_type,
                              dap_hash_fast_t *a_tx_hash,
                              dap_chain_net_id_t a_net_id);
+bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum,
+                             const char *a_ticker,
+                             json_object* json_obj_out,
+                             const char *a_hash_out_type,
+                             dap_hash_fast_t *a_tx_hash,
+                             dap_chain_net_id_t a_net_id);
 json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum);
+void dap_chain_datum_dump_json(json_object  *a_obj_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id);
diff --git a/modules/common/include/dap_chain_datum_anchor.h b/modules/common/include/dap_chain_datum_anchor.h
index 044b8165f6..16c1ab9159 100644
--- a/modules/common/include/dap_chain_datum_anchor.h
+++ b/modules/common/include/dap_chain_datum_anchor.h
@@ -51,3 +51,5 @@ DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_
 int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * l_out_hash);
 void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_signs,
                                        size_t a_certs_size, const char *a_hash_out_type);
+
+void dap_chain_datum_anchor_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type);
diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h
index 5c854559f7..f8f40ea74f 100644
--- a/modules/common/include/dap_chain_datum_decree.h
+++ b/modules/common/include/dap_chain_datum_decree.h
@@ -86,11 +86,11 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH                                0x0107
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE                         0x0108
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR                  0x0109
-#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR              0x0110
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR                           0x0110
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE                     0x0111
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT             0x0112
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST                                0x0113
-#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR                           0x0115
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING                              0x0115
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION                              0x010A
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE                      0x010B
 
@@ -148,16 +148,16 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_
         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR:
         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR";
-    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR:
-        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE:
         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT:
         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST";
-    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
-        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING:
+        return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION:
          return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE:
@@ -279,6 +279,15 @@ int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, cons
  */
 void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type);
 
+/**
+ * @breif dap_chain_datum_decree_dump Dump information about decree
+ * @param a_obj_out pointer to output json object
+ * @param a_decree pointer to decree
+ * @param a_decree_size size data
+ * @param a_hash_out_type
+ */
+void dap_chain_datum_decree_dump_json(json_object  *a_obj_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type);
+
 /**
  * @brief dap_chain_datum_decree_certs_dump compose decree signatures output string
  * @param a_str_out pointer to output text buffer
@@ -287,6 +296,8 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree
  */
 void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type);
 
+void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type);
+
 /**
  * @brief dap_chain_datum_decree_sign_in_cycle
  * sign data (datum_decree) by certificates (1 or more)
diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h
index 4fb52984e1..e993e219a0 100644
--- a/modules/common/include/dap_chain_datum_token.h
+++ b/modules/common/include/dap_chain_datum_token.h
@@ -500,6 +500,22 @@ typedef struct dap_chain_datum_token_emission {
 #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID         0x000F
 #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH      0x0010
 
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING "STAKING"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAIN "CONTRACT"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAINV2 "CONTRACT_NFT"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_HARVEST "HARVEST"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_ADDLIQ "ADDLIQ"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_EMSFIX "EMSFIX"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_BONUS "BONUS"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION "UNSTAKE"
+
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_BRIDGE "BRIDGE"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_TRANSFER "TO_WALLET"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION_OLD "COMISSION"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION "COMMISSION"
+#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_CROSSCHAIN "CROSSCHAIN"
+
+
 extern const char *c_dap_chain_datum_token_emission_type_str[];
 
 /// TDS op funcs
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 396fa43dfb..3473e3ffe8 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -153,6 +153,5 @@ dap_sign_t *dap_chain_datum_tx_get_sign(dap_chain_datum_tx_t *a_tx, int a_sign_n
  */
 int dap_chain_datum_tx_verify_sign(dap_chain_datum_tx_t *a_tx);
 
-//json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx);
 
 int dap_chain_datum_tx_get_fee_value (dap_chain_datum_tx_t *a_tx, uint256_t *a_value);
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index 8c312f097c..b81995e3ff 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -85,6 +85,42 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_
     }
 }
 
+typedef struct dap_chain_datum_tx_item_groups {
+
+    dap_list_t *items_in_all;
+    dap_list_t *items_in;
+    dap_list_t *items_in_cond;
+    dap_list_t *items_in_reward;
+    dap_list_t *items_sig;
+
+    
+    dap_list_t *items_out;
+    dap_list_t *items_out_all;
+    dap_list_t *items_out_old;
+    dap_list_t *items_out_ext;
+    dap_list_t *items_out_cond;
+    dap_list_t *items_out_cond_srv_fee;
+    dap_list_t *items_out_cond_srv_pay;
+    dap_list_t *items_out_cond_srv_xchange;
+    dap_list_t *items_out_cond_srv_stake_pos_delegate;
+    dap_list_t *items_out_cond_srv_stake_lock;
+    dap_list_t *items_out_cond_unknonwn;
+    dap_list_t *items_out_cond_undefined;
+    
+    dap_list_t *items_in_ems;
+    dap_list_t *items_vote;
+    dap_list_t *items_voting;
+    dap_list_t *items_tsd;
+    dap_list_t *items_pkey;
+    dap_list_t *items_receipt;
+
+    dap_list_t *items_unknown;
+
+} dap_chain_datum_tx_item_groups_t;
+
+bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_res_group);
+void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_group);
+
 /**
  * Get item type by item name
  *
diff --git a/modules/consensus/block-poa/dap_chain_cs_block_poa.c b/modules/consensus/block-poa/dap_chain_cs_block_poa.c
index 46a6586ad7..baf209edce 100644
--- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c
+++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c
@@ -211,9 +211,9 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
             }
             char l_cert_name[512];
             for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){
-                snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i);
+                snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu",l_poa_pvt->auth_certs_prefix, i);
                 if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) {
-                    snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i);
+                    snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i);
                     if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) {
                         log_it(L_ERROR, "Can't find cert \"%s\"", l_cert_name);
                         return -1;
diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
index 412e3813d3..a848dc2a2c 100644
--- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
+++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c
@@ -378,9 +378,9 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
             }
             char l_cert_name[512];
             for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){
-                snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i);
+                snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu",l_poa_pvt->auth_certs_prefix, i);
                 if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) {
-                    snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i);
+                    snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i);
                     if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) {
                         log_it(L_ERROR, "Can't find cert \"%s\"", l_cert_name);
                         return -1;
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index db6cd9cb2c..90c25c95b5 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -359,39 +359,40 @@ static void s_check_db_collect_callback(dap_global_db_instance_t UNUSED_ARG *a_d
     dap_global_db_objs_delete(l_objs, l_objs_count);
 }
 
-void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a_block_size,
-                                        dap_chain_esbocs_block_collect_t *a_block_collect_params,int a_type)
+void dap_chain_esbocs_add_block_collect(dap_chain_block_cache_t *a_block_cache,
+                                        dap_chain_esbocs_block_collect_t *a_block_collect_params,
+                                        dap_chain_block_autocollect_type_t a_type)
 {
-    dap_hash_fast_t l_last_block_hash;
-    dap_chain_get_atom_last_hash(a_block_collect_params->chain, a_block_collect_params->cell_id, &l_last_block_hash);
+    dap_return_if_fail(a_block_cache && a_block_collect_params);
     dap_chain_t *l_chain = a_block_collect_params->chain;
-    dap_sign_t *l_sign = dap_chain_block_sign_get(a_block_ptr, a_block_size, 0);
-    if (dap_pkey_match_sign(a_block_collect_params->block_sign_pkey, l_sign)&&(!a_type||a_type==1)) {
-        dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t);
-        l_block_collect_params->collecting_level = a_block_collect_params->collecting_level;
-        l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee;
-        l_block_collect_params->chain = a_block_collect_params->chain;
-        l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key;
-        l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey;
-        l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr;
-
-        dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
-        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_last_block_hash);
-        assert(l_block_cache);
-        dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id);
-        assert(l_net);
-        uint256_t l_value_fee = uint256_0;
-        dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(
-                                        l_net->pub.ledger, l_block_cache, &l_value_fee);
-        if (!IS_ZERO_256(l_value_fee)) {
-            char *l_fee_group = dap_chain_cs_blocks_get_fee_group(l_chain->net_name);
-            dap_global_db_set(l_fee_group, l_block_cache->block_hash_str, &l_value_fee, sizeof(l_value_fee),
-                                false, s_check_db_collect_callback, l_block_collect_params);
-            DAP_DELETE(l_fee_group);
-        }
-        dap_list_free_full(l_list_used_out, NULL);
-    }
-    if (dap_chain_block_sign_match_pkey(a_block_ptr, a_block_size, a_block_collect_params->block_sign_pkey)&&(!a_type||a_type==2)) {
+    if (a_type == DAP_CHAIN_BLOCK_COLLECT_BOTH || a_type == DAP_CHAIN_BLOCK_COLLECT_FEES) {
+        dap_sign_t *l_sign = dap_chain_block_sign_get(a_block_cache->block, a_block_cache->block_size, 0);
+        if (dap_pkey_match_sign(a_block_collect_params->block_sign_pkey, l_sign)) {
+            dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t);
+            l_block_collect_params->collecting_level = a_block_collect_params->collecting_level;
+            l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee;
+            l_block_collect_params->chain = a_block_collect_params->chain;
+            l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key;
+            l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey;
+            l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr;
+            dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id);
+            assert(l_net);
+            uint256_t l_value_fee = uint256_0;
+            dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val(
+                                            l_net->pub.ledger, a_block_cache, &l_value_fee);
+            if (!IS_ZERO_256(l_value_fee)) {
+                char *l_fee_group = dap_chain_cs_blocks_get_fee_group(l_chain->net_name);
+                dap_global_db_set(l_fee_group, a_block_cache->block_hash_str, &l_value_fee, sizeof(l_value_fee),
+                                    false, s_check_db_collect_callback, l_block_collect_params);
+                DAP_DELETE(l_fee_group);
+            }
+            dap_list_free_full(l_list_used_out, NULL);
+        }
+    }
+    if (a_type != DAP_CHAIN_BLOCK_COLLECT_BOTH && a_type != DAP_CHAIN_BLOCK_COLLECT_REWARDS)
+        return;
+    if (dap_chain_block_sign_match_pkey(a_block_cache->block, a_block_cache->block_size,
+                                        a_block_collect_params->block_sign_pkey)) {
         dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t);
         l_block_collect_params->collecting_level = a_block_collect_params->collecting_level;
         l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee;
@@ -399,19 +400,15 @@ void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a
         l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key;
         l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey;
         l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr;
-
-        dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
-        dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_last_block_hash);
-        assert(l_block_cache);
         dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id);
         assert(l_net);
-        if (!dap_ledger_is_used_reward(l_net->pub.ledger, &l_block_cache->block_hash,
+        if (!dap_ledger_is_used_reward(l_net->pub.ledger, &a_block_cache->block_hash,
                                         &l_block_collect_params->collecting_addr->data.hash_fast)) {
-            uint256_t l_value_reward = l_chain->callback_calc_reward(l_chain, &l_block_cache->block_hash,
+            uint256_t l_value_reward = l_chain->callback_calc_reward(l_chain, &a_block_cache->block_hash,
                                                                      l_block_collect_params->block_sign_pkey);
             if (!IS_ZERO_256(l_value_reward)) {
                 char *l_reward_group = dap_chain_cs_blocks_get_reward_group(l_chain->net_name);
-                dap_global_db_set(l_reward_group, l_block_cache->block_hash_str, &l_value_reward, sizeof(l_value_reward),
+                dap_global_db_set(l_reward_group, a_block_cache->block_hash_str, &l_value_reward, sizeof(l_value_reward),
                                     false, s_check_db_collect_callback, l_block_collect_params);
                 DAP_DELETE(l_reward_group);
             }
@@ -441,7 +438,8 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel
             .collecting_addr = PVT(l_session->esbocs)->collecting_addr,
             .cell_id = a_id
     };
-    dap_chain_esbocs_add_block_collect(a_atom, a_atom_size, &l_block_collect_params,0);
+    dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(DAP_CHAIN_CS_BLOCKS(a_chain), &l_last_block_hash);
+    dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_BOTH);
 }
 
 bool dap_chain_esbocs_get_autocollect_status(dap_chain_net_id_t a_net_id)
@@ -865,14 +863,14 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_t *a_esbocs, dap_hash_
                 const char *l_chosen_weight_str, *l_total_weight_str, *l_raw_result_str;
                 char l_str[l_strlen];
                 dap_uint256_to_char(l_chosen_weight, &l_chosen_weight_str);
-                l_off = dap_snprintf(l_str, l_strlen,
+                l_off = snprintf(l_str, l_strlen,
                                      "Round seed %s, sync attempt %"DAP_UINT64_FORMAT_U", chosen weight %s ",
                                      dap_hash_fast_to_str_static(a_last_hash),
                                      a_skip_count + 1, l_chosen_weight_str);
                 dap_uint256_to_char(l_total_weight, &l_total_weight_str);
-                l_off += dap_snprintf(l_str + l_off, l_strlen - l_off, "from %s, ", l_total_weight_str);
+                l_off += snprintf(l_str + l_off, l_strlen - l_off, "from %s, ", l_total_weight_str);
                 dap_uint256_to_char(l_raw_result, &l_raw_result_str);
-                l_off += dap_snprintf(l_str + l_off, l_strlen - l_off, "by number %s", l_raw_result_str);
+                l_off += snprintf(l_str + l_off, l_strlen - l_off, "by number %s", l_raw_result_str);
                 log_it(L_MSG, "%s", l_str);
             }
             dap_list_t *l_chosen = NULL;
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index 2374f776de..fc2c218bdf 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -223,6 +223,12 @@ typedef struct dap_chain_esbocs_block_collect{
 
 #define DAP_CHAIN_ESBOCS(a) ((dap_chain_esbocs_t *)(a)->_inheritor)
 
+typedef enum dap_chain_block_autocollect_type {
+    DAP_CHAIN_BLOCK_COLLECT_BOTH,
+    DAP_CHAIN_BLOCK_COLLECT_FEES,
+    DAP_CHAIN_BLOCK_COLLECT_REWARDS
+} dap_chain_block_autocollect_type_t;
+
 int dap_chain_cs_esbocs_init();
 void dap_chain_cs_esbocs_deinit(void);
 
@@ -233,8 +239,9 @@ void dap_chain_esbocs_start_timer(dap_chain_net_id_t a_net_id);
 dap_pkey_t *dap_chain_esbocs_get_sign_pkey(dap_chain_net_id_t a_net_id);
 uint256_t dap_chain_esbocs_get_fee(dap_chain_net_id_t a_net_id);
 bool dap_chain_esbocs_get_autocollect_status(dap_chain_net_id_t a_net_id);
-void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a_block_size,
-                                        dap_chain_esbocs_block_collect_t *a_block_collect_params,int a_type);
+void dap_chain_esbocs_add_block_collect(dap_chain_block_cache_t *a_block_cache,
+                                        dap_chain_esbocs_block_collect_t *a_block_collect_params,
+                                        dap_chain_block_autocollect_type_t a_type);
 bool dap_chain_esbocs_add_validator_to_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr);
 bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr);
 
diff --git a/modules/json_rpc/CMakeLists.txt b/modules/json_rpc/CMakeLists.txt
deleted file mode 100644
index 526bc29d75..0000000000
--- a/modules/json_rpc/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-add_subdirectory(mempool)
-add_subdirectory(common)
diff --git a/modules/json_rpc/common/CMakeLists.txt b/modules/json_rpc/common/CMakeLists.txt
deleted file mode 100644
index 4cd22f1220..0000000000
--- a/modules/json_rpc/common/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-project(dap_json_rpc_chain_common)
-
-file(GLOB DAP_JSON_RPC_CHAIN_COMMON_HEADERS include/*.h)
-file(GLOB DAP_JSON_RPC_CHAIN_COMMON_SRCS *.c)
-
-add_library(${PROJECT_NAME}  STATIC ${DAP_JSON_RPC_CHAIN_COMMON_SRCS} ${DAP_JSON_RPC_CHAIN_COMMON_HEADERS})
-
-target_link_libraries(dap_json_rpc_chain_common dap_core dap_crypto dap_chain_common dap_json-c dap_json_rpc_core dap_json_rpc_crypto)
-target_include_directories(dap_json_rpc_chain_common PUBLIC include/)
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_common.c b/modules/json_rpc/common/dap_json_rpc_chain_common.c
deleted file mode 100644
index c26cbe7330..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_common.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "dap_json_rpc_chain_common.h"
-#include "json.h"
-
-#define LOG_TAG "dap_json_rpc_chain_common"
-
-/**
- * @brief dap_chain_addr_to_json
- * @param a_addr
- * @return
- */
-json_object *dap_chain_addr_to_json(const dap_chain_addr_t *a_addr) {
-    return json_object_new_string(dap_chain_addr_to_str(a_addr));
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum.c b/modules/json_rpc/common/dap_json_rpc_chain_datum.c
deleted file mode 100644
index 58ee1ab7cc..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum.c
+++ /dev/null
@@ -1,744 +0,0 @@
-
-#include "dap_common.h"
-#include "dap_time.h"
-#include "dap_chain_datum.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_token.h"
-#include "dap_chain_datum_tx_items.h"
-#include "dap_chain_datum_decree.h"
-#include "dap_chain_datum_anchor.h"
-#include "dap_chain_datum_hashtree_roots.h"
-#include "dap_enc_base58.h"
-
-#include "dap_json_rpc_chain_datum.h"
-#include "dap_json_rpc_chain_datum_tx.h"
-#include "dap_json_rpc_chain_datum_token.h"
-#include "dap_json_rpc_chain_datum_anchor.h"
-#include "dap_json_rpc_chain_datum_decree.h"
-#include "json.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum"
-
-json_object *s_dap_chain_datum_token_tsd_to_json(dap_chain_datum_token_t *a_token, size_t a_token_size) {
-    dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size);
-    if (l_tsd == NULL) {
-        json_object *l_tsd_wgn = json_object_new_object();
-        if (!l_tsd_wgn){
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        json_object *l_tsd_wgn_warning = json_object_new_string("<CORRUPTED TSD SECTION>");
-        if (!l_tsd_wgn_warning) {
-            json_object_put(l_tsd_wgn);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        json_object_object_add(l_tsd_wgn, "warning", l_tsd_wgn_warning);
-        return l_tsd_wgn;
-    }
-    json_object *l_tsd_array = json_object_new_array();
-    if (!l_tsd_array) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    size_t l_tsd_total_size = 0;
-    switch (a_token->type) {
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL:
-            switch (a_token->subtype) {
-                case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:
-                    l_tsd_total_size = a_token->header_private_decl.tsd_total_size; break;
-                case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
-                    l_tsd_total_size = a_token->header_native_decl.tsd_total_size; break;
-                default: break;
-            } break;
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE:
-            switch (a_token->subtype) {
-                case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:
-                    l_tsd_total_size = a_token->header_private_update.tsd_total_size; break;
-                case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE:
-                    l_tsd_total_size = a_token->header_native_update.tsd_total_size; break;
-                default: break;
-            } break;
-        default: break;
-    }
-    size_t l_tsd_size = 0;
-    for (size_t l_offset = 0; l_offset < l_tsd_total_size; l_offset += l_tsd_size) {
-        json_object *l_jobj_tsd = json_object_new_object();
-        l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd) + l_tsd_size);
-        l_tsd_size = l_tsd ? dap_tsd_size(l_tsd) : 0;
-        if (l_tsd_size == 0) {
-            json_object *l_wgn_text = json_object_new_string("Wrong zero TSD size, exiting s_datum_token_dump_tsd()");
-            if (!l_wgn_text) {
-                json_object_put(l_tsd_array);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_wgn = json_object_new_object();
-            if (!l_wgn) {
-                json_object_put(l_wgn_text);
-                json_object_put(l_tsd_array);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_wgn, "error", l_wgn_text);
-            json_object_array_add(l_tsd_array, l_wgn);
-            break;
-        } else if (l_tsd_size+l_offset > l_tsd_total_size) {
-            char *l_wgn_str = dap_strdup_printf("<CORRUPTED TSD> too big size %u when left maximum %zu",
-                                           l_tsd->size, l_tsd_total_size - l_offset);
-            if (!l_wgn_str) {
-                json_object_put(l_tsd_array);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_wgn_text = json_object_new_string(l_wgn_str);
-            DAP_DELETE(l_wgn_str);
-            if (!l_wgn_text) {
-                json_object_put(l_tsd_array);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_wgn = json_object_new_object();
-            if (!l_wgn) {
-                json_object_put(l_wgn_text);
-                json_object_put(l_tsd_array);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_wgn, "error", l_wgn_text);
-            json_object_array_add(l_tsd_array, l_wgn);
-            break;
-        }
-        switch( l_tsd->type){
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                uint16_t l_flags = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_flags);
-                json_object *l_jobj_tsd_flag = dap_chain_datum_token_flags_to_json(l_flags);
-                if (!l_jobj_tsd_flag) {
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "flags", l_jobj_tsd_flag);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                uint16_t l_flags = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_flags);
-                json_object *l_jobj_tsd_flag = dap_chain_datum_token_flags_to_json(l_flags);
-                if (!l_jobj_tsd_flag) {
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "flags", l_jobj_tsd_flag);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                uint256_t l_balance_native = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_balance_native);
-                json_object *l_jobj_tsd_value = json_object_new_string(dap_uint256_to_char(l_balance_native, NULL));
-                if (!l_jobj_tsd_value) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "value", l_jobj_tsd_value);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: {// 128
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                uint128_t l_balance_native_old = uint128_0;
-                _dap_tsd_get_scalar(l_tsd, &l_balance_native_old);
-                json_object *l_jobj_tsd_value =
-                    json_object_new_string(dap_uint256_to_char(GET_256_FROM_128(l_balance_native_old), NULL));
-                if (!l_jobj_tsd_value) {
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "value", l_jobj_tsd_value);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID");
-                uint16_t l_flags = 0;
-                _dap_tsd_get_scalar(l_tsd, &l_flags);
-                json_object *l_jobj_value = json_object_new_uint64(l_flags);
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "total_signs_valid", l_jobj_value);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                if (l_tsd->size >= sizeof(dap_pkey_t)) {
-                    dap_pkey_t *l_pkey = (dap_pkey_t *) l_tsd->data;
-                    dap_hash_fast_t l_hf = {0};
-                    if (!dap_pkey_get_hash(l_pkey, &l_hf)) {
-                        json_object *l_wgn_text = json_object_new_string("total_pkeys_add: <WRONG CALCULATION FINGERPRINT>");
-                        if (!l_wgn_text) {
-                            json_object_put(l_jobj_tsd);
-                            json_object_put(l_tsd_array);
-                            dap_json_rpc_allocation_error;
-                            return NULL;
-                        }
-                        json_object_object_add(l_jobj_tsd, "warning", l_wgn_text);
-                    } else {
-                        json_object_object_add(l_jobj_tsd, "pkey",
-                            json_object_new_string(dap_chain_hash_fast_to_str_static(&l_hf)));
-                    }
-                } else {
-                    char *l_wgn_text = dap_strdup_printf("total_pkeys_add: <WRONG SIZE %u>\n", l_tsd->size);
-                    if (!l_wgn_text) {
-                        json_object_put(l_jobj_tsd);
-                        json_object_put(l_tsd_array);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text);
-                    DAP_DELETE(l_wgn_text);
-                    if (!l_jobj_wgn_text) {
-                        json_object_put(l_jobj_tsd);
-                        json_object_put(l_tsd_array);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn_text);
-                }
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd){
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                if (l_tsd->size == sizeof(dap_chain_hash_fast_t)) {
-                    json_object_object_add(l_jobj_tsd, "pkey",
-                        json_object_new_string(dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*) l_tsd->data)));
-                } else {
-                    char *l_wgn_text = dap_strdup_printf("total_pkeys_remove: <WRONG SIZE %u>\n", l_tsd->size);
-                    if (!l_wgn_text) {
-                        json_object_put(l_jobj_tsd);
-                        json_object_put(l_tsd_array);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text);
-                    DAP_DELETE(l_wgn_text);
-                    if (!l_jobj_wgn_text) {
-                        json_object_put(l_jobj_tsd);
-                        json_object_put(l_tsd_array);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn_text);
-                }
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t);
-                json_object *l_jobj_ticker_token_from = json_object_new_string((char*)l_tsd_section->ticker_token_from);
-                if (!l_jobj_ticker_token_from) {
-                    json_object_put(l_jobj_ticker_token_from);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "ticker_token_from", l_jobj_ticker_token_from);
-                const char *balance; dap_uint256_to_char(l_tsd_section->emission_rate, &balance);
-                json_object *l_jobj_emission_rate = json_object_new_string(balance);
-                if (!l_jobj_emission_rate) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "emission_rate", l_jobj_emission_rate);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                if (!l_jobj_tsd) {
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD");
-                if (!l_jobj_tsd_type) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object *l_jobj_datum_type_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_datum_type_allowed_add) {
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "datum_type_allowed_add", l_jobj_datum_type_allowed_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            }continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE");
-                json_object *l_jobj_datum_type_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_allowed_remove) {
-                    json_object_put(l_jobj_datum_type_allowed_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "datum_type_allowed_remove", l_jobj_datum_type_allowed_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            }continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD");
-                json_object *l_jobj_datum_type_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_blocked_add) {
-                    json_object_put(l_jobj_datum_type_blocked_add);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "datum_type_blocked_add", l_jobj_datum_type_blocked_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE");
-                json_object *l_jobj_datum_type_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_blocked_remove) {
-                    json_object_put(l_jobj_datum_type_blocked_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "datum_type_blocked_remove", l_jobj_datum_type_blocked_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD");
-                json_object *l_jobj_tx_sender_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_allowed_add) {
-                    json_object_put(l_jobj_tx_sender_allowed_add);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_sender_allowed_add",l_jobj_tx_sender_allowed_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE");
-                json_object *l_jobj_tx_sender_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_allowed_remove) {
-                    json_object_put(l_jobj_tx_sender_allowed_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_sender_allowed_remove",l_jobj_tx_sender_allowed_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            }continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD");
-                json_object *l_jobj_tx_sender_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_blocked_add) {
-                    json_object_put(l_jobj_tx_sender_blocked_add);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_sender_blocked_add", l_jobj_tx_sender_blocked_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE");
-                json_object *l_jobj_tx_sender_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_blocked_remove) {
-                    json_object_put(l_jobj_tx_sender_blocked_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_sender_blocked_remove", l_jobj_tx_sender_blocked_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD");
-                json_object *l_tx_receiver_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_tx_receiver_allowed_add) {
-                    json_object_put(l_tx_receiver_allowed_add);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_receiver_allowed_add", l_tx_receiver_allowed_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE");
-                json_object *l_jobj_tx_receiver_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_allowed_remove){
-                    json_object_put(l_jobj_tx_receiver_allowed_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_receiver_allowed_remove", l_jobj_tx_receiver_allowed_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD");
-                json_object *l_jobj_tx_receiver_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_blocked_add){
-                    json_object_put(l_jobj_tx_receiver_blocked_add);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_receiver_blocked_add", l_jobj_tx_receiver_blocked_add);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE");
-                json_object *l_jobj_tx_receiver_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_blocked_remove) {
-                    json_object_put(l_jobj_tx_receiver_blocked_remove);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "tx_receiver_blocked_remove", l_jobj_tx_receiver_blocked_remove);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: {
-                json_object *l_jobj_tsd = json_object_new_object();
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION");
-                json_object *l_jobj_tsd_description = json_object_new_string(dap_tsd_get_string_const(l_tsd));
-                if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tsd_description) {
-                    json_object_put(l_jobj_tsd_description);
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "description", l_jobj_tsd_description);
-                json_object_array_add(l_tsd_array, l_jobj_tsd);
-            } continue;
-            default: {
-                char *l_wgn_text = dap_strdup_printf("<0x%04hX>: <size %u>\n", l_tsd->type, l_tsd->size);
-                if (!l_wgn_text){
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text);
-                DAP_DELETE(l_wgn_text);
-                json_object *l_jobj_warning = json_object_new_object();
-                if (!l_jobj_wgn_text || !l_jobj_warning) {
-                    json_object_put(l_jobj_wgn_text);
-                    json_object_put(l_jobj_warning);
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_tsd_array);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_warning, "warning", l_jobj_wgn_text);
-                json_object_array_add(l_tsd_array, l_jobj_warning);
-            }
-        }
-    }
-    return l_tsd_array;
-}
-
-typedef enum dap_chain_datum_to_json_err_list {
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TX_TO_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECL_TO_JSON,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_DECL,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TSD_SECTION_DECL_TO_JSON,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_EMISSION_TO_JSON,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_EMISSION,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_ANCHOR_TO_JSON,
-    CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECREE_TO_JSON
-}dap_chain_datum_to_json_err_list_t;
-
-json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum){
-    json_object *l_object = json_object_new_object();
-    if (!l_object){
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    char *l_hash_data_str;
-    dap_get_data_hash_str_static(a_datum->data, a_datum->header.data_size, l_hash_data_str);
-    json_object *l_obj_data_hash = json_object_new_string(l_hash_data_str);
-    if (!l_obj_data_hash) {
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_version = json_object_new_int(a_datum->header.version_id);
-    if (!l_obj_version) {
-        json_object_put(l_object);
-        json_object_put(l_obj_data_hash);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_size = json_object_new_int(a_datum->header.data_size);
-    if (!l_obj_size) {
-        json_object_put(l_object);
-        json_object_put(l_obj_data_hash);
-        json_object_put(l_obj_version);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_type = json_object_new_string(dap_chain_datum_type_id_to_str(a_datum->header.type_id));
-    if (!l_obj_type) {
-        json_object_put(l_object);
-        json_object_put(l_obj_data_hash);
-        json_object_put(l_obj_version);
-        json_object_put(l_obj_size);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_data = dap_chain_datum_data_to_json(a_datum);
-
-    json_object_object_add(l_object, "hash", l_obj_data_hash);
-    json_object_object_add(l_object, "data_size", l_obj_size);
-    json_object_object_add(l_object, "version", l_obj_version);
-
-    char l_time_str[DAP_TIME_STR_SIZE];
-    if (a_datum->header.ts_create) {
-        dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, a_datum->header.ts_create); /* Convert ts to  "Sat May 17 01:17:08 2014\n" */
-        l_time_str[strlen(l_time_str)-1] = '\0';                    /* Remove "\n"*/
-    }
-    json_object *l_obj_ts_created = json_object_new_string(l_time_str);
-    json_object_object_add(l_object, "ts_create", l_obj_ts_created);
-    json_object_object_add(l_object, "type", l_obj_type);
-    if (a_datum->header.type_id == DAP_CHAIN_DATUM_TX) {
-        json_object_object_add(l_object, "items", l_obj_data);
-    } else {
-        json_object_object_add(l_object, "data", l_obj_data);
-    }
-    return l_object;
-}
-
-json_object * dap_chain_datum_data_to_json(dap_chain_datum_t *a_datum) {
-    if (!a_datum)
-        return json_object_new_null();
-    json_object *l_obj_data;
-    switch (a_datum->header.type_id) {
-        case DAP_CHAIN_DATUM_TX:
-            l_obj_data = dap_chain_datum_tx_to_json((dap_chain_datum_tx_t*)a_datum->data, NULL);
-            if (!l_obj_data) {
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TX_TO_JSON,
-                                       "Can't convert DAP_CHAIN_DATUM_TX to JSON");
-                return NULL;
-            }
-            break;
-        case DAP_CHAIN_DATUM_DECREE:
-            l_obj_data = dap_chain_datum_decree_to_json((dap_chain_datum_decree_t*)a_datum->data);
-            if (!l_obj_data) {
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECREE_TO_JSON,
-                                       "Can't convert DAP_CHAIN_DATUM_DECREE to JSON");
-                return NULL;
-            }
-            break;
-        case DAP_CHAIN_DATUM_ANCHOR:
-            l_obj_data = dap_chain_datum_anchor_to_json((dap_chain_datum_anchor_t*)a_datum->data);
-            if (!l_obj_data) {
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_ANCHOR_TO_JSON,
-                                       "Can't convert DAP_CHAIN_DATUM_ANCHOR to JSON");
-                return NULL;
-            }
-            break;
-        case DAP_CHAIN_DATUM_TOKEN_DECL: {
-            size_t l_token_size = a_datum->header.data_size;
-            dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size);
-            if (!l_token) {
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_DECL,
-                                       "The contents of the token delcaration could not be read.");
-                return NULL;
-            }
-            l_obj_data = dap_chain_datum_token_to_json(l_token, l_token_size);
-            if (!l_obj_data) {
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECL_TO_JSON,
-                                       "Can't convert DAP_CHAIN_DATUM_TOKEN_DECL to JSON");
-                DAP_DELETE(l_token);
-                return NULL;
-            }
-            json_object *l_obj_tsd_data = s_dap_chain_datum_token_tsd_to_json(l_token, l_token_size);
-            if (!l_obj_tsd_data) {
-                json_object_put(l_obj_data);
-                DAP_DELETE(l_token);
-                log_it(L_ERROR, "It was not possible to read the contents of the TSD sections of the token delcaration.");
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TSD_SECTION_DECL_TO_JSON,
-                                       "It was not possible to read the contents of the TSD sections of the token delcaration.");
-                return NULL;
-            }
-            json_object_object_add(l_obj_data, "TSD", l_obj_tsd_data);
-            DAP_DELETE(l_token);
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
-            size_t l_emission_size = a_datum->header.data_size;
-            dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size);
-            if (l_emission_size == 0 || !l_emission) {
-                log_it(L_ERROR, "Failed to read emission");
-                dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_EMISSION,
-                                       "Failed to read emission.");
-                return NULL;
-            } else {
-                l_obj_data = dap_chain_datum_emission_to_json(l_emission, l_emission_size);
-                DAP_DELETE(l_emission);
-                if (!l_obj_data) {
-                    dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_EMISSION_TO_JSON,
-                                           "Can't convert DAP_CHAIN_DATUM_TOKEN_DECL to JSON");
-                    return NULL;
-                }
-            }
-        } break;
-        default:
-            l_obj_data = json_object_new_null();
-            break;
-    }
-    return l_obj_data;
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c
deleted file mode 100644
index e41c242d97..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "dap_json_rpc_chain_datum_anchor.h"
-#include "json.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_anchor"
-
-
-json_object *s_dap_chain_datum_anchor_sign_to_json(byte_t * a_signs, size_t a_certs_size) {
-    json_object *l_jobs_signs = json_object_new_array();
-    size_t l_offset = 0;
-    for (int i = 1; l_offset < (a_certs_size); i++) {
-        json_object *l_jobj_sign = json_object_new_object();
-        dap_sign_t *l_sign = (dap_sign_t*)(a_signs + l_offset);
-        l_offset += dap_sign_get_size(l_sign);
-        if (l_sign->header.sign_size == 0) {
-            json_object *l_wrn_text = json_object_new_string("<CORRUPTED - 0 size signature>");
-            json_object_object_add(l_jobj_sign, "warning", l_wrn_text);
-            continue;
-        }
-
-        dap_chain_hash_fast_t l_pkey_hash = {0};
-        if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) {
-            json_object *l_wrn_text = json_object_new_string("<CORRUPTED - can't calc hash>");
-            json_object_object_add(l_jobj_sign, "warning", l_wrn_text);
-            continue;
-        }
-        json_object *l_jobj_hash_str = json_object_new_string(dap_chain_hash_fast_to_str_static(&l_pkey_hash));
-        json_object *l_jobj_type_str = json_object_new_string(dap_sign_type_to_str(l_sign->header.type));
-        json_object *l_jobj_sign_size = json_object_new_uint64(l_sign->header.sign_size);
-        json_object_object_add(l_jobj_sign, "hash", l_jobj_hash_str);
-        json_object_object_add(l_jobj_sign, "type", l_jobj_type_str);
-        json_object_object_add(l_jobj_sign, "size", l_jobj_sign_size);
-        json_object_array_add(l_jobs_signs, l_jobj_sign);
-    }
-    return l_jobs_signs;
-}
-
-json_object *dap_chain_datum_anchor_to_json(dap_chain_datum_anchor_t *a_anchor){
-    json_object *l_obj_anchor = json_object_new_object();
-    if (!l_obj_anchor) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_version = json_object_new_uint64(a_anchor->anchor_version);
-    if (!l_obj_version){
-        json_object_put(l_obj_anchor);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_ts_created = json_object_new_uint64(a_anchor->header.ts_created);
-    if (!l_obj_ts_created) {
-        json_object_put(l_obj_version);
-        json_object_put(l_obj_anchor);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_tsd_array = json_object_new_array();
-    if(!l_obj_tsd_array) {
-        json_object_put(l_obj_ts_created);
-        json_object_put(l_obj_version);
-        json_object_put(l_obj_anchor);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    size_t l_tsd_offset = 0, tsd_data_size = a_anchor->header.data_size;
-
-    while(l_tsd_offset < tsd_data_size){
-        json_object *l_jobj_tsd = json_object_new_object();
-        if (!l_jobj_tsd) {
-            json_object_put(l_obj_tsd_array);
-            json_object_put(l_obj_ts_created);
-            json_object_put(l_obj_version);
-            json_object_put(l_obj_anchor);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        dap_tsd_t *l_tsd = (dap_tsd_t*)a_anchor->data_n_sign + l_tsd_offset;
-        size_t l_tsd_size = l_tsd->size + sizeof(dap_tsd_t);
-        if(l_tsd_size > tsd_data_size){
-            json_object *l_jobj_wgn = json_object_new_string("TSD size is greater than all data size. It's possible corrupt data.");
-            if (!l_jobj_wgn){
-                json_object_put(l_jobj_tsd);
-                json_object_put(l_obj_tsd_array);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_version);
-                json_object_put(l_obj_anchor);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn);
-            json_object_array_add(l_obj_tsd_array, l_jobj_tsd);
-            break;
-        }
-        if (l_tsd->type == DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH){
-            json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH");
-            if (!l_obj_tsd_type){
-                json_object_put(l_jobj_tsd);
-                json_object_put(l_obj_tsd_array);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_version);
-                json_object_put(l_obj_anchor);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-            if(l_tsd->size > sizeof(dap_hash_fast_t)){
-                json_object *l_jobj_wgn = json_object_new_string("Wrong fee tsd data size.");
-                if (!l_jobj_wgn){
-                    json_object_put(l_jobj_tsd);
-                    json_object_put(l_obj_tsd_array);
-                    json_object_put(l_obj_ts_created);
-                    json_object_put(l_obj_ts_created);
-                    json_object_put(l_obj_version);
-                    json_object_put(l_obj_anchor);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn);
-                json_object_array_add(l_obj_tsd_array, l_jobj_tsd);
-                break;
-            }
-            dap_hash_fast_t l_out_hash = {0};
-            _dap_tsd_get_scalar(l_tsd, &l_out_hash);
-            char *l_hash_str = dap_hash_fast_to_str_new(&l_out_hash);
-            if (!l_hash_str) {
-                json_object_put(l_jobj_tsd);
-                json_object_put(l_obj_tsd_array);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_version);
-                json_object_put(l_obj_anchor);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_obj_tsd_hash = json_object_new_string(l_hash_str);
-            DAP_DELETE(l_hash_str);
-            if (!l_obj_tsd_hash){
-                json_object_put(l_jobj_tsd);
-                json_object_put(l_obj_tsd_array);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_ts_created);
-                json_object_put(l_obj_version);
-                json_object_put(l_obj_anchor);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_tsd, "hash", l_obj_tsd_hash);
-        }
-        json_object_array_add(l_obj_tsd_array, l_jobj_tsd);
-        l_tsd_offset += l_tsd_size;
-    }
-    json_object_object_add(l_obj_anchor, "version", l_obj_version);
-    json_object_object_add(l_obj_anchor, "ts_created", l_obj_ts_created);
-    json_object_object_add(l_obj_anchor, "TSD", l_obj_tsd_array);
-    json_object *l_jobj_signs = s_dap_chain_datum_anchor_sign_to_json(a_anchor->data_n_sign + a_anchor->header.data_size,
-                                                                      a_anchor->header.signs_size);
-    if (!l_jobj_signs) {
-        json_object_put(l_obj_tsd_array);
-        json_object_put(l_obj_ts_created);
-        json_object_put(l_obj_ts_created);
-        json_object_put(l_obj_version);
-        json_object_put(l_obj_anchor);
-        dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "I can't serialize the anchor signature in JSON.");
-        return NULL;
-    }
-    json_object_object_add(l_obj_anchor, "signs", l_jobj_signs);
-    return l_obj_anchor;
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
deleted file mode 100644
index ed4722d277..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c
+++ /dev/null
@@ -1,583 +0,0 @@
-
-#include "dap_json_rpc_chain_datum_decree.h"
-#include "dap_json_rpc_chain_common.h"
-#include "dap_tsd.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_decree"
-
-json_object *s_dap_chain_datum_decree_certs_dump_json(byte_t * a_signs, size_t a_certs_size){
-    json_object *l_jobj_signatures = json_object_new_array();
-    if (!l_jobj_signatures) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    size_t l_offset = 0;
-    for (int i = 1; l_offset < (a_certs_size); i++) {
-        json_object *l_jobj_signature = json_object_new_object();
-        if (!l_jobj_signature) {
-            json_object_put(l_jobj_signatures);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset);
-        l_offset += dap_sign_get_size(l_sign);
-        if (l_sign->header.sign_size == 0) {
-            json_object *l_wrn_text = json_object_new_string("<CORRUPTED - 0 size signature>");
-            if(!l_wrn_text) {
-                json_object_put(l_jobj_signature);
-                json_object_put(l_jobj_signatures);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_signature, "warning", l_wrn_text);
-            continue;
-        }
-
-        dap_chain_hash_fast_t l_pkey_hash = {0};
-        if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) {
-            json_object *l_wrn_text = json_object_new_string("<CORRUPTED - can't calc hash>");
-            if (!l_wrn_text){
-                json_object_put(l_jobj_signature);
-                json_object_put(l_jobj_signatures);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_signature, "warning", l_wrn_text);
-            continue;
-        }
-
-        json_object *l_jobj_hash_str 
-            = json_object_new_string(dap_chain_hash_fast_to_str_static(&l_pkey_hash));
-        if (!l_jobj_hash_str) {
-            json_object_put(l_jobj_signature);
-            json_object_put(l_jobj_signatures);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        json_object *l_jobj_type_str = json_object_new_string(dap_sign_type_to_str(l_sign->header.type));
-        if (!l_jobj_type_str) {
-            json_object_put(l_jobj_hash_str);
-            json_object_put(l_jobj_signature);
-            json_object_put(l_jobj_signatures);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        json_object *l_jobj_sign_size = json_object_new_uint64(l_sign->header.sign_size);
-        if (!l_jobj_sign_size) {
-            json_object_put(l_jobj_hash_str);
-            json_object_put(l_jobj_type_str);
-            json_object_put(l_jobj_signature);
-            json_object_put(l_jobj_signatures);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        json_object_object_add(l_jobj_signature, "hash", l_jobj_hash_str);
-        json_object_object_add(l_jobj_signature, "type", l_jobj_type_str);
-        json_object_object_add(l_jobj_signature, "size", l_jobj_sign_size);
-        json_object_array_add(l_jobj_signatures, l_jobj_signature);
-    }
-    return l_jobj_signatures;
-}
-
-json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){
-    json_object *l_jobj_decree = json_object_new_object();
-    if (!l_jobj_decree) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    char *l_type_str = "";
-    switch(a_decree->header.type)
-    {
-        case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON:
-            l_type_str = "DECREE_TYPE_COMMON";
-            break;
-        case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE:
-            l_type_str = "DECREE_TYPE_SERVICE";
-            break;
-        default:
-            l_type_str = "DECREE_TYPE_UNKNOWN";
-    }
-    json_object *l_jobj_type = json_object_new_string(l_type_str);
-    if (!l_jobj_type) {
-        json_object_put(l_jobj_decree);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type);
-    json_object *l_json_subtype = json_object_new_string(l_subtype_str);
-    if (!l_json_subtype) {
-        json_object_put(l_jobj_type);
-        json_object_put(l_jobj_decree);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_json_tsd_array = json_object_new_array();
-    if (!l_json_tsd_array){
-        json_object_put(l_json_subtype);
-        json_object_put(l_jobj_type);
-        json_object_put(l_jobj_decree);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) {
-        dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset);
-        l_offset += dap_tsd_size(l_tsd);
-        json_object *l_jobj_tsd = json_object_new_object();
-        if (!l_jobj_tsd) {
-            json_object_put(l_json_tsd_array);
-            json_object_put(l_json_subtype);
-            json_object_put(l_jobj_type);
-            json_object_put(l_jobj_decree);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        switch(l_tsd->type) {
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN");
-                if (!l_obj_tsd_type) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE");
-                if (!l_obj_tsd_type) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Fee: <WRONG SIZE>");
-                    if (!l_text_wgn) {
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                uint256_t l_fee_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_fee_value);
-                json_object *l_jobj_fee = json_object_new_string(dap_uint256_to_char(l_fee_value, NULL));
-                if (!l_jobj_fee) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "value", l_jobj_fee);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER");
-                if (!l_obj_tsd_type){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size < sizeof(dap_pkey_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Owner fingerprint: <WRONG SIZE>");
-                    if (!l_text_wgn){
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                dap_pkey_t *l_owner_pkey = DAP_NEW_Z_SIZE(dap_pkey_t, l_tsd->size);
-                if(!l_owner_pkey) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);
-                dap_hash_fast_t l_owner_pkey_hash = {0};
-                dap_hash_fast(l_owner_pkey->pkey, l_owner_pkey->header.size, &l_owner_pkey_hash);
-                char l_owner_pkey_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-                dap_chain_hash_fast_to_str(&l_owner_pkey_hash, l_owner_pkey_str, sizeof(l_owner_pkey_str));
-                json_object *l_jobj_owner_pkey = json_object_new_string(l_owner_pkey_str);
-                if (!l_jobj_owner_pkey) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "owner_fingerprint", l_jobj_owner_pkey);
-                DAP_DELETE(l_owner_pkey);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER");
-                if (!l_obj_tsd_type){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(uint256_t)){
-                    json_object *l_text_wgn = json_object_new_string("Owner min: <WRONG SIZE>");
-                    if (!l_text_wgn) {
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                uint256_t l_owner_min = {0};
-                _dap_tsd_get_scalar(l_tsd, &l_owner_min);
-                json_object *l_jobj_owner_min = json_object_new_string(dap_uint256_to_char(l_owner_min, NULL));
-                if (!l_jobj_owner_min) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "owner_min", l_jobj_owner_min);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET");
-                if (!l_obj_tsd_type) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Wallet for fee: <WRONG SIZE>");
-                    if (!l_text_wgn) {
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                dap_chain_addr_t l_addr_fee_wallet = {0};
-                _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);
-                json_object *l_jobj_addr_fee_wallet = dap_chain_addr_to_json(&l_addr_fee_wallet);
-                if (!l_jobj_addr_fee_wallet) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "addr", l_jobj_addr_fee_wallet);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH");
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(dap_hash_fast_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Stake tx: <WRONG SIZE>");
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                dap_hash_fast_t l_stake_tx = {0};
-                _dap_tsd_get_scalar(l_tsd, &l_stake_tx);
-                json_object *l_jobj_tx_hash =
-                    json_object_new_string(dap_chain_hash_fast_to_str_static(&l_stake_tx));
-                if (!l_jobj_tx_hash) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "hash", l_jobj_tx_hash);
-//                char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex")
-//                                        ? dap_enc_base58_encode_hash_to_str(&l_stake_tx)
-//                                        : dap_chain_hash_fast_to_str_new(&l_stake_tx);
-//                dap_string_append_printf(a_str_out, "\tStake tx: %s\n", l_stake_tx_hash);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE");
-                if (!l_obj_tsd_type){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Stake value: <WRONG SIZE>");
-                    if (!l_text_wgn){
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                uint256_t l_stake_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_stake_value);
-                json_object *l_jobj_stake_value = json_object_new_string(dap_uint256_to_char(l_stake_value, NULL));
-                if (!l_jobj_stake_value){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "value", l_jobj_stake_value);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: {
-                json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR");
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(dap_chain_addr_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Signing addr: <WRONG SIZE>");
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                dap_chain_addr_t l_stake_addr_signing = {0};
-                _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);
-//                dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", l_stake_addr_signing_str);
-                dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing.data.hash_fast;
-                const char *l_pkey_signing_str = dap_chain_hash_fast_to_str_static(&l_pkey_signing);
-                json_object *l_jobj_stake_addr_signing = dap_chain_addr_to_json(&l_stake_addr_signing);
-                json_object *l_jobj_pkey_signing = json_object_new_string(l_pkey_signing_str);
-                json_object_object_add(l_jobj_tsd, "addr", l_jobj_stake_addr_signing);
-                json_object_object_add(l_jobj_tsd, "pkey", l_jobj_pkey_signing);
-//                char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex")
-//                                           ? dap_enc_base58_encode_hash_to_str(l_pkey_signing)
-//                                           : dap_chain_hash_fast_to_str_new(l_pkey_signing);
-//                dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR: {
-                json_object *l_obj_tsd_type = json_object_new_string(
-                        "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR");
-                if (!l_obj_tsd_type) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if(l_tsd->size > sizeof(dap_chain_node_addr_t)){
-                    json_object *l_text_wgn = json_object_new_string("Node addr: <WRONG SIZE>");
-                    if (!l_text_wgn){
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                dap_chain_node_addr_t l_node_addr = {0};
-                _dap_tsd_get_scalar(l_tsd, &l_node_addr);
-                char *l_node_addr_str = dap_strdup_printf(NODE_ADDR_FP_STR,NODE_ADDR_FP_ARGS_S(l_node_addr));
-                if (!l_node_addr_str) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_jobj_node_addr = json_object_new_string(l_node_addr_str);
-                DAP_DELETE(l_node_addr_str);
-                if (!l_jobj_node_addr){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "node", l_jobj_node_addr);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE: {
-                json_object *l_obj_tsd_type = json_object_new_string(
-                        "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE");
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Min value: <WRONG SIZE>");
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                uint256_t l_min_value = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_value);
-                json_object_object_add(l_jobj_tsd, "value", json_object_new_string(dap_uint256_to_char(l_min_value, NULL)));
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: {
-                json_object *l_obj_tsd_type = json_object_new_string(
-                        "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT");
-                if (!l_obj_tsd_type) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-                if (l_tsd->size > sizeof(uint256_t)) {
-                    json_object *l_text_wgn = json_object_new_string("Min signers count: <WRONG SIZE>");
-                    if(!l_text_wgn){
-                        json_object_put(l_json_tsd_array);
-                        json_object_put(l_json_subtype);
-                        json_object_put(l_jobj_type);
-                        json_object_put(l_jobj_decree);
-                        json_object_put(l_jobj_tsd);
-                        dap_json_rpc_allocation_error;
-                        return NULL;
-                    }
-                    json_object_object_add(l_jobj_tsd, "warning", l_text_wgn);
-                    break;
-                }
-                uint256_t l_min_signers_count = uint256_0;
-                _dap_tsd_get_scalar(l_tsd, &l_min_signers_count);
-                json_object *l_jobj_min_signers_count = json_object_new_string(dap_uint256_to_char(l_min_signers_count, NULL));
-                if (!l_jobj_min_signers_count) {
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "count", l_jobj_min_signers_count);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: {
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR");
-                json_object *l_jobj_node_addr = json_object_new_string((char *)l_tsd->data);
-                if (!l_jobj_tsd_type && !l_jobj_node_addr) {
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_node_addr);
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "node_addr", l_jobj_node_addr);
-            } break;
-            case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: {
-                json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST");
-                json_object *l_jobj_host = json_object_new_string((char *)l_tsd->data);
-                if (!l_jobj_tsd_type && !l_jobj_host) {
-                    json_object_put(l_jobj_tsd_type);
-                    json_object_put(l_jobj_host);
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type);
-                json_object_object_add(l_jobj_tsd, "host", l_jobj_host);
-            } break;
-            default: {
-                json_object *l_obj_tsd_type = json_object_new_string(
-                        "<UNKNOWN_TYPE_TSD_SECTION>");
-                if (!l_obj_tsd_type){
-                    json_object_put(l_json_tsd_array);
-                    json_object_put(l_json_subtype);
-                    json_object_put(l_jobj_type);
-                    json_object_put(l_jobj_decree);
-                    json_object_put(l_jobj_tsd);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type);
-            } break;
-        }
-        json_object_array_add(l_json_tsd_array, l_jobj_tsd);
-    }
-    json_object *l_jobj_signs = s_dap_chain_datum_decree_certs_dump_json(a_decree->data_n_signs + a_decree->header.data_size,
-                                                                         a_decree->header.signs_size);
-    if (!l_jobj_signs){
-        json_object_put(l_json_tsd_array);
-        json_object_put(l_json_subtype);
-        json_object_put(l_jobj_type);
-        json_object_put(l_jobj_decree);
-        dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "Can't serialize the decree signature in JSON.");
-        return NULL;
-    }
-    json_object_object_add(l_jobj_decree, "type", l_jobj_type);
-    json_object_object_add(l_jobj_decree, "subtype", l_json_subtype);
-    json_object_object_add(l_jobj_decree, "TSD", l_json_tsd_array);
-    json_object_object_add(l_jobj_decree, "signs", l_jobj_signs);
-    return l_jobj_decree;
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c
deleted file mode 100644
index aa4139aa4c..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c
+++ /dev/null
@@ -1,379 +0,0 @@
-
-
-#include "dap_json_rpc_chain_datum_token.h"
-#include "dap_json_rpc_chain_common.h"
-#include "dap_json_rpc_sign.h"
-#include "json.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_token"
-
-json_object *dap_chain_datum_token_flags_to_json(uint16_t a_flags){
-    if (!a_flags) {
-        return json_object_new_null();
-    }
-    json_object *l_jobj_flags = json_object_new_array();
-    for (uint16_t i = 0; BIT(i) <= DAP_CHAIN_DATUM_TOKEN_FLAG_MAX; i++){
-        if(a_flags & (1 << i)){
-            json_object *l_jobj_flag_txt = json_object_new_string(c_dap_chain_datum_token_flag_str[BIT(i)]);
-            json_object_array_add(l_jobj_flags, l_jobj_flag_txt);
-        }
-    }
-    return l_jobj_flags;
-}
-
-
-json_object *dap_chain_datum_token_to_json(dap_chain_datum_token_t * a_token, size_t a_token_size){
-    json_object *l_jobj_token = json_object_new_object();
-    if (!l_jobj_token){
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_jobj_type;
-    json_object *l_jobj_version = json_object_new_uint64(a_token->version);
-    if (!l_jobj_version) {
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    switch (a_token->type) {
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL:
-            l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_DECL");
-            break;
-        case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE:
-            l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE");
-            break;
-        default:
-            l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_UNKNOWN");
-            break;
-    }
-    if (!l_jobj_type) {
-        json_object_put(l_jobj_version);
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_jobj_token, "version", l_jobj_version);
-    json_object_object_add(l_jobj_token, "type", l_jobj_type);
-    json_object *l_jobj_subtype = NULL;
-    json_object *l_jobj_header = json_object_new_object();
-    if (!l_jobj_header){
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    size_t l_tsd_total_size = 0;
-    switch (a_token->subtype) {
-        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: {
-            json_object *l_jobj_decimals  = json_object_new_uint64(a_token->header_simple.decimals);
-            if (!l_jobj_decimals){
-                json_object_put(l_jobj_header);
-                json_object_put(l_jobj_token);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals);
-            l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE");
-        }break;
-        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: {
-            json_object *l_jobj_flags = NULL;
-            json_object *l_jobj_decimals  = NULL;
-            if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) {
-                l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_private_decl.flags));
-                if (!l_jobj_flags){
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_jobj_decimals = json_object_new_uint64(a_token->header_private_decl.decimals);
-                if (!l_jobj_decimals) {
-                    json_object_put(l_jobj_flags);
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_tsd_total_size = a_token->header_private_decl.tsd_total_size;
-            } else {
-                l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_private_update.flags));
-                if (!l_jobj_flags) {
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_jobj_decimals = json_object_new_uint64(a_token->header_private_update.decimals);
-                if (!l_jobj_decimals) {
-                    json_object_put(l_jobj_flags);
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_tsd_total_size = a_token->header_private_update.tsd_total_size;
-            }
-            json_object_object_add(l_jobj_header, "flags", l_jobj_flags);
-            json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals);
-            l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE");
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: {
-            json_object *l_jobj_flags = NULL;
-            json_object *l_jobj_decimals  = NULL;
-            if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) {
-                l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_native_decl.flags));
-                if (!l_jobj_flags) {
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_jobj_decimals = json_object_new_uint64(a_token->header_native_decl.decimals);
-                if (!l_jobj_decimals){
-                    json_object_put(l_jobj_flags);
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_tsd_total_size = a_token->header_native_decl.tsd_total_size;
-            } else {
-                l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_native_update.flags));
-                if (!l_jobj_flags) {
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_jobj_decimals = json_object_new_uint64(a_token->header_native_update.decimals);
-                if (!l_jobj_decimals) {
-                    json_object_put(l_jobj_flags);
-                    json_object_put(l_jobj_header);
-                    json_object_put(l_jobj_token);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                l_tsd_total_size = a_token->header_native_update.tsd_total_size;
-            }
-            json_object_object_add(l_jobj_header, "flags", l_jobj_flags);
-            json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals);
-            l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE");
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: {
-            json_object *l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_public.flags));
-            if (!l_jobj_flags){
-                json_object_put(l_jobj_header);
-                json_object_put(l_jobj_token);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_jobj_premine_supply = json_object_new_string(dap_uint256_to_char(a_token->header_public.premine_supply, NULL));
-            if (!l_jobj_premine_supply) {
-                json_object_put(l_jobj_flags);
-                json_object_put(l_jobj_header);
-                json_object_put(l_jobj_token);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object *l_jobj_premine_address = dap_chain_addr_to_json(&a_token->header_public.premine_address);
-            if (!l_jobj_premine_address) {
-                json_object_put(l_jobj_flags);
-                json_object_put(l_jobj_premine_supply);
-                json_object_put(l_jobj_header);
-                json_object_put(l_jobj_token);
-                dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_ADDR_TO_JSON,
-                                       "Failed to convert address to JSON.");
-                return NULL;
-            }
-            json_object_object_add(l_jobj_header, "flags", l_jobj_flags);
-            json_object_object_add(l_jobj_header, "premine_supply", l_jobj_premine_supply);
-            json_object_object_add(l_jobj_header, "premine_address", l_jobj_premine_address);
-            l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC");
-        } break;
-        default: {
-            l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_UNKNOWN");
-        } break;
-    }
-    if (!l_jobj_subtype) {
-        json_object_put(l_jobj_header);
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_jobj_token, "subtype", l_jobj_subtype);
-    json_object_object_add(l_jobj_token, "header", l_jobj_header);
-    json_object *l_jobj_ticker = json_object_new_string(a_token->ticker);
-    if (!l_jobj_ticker) {
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_jobj_token, "ticker", l_jobj_ticker);
-    json_object *l_jobj_signs_valid = json_object_new_uint64(a_token->signs_valid);
-    if (!l_jobj_signs_valid) {
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_jobj_token, "signs_valid", l_jobj_signs_valid);
-    json_object *l_jobj_signs_total = json_object_new_uint64(a_token->signs_total);
-    if (!l_jobj_signs_total) {
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_jobj_token, "signs_total", l_jobj_signs_total);
-    json_object *l_obj_signs = json_object_new_array();
-    if (!l_obj_signs) {
-        json_object_put(l_jobj_token);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    size_t l_offset = 0;
-    size_t l_certs_field_size = a_token_size - sizeof(*a_token);
-    while ((l_offset + l_tsd_total_size) < l_certs_field_size) {
-        dap_sign_t *l_sign = (dap_sign_t *) ((byte_t*)a_token->data_n_tsd + l_tsd_total_size + l_offset);
-        l_offset += dap_sign_get_size(l_sign);
-        json_object *l_obj_sign = dap_sign_to_json(l_sign);
-        if (!l_obj_sign || !dap_sign_get_size(l_sign)) {
-            json_object_put(l_obj_signs);
-            json_object_put(l_jobj_token);
-            dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "Failed to convert signature to JSON.");
-            return NULL;
-        }
-        json_object_array_add(l_obj_signs, l_obj_sign);
-    }
-    json_object_object_add(l_jobj_token, "signs", l_obj_signs);
-    return l_jobj_token;
-}
-
-
-json_object *dap_chain_datum_emission_to_json(dap_chain_datum_token_emission_t *a_emission, size_t a_emission_size){
-    json_object *l_emi_obj = json_object_new_object();
-    json_object *l_emi_version = json_object_new_uint64(a_emission->hdr.version);
-    json_object *l_emi_type = json_object_new_string(c_dap_chain_datum_token_emission_type_str[a_emission->hdr.type]);
-    json_object *l_emi_address = dap_chain_addr_to_json(&a_emission->hdr.address);
-    json_object *l_emi_header = json_object_new_object();
-    json_object *l_emi_data = json_object_new_object();
-    if (!l_emi_obj || !l_emi_version || !l_emi_type || !l_emi_address || !l_emi_header || ! l_emi_data) {
-        json_object_put(l_emi_obj);
-        json_object_put(l_emi_version);
-        json_object_put(l_emi_type);
-        json_object_put(l_emi_address);
-        json_object_put(l_emi_header);
-        json_object_put(l_emi_data);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_emi_header, "version", l_emi_version);
-    json_object_object_add(l_emi_header, "type", l_emi_type);
-    json_object_object_add(l_emi_header, "address", l_emi_address);
-    json_object_object_add(l_emi_obj, "header", l_emi_header);
-    switch (a_emission->hdr.type){
-        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: {
-            json_object *l_obj_size = json_object_new_uint64(a_emission->data.type_auth.size);
-            json_object *l_obj_tsd_total_size = json_object_new_uint64(a_emission->data.type_auth.tsd_total_size);
-            json_object *l_obj_signs_count = json_object_new_uint64(a_emission->data.type_auth.signs_count);
-            if (!l_obj_size || !l_obj_tsd_total_size || !l_obj_signs_count) {
-                json_object_put(l_obj_size);
-                json_object_put(l_obj_tsd_total_size);
-                json_object_put(l_obj_signs_count);
-                json_object_put(l_emi_data);
-                json_object_put(l_emi_obj);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_emi_data, "size", l_obj_size);
-            json_object_object_add(l_emi_data, "tsd_total_size", l_obj_tsd_total_size);
-            json_object_object_add(l_emi_data, "signs_count", l_obj_signs_count);
-            if (((void *) a_emission->tsd_n_signs + a_emission->data.type_auth.tsd_total_size) >
-                  ((void *) a_emission + a_emission_size)) {
-                char *l_err_str = dap_strdup_printf("Malformed DATUM type %d, TSD section is out-of-buffer (%" DAP_UINT64_FORMAT_U " vs %zu)",
-                                                            a_emission->hdr.type, a_emission->data.type_auth.tsd_total_size, a_emission_size);
-                if (!l_err_str){
-                    json_object_put(l_emi_data);
-                    json_object_put(l_emi_obj);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object *l_err_tsd = json_object_new_string(l_err_str);
-                DAP_DELETE(l_err_str);
-                if (!l_err_tsd) {
-                    json_object_put(l_emi_data);
-                    json_object_put(l_emi_obj);
-                    dap_json_rpc_allocation_error;
-                    return NULL;
-                }
-                json_object_object_add(l_emi_data, "ERROR", l_err_tsd);
-            }
-            json_object *l_obj_signs = json_object_new_array();
-            if (!l_obj_signs){
-                json_object_put(l_emi_data);
-                json_object_put(l_emi_obj);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            size_t l_offset = a_emission->data.type_auth.tsd_total_size;
-            for (int i = 0; i < a_emission->data.type_auth.signs_count; i++) {
-                dap_sign_t *l_sign = (dap_sign_t *) ((byte_t*)a_emission->tsd_n_signs + l_offset);
-                l_offset += dap_sign_get_size(l_sign);
-                json_object *l_obj_sign = dap_sign_to_json(l_sign);
-                if (!l_obj_sign) {
-                    json_object_put(l_obj_signs);
-                    json_object_put(l_emi_data);
-                    json_object_put(l_emi_obj);
-                    dap_json_rpc_error_add(3, "Failed to serialize signature to JSON object.");
-                    return NULL;
-                }
-                json_object_array_add(l_obj_signs, l_obj_sign);
-            }
-            json_object_object_add(l_emi_data, "signs", l_obj_signs);
-
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: {
-            json_object *l_code_name = json_object_new_string(a_emission->data.type_algo.codename);
-            if (!l_code_name) {
-                json_object_put(l_emi_data);
-                json_object_put(l_emi_obj);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_emi_data, "codename", l_code_name);
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: {
-            json_object *l_value_start = json_object_new_uint64(a_emission->data.type_atom_owner.value_start);
-            json_object *l_value_change_algo_codename = json_object_new_string(
-                    a_emission->data.type_atom_owner.value_change_algo_codename);
-            if (!l_value_start || !l_value_change_algo_codename) {
-                json_object_put(l_value_start);
-                json_object_put(l_value_change_algo_codename);
-                json_object_put(l_emi_data);
-                json_object_put(l_emi_obj);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_emi_data, "value_start", l_value_start);
-            json_object_object_add(l_emi_data, "value_change_algo_codename", l_value_change_algo_codename);
-        } break;
-        case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT:
-        {
-            json_object *l_obj_addr = dap_chain_addr_to_json(&a_emission->data.type_presale.addr);
-            json_object *l_obj_flags = json_object_new_int64(a_emission->data.type_presale.flags);
-            json_object *l_obj_lock_time = json_object_new_uint64(a_emission->data.type_presale.lock_time);
-            if (!l_obj_addr || !l_obj_flags || !l_obj_lock_time) {
-                json_object_put(l_obj_addr);
-                json_object_put(l_obj_flags);
-                json_object_put(l_obj_lock_time);
-                json_object_put(l_emi_data);
-                json_object_put(l_emi_obj);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_emi_data, "addr", l_obj_addr);
-            json_object_object_add(l_emi_data, "flags", l_obj_flags);
-            json_object_object_add(l_emi_data, "lock_time", l_obj_lock_time);
-        }break;
-    }
-    json_object_object_add(l_emi_obj, "data", l_emi_data);
-    return  l_emi_obj;
-}
-
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
deleted file mode 100644
index 46997d59d1..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <memory.h>
-#include <assert.h>
-#include "dap_common.h"
-#include "dap_sign.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_tx_items.h"
-
-#include "dap_json_rpc_chain_datum_tx.h"
-#include "dap_json_rpc_chain_datum_tx_items.h"
-#include "dap_json_rpc_chain_datum_tx_receipt.h"
-#include "json.h"
-#include "dap_chain_datum_tx_voting.h"
-#include "dap_chain_net.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_tx"
-
-
-
-json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id){
-    json_object *l_obj_items = json_object_new_array();
-    if (!l_obj_items) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    uint32_t
-        l_tx_items_size_total = 0,
-        l_tx_items_size = a_tx->header.tx_items_size;
-    while(l_tx_items_size_total < l_tx_items_size) {
-        uint8_t *item = a_tx->tx_items + l_tx_items_size_total;
-        size_t l_tx_item_size = dap_chain_datum_item_tx_get_size(item);
-        if (l_tx_item_size == 0) {
-            json_object_put(l_obj_items);
-            l_obj_items = json_object_new_null();
-            break;
-        }
-        dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_get_type(item);
-        json_object *l_obj_item_type = NULL, *l_obj_item_data = NULL;
-        switch (l_item_type) {
-            case TX_ITEM_TYPE_IN:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN");
-                l_obj_item_data = dap_chain_datum_tx_item_in_to_json((dap_chain_tx_in_t*)item);
-                break;
-            case TX_ITEM_TYPE_OUT:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT");
-                l_obj_item_data = dap_chain_datum_tx_item_out_to_json((dap_chain_tx_out_t*)item);
-                break;
-            case TX_ITEM_TYPE_IN_REWARD:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_REWARD");
-                l_obj_item_data = dap_chain_datum_tx_item_in_reward_to_json((dap_chain_tx_in_reward_t*)item);
-                break;
-            case TX_ITEM_TYPE_IN_EMS:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_EMS");
-                l_obj_item_data = dap_chain_datum_tx_item_in_ems_to_json((dap_chain_tx_in_ems_t*)item);
-                break;
-            case TX_ITEM_TYPE_SIG:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_SIG");
-                l_obj_item_data = dap_chain_datum_tx_item_sig_to_json((dap_chain_tx_sig_t*)item);
-                break;
-            case TX_ITEM_TYPE_RECEIPT:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_RECEIPT");
-                l_obj_item_data = dap_chain_datum_tx_receipt_to_json((dap_chain_datum_tx_receipt_t*)item);
-                break;
-            case TX_ITEM_TYPE_IN_COND:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_COND");
-                l_obj_item_data = dap_chain_datum_tx_item_in_cond_to_json((dap_chain_tx_in_cond_t*)item);
-                break;
-            case TX_ITEM_TYPE_OUT_COND:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT_COND");
-                
-
-                switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:
-                        l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_pay_to_json((dap_chain_tx_out_cond_t*)item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:
-                        l_obj_item_data = dap_chain_net_srv_stake_lock_cond_out_to_json((dap_chain_tx_out_cond_t*)item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:
-                        l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_stake_to_json((dap_chain_tx_out_cond_t*)item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE:
-                        l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_xchange_to_json((dap_chain_tx_out_cond_t*)item);
-                        break;
-                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE:
-                        l_obj_item_data = json_object_new_object();
-                        break;
-                   default:break;
-                }
-                // add time
-                dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires;
-                char l_time_str[32] = "never";
-                if (l_ts_exp) {
-                    dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_ts_exp); /* Convert ts to  "Sat May 17 01:17:08 2014\n" */
-                    l_time_str[strlen(l_time_str)-1] = '\0';                    /* Remove "\n"*/
-                }
-                json_object_object_add(l_obj_item_data, "ts_expires", json_object_new_string(l_time_str));
-                json_object_object_add(l_obj_item_data, "subtype", json_object_new_string(dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype)));
-                const char *l_val_str, *l_val_datoshi_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_val_str);
-                json_object_object_add(l_obj_item_data, "value", json_object_new_string(l_val_str));
-                json_object_object_add(l_obj_item_data, "value_datoshi", json_object_new_string(l_val_datoshi_str));
-                char uid_str[32];
-                sprintf(uid_str, "0x%016"DAP_UINT64_FORMAT_x"", ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64);
-                json_object_object_add(l_obj_item_data, "uid", json_object_new_string(uid_str));
-                break;
-            case TX_ITEM_TYPE_OUT_EXT:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT_EXT");
-                l_obj_item_data = dap_chain_datum_tx_item_out_ext_to_json((dap_chain_tx_out_ext_t*)item);
-                break;
-            case TX_ITEM_TYPE_TSD:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_TSD");
-                l_obj_item_data = dap_chain_datum_tx_item_tsd_to_json((dap_chain_tx_tsd_t*)item);
-                break;
-            case TX_ITEM_TYPE_VOTE:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTE");
-                dap_chain_net_t *l_net = dap_chain_net_by_id(*a_net_id);
-                l_obj_item_data = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)item, l_net->pub.ledger);
-            break;
-            case TX_ITEM_TYPE_VOTING:
-                l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTING");
-                l_obj_item_data = dap_chain_datum_tx_item_voting_tsd_to_json(a_tx);
-            break;
-            default: {
-                char *l_hash_str;
-                dap_get_data_hash_str_static(a_tx, dap_chain_datum_tx_get_size(a_tx), l_hash_str);
-                log_it(L_NOTICE, "Transaction %s has an item whose type cannot be handled by the dap_chain_datum_tx_to_json function.", l_hash_str);
-                break;
-            }
-        }
-        if (!l_obj_item_type){
-            json_object_array_add(l_obj_items, json_object_new_null());
-        } else {
-            if (!l_obj_item_data)
-                l_obj_item_data = json_object_new_null();
-            json_object *l_obj_item = json_object_new_object();
-            if (!l_obj_item) {
-                json_object_put(l_obj_item_type);
-                json_object_put(l_obj_item_data);
-                json_object_put(l_obj_items);
-                dap_json_rpc_allocation_error;
-                return NULL;
-            }
-            json_object_object_add(l_obj_item, "type", l_obj_item_type);
-            json_object_object_add(l_obj_item, "data", l_obj_item_data);
-            json_object_array_add(l_obj_items, l_obj_item);
-        }
-        l_tx_items_size_total += l_tx_item_size;
-    }
-    return l_obj_items;
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
deleted file mode 100644
index 56a7f87389..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c
+++ /dev/null
@@ -1,302 +0,0 @@
-#include <stdint.h>
-#include <string.h>
-
-#include "dap_common.h"
-#include "dap_chain_common.h"
-#include "dap_sign.h"
-#include "dap_hash.h"
-#include "dap_chain_datum_tx_in.h"
-#include "dap_chain_datum_tx_out.h"
-#include "dap_chain_datum_tx_in_cond.h"
-#include "dap_chain_datum_tx_out_cond.h"
-#include "dap_chain_datum_tx_items.h"
-#include "dap_enc_base58.h"
-
-#include "dap_json_rpc_chain_datum_tx_items.h"
-#include "dap_json_rpc_chain_common.h"
-#include "dap_json_rpc_sign.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_tx_items"
-
-json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item) {
-        const char *l_coins_str,
-             *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str);
-        char *l_hash_str = dap_enc_base58_encode_hash_to_str_static(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash);
-        json_object *l_obj = json_object_new_object();
-        char unit_str[32];
-        snprintf(unit_str, 32, "0x%08x", ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32);
-        json_object_object_add(l_obj, "unit", json_object_new_string(unit_str));
-        json_object_object_add(l_obj, "pkey", json_object_new_string(l_hash_str));
-        json_object_object_add(l_obj, "max_price", json_object_new_string(l_coins_str));
-        json_object_object_add(l_obj, "max_price_datoshi", json_object_new_string(l_value_str));
-        return l_obj;
-}
-
-json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange) {
-    if (a_srv_xchange->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE){
-        json_object *l_object = json_object_new_object();
-        json_object_object_add(l_object, "value", json_object_new_string(dap_uint256_to_char(a_srv_xchange->header.value, NULL)));
-        json_object_object_add(l_object, "rate", ( { 
-            const char *l_rate; dap_uint256_to_char(a_srv_xchange->subtype.srv_xchange.rate, &l_rate);
-            json_object_new_string(l_rate); } ));
-        json_object_object_add(l_object, "srv_uid", json_object_new_uint64(a_srv_xchange->header.srv_uid.uint64));
-        json_object_object_add(l_object, "buy_net_id", dap_chain_net_id_to_json(a_srv_xchange->subtype.srv_xchange.buy_net_id));
-        json_object_object_add(l_object, "sell_net_id", dap_chain_net_id_to_json(a_srv_xchange->subtype.srv_xchange.sell_net_id));
-        json_object_object_add(l_object, "buy_token", json_object_new_string(a_srv_xchange->subtype.srv_xchange.buy_token));
-        json_object_object_add(l_object, "seller_addr", dap_chain_addr_to_json(&a_srv_xchange->subtype.srv_xchange.seller_addr));
-        //TODO: Parse TSD
-        return l_object;
-    }
-    return NULL;
-}
-
-json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake) {
-    if (a_srv_stake->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE) {
-        json_object *l_object = json_object_new_object();
-        json_object *l_obj_value = json_object_new_string(dap_uint256_to_char(a_srv_stake->header.value, NULL));
-        json_object *l_obj_srv_uid = json_object_new_uint64(a_srv_stake->header.srv_uid.uint64);
-        json_object *l_obj_signing_addr = dap_chain_addr_to_json(&a_srv_stake->subtype.srv_stake_pos_delegate.signing_addr);
-        char *l_signer_node_addr = dap_strdup_printf(
-                NODE_ADDR_FP_STR,
-                NODE_ADDR_FP_ARGS_S(a_srv_stake->subtype.srv_stake_pos_delegate.signer_node_addr));
-        json_object *l_obj_signer_node_addr = json_object_new_string(l_signer_node_addr);
-        DAP_DELETE(l_signer_node_addr);
-        json_object_object_add(l_object, "value", l_obj_value);
-        json_object_object_add(l_object, "srv_uid", l_obj_srv_uid);
-        json_object_object_add(l_object, "signind_addr", l_obj_signing_addr);
-        json_object_object_add(l_object, "signer_node_addr", l_obj_signer_node_addr);
-        return l_object;
-    }
-    return NULL;
-}
-
-
-json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond_t *a_stake_lock)
-{
-    if (a_stake_lock->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) {
-        json_object *l_object = json_object_new_object();
-        json_object_object_add(l_object, "value", json_object_new_string(dap_uint256_to_char(a_stake_lock->header.value, NULL)));
-        json_object_object_add(l_object, "srv_uid", json_object_new_uint64(a_stake_lock->header.srv_uid.uint64));
-        json_object_object_add(l_object, "reinvest_percent",
-            json_object_new_string(dap_uint256_to_char(a_stake_lock->subtype.srv_stake_lock.reinvest_percent, NULL)));
-        json_object_object_add(l_object, "time_unlock", json_object_new_uint64(a_stake_lock->subtype.srv_stake_lock.time_unlock));
-        json_object_object_add(l_object, "flags", json_object_new_uint64(a_stake_lock->subtype.srv_stake_lock.flags));
-        return l_object;
-    }
-    return NULL;
-}
-
-
-json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out) {
-    json_object *l_object = json_object_new_object();
-    const char *l_val_coins, *l_val_datoshi = dap_uint256_to_char(a_out->header.value, &l_val_coins);
-    json_object_object_add(l_object, "value", json_object_new_string(l_val_coins));
-    json_object_object_add(l_object, "value_datoshi", json_object_new_string(l_val_datoshi));
-    json_object_object_add(l_object, "address", dap_chain_addr_to_json(&a_out->addr));
-    return l_object;
-}
-
-
-json_object* dap_chain_datum_tx_item_out_ext_to_json(const dap_chain_tx_out_ext_t *a_out_ext) {
-    json_object *l_obj = json_object_new_object();
-    json_object_object_add(l_obj, "value", json_object_new_string(dap_uint256_to_char(a_out_ext->header.value, NULL)));
-    json_object_object_add(l_obj, "addr", dap_chain_addr_to_json(&a_out_ext->addr));
-    json_object_object_add(l_obj, "token", json_object_new_string(a_out_ext->token));
-    return l_obj;
-}
-
-json_object* dap_chain_datum_tx_item_in_cond_to_json(dap_chain_tx_in_cond_t *a_in_cond){
-    json_object *l_obj = json_object_new_object();
-    if (!l_obj) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_receipt_idx = json_object_new_uint64(a_in_cond->header.receipt_idx);
-    if (!l_obj_receipt_idx) {
-        json_object_put(l_obj);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_out_prev_idx = json_object_new_uint64(a_in_cond->header.tx_out_prev_idx);
-    if (!l_obj_out_prev_idx) {
-        json_object_put(l_obj_receipt_idx);
-        json_object_put(l_obj);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_prev_hash = NULL;
-    if (dap_hash_fast_is_blank(&a_in_cond->header.tx_prev_hash)){
-        l_obj_prev_hash = json_object_new_null();
-    } else {
-        char *l_prev_hash = dap_hash_fast_to_str_new(&a_in_cond->header.tx_prev_hash);
-        if(!l_prev_hash) {
-            json_object_put(l_obj_out_prev_idx);
-            json_object_put(l_obj_receipt_idx);
-            json_object_put(l_obj);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        l_obj_prev_hash = json_object_new_string(dap_strdup(l_prev_hash));
-        if (!l_obj_prev_hash) {
-            json_object_put(l_obj_out_prev_idx);
-            json_object_put(l_obj_receipt_idx);
-            json_object_put(l_obj);
-            DAP_DELETE(l_prev_hash);
-            dap_json_rpc_allocation_error;
-            return NULL;
-        }
-        DAP_DELETE(l_prev_hash);
-    }
-    json_object_object_add(l_obj, "receipt_idx", l_obj_receipt_idx);
-    json_object_object_add(l_obj, "out_prev_idx", l_obj_out_prev_idx);
-    json_object_object_add(l_obj, "tx_prev_hash", l_obj_prev_hash);
-    return l_obj;
-}
-
-json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in){
-    json_object *l_obj_in = json_object_new_object();
-    if (!l_obj_in) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_prev_idx = json_object_new_uint64(a_in->header.tx_out_prev_idx);
-    if (!l_obj_prev_idx) {
-        json_object_put(l_obj_in);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    char l_hash[DAP_CHAIN_HASH_FAST_STR_SIZE];
-    dap_chain_hash_fast_to_str(&a_in->header.tx_prev_hash, l_hash, sizeof(l_hash));
-    json_object *l_obj_hash = json_object_new_string(l_hash);
-    if (!l_obj_hash) {
-        json_object_put(l_obj_in);
-        json_object_put(l_obj_prev_idx);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_obj_in, "prev_idx", l_obj_prev_idx);
-    json_object_object_add(l_obj_in, "prev_hash", l_obj_hash);
-    return l_obj_in;
-}
-
-json_object* dap_chain_datum_tx_item_in_reward_to_json(dap_chain_tx_in_reward_t *a_in_reward){
-    json_object *l_jobj_ret = json_object_new_object();
-    char *l_hash_block = dap_hash_fast_to_str_new(&a_in_reward->block_hash);
-    if (!l_jobj_ret && !l_hash_block) {
-        json_object_put(l_jobj_ret);
-        DAP_DEL_Z(l_hash_block);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_jobj_block_hash = json_object_new_string(l_hash_block);
-    DAP_DEL_Z(l_hash_block);
-    if (!l_jobj_block_hash) {
-        return NULL;
-    }
-    json_object_object_add(l_jobj_ret, "block_hash", l_jobj_block_hash);
-    return l_jobj_ret;
-}
-
-json_object* dap_chain_datum_tx_item_tsd_to_json(dap_chain_tx_tsd_t *a_tsd){
-    json_object *l_object = json_object_new_object();
-    if (!l_object) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_tsd_type = json_object_new_int(a_tsd->header.type);
-    if(!l_obj_tsd_type) {
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_tsd_size = json_object_new_uint64(a_tsd->header.size);
-    if (!l_obj_tsd_size) {
-        json_object_put(l_obj_tsd_type);
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_data = json_object_new_string_len((char *)a_tsd->tsd, a_tsd->header.size);
-    if (!l_obj_data) {
-        json_object_put(l_obj_tsd_size);
-        json_object_put(l_obj_tsd_type);
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_object, "type", l_obj_tsd_type);
-    json_object_object_add(l_object, "size", l_obj_tsd_size);
-    json_object_object_add(l_object, "data", l_obj_data);
-    return l_object;
-}
-
-json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t *a_in_ems)
-{
-    json_object *l_object = json_object_new_object();
-    if (!l_object) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_ticker = json_object_new_string(a_in_ems->header.ticker);
-    if (!l_obj_ticker){
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_chain_id = json_object_new_uint64(a_in_ems->header.token_emission_chain_id.uint64);
-    if (!l_obj_chain_id) {
-        json_object_put(l_object);
-        json_object_put(l_obj_ticker);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    char l_ehf[DAP_CHAIN_HASH_FAST_STR_SIZE];
-    dap_chain_hash_fast_to_str(&a_in_ems->header.token_emission_hash, l_ehf, sizeof(l_ehf));
-    json_object *l_obj_ehf = json_object_new_string(l_ehf);
-    if (!l_obj_ehf) {
-        json_object_put(l_object);
-        json_object_put(l_obj_chain_id);
-        json_object_put(l_obj_ticker);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_object, "ticker", l_obj_ticker);
-    json_object_object_add(l_object, "chain_id", l_obj_chain_id);
-    json_object_object_add(l_object, "emission_hash", l_obj_ehf);
-    return l_object;
-}
-
-json_object *dap_chain_datum_tx_item_out_cond_fee_to_json(dap_chain_tx_out_cond_t *a_fee) {
-    return a_fee->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE
-        ? ( {
-                json_object *l_obj = json_object_new_object();
-                json_object_object_add(l_obj, "balance", json_object_new_string(dap_uint256_to_char(a_fee->header.value, NULL)));
-                l_obj;
-            } )
-        : NULL;
-}
-
-json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig){
-    json_object *l_object = json_object_new_object();
-    if (!l_object) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_sign_size = json_object_new_uint64(a_sig->header.sig_size);
-    if (!l_sign_size) {
-        json_object_put(l_object);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_sign = dap_sign_to_json((dap_sign_t*)a_sig->sig);
-    if (!l_sign) {
-        json_object_put(l_object);
-        json_object_put(l_sign_size);
-        dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON,
-                               "Error serializing signature to JSON.");
-        return NULL;
-    }
-    json_object_object_add(l_object, "sign_size", l_sign_size);
-    json_object_object_add(l_object, "sign", l_sign);
-    return l_object;
-}
diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
deleted file mode 100644
index 439a03ff34..0000000000
--- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "dap_common.h"
-#include "dap_sign.h"
-#include "dap_chain_datum_tx_receipt.h"
-
-#include "dap_json_rpc_sign.h"
-#include "dap_json_rpc_chain_datum_tx_receipt.h"
-
-#define LOG_TAG "dap_json_rpc_chain_datum_tx_receipt"
-
-
-json_object* dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info){
-    json_object *l_obj = json_object_new_object();
-    if (!l_obj) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_obj, "uid", json_object_new_uint64(a_info->srv_uid.uint64));
-#if DAP_CHAIN_NET_SRV_UID_SIZE == 8
-    json_object_object_add(l_obj, "ext_size", json_object_new_uint64(a_info->addition));
-#endif
-    json_object_object_add(l_obj, "units", json_object_new_uint64(a_info->units));
-    json_object_object_add(l_obj, "units_type", json_object_new_string(dap_chain_srv_unit_enum_to_str(a_info->units_type.enm)));
-
-    const char *l_value, *l_datoshi_value = dap_uint256_to_char(a_info->value_datoshi, &l_value);
-    json_object_object_add(l_obj, "value", json_object_new_string(l_value));
-    json_object_object_add(l_obj, "value_datoshi", json_object_new_string(l_datoshi_value));
-    return l_obj;
-}
-
-json_object *dap_chain_datum_tx_receipt_to_json(dap_chain_datum_tx_receipt_t *a_receipt) {
-    json_object *l_obj = json_object_new_object();
-    if (!l_obj) {
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_info = dap_chain_receipt_info_to_json(&a_receipt->receipt_info);
-    if (!l_obj_info) {
-        json_object_put(l_obj);
-        return NULL;
-    }
-    json_object *l_obj_size = json_object_new_uint64(a_receipt->size);
-    if (!l_obj_size) {
-        json_object_put(l_obj);
-        json_object_put(l_obj_info);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    //Provider
-    dap_sign_t *l_first_sign  = dap_chain_datum_tx_receipt_sign_get(a_receipt, a_receipt->size, 1);
-    //Client
-    dap_sign_t *l_second_sign  = dap_chain_datum_tx_receipt_sign_get(a_receipt, a_receipt->size, 2);
-    json_object *l_obj_signs = json_object_new_object();
-    if (!l_obj_signs) {
-        json_object_put(l_obj_size);
-        json_object_put(l_obj_info);
-        json_object_put(l_obj);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object *l_obj_provider_sign = dap_sign_to_json(l_first_sign);
-    json_object *l_obj_client_sign = dap_sign_to_json(l_second_sign);
-    json_object_object_add(l_obj_signs, "provider", l_obj_provider_sign);
-    json_object_object_add(l_obj_signs, "client", l_obj_client_sign);
-    json_object *l_exts_data = json_object_new_string_len((char *)a_receipt->exts_n_signs, a_receipt->exts_size);
-    if (!l_exts_data) {
-        json_object_put(l_obj_size);
-        json_object_put(l_obj_info);
-        json_object_put(l_obj_signs);
-        json_object_put(l_obj);
-        dap_json_rpc_allocation_error;
-        return NULL;
-    }
-    json_object_object_add(l_obj, "info", l_obj_info);
-    json_object_object_add(l_obj, "size", l_obj_size);
-    json_object_object_add(l_obj, "sings", l_obj_signs);
-    json_object_object_add(l_obj, "exts_data", l_exts_data);
-    return l_obj;
-}
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_common.h b/modules/json_rpc/common/include/dap_json_rpc_chain_common.h
deleted file mode 100644
index d88b9b4a56..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_common.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "dap_chain_common.h"
-#include "dap_json_rpc_errors.h"
-
-json_object *dap_chain_addr_to_json(const dap_chain_addr_t *a_addr);
-
-DAP_STATIC_INLINE json_object *dap_chain_net_id_to_json(dap_chain_net_id_t a_net_id) {
-    return json_object_new_uint64(a_net_id.uint64);
-}
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h
deleted file mode 100644
index 6f4767fae3..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once 
-
-#include "dap_chain_datum.h"
-#include "dap_json_rpc_errors.h"
-
-json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum);
-json_object * dap_chain_datum_data_to_json(dap_chain_datum_t *a_datum);
\ No newline at end of file
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h
deleted file mode 100644
index 64c2f0bf16..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#pragma once
-
-#include "dap_chain_datum_anchor.h"
-#include "dap_json_rpc_errors.h"
-
-json_object *dap_chain_datum_anchor_to_json(dap_chain_datum_anchor_t *a_anchor);
-
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h
deleted file mode 100644
index de30d1c0d5..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "dap_chain_datum_decree.h"
-#include "dap_json_rpc_errors.h"
-
-/**
- * @brief dap_chain_datum_decree_to_json Convert dap_chain_datum_decree_t tp json_object
- * @param a_decree pointer to decree
- * @return pointer json_object
- */
-json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree);
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h
deleted file mode 100644
index b63649e547..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "dap_chain_datum_token.h"
-#include "dap_json_rpc_errors.h"
-
-json_object *dap_chain_datum_token_to_json(dap_chain_datum_token_t * a_token, size_t a_token_size);
-json_object *dap_chain_datum_token_flags_to_json(uint16_t a_flags);
-json_object *dap_chain_datum_emission_to_json(dap_chain_datum_token_emission_t *a_emission, size_t a_emission_size);
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h
deleted file mode 100644
index 7d4e64ef59..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "dap_chain_datum_tx.h"
-#include "dap_json_rpc_errors.h"
-
-json_object * dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id);
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h
deleted file mode 100644
index 815c8e89b2..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "dap_chain_datum_tx_items.h"
-#include "dap_json_rpc_errors.h"
-
-
-json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t *a_in_ems);
-json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in);
-json_object* dap_chain_datum_tx_item_in_reward_to_json(dap_chain_tx_in_reward_t *a_in_reward);
-json_object* dap_chain_datum_tx_item_tsd_to_json(dap_chain_tx_tsd_t *a_tsd);
-json_object* dap_chain_datum_tx_item_in_cond_to_json(dap_chain_tx_in_cond_t *a_in_cond);
-json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out);
-json_object* dap_chain_datum_tx_item_out_ext_to_json(const dap_chain_tx_out_ext_t *a_out_ext);
-json_object *dap_chain_datum_tx_item_out_cond_fee_to_json(dap_chain_tx_out_cond_t *a_fee);
-json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item);
-json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange);
-json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake);
-json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond_t *a_stake_lock);
-json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig);
diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h
deleted file mode 100644
index c27cfcfd0b..0000000000
--- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "dap_chain_datum_tx_receipt.h"
-#include "dap_json_rpc_errors.h"
-
-json_object *dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info);
-json_object *dap_chain_datum_tx_receipt_to_json(dap_chain_datum_tx_receipt_t *a_receipt);
\ No newline at end of file
diff --git a/modules/json_rpc/mempool/CMakeLists.txt b/modules/json_rpc/mempool/CMakeLists.txt
deleted file mode 100644
index 86dd39002f..0000000000
--- a/modules/json_rpc/mempool/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-project (dap_json_rpc_chain_mempool)
-
-
-file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS include/*.h)
-file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS  *.c)
-
-add_library(${PROJECT_NAME}  STATIC ${DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS} ${DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS})
-
-target_link_libraries(dap_json_rpc_chain_mempool dap_http_server dap_client dap_chain_net dap_global_db dap_core dap_chain_cs_blocks dap_chain_mempool dap_json_rpc_core dap_chain_btc_rpc)
-target_include_directories(dap_json_rpc_chain_mempool PUBLIC include/ )
diff --git a/modules/json_rpc/mempool/dap_chain_mempool_rpc.c b/modules/json_rpc/mempool/dap_chain_mempool_rpc.c
deleted file mode 100644
index 3f97641be0..0000000000
--- a/modules/json_rpc/mempool/dap_chain_mempool_rpc.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <memory.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <time.h>
-#include <pthread.h>
-#endif
-
-#include "dap_common.h"
-#include "dap_hash.h"
-#include "dap_http_client.h"
-#include "dap_http_simple.h"
-#include "dap_enc_base58.h"
-#include "dap_enc_http.h"
-#include "http_status_code.h"
-#include "dap_chain_common.h"
-#include "dap_chain_node.h"
-#include "dap_global_db.h"
-#include "dap_enc.h"
-#include <dap_enc_http.h>
-#include <dap_enc_key.h>
-#include <dap_enc_ks.h>
-#include "dap_chain_mempool.h"
-
-#include "dap_common.h"
-#include "dap_list.h"
-#include "dap_chain.h"
-#include "dap_chain_net.h"
-#include "dap_chain_net_tx.h"
-#include "dap_sign.h"
-#include "dap_chain_datum_tx.h"
-#include "dap_chain_datum_tx_items.h"
-#include "dap_chain_net_srv.h"
-#include "dap_chain_cs_blocks.h"
-
-#include "dap_chain_mempool_rpc.h"
-#include "dap_json_rpc_chain_datum.h"
-#include "dap_json_rpc_request_handler.h"
-#include "dap_json_rpc_response_handler.h"
-#include "json.h"
-
-#define LOG_TAG "dap_chain_mempool_rpc"
-
-int dap_chain_mempool_rpc_init(void) {
-    dap_json_rpc_registration_request_handler("mempool_list", dap_chain_mempool_rpc_handler_list);
-    dap_json_rpc_registration_request_handler("memtest", dap_chain_mempool_rpc_handler_test);
-    return 0;
-}
-
-void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
-                                        dap_json_rpc_response_t *a_response, const char *a_method) {
-    UNUSED(a_method);
-    char *l_tn = NULL;
-//    char *l_chain_str = NULL;
-    for (uint32_t i = 0; i < a_params->length; i++) {
-        dap_json_rpc_param_t *l_prm = a_params->params[i];
-        if (i == 0)
-            l_tn = l_prm->value_param;
-    }
-    if (dap_strcmp(l_tn, "NULL") == 0) {
-        a_response->type = TYPE_RESPONSE_NULL;
-    } else if (dap_strcmp(l_tn, "STRING") == 0) {
-        a_response->type = TYPE_RESPONSE_STRING;
-        a_response->result_string = dap_strdup("This test string");
-    } else if (dap_strcmp(l_tn, "INTEGER") == 0) {
-        a_response->type = TYPE_RESPONSE_INTEGER;
-        a_response->result_int = 4555745;
-    } else if (dap_strcmp(l_tn, "BOOLEAN") == 0) {
-        a_response->type = TYPE_RESPONSE_BOOLEAN;
-        a_response->result_boolean = true;
-    } else if (dap_strcmp(l_tn, "DOUBLE") == 0) {
-        a_response->type = TYPE_RESPONSE_DOUBLE;
-        a_response->result_double = 75.545;
-    } else if (dap_strcmp(l_tn, "JSON") == 0) {
-        a_response->type = TYPE_RESPONSE_JSON;
-        json_object *l_obj = json_object_new_object();
-        json_object *l_int = json_object_new_uint64(45577445);
-        json_object *l_boolean = json_object_new_boolean((json_bool)1);
-        json_object *l_double = json_object_new_double(457.74514);
-        json_object *l_arr = json_object_new_array();
-        for (int i = 1000; i < 1997; i++) {
-            json_object *l_cur = json_object_new_int(i);
-            json_object_array_add(l_arr, l_cur);
-        }
-        json_object_object_add(l_obj, "int", l_int);
-        json_object_object_add(l_obj, "boolean", l_boolean);
-        json_object_object_add(l_obj, "double", l_double);
-        json_object_object_add(l_obj, "array", l_arr);
-        a_response->result_json_object = json_object_get(l_obj);
-        json_object_put(l_obj);
-    } else {
-        //set ERR code
-    }
-}
-
-void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
-                                        dap_json_rpc_response_t *a_response, const char *a_method) {
-    char *l_net_str = NULL;
-    char *l_chain_str = NULL;
-    for (uint32_t i = 0; i < a_params->length; i++) {
-        dap_json_rpc_param_t *l_prm = a_params->params[i];
-        if (i == 0)
-            l_net_str = l_prm->value_param;
-        if (i == 1)
-            l_chain_str = l_prm->value_param;
-    }
-    dap_chain_net_t  *l_net = dap_chain_net_by_name(l_net_str);
-    dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str);
-    a_response->type = TYPE_RESPONSE_STRING;
-    char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain);
-    if(!l_gdb_group_mempool){
-        a_response->result_string = "{\"datums\":[]}";
-        return;
-    }
-    size_t l_objs_size = 0;
-    dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_objs_size);
-    json_object *l_object = json_object_new_object();
-    json_object *l_object_array = json_object_new_array();
-
-    for(size_t i = 0; i < l_objs_size; i++) {
-        dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value;
-        //dap_time_t l_ts_create = (dap_time_t) l_datum->header.ts_create;
-        if (!l_datum->header.data_size || (l_datum->header.data_size > l_objs[i].value_len)) {
-            log_it(L_ERROR, "Trash datum in GDB %s.%s, key: %s data_size:%u, value_len:%zu",
-                   l_net->pub.name, l_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len);
-            dap_global_db_del(l_gdb_group_mempool, l_objs[i].key, NULL, NULL);
-            continue;
-        }
-
-        json_object *l_obj_datum = dap_chain_datum_to_json(l_datum);
-        json_object_array_add(l_object_array, l_obj_datum);
-    }
-    json_object_object_add(l_object, "datums", l_object_array);
-    a_response->type = TYPE_RESPONSE_JSON;
-    a_response->result_json_object = l_object;
-
-    DAP_DELETE(l_gdb_group_mempool);
-}
-
-#undef LOG_TAG
diff --git a/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h b/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h
deleted file mode 100644
index b9c0efa9bb..0000000000
--- a/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Authors:
- * Alexey V. Stratulat <alexey.stratulat@demlabs.net>
- * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
- * Copyright  (c) 2017-2023
- * All rights reserved.
-
- This file is part of DAP (Demlabs Application Protocol) the open source project
-
-    DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "dap_json_rpc_errors.h"
-#include "dap_json_rpc_response.h"
-#include "dap_json_rpc_params.h"
-
-
-int dap_chain_mempool_rpc_init(void);
-void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
-                                        dap_json_rpc_response_t *a_response, const char *a_method);
-void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
-                                        dap_json_rpc_response_t *a_response, const char *a_method);
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 3d3e862c76..b5628e56bb 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -627,7 +627,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
         if (compare256(l_value_to_items, l_single_val) == -1) {
             char l_log_str[256] = { '\0' };
             l_balance = dap_uint256_to_char(l_value_to_items, NULL);
-            dap_snprintf(l_log_str, sizeof(l_log_str),
+            snprintf(l_log_str, sizeof(l_log_str),
                          "Not enough values on output to produce enough inputs: %s when need ", l_balance);
             strcat(l_log_str, dap_uint256_to_char(l_single_val, NULL));
             log_it(L_ERROR, "%s", l_log_str);
diff --git a/modules/mempool/include/dap_chain_mempool_rpc.h b/modules/mempool/include/dap_chain_mempool_rpc.h
index 6038890810..90aca98b32 100644
--- a/modules/mempool/include/dap_chain_mempool_rpc.h
+++ b/modules/mempool/include/dap_chain_mempool_rpc.h
@@ -2,7 +2,9 @@
 #include "dap_json_rpc.h"
 
 int dap_chain_mempool_rpc_init(void);
+
 void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
                                         dap_json_rpc_response_t *a_response, const char *a_method);
 void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
                                         dap_json_rpc_response_t *a_response, const char *a_method);
+                                        
diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt
index 4cc53c5c4e..f07876b697 100644
--- a/modules/net/CMakeLists.txt
+++ b/modules/net/CMakeLists.txt
@@ -29,8 +29,8 @@ endif()
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
 
 target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_io dap_notify_srv dap_cli_server dap_chain dap_chain_wallet
-                                        dap_chain_net_srv dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none
-                                        dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc dap_json_rpc_chain_common)
+                                        dap_chain_net_srv dap_chain_net_srv_voting dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none
+                                        dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc )
 if(LINUX)
     target_link_libraries(${PROJECT_NAME} resolv)
 endif()
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 4f88bd46d8..986123b2b0 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -67,8 +67,18 @@ typedef struct dap_ledger_verificator {
     UT_hash_handle hh;
 } dap_ledger_verificator_t;
 
+typedef struct dap_ledger_service_info {
+    dap_chain_net_srv_uid_t service_uid;    // hash key
+    char tag_str[32];   // tag string name
+    dap_ledger_tag_check_callback_t callback; //callback for check if a tx for particular service
+    UT_hash_handle hh;
+} dap_ledger_service_info_t;
+
 static dap_ledger_verificator_t *s_verificators;
+static dap_ledger_service_info_t *s_services;
+
 static  pthread_rwlock_t s_verificators_rwlock;
+static  pthread_rwlock_t s_services_rwlock;
 
 static dap_chain_ledger_voting_callback_t s_voting_callback;
 
@@ -211,6 +221,8 @@ typedef struct dap_ledger_tx_item {
         byte_t multichannel;
         dap_time_t ts_spent;
         byte_t pad[7];
+        dap_chain_net_srv_uid_t tag; //tag (or service this tx is belong to)
+        dap_chain_tx_tag_action_type_t action;
         // TODO dynamically allocates the memory in order not to limit the number of outputs in transaction
         dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list
     } DAP_ALIGN_PACKED cache_data;
@@ -359,6 +371,157 @@ static size_t s_threshold_free_timer_tick = 900000; // 900000 ms = 15 minutes.
 
 struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t* a_bal);
 
+//add a service declaration for tx tagging and more
+static bool s_tag_check_block_reward(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //reward tag
+    if (a_items_grp->items_in_reward)
+    {
+        if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
+        return true;
+    }
+    return false;
+}
+
+dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond)
+{
+        dap_hash_fast_t *l_tx_prev_hash = &a_in_cond->header.tx_prev_hash;    
+        uint32_t l_tx_prev_out_idx = a_in_cond->header.tx_out_prev_idx;
+        dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
+        
+        if (!l_tx_prev) return NULL;
+        byte_t* l_item_res = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx);
+        dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_res;
+        
+        if (l_type != TX_ITEM_TYPE_OUT_COND) return NULL;
+
+        
+        return (dap_chain_tx_out_cond_t*)l_item_res;
+}
+
+static dap_chain_addr_t s_get_out_addr(byte_t *out_item) {
+    dap_chain_tx_item_type_t l_type = *(uint8_t *)out_item;
+    
+    switch (l_type) {
+        case TX_ITEM_TYPE_OUT: { 
+            dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)out_item;
+            return l_tx_out->addr;
+        } break;
+        case TX_ITEM_TYPE_OUT_EXT: { // 256
+            dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)out_item;
+            return l_tx_out->addr;
+        } break;
+    }
+
+    dap_chain_addr_t l_tx_out_to={0};
+    return l_tx_out_to;
+}
+
+static bool s_tag_check_transfer(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //crosschain transfer
+    //regular transfer
+    //comission transfer
+    
+    // fee transfer: in_cond item linked to out_cond_fee
+    if (a_items_grp->items_in_cond) 
+    {
+       for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
+            dap_chain_tx_in_cond_t *l_tx_in = it->data;
+            dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
+
+            if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) {
+                if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
+                return true;
+            }   
+        }
+    }
+
+    //crosschain transfer: outs destination net-id differs from current net-id
+    // to differ with wrong stakes -> no ems in required
+
+    if (!a_items_grp->items_in_ems)
+    {
+        dap_chain_addr_t addr_to = {0};
+        for (dap_list_t *it =  a_items_grp->items_out_all; it; it = it->next) {
+            
+            dap_chain_addr_t l_tx_out_to = s_get_out_addr(it->data);
+        
+            //tag cross-chain _outputs_ transactions (recepient-tx is emission-based)
+            if (l_tx_out_to.net_id.uint64 != a_ledger->net->pub.id.uint64 && !dap_chain_addr_is_blank(&l_tx_out_to)) {
+                if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN;
+                return true;
+            }
+        }   
+    }
+
+
+    //regular transfers 
+    //have no other ins except regular in
+    //have no OUT_COND except fee
+    //have no vote
+    //no TSD!
+
+
+    //have any of those -> not regular transfer
+    if (a_items_grp->items_in_cond ||
+        a_items_grp->items_in_ems ||
+        a_items_grp->items_in_reward ) {
+        return false;   
+    }
+    
+    //have any of those -> not regular transfer
+    if ( 
+        a_items_grp->items_out_cond_srv_pay ||
+        a_items_grp->items_out_cond_srv_stake_lock ||
+        a_items_grp->items_out_cond_srv_stake_pos_delegate ||
+        a_items_grp->items_out_cond_srv_xchange) 
+    {
+        return false;
+    }
+    
+    //not voting or vote...
+    if (a_items_grp->items_vote || a_items_grp->items_voting || a_items_grp->items_tsd)
+        return false;
+
+    //not tsd sects (staking!)
+    if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
+    return true;
+}
+
+int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback)
+{
+    
+    dap_ledger_service_info_t *l_new_sinfo;
+    
+    int l_tmp = a_uid.raw_ui64;
+
+    pthread_rwlock_rdlock(&s_services_rwlock);
+    HASH_FIND_INT(s_services, &l_tmp, l_new_sinfo);
+    pthread_rwlock_unlock(&s_services_rwlock);
+    if (l_new_sinfo) {
+        l_new_sinfo->callback = a_callback;
+        return 1;
+    }
+
+    l_new_sinfo = DAP_NEW(dap_ledger_service_info_t);
+    if (!l_new_sinfo) {
+        log_it(L_CRITICAL, "Memory allocation error");
+        return -1;
+    }
+    l_new_sinfo->service_uid = a_uid;
+    l_new_sinfo->callback = a_callback;
+    strcpy(l_new_sinfo->tag_str, tag_str);
+    
+    pthread_rwlock_wrlock(&s_services_rwlock);
+    HASH_ADD_INT(s_services, service_uid.raw_ui64, l_new_sinfo);
+    pthread_rwlock_unlock(&s_services_rwlock);
+
+    log_it(L_NOTICE, "Successfully registered service tag %s with uid %02" DAP_UINT64_FORMAT_X, tag_str, a_uid.raw_ui64);
+
+    return 0;
+}
+
 /**
  * @brief dap_ledger_init
  * current function version set s_debug_more parameter, if it define in config, and returns 0
@@ -367,7 +530,16 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
 int dap_ledger_init()
 {
     s_debug_more = dap_config_get_item_bool_default(g_config,"ledger","debug_more",false);
+    
     pthread_rwlock_init(&s_verificators_rwlock, NULL);
+    pthread_rwlock_init(&s_services_rwlock, NULL);
+
+    //register native ledger services
+    dap_chain_net_srv_uid_t l_uid_transfer = { .uint64 = DAP_CHAIN_NET_SRV_TRANSFER_ID };
+    dap_ledger_service_add(l_uid_transfer, "transfer", s_tag_check_transfer);
+
+    dap_chain_net_srv_uid_t l_uid_breward = { .uint64 = DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID };
+    dap_ledger_service_add(l_uid_breward, "block_reward", s_tag_check_block_reward);
     return 0;
 }
 
@@ -378,6 +550,7 @@ int dap_ledger_init()
 void dap_ledger_deinit()
 {
     pthread_rwlock_destroy(&s_verificators_rwlock);
+    pthread_rwlock_destroy(&s_services_rwlock);
 }
 
 /**
@@ -1775,6 +1948,9 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_t
         uint16_t l_tmp = 0;
         a_token_item->auth_signs_valid = _dap_tsd_get_scalar(l_new_signs_valid, &l_tmp);
     }
+
+    if (l_added_pkeys) dap_list_free(l_added_pkeys);
+    if (l_remove_pkeys) dap_list_free(l_remove_pkeys);
     return 0;
 }
 
@@ -3510,14 +3686,148 @@ inline static bool s_ledger_check_token_ticker(const char *a_ticker)
     return false;
 }
 
+/*
+services we know now
+0x01 - VPN
+0x02 - xchange
+0x03, 0x13 -  pos_delegate
+0x04 bridge
+0x.05 - custom datum
+0x06 voting
+0x12 - stake_lock 
+*/
+
+const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag)
+{
+
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_UNKNOWN) return "unknown";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR) return "regular";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION) return "comission";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN) return "crosschain";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD) return "reward";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_OPEN) return "open";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_USE) return "use";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EXTEND) return "extend";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CLOSE) return "close";
+    if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CHANGE) return "change";
+
+    return "WTFSUBTAG";
+
+}
+
+dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str)
+{
+    if (!a_str)
+        return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+    
+    if (strcmp("unknown", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+    if (strcmp("regular", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
+    if (strcmp("comission", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
+    if (strcmp("crosschain", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN;
+    if (strcmp("reward", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD;
+    if (strcmp("open", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_OPEN;
+    if (strcmp("use", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_USE;
+    if (strcmp("extend", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EXTEND;
+    if (strcmp("close", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CLOSE;
+    if (strcmp("change", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CHANGE;
+
+    return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+}
+
+bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, 
+                                dap_chain_net_srv_uid_t *a_uid, char **a_service_name,  dap_chain_tx_tag_action_type_t *a_action)
+{
+    //find tx
+    dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
+    dap_chain_datum_tx_t *l_tx_ret = NULL;
+    dap_ledger_tx_item_t *l_tx_item;
+    pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
+    HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item);
+    pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
+    
+    
+    if(l_tx_item) {
+        dap_ledger_service_info_t *l_sinfo;    
+        pthread_rwlock_rdlock(&s_services_rwlock);
+        HASH_FIND_INT(s_services, &l_tx_item->cache_data.tag, l_sinfo);
+        pthread_rwlock_unlock(&s_services_rwlock);
+        if (l_sinfo)
+        { 
+            if(a_uid) *a_uid = l_sinfo->service_uid;
+            if (a_service_name) *a_service_name = l_sinfo->tag_str;
+            if (a_action) *a_action = l_tx_item->cache_data.action;
+            return true; 
+        } 
+    }
+
+    if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+    return false;
+}
+
+
+bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *a_tag, dap_chain_tx_tag_action_type_t *a_action)
+{
+    dap_ledger_service_info_t *l_sinfo_current, *l_sinfo_tmp;
+
+    
+    dap_chain_datum_tx_item_groups_t l_items_groups = {0};
+    dap_chain_datum_tx_group_items(a_tx, &l_items_groups);
+
+    bool l_res = false;
+    int l_deductions_ok = 0;
+
+    pthread_rwlock_rdlock(&s_services_rwlock);
+    HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) {
+        dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+        if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups, &action)){
+            if (a_tag) *a_tag =  l_sinfo_current->service_uid;
+            if (a_action) *a_action =  action;
+            l_res = true;
+            l_deductions_ok ++;
+        }
+    } 
+    pthread_rwlock_unlock(&s_services_rwlock);
+
+    if (l_deductions_ok > 1)
+    {
+        char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+        dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+        dap_chain_hash_fast_to_str(l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
+
+
+        log_it(L_WARNING, "Transaction %s identyfied by multiple services (%d):", l_tx_hash_str, l_deductions_ok);
+    
+        pthread_rwlock_rdlock(&s_services_rwlock);
+        HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) {
+            dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+            if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups,&action))  {
+                log_it(L_WARNING, "%s %s", l_sinfo_current->tag_str, dap_ledger_tx_action_str(action));
+            }
+        } 
+
+        pthread_rwlock_unlock(&s_services_rwlock);
+    }
+    
+    dap_chain_datum_tx_group_items_free(&l_items_groups);
+
+    return l_res;
+}
+
 /**
  * Checking a new transaction before adding to the cache
  *
  * return 0 OK, otherwise error
  */
 // Checking a new transaction before adding to the cache
-int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
-                                    bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker)
+int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger,
+                                 dap_chain_datum_tx_t *a_tx,
+                                  dap_hash_fast_t *a_tx_hash,
+                                    bool a_from_threshold, 
+                                    dap_list_t **a_list_bound_items,
+                                     dap_list_t **a_list_tx_out,
+                                      char **a_main_ticker,
+                                      dap_chain_net_srv_uid_t *a_tag,
+                                      dap_chain_tx_tag_action_type_t *a_action)
 {
     if (!a_tx) {
         log_it(L_DEBUG, "NULL transaction, check broken");
@@ -3533,6 +3843,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                 char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
                 dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
                 log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str);
+                if (a_tag) *a_tag = l_ledger_item->cache_data.tag;
+                if (a_action) *a_action = l_ledger_item->cache_data.action;
             }
             return DAP_LEDGER_TX_ALREADY_CACHED;
         }
@@ -3580,6 +3892,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
     dap_pkey_t *l_tx_first_sign_pkey = NULL;
     bool l_girdled_ems_used = false;
     uint256_t l_taxed_value = {};
+    
+    if(a_tag) dap_ledger_deduct_tx_tag(a_ledger, a_tx, a_tag, a_action);
 
     // find all previous transactions
     for (dap_list_t *it = l_list_in; it; it = it->next) {
@@ -4405,7 +4719,7 @@ int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
     }
 
     int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash,
-                                                      false, NULL, NULL, NULL);
+                                                      false, NULL, NULL, NULL, NULL, NULL);
     if(s_debug_more) {
         char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
         dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
@@ -4492,9 +4806,12 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
 
     int l_ret_check;
     l_item_tmp = NULL;
+    dap_chain_net_srv_uid_t l_tag =  { .uint64 = 0 }; 
+    dap_chain_tx_tag_action_type_t l_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+
     if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold,
                                                        &l_list_bound_items, &l_list_tx_out,
-                                                       &l_main_token_ticker))) {
+                                                       &l_main_token_ticker, &l_tag, &l_action))) {
         if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS ||
                 l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION) {
             if (!l_from_threshold) {
@@ -4533,6 +4850,10 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
             debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str,
                         dap_ledger_tx_check_err_str(l_ret_check));
         }
+        
+        if ( l_list_bound_items )
+            dap_list_free_full(l_list_bound_items, NULL);
+        
         return l_ret_check;
     }
     debug_if(s_debug_more, L_DEBUG, "dap_ledger_tx_add() check passed for tx %s", l_tx_hash_str);
@@ -4624,6 +4945,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
                 if(s_debug_more)
                     log_it(L_ERROR,"!!! Attempt to SPEND from some non-existent balance !!!: %s %s", l_addr_str, l_cur_token_ticker);
             }
+            
             DAP_DELETE(l_wallet_balance_key);
         } break;
 
@@ -4783,6 +5105,8 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
     int l_outs_count = 0;
     dap_list_t *l_list_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count);
     l_tx_item->cache_data.n_outs = l_outs_count;
+    l_tx_item->cache_data.tag = l_tag;
+    l_tx_item->cache_data.action = l_action;
     // TODO: dump the UTXO in debug mode if need
 
     if(l_list_tmp)
@@ -5959,14 +6283,14 @@ void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_c
     PVT(a_ledger)->cache_tx_check_callback = a_callback;
 }
 
-const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc)
+const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc)
 {
-    const char *l_main_ticker = NULL;
-    dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
-    int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, (char **)&l_main_ticker);   
-
+    char *l_main_ticker = NULL;
+    dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
+    int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, &l_main_ticker, NULL, NULL);  
     if (l_rc == DAP_LEDGER_TX_ALREADY_CACHED)
-        l_main_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash);
+        l_main_ticker = (char *)dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash);
+    DAP_DEL_Z(l_tx_hash);
 
     if (a_ledger_rc)
         *a_ledger_rc = l_rc;
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 1432327e53..450b724125 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -101,7 +101,7 @@
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_net_srv_xchange.h"
 #include "dap_chain_cs_esbocs.h"
-#include "dap_chain_net_voting.h"
+#include "dap_chain_net_srv_voting.h"
 #include "dap_global_db_cluster.h"
 #include "dap_link_manager.h"
 #include "dap_stream_cluster.h"
@@ -254,7 +254,7 @@ int dap_chain_net_init()
     dap_chain_ch_init();
     dap_stream_ch_chain_net_init();
     dap_chain_node_client_init();
-    dap_chain_net_voting_init();
+    dap_chain_net_srv_voting_init();
     dap_http_ban_list_client_init();
     dap_link_manager_init(&s_link_manager_callbacks);
     dap_chain_node_init();
@@ -296,7 +296,7 @@ int dap_chain_net_init()
                 continue;
             // don't search in directories
             char l_full_path[MAX_PATH + 1] = {0};
-            dap_snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
+            snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
             if(dap_dir_test(l_full_path)) {
                 continue;
             }
@@ -2965,7 +2965,7 @@ static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pke
 {
     const char l_path[] = "network/";
     char l_cfg_path[strlen(a_net->pub.name) + strlen(l_path) + 1];
-    dap_snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name);
+    snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name);
     dap_config_t *l_cfg = dap_config_open(l_cfg_path);
     const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type");
     bool l_authorized = true;
diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c
index fb04985c33..1c0ed5b4ce 100644
--- a/modules/net/dap_chain_net_balancer.c
+++ b/modules/net/dap_chain_net_balancer.c
@@ -155,7 +155,7 @@ static void s_balancer_link_prepare_error(dap_balancer_link_request_t *a_request
 {
     struct json_object *l_json = s_balancer_states_json_collect(a_request->net, a_host_addr, a_host_port);
     char l_err_str[512] = { '\0' };
-    dap_snprintf(l_err_str, sizeof(l_err_str)
+    snprintf(l_err_str, sizeof(l_err_str)
                  , "Link from balancer %s can't be prepared, errno %d"
                  , a_host_addr, a_errno);
     log_it(L_WARNING, "%s", l_err_str);
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index fd5e25bb43..80a0a27b6c 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -400,11 +400,11 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
             break;
         case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN:
             if (dap_chain_datum_decree_get_min_owners(a_decree, &l_value)) {
-                log_it(L_WARNING,"Can't get min number of ownners from decree.");
+                log_it(L_WARNING, "Can't get min number of ownners from decree.");
                 return -105;
             }
-            if (!IS_ZERO_256(l_value) || compare256(l_value, GET_256_FROM_64(UINT16_MAX)) == 1) {
-                log_it(L_WARNING,"Illegal min number of ownners %s", dap_uint256_to_char(l_value, NULL));
+            if (IS_ZERO_256(l_value) || compare256(l_value, GET_256_FROM_64(UINT16_MAX)) == 1) {
+                log_it(L_WARNING, "Illegal min number of owners %s", dap_uint256_to_char(l_value, NULL));
                 return -116;
             }
             if (!a_apply)
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index f7e2b73be3..91d5b3882f 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -101,9 +101,9 @@
 #include "dap_chain_net_node_list.h"
 
 #include "dap_json_rpc_errors.h"
-#include "dap_json_rpc_chain_datum.h"
 #include "dap_http_ban_list_client.h"
 #include "dap_chain_datum_tx_voting.h"
+#include "dap_enc_ks.h"
 
 
 #define LOG_TAG "chain_node_cli_cmd"
@@ -794,9 +794,13 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
 
 static dap_tsd_t* s_chain_node_cli_com_node_create_tsd_addr(char **a_argv, int a_arg_start, int a_arg_end, void **a_str_reply, const char *a_specified_decree) {
     const char *l_ban_addr_str = NULL;
-    if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str))
-        return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR, l_ban_addr_str);
-    else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str))
+    if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str)) {
+        dap_chain_addr_t *l_format = dap_chain_addr_from_str(l_ban_addr_str);
+        if (!l_format)
+            return dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert the -addr option value to node address"), NULL;
+        DAP_DELETE(l_format);
+        return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING, l_ban_addr_str);
+    } else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str))
         return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST, l_ban_addr_str);
     else
         return dap_cli_server_cmd_set_reply_text(a_str_reply, "The -host or -addr option was not "
@@ -1818,7 +1822,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                             const char *l_addr_str = dap_chain_addr_to_str(l_addr);
                             json_object_object_add(json_obj_wall, "Wallet", json_object_new_string(l_file_name));
                             if(l_wallet->flags & DAP_WALLET$M_FL_ACTIVE)
-                                json_object_object_add(json_obj_wall, "status", json_object_new_string("Active"));
+                                json_object_object_add(json_obj_wall, "status", json_object_new_string("active"));
                             else
                                 json_object_object_add(json_obj_wall, "status", json_object_new_string("not active"));
                             json_object_object_add(json_obj_wall, "sign_status", json_object_new_string(
@@ -2317,6 +2321,88 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc,
     return 0;
 }
 
+/**
+ * @brief dap_chain_node_cli_cmd_values_parse_net_chain_json
+ * @param argc
+ * @param argv
+ * @param a_chain
+ * @param a_net
+ * @return
+ */
+int dap_chain_node_cli_cmd_values_parse_net_chain_json(int *a_arg_index, int a_argc, char **a_argv,
+        dap_chain_t **a_chain, dap_chain_net_t **a_net)
+{
+    const char * l_chain_str = NULL;
+    const char * l_net_str = NULL;
+
+    // Net name
+    if(a_net)
+        dap_cli_server_cmd_find_option_val(a_argv, *a_arg_index, a_argc, "-net", &l_net_str);
+    else
+        return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_STR_ERR;
+
+    // Select network
+    if(!l_net_str) {
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR, "%s requires parameter '-net'", a_argv[0]);
+        return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR;
+    }
+
+    if((*a_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR, "%s can't find network \"%s\"", a_argv[0], l_net_str);
+        char l_str_to_reply_chain[500] = {0};
+        char *l_str_to_reply = NULL;
+        sprintf(l_str_to_reply_chain, "%s can't find network \"%s\"\n", a_argv[0], l_net_str);
+        l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
+        dap_string_t* l_net_str = dap_cli_list_net();
+        l_str_to_reply = dap_strcat2(l_str_to_reply,l_net_str->str);
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR, l_str_to_reply);
+        DAP_DELETE(l_str_to_reply);
+        dap_string_free(l_net_str, true);
+        return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR;
+    }
+
+    // Chain name
+    if(a_chain) {
+        dap_cli_server_cmd_find_option_val(a_argv, *a_arg_index, a_argc, "-chain", &l_chain_str);
+
+        // Select chain
+        if(l_chain_str) {
+            if ((*a_chain = dap_chain_net_get_chain_by_name(*a_net, l_chain_str)) == NULL) { // Can't find such chain
+                char l_str_to_reply_chain[500] = {0};
+                char *l_str_to_reply = NULL;
+                sprintf(l_str_to_reply_chain, "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid\n",
+                        a_argv[0], l_net_str, l_chain_str);
+                l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
+                dap_chain_t * l_chain;
+                dap_chain_net_t * l_chain_net = *a_net;
+                l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chains:\n");
+                DL_FOREACH(l_chain_net->pub.chains, l_chain) {
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,"\t");
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,l_chain->name);
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,"\n");
+                }
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, l_str_to_reply);
+                DAP_DELETE(l_str_to_reply);
+                return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
+            }
+        }
+        else if (	!strcmp(a_argv[0], "token_decl")
+        ||			!strcmp(a_argv[0], "token_decl_sign")) {
+            if (	(*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL )
+            {
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, "%s requires parameter '-chain' or set default datum type in chain configuration file",
+                                       a_argv[0]);
+                return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
+            }
+        } else {
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, "%s requires parameter '-chain'", a_argv[0]);
+            return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
+        }
+    }
+    return 0;
+}
+
+
 /**
  * @brief
  * sign data (datum_token) by certificates (1 or more)
@@ -2461,7 +2547,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply)
                 l_datum_token->signs_total = 0;
                 for (i = 1; i <= l_tmp_signs_total; i++){
                     dap_sign_t *l_sign = (dap_sign_t *)(l_datum_token->data_n_tsd + l_tsd_size + l_signs_size);
-                    if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) != 1) {
+                    if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) ) {
                         log_it(L_WARNING, "Wrong signature %zu for datum_token with key %s in mempool!", i, l_datum_hash_out_str);
                         dap_cli_server_cmd_set_reply_text(a_str_reply,
                                 "Datum %s with datum token has wrong signature %zu, break process and exit",
@@ -2714,7 +2800,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                         dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data;
 
                         int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX;
-                        const char *l_main_ticker = dap_ledger_tx_get_main_ticker(a_net->pub.ledger, l_tx,
+                        const char *l_main_ticker = dap_ledger_tx_calculate_main_ticker(a_net->pub.ledger, l_tx,
                                                                                   &l_ledger_rc);
                         char *l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc);
 
@@ -3063,11 +3149,11 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
                         if (l_wallet_addr && l_emi && dap_chain_addr_compare(l_wallet_addr, &l_emi->hdr.address))
                             datum_is_accepted_addr = true;
                         DAP_DELETE(l_emi);
-                        json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
+                        dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id);
                     }
                         break;
                     default:
-                        json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
+                        dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id);
                 }
             }
             if (l_wallet_addr) {
@@ -3313,8 +3399,10 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
             json_object_object_add(l_obj_atom, "hash", l_jobj_atom_hash);
             json_object_object_add(l_obj_atom, "ledger_response_code", l_jobj_atom_err);
             json_object_object_add(l_jobj_datum, "atom", l_obj_atom);
-        }
-        json_object *l_datum_obj_inf = dap_chain_datum_to_json(l_datum);
+        }        
+
+        json_object *l_datum_obj_inf = json_object_new_object();
+        dap_chain_datum_dump_json(l_datum_obj_inf,l_datum,NULL,a_net->pub.id);        
         if (!l_datum_obj_inf) {
             if (!l_found_in_chains)
                 DAP_DELETE(l_datum);
@@ -3323,6 +3411,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
                                     "Failed to serialize datum to JSON.");
             return DAP_JSON_RPC_ERR_CODE_SERIALIZATION_DATUM_TO_JSON;
         }
+        json_object_object_add(l_jobj_datum, "datum", l_datum_obj_inf);
         if (!l_found_in_chains)
             DAP_DELETE(l_datum);
         json_object_array_add(*a_json_reply, l_jobj_datum);
@@ -3619,7 +3708,9 @@ int _cmd_mempool_dump_from_group(dap_chain_net_id_t a_net_id, const char *a_grou
         json_object *l_jobj_message = json_object_new_string(l_msg_str);
         return COM_DUMP_ERROR_CAN_NOT_FIND_DATUM;
     }
-    json_object *l_jobj_datum = dap_chain_datum_to_json(l_datum);
+
+    json_object *l_jobj_datum = json_object_new_object();
+    dap_chain_datum_dump_json(l_jobj_datum,l_datum,NULL,a_net_id);
     json_object_array_add(*a_json_reply, l_jobj_datum);
     return 0;
 }
@@ -7041,6 +7132,8 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
     const char *l_net_str = NULL;
     const char *l_chain_str = NULL;
     const char *l_tx_hash_str = NULL;
+    const char *l_tx_srv_str = NULL;
+    const char *l_tx_act_str = NULL;
     const char *l_limit_str = NULL;
     const char *l_offset_str = NULL;
 
@@ -7063,6 +7156,18 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str);
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str);
     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-tx", &l_tx_hash_str);
+    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv", &l_tx_srv_str);
+    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-act", &l_tx_act_str);
+    
+    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
+    dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
+    size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
+    size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
+
+    //default is ALL/ANY
+    dap_chain_tx_tag_action_type_t l_action = dap_ledger_tx_action_str_to_action_t(l_tx_act_str); 
+
+    bool l_brief = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false;
 
     bool l_is_tx_all = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-all", NULL);
 
@@ -7108,7 +7213,15 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
                                                         "Wallet address not recognized");
             return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ADDR_ERR;
         }
-        l_net = dap_chain_net_by_id(l_addr->net_id);
+        if (l_net) {
+            if (l_net->pub.id.uint64 != l_addr->net_id.uint64) {
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR,
+                                        "Network ID with '-net' param and network ID with '-addr' param are different");
+                DAP_DELETE(l_addr);
+                return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR;
+            }
+        } else
+            l_net = dap_chain_net_by_id(l_addr->net_id);
     }
     if (l_wallet_name) {
         const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
@@ -7169,11 +7282,7 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
         if (!json_obj_summary) {
             return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR;
         }
-        dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
-        dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
-        size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
-        size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
-        json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), json_obj_summary, l_limit, l_offset);
+        json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), json_obj_summary, l_limit, l_offset, l_brief, l_tx_srv_str, l_action);
         if (!json_obj_out) {
             dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR,
                                     "something went wrong in tx_history");
@@ -7185,22 +7294,13 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
         return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_OK;        
     } else if (l_is_tx_all) {
         // history all
-        const char * l_brief_type = NULL;
-        bool l_brief_out = false;
-        if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-brief", &l_brief_type))
-            l_brief_out = true;
-        
- 
         json_object * json_obj_summary = json_object_new_object();
         if (!json_obj_summary) {
             return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR;
         }
-        dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
-        dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
-        size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
-        size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
+
         json_object* json_arr_history_all = dap_db_history_tx_all(l_chain, l_net, l_hash_out_type, json_obj_summary,
-                                                                  l_limit, l_offset, l_brief_out);
+                                                                l_limit, l_offset, l_brief,  l_tx_srv_str, l_action);
         if (!json_arr_history_all) {
             dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR,
                                     "something went wrong in tx_history");
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index f7cfd20b00..d58a9ad326 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -48,7 +48,6 @@
 #include "dap_math_convert.h"
 
 #include "dap_json_rpc_errors.h"
-#include "dap_json_rpc_chain_datum_tx.h"
 
 #define LOG_TAG "chain_node_cli_cmd_tx"
 
@@ -93,7 +92,7 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_
  * @param l_tx_num
  */
 
-static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
+bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
                                           dap_ledger_t *a_ledger,
                                           json_object * json_obj_out,
                                           const char *a_hash_out_type,
@@ -115,8 +114,8 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
     json_object_object_add(json_obj_out, "Token_ticker", json_object_new_string(l_ticker));
     json_object_object_add(json_obj_out, "Token_description", l_description ? json_object_new_string(l_description)
                                                                             : json_object_new_null());
-    json_object* datum_tx = dap_chain_datum_tx_to_json(a_datum,&a_ledger->net->pub.id);
-    json_object_object_add(json_obj_out, "Datum_tx", datum_tx);
+    dap_chain_datum_dump_tx_json(a_datum, l_ticker, json_obj_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id);
+
     dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL);
     int l_out_idx = 0;
     json_object* json_arr_items = json_object_new_array();
@@ -197,6 +196,21 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
     json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(l_ret_code));
     json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(l_ret_code)));
 
+    dap_chain_net_srv_uid_t uid;
+    char *service_name;
+    dap_chain_tx_tag_action_type_t action;
+
+    if (dap_ledger_tx_service_info(l_ledger, a_tx_hash, &uid, &service_name, &action))
+    {
+        json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name));
+        json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action)));
+    }
+    else
+    {   
+        json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN"));
+        json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN"));
+    }
+
     char l_time_str[DAP_TIME_STR_SIZE];
     if (l_tx->header.ts_created) {
         dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_tx->header.ts_created);/* Convert ts to  "Sat May 17 01:17:08 2014\n" */
@@ -206,9 +220,8 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
     json_object_object_add(json_obj_datum, "tx_created", l_obj_ts_created);
     
     if(!brief_out)
-    {
-        json_object* datum_tx = dap_chain_datum_tx_to_json(l_tx,&a_chain->net_id);
-        json_object_object_add(json_obj_datum, "items", datum_tx);
+    {        
+        dap_chain_datum_dump_tx_json(l_tx,NULL,json_obj_datum,a_hash_out_type,a_tx_hash,a_chain->net_id);        
     }
 
     return json_obj_datum;
@@ -285,6 +298,23 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro
     json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str));
     json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(a_ret_code));
     json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(a_ret_code)));
+
+
+    dap_chain_net_srv_uid_t uid;
+    char *service_name;
+    dap_chain_tx_tag_action_type_t action;
+    
+    if (dap_ledger_tx_service_info(a_ledger, a_tx_hash, &uid, &service_name, &action))
+    {
+        json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name));
+        json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action)));
+    }
+    else
+    {
+        json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN"));
+        json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN"));
+    }
+
     json_object_object_add(json_obj_datum, "tx_created", json_object_new_string(l_time_str));
 
     DAP_DELETE(l_tx_hash_str);
@@ -304,7 +334,7 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro
  */
 json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, 
                                  const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary,
-                                 size_t a_limit, size_t a_offset)
+                                 size_t a_limit, size_t a_offset, bool a_brief, const char *a_srv, dap_chain_tx_tag_action_type_t a_action)
 {
     json_object* json_obj_datum = json_object_new_array();
     if (!json_obj_datum){
@@ -339,24 +369,23 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
     bool l_net_fee_used = dap_chain_net_tx_get_fee(l_net->pub.id, NULL, &l_net_fee_addr);
     bool l_is_need_correction = false;
     uint256_t l_corr_value = {}, l_unstake_value = {};    
+    bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
 
+    json_object* json_obj_lim = json_object_new_object();
     size_t l_arr_start = 0;
     if (a_offset){
         l_arr_start = a_offset;
-        json_object* json_obj_off = json_object_new_object();
-        json_object_object_add(json_obj_off, "offset", json_object_new_int(l_arr_start));
-        json_object_array_add(json_obj_datum, json_obj_off);
+        json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start));
     }        
     size_t l_arr_end = a_chain->callback_count_atom(a_chain);
     if (a_limit) {
-        json_object* json_obj_lim = json_object_new_object();
-        json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));
-        json_object_array_add(json_obj_datum, json_obj_lim);        
+        json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));        
         l_arr_end = l_arr_start + a_limit;
         size_t l_length = a_chain->callback_count_atom(a_chain);
         if (l_arr_end > l_length)
             l_arr_end = l_length;
     }
+    json_object_array_add(json_obj_datum, json_obj_lim);
     size_t i_tmp = 0;
     // load transactions
     dap_chain_datum_iter_t *l_datum_iter = a_chain->callback_datum_iter_create(a_chain);
@@ -368,7 +397,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
         json_object *l_corr_object = NULL;
         if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX)
             // go to next datum
-            continue;
+            continue;        
         // it's a transaction        
         bool l_is_unstake = false;
         dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
@@ -376,6 +405,11 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
         if (!l_list_in_items) // a bad tx
             continue;
         // all in items should be from the same address
+        if (i_tmp >= l_arr_end || i_tmp < l_arr_start) {
+            i_tmp++;
+            continue;                    
+        }
+        i_tmp++;
         dap_chain_addr_t *l_src_addr = NULL;
         bool l_base_tx = false, l_reward_collect = false;
         const char *l_noaddr_token = NULL;
@@ -523,6 +557,29 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
 
             if (l_dst_addr && l_net_fee_used && dap_chain_addr_compare(&l_net_fee_addr, l_dst_addr))
                 SUM_256_256(l_fee_sum, l_value, &l_fee_sum);
+            
+            //tag
+            char *service_name = NULL;
+            dap_chain_tx_tag_action_type_t l_action;
+            bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_tx_hash, NULL, &service_name, &l_action);
+            if (!(l_action & a_action))
+                continue;
+
+            if (a_srv)
+            {
+              
+                //skip if looking for UNKNOWN + it is known
+                if (look_for_unknown_service && srv_found) {
+                    continue;
+                }
+                            
+                //skip if search condition provided, it not UNKNOWN and found name not match
+                if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0))
+                {
+                    continue;
+                }
+            }
+
             if (l_dst_addr && dap_chain_addr_compare(l_dst_addr, a_addr)) {
                 if (!l_header_printed) {
                     s_tx_header_print(j_obj_tx, &l_tx_data_ht, l_tx, l_datum_iter->cur_atom_hash,
@@ -543,26 +600,25 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
                     l_corr_value = l_value;
                 }
                 const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
-                if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
-                    json_object *j_obj_data = json_object_new_object();
-                    if (!j_obj_data) {
-                        dap_json_rpc_allocation_error;
-                        json_object_put(j_obj_tx);
-                        json_object_put(j_arr_data);
-                        return NULL;
-                    }
-                    json_object_object_add(j_obj_data, "tx_type", json_object_new_string("recv"));
-                    json_object_object_add(j_obj_data, "recv_coins", json_object_new_string(l_coins_str));
-                    json_object_object_add(j_obj_data, "recv_datoshi", json_object_new_string(l_value_str));
-                    json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
-                                                                                : json_object_new_string("UNKNOWN"));
-                    json_object_object_add(j_obj_data, "source_address", json_object_new_string(l_src_str));
-                    if (l_is_need_correction)
-                        l_corr_object = j_obj_data;
-                    else
-                        json_object_array_add(j_arr_data, j_obj_data);
+                
+                json_object *j_obj_data = json_object_new_object();
+                if (!j_obj_data) {
+                    dap_json_rpc_allocation_error;
+                    json_object_put(j_obj_tx);
+                    json_object_put(j_arr_data);
+                    return NULL;
                 }
-                i_tmp++;
+                json_object_object_add(j_obj_data, "tx_type", json_object_new_string("recv"));
+                json_object_object_add(j_obj_data, "recv_coins", json_object_new_string(l_coins_str));
+                json_object_object_add(j_obj_data, "recv_datoshi", json_object_new_string(l_value_str));
+                json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
+                                                                            : json_object_new_string("UNKNOWN"));
+                json_object_object_add(j_obj_data, "source_address", json_object_new_string(l_src_str));
+                if (l_is_need_correction)
+                    l_corr_object = j_obj_data;
+                else
+                    json_object_array_add(j_arr_data, j_obj_data);
+                
             } else if (!l_src_addr || dap_chain_addr_compare(l_src_addr, a_addr)) {
                 if (!l_dst_addr && ((dap_chain_tx_out_cond_t *)it->data)->header.subtype == l_src_subtype && l_src_subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
                     continue;
@@ -578,23 +634,20 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
                                                         : dap_chain_tx_out_cond_subtype_to_str(
                                                               ((dap_chain_tx_out_cond_t *)it->data)->header.subtype);
                 const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
-                if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
-                    json_object * j_obj_data = json_object_new_object();
-                    if (!j_obj_data) {
-                        dap_json_rpc_allocation_error;
-                        json_object_put(j_obj_tx);
-                        json_object_put(j_arr_data);
-                        return NULL;
-                    }
-                    json_object_object_add(j_obj_data, "tx_type", json_object_new_string("send"));
-                    json_object_object_add(j_obj_data, "send_coins", json_object_new_string(l_coins_str));
-                    json_object_object_add(j_obj_data, "send_datoshi", json_object_new_string(l_value_str));
-                    json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
-                                                                            : json_object_new_string("UNKNOWN"));
-                    json_object_object_add(j_obj_data, "destination_address", json_object_new_string(l_dst_addr_str));
-                    json_object_array_add(j_arr_data, j_obj_data);
+                json_object * j_obj_data = json_object_new_object();
+                if (!j_obj_data) {
+                    dap_json_rpc_allocation_error;
+                    json_object_put(j_obj_tx);
+                    json_object_put(j_arr_data);
+                    return NULL;
                 }
-                i_tmp++;
+                json_object_object_add(j_obj_data, "tx_type", json_object_new_string("send"));
+                json_object_object_add(j_obj_data, "send_coins", json_object_new_string(l_coins_str));
+                json_object_object_add(j_obj_data, "send_datoshi", json_object_new_string(l_value_str));
+                json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
+                                                                        : json_object_new_string("UNKNOWN"));
+                json_object_object_add(j_obj_data, "destination_address", json_object_new_string(l_dst_addr_str));
+                json_object_array_add(j_arr_data, j_obj_data);                
             }
         }
         if (json_object_array_length(j_arr_data) > 0) {
@@ -637,7 +690,9 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
 
 json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
                                    const char *l_hash_out_type, json_object *json_obj_summary,
-                                   size_t a_limit, size_t a_offset, bool out_brief)
+                                   size_t a_limit, size_t a_offset, bool out_brief,
+					const char *a_srv, 
+                                    dap_chain_tx_tag_action_type_t a_action)
 {
         log_it(L_DEBUG, "Start getting tx from chain");
         size_t
@@ -650,43 +705,65 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
                             *l_cell_tmp = NULL;
         dap_chain_atom_iter_t *l_iter = NULL;
         json_object * json_arr_out = json_object_new_array();
+        json_object* json_obj_lim = json_object_new_object();
         size_t l_arr_start = 0;
         if (a_offset) {
             l_arr_start = a_offset;
-            json_object* json_obj_off = json_object_new_object();
-            json_object_object_add(json_obj_off, "offset", json_object_new_int(l_arr_start));
-            json_object_array_add(json_arr_out, json_obj_off);
+            json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start));            
         }
         size_t l_arr_end =  l_chain->callback_count_atom(l_chain);
-        if (a_limit) {
-            l_arr_end = l_arr_start + a_limit;
-            json_object* json_obj_lim = json_object_new_object();
-            json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));
-            json_object_array_add(json_arr_out, json_obj_lim);
-            if (l_arr_end > l_chain->callback_count_atom(l_chain)) {
-                l_arr_end = l_chain->callback_count_atom(l_chain);
-            }
+        l_arr_end = a_limit ? l_arr_start + a_limit : l_arr_start + 1000;
+        json_object_object_add(json_obj_lim, "limit", json_object_new_int(l_arr_end - l_arr_start));
+        json_object_array_add(json_arr_out, json_obj_lim);
+        if (l_arr_end > l_chain->callback_count_atom(l_chain)) {
+            l_arr_end = l_chain->callback_count_atom(l_chain);
         }
-        size_t i_tmp = 1;
+
+        bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
+
         HASH_ITER(hh, l_chain->cells, l_cell, l_cell_tmp) {
-            if (a_limit && l_count_tx >= a_limit)
+            if (l_count_tx >= l_arr_end)
                 break;
             l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell->id, NULL);
             size_t l_atom_size = 0;
             dap_chain_atom_ptr_t l_ptr = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size);
-            while (l_ptr && l_atom_size && (a_limit ? l_count_tx < a_limit : true)) {
+            while (l_ptr && l_atom_size && (l_count_tx < l_arr_end)) {
                 size_t l_datums_count = 0;
                 dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_ptr, l_atom_size, &l_datums_count);
-                for (size_t i = 0; i < l_datums_count && (a_limit ? l_count_tx < a_limit : true); i++) {
+                for (size_t i = 0; i < l_datums_count && (l_count_tx < l_arr_end); i++) {
                     if (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX) {
-                        if (i_tmp < l_arr_start || i_tmp >= l_arr_end) {
-                            i_tmp++;
+                        if (l_count_tx < l_arr_start) {
+                            l_count_tx++;
                             continue;
                         }
-                        i_tmp++;
                         dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datums[i]->data;
                         dap_hash_fast_t l_ttx_hash = {0};
                         dap_hash_fast(l_tx, l_datums[i]->header.data_size, &l_ttx_hash);
+
+                        char *service_name = NULL;
+                        dap_chain_tx_tag_action_type_t l_action;
+                        dap_ledger_t *l_ledger = l_net->pub.ledger;
+                        bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, &l_action);
+                        
+                        if (!(l_action & a_action))
+                            continue;
+
+                        if (a_srv)
+                        {
+                            char *service_name = NULL;
+                            bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, NULL);
+                            //skip if looking for UNKNOWN + it is known
+                            if (look_for_unknown_service && srv_found) {
+                                continue;
+                            }
+                            
+                            //skip if search condition provided, it not UNKNOWN and found name not match
+                            if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0))
+                            {
+                                continue;
+                            }
+                        }        
+                        
                         bool accepted_tx;
                         json_object* json_obj_datum = dap_db_tx_history_to_json(&l_ttx_hash, NULL, l_tx, l_chain, l_hash_out_type, l_net, 0, &accepted_tx, out_brief);
                         if (!json_obj_datum) {
@@ -699,8 +776,9 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
                             ++l_tx_ledger_rejected;
                         }
                         json_object_array_add(json_arr_out, json_obj_datum);
-                        const char * debug_json_string = json_object_to_json_string(json_obj_datum);
+                        //const char * debug_json_string = json_object_to_json_string(json_obj_datum);
                         ++l_count_tx;
+                        l_count++;
                     }
                 }
                 DAP_DEL_Z(l_datums);
@@ -712,7 +790,7 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
 
         json_object_object_add(json_obj_summary, "network", json_object_new_string(l_net->pub.name));
         json_object_object_add(json_obj_summary, "chain", json_object_new_string(l_chain->name));
-        json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count_tx));
+        json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count));
         json_object_object_add(json_obj_summary, "accepted_tx", json_object_new_int(l_tx_ledger_accepted));
         json_object_object_add(json_obj_summary, "rejected_tx", json_object_new_int(l_tx_ledger_rejected));
         return json_arr_out;
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index db8546e97d..ab4105e834 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -37,6 +37,9 @@
 #include "dap_chain_datum_tx_items.h"
 #include "dap_chain_net.h"
 
+#define DAP_CHAIN_NET_SRV_TRANSFER_ID 0x07
+#define DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID 0x08
+
 typedef struct dap_ledger {
     dap_chain_net_t *net;
     void *_internal;
@@ -114,6 +117,27 @@ typedef enum dap_ledger_token_decl_add_err{
     DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */
 } dap_ledger_token_decl_add_err_t;
 
+typedef enum dap_chain_tx_tag_action_type {    
+
+    //subtags, till 32
+    DAP_CHAIN_TX_TAG_ACTION_UNKNOWN  =              1 << 1,
+    
+    DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR =      1 << 2,
+    DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION =    1 << 3,
+    DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN =   1 << 4,
+    DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD =       1 << 5,
+
+    DAP_CHAIN_TX_TAG_ACTION_OPEN =                  1 << 6,
+    DAP_CHAIN_TX_TAG_ACTION_USE =                   1 << 7,
+    DAP_CHAIN_TX_TAG_ACTION_EXTEND =                1 << 8,
+    DAP_CHAIN_TX_TAG_ACTION_CHANGE =                1 << 9,
+    DAP_CHAIN_TX_TAG_ACTION_CLOSE =                 1 << 10,
+    
+    
+    DAP_CHAIN_TX_TAG_ACTION_ALL =                          ~0,
+} dap_chain_tx_tag_action_type_t;
+
+
 typedef struct dap_ledger_datum_iter {
     dap_chain_net_t *net;
     dap_chain_datum_tx_t *cur;
@@ -130,6 +154,7 @@ typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chai
 typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
 typedef struct dap_chain_net dap_chain_net_t;
 typedef bool (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, bool a_apply);
+typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action);
 
 //Change this UUID to automatically reload ledger cache on next node startup
 #define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc"
@@ -271,11 +296,30 @@ const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const c
 
 bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
 
-// Checking a new transaction before adding to the cache
-int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
-                                    bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker);
+//TX service-tags
+bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *uid, dap_chain_tx_tag_action_type_t *action);
+const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag);
+dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str);
 
-const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc);
+bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, 
+                                dap_chain_net_srv_uid_t *a_uid, char **a_service_name,  dap_chain_tx_tag_action_type_t *a_action);
+
+
+int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback);
+
+
+// Checking a new transaction before adding to the cache
+int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, 
+                                        dap_chain_datum_tx_t *a_tx, 
+                                        dap_hash_fast_t *a_tx_hash,
+                                        bool a_from_threshold, 
+                                        dap_list_t **a_list_bound_items, 
+                                        dap_list_t **a_list_tx_out, 
+                                        char **a_main_ticker,
+                                        dap_chain_net_srv_uid_t *a_tag,
+                                        dap_chain_tx_tag_action_type_t *a_action);
+
+const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc);
 
 /**
  * Delete all transactions from the cache
@@ -376,3 +420,4 @@ void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged
 
 bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger);
 void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback);
+dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond);
diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h
index f704cdd943..7ce2131640 100644
--- a/modules/net/include/dap_chain_node_cli_cmd.h
+++ b/modules/net/include/dap_chain_node_cli_cmd.h
@@ -39,6 +39,21 @@ int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int
 int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, char **a_argv, void **a_str_reply,
                              dap_chain_t ** a_chain, dap_chain_net_t ** a_net);
 
+int dap_chain_node_cli_cmd_values_parse_net_chain_json(int *a_arg_index, int a_argc, char **a_argv,
+        dap_chain_t **a_chain, dap_chain_net_t **a_net);
+
+typedef enum s_com_parse_net_chain_err{
+    DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_STR_ERR = 100,
+    DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR,
+    DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR,
+
+    /* add custom codes here */
+
+    DAP_CHAIN_NODE_CLI_COM_PARSE_NET_UNKNOWN /* MAX */
+} s_com_parse_net_chain_err_t;
+
+
 /**
  * global_db command
  */
@@ -315,4 +330,4 @@ int com_chain_ca_pub( int a_argc,  char **a_argv, void **a_str_reply);
 int com_chain_ca_copy( int a_argc,  char **a_argv, void **a_str_reply);
 int com_signer(int a_argc, char **a_argv, void **a_str_reply);
 //remove func
-int cmd_remove(int a_argc, char **a_argv, void **a_str_reply);
\ No newline at end of file
+int cmd_remove(int a_argc, char **a_argv, void **a_str_reply);
diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h
index 619ef18662..6bc3dd7582 100644
--- a/modules/net/include/dap_chain_node_cli_cmd_tx.h
+++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h
@@ -25,6 +25,7 @@
 #pragma once
 
 #include "dap_chain.h"
+#include "dap_chain_ledger.h"
 #include "dap_chain_common.h"
 #include "dap_chain_net.h"
 
@@ -40,7 +41,10 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_
  * return history json
  */
 json_object * dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, const char *a_hash_out_type, dap_chain_net_t * l_net);
-json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary, size_t a_limit, size_t a_offset);
+json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary, size_t a_limit, size_t a_offset,
+bool a_brief,
+const char *a_srv,
+dap_chain_tx_tag_action_type_t a_action);
 json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
                                         dap_hash_fast_t * l_atom_hash,
                                         dap_chain_datum_tx_t * l_tx,
@@ -52,8 +56,17 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
                                         bool out_brief);
 
 json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
-                                   const char *l_hash_out_type, json_object *json_obj_summary,
-                                   size_t a_limit, size_t a_offset, bool out_brief);
+                                    const char *l_hash_out_type, json_object *json_obj_summary,
+                                    size_t a_limit, size_t a_offset, bool out_brief,
+                                    const char *a_srv,
+                                    dap_chain_tx_tag_action_type_t a_action);
+
+bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
+                                          dap_ledger_t *a_ledger,
+                                          json_object * json_obj_out,
+                                          const char *a_hash_out_type,
+                                          dap_chain_hash_fast_t *a_tx_hash);
+
 /**
  * ledger command
  *
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 559d9fdb29..48e461a3d6 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -136,7 +136,7 @@ void s_load_all()
                 continue;
             // don't search in directories
             char l_full_path[MAX_PATH + 1] = {0};
-            dap_snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
+            snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
             if(dap_dir_test(l_full_path)) {
                 continue;
             }
diff --git a/modules/service/bridge/CMakeLists.txt b/modules/service/bridge/CMakeLists.txt
new file mode 100644
index 0000000000..6c68b74fa5
--- /dev/null
+++ b/modules/service/bridge/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.10)
+project (dap_chain_net_srv_bridge)
+
+file(GLOB DAP_SRV_BRG_SRCS *.c)
+
+file(GLOB DAP_SRV_BRG_HEADERS include/*.h)
+
+add_library(${PROJECT_NAME} STATIC ${DAP_SRV_BRG_SRCS} ${DAP_SRV_BRG_HEADERS})
+
+target_include_directories(${PROJECT_NAME} INTERFACE .)
+target_include_directories(${PROJECT_NAME} PUBLIC include)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_net dap_chain_net_srv)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../dap-sdk/3rdparty/json-c)
+
+if (INSTALL_SDK)
+set_target_properties(${PROJECT_NAME}  PROPERTIES PUBLIC_HEADER "${DAP_SRV_BRG_HEADERS}")
+INSTALL(TARGETS ${PROJECT_NAME} 
+        LIBRARY DESTINATION lib/modules/service/bridge/
+        ARCHIVE DESTINATION lib/modules/service/bridge/
+        PUBLIC_HEADER DESTINATION include/modules/service/bridge/
+)
+endif()
\ No newline at end of file
diff --git a/modules/service/bridge/dap_chain_net_srv_bridge.c b/modules/service/bridge/dap_chain_net_srv_bridge.c
new file mode 100644
index 0000000000..439d0556d0
--- /dev/null
+++ b/modules/service/bridge/dap_chain_net_srv_bridge.c
@@ -0,0 +1,161 @@
+/*
+ * Authors:
+ * Roman Khlopkov <roman.khlopkov@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://gitlab.demlabs.net
+ * Copyright  (c) 2017-2020
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <math.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include "dap_chain_net.h"
+#include "dap_chain_datum_tx.h"
+#include "dap_chain_datum_tx_out_cond.h"
+#include "dap_chain_datum_tx_sig.h"
+#include "dap_list.h"
+#include "dap_sign.h"
+#include "dap_time.h"
+#include "dap_chain_net_srv.h"
+#include "dap_chain_ledger.h"
+#include "dap_chain_node_cli.h"
+#include "dap_common.h"
+#include "dap_hash.h"
+#include "dap_math_ops.h"
+#include "dap_string.h"
+#include "dap_chain_common.h"
+#include "dap_chain_mempool.h"
+#include "dap_chain_datum_decree.h"
+#include "dap_tsd.h"
+#include "dap_chain_net_tx.h"
+#include "dap_chain_net_srv.h"
+#include "dap_chain_net_srv_bridge.h"
+#include "uthash.h"
+
+#define LOG_TAG "dap_chain_net_srv_bridge"
+
+
+static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize,  const char *str ) {
+    size_t l_strlen = (size_t)strlen(str);
+    if (l_strlen != a_tsdsize) return -1;
+    return memcmp(a_tsdata, str, l_strlen);
+}
+
+//emission tags
+//inherits from emission tsd section for engine-produced auth emissions
+bool s_get_ems_bridge_action(dap_chain_datum_token_emission_t *a_ems, dap_chain_tx_tag_action_type_t *a_action)
+{
+    if (!a_ems || !a_action)
+        return false;
+
+    if (a_action)
+        *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+
+    size_t src_tsd_size = 0;
+    
+    src_tsd_size = 0;
+    size_t subsrc_tsd_size = 0;
+    
+    byte_t *ems_src = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE, &src_tsd_size);
+    byte_t *ems_subsrc = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE, &subsrc_tsd_size);
+
+    if (ems_src && src_tsd_size)
+    {   
+        //old bridge ems
+        if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION_OLD) == 0)
+        {
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
+            return true;      
+        }
+        
+        //not bridge
+        if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_BRIDGE) != 0)
+            return false;
+    }
+    else
+    {
+        //special case for old bridge datums
+        //no SOURCE, but have all this
+        //if emission has 5, 8, 6 section (it's enough) -> this is old bridge tx
+        if (dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_NET_ID, &src_tsd_size) &&
+            dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BLOCK_NUM, &src_tsd_size) &&
+            dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_OUTER_TX_HASH, &src_tsd_size))
+        {
+            *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
+            return true;
+        }
+    }
+
+    if (ems_subsrc && subsrc_tsd_size)
+    {
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION)==0)
+        {
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
+            return true;
+        }
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_TRANSFER)==0)
+        {
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
+            return true;
+        }    
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_CROSSCHAIN)==0)
+        {   
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN;
+            return true;
+        }
+    }
+    return false;
+}
+
+
+static bool s_tag_check_bridge(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //bridged native transfer: destination addr netid differs from net we get datum
+    //such tx are marked by TRANSFER service as CROSSCHAIN_TRANSFER
+    //bridge txs are only received one
+    
+
+    //crosschain bridge AUTH emissions 
+    
+    if (!a_items_grp->items_in_ems)
+        return false;
+
+    dap_chain_tx_in_ems_t *l_tx_in_ems = a_items_grp->items_in_ems->data;
+    dap_hash_fast_t ems_hash = l_tx_in_ems->header.token_emission_hash;
+    dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(a_ledger, &ems_hash);
+    if(l_emission)
+        return s_get_ems_bridge_action(l_emission, a_action);
+
+    return false;
+}
+
+int dap_chain_net_srv_bridge_init()
+{
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_BRIDGE_ID };
+    dap_ledger_service_add(l_uid, "bridge", s_tag_check_bridge);
+    return 0;
+}
+
+void dap_chain_net_srv_bridge_deinit()
+{
+    
+}
+
diff --git a/modules/service/bridge/include/dap_chain_net_srv_bridge.h b/modules/service/bridge/include/dap_chain_net_srv_bridge.h
new file mode 100644
index 0000000000..c5d9cb013f
--- /dev/null
+++ b/modules/service/bridge/include/dap_chain_net_srv_bridge.h
@@ -0,0 +1,5 @@
+#define DAP_CHAIN_NET_SRV_BRIDGE_ID 0x04
+
+int dap_chain_net_srv_bridge_init();
+
+void dap_chain_net_srv_bridge_deinit();
diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c
index 0132dbef97..9bed8a731c 100644
--- a/modules/service/datum/dap_chain_net_srv_datum.c
+++ b/modules/service/datum/dap_chain_net_srv_datum.c
@@ -38,6 +38,12 @@ static int s_srv_datum_cli(int argc, char ** argv, void **a_str_reply);
 
 void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg);
 
+static bool s_tag_check_datum(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //datum service do not produce transactions for now.
+    return false;
+}
+
 int dap_chain_net_srv_datum_init()
 {
     dap_cli_server_cmd_add("srv_datum", s_srv_datum_cli, "Service Datum commands", 
@@ -51,6 +57,10 @@ int dap_chain_net_srv_datum_init()
         return -1;
     }
     s_srv_datum->uid.uint64 = DAP_CHAIN_NET_SRV_DATUM_ID;
+
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_DATUM_ID };
+    dap_ledger_service_add(l_uid, "datum", s_tag_check_datum);
+    
     return 0;
 }
 
diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c
index e779348930..71bca901ff 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -109,6 +109,140 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k
 // Callbacks
 static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_out_item);
 static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner);
+
+static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize,  const char *str ) {
+    size_t l_strlen = (size_t)strlen(str);
+    if (l_strlen != a_tsdsize) return -1;
+    return memcmp(a_tsdata, str, l_strlen);
+}
+
+//emission tags
+//inherits from emission tsd section for engine-produced auth emissions
+bool s_get_ems_staking_action(dap_chain_datum_token_emission_t *a_ems, dap_chain_tx_tag_action_type_t *a_action)
+{
+    if (!a_ems || !a_action)
+        return false;
+
+    *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+
+    
+    size_t src_tsd_size = 0;
+    size_t subsrc_tsd_size = 0;
+    
+    byte_t *ems_src = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE, &src_tsd_size);
+    byte_t *ems_subsrc = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE, &subsrc_tsd_size);
+
+    if (ems_src && src_tsd_size)
+    {
+        if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING) != 0)
+            return false;
+    }
+
+    //special processing for old stakes: they have only STAKING in tsd 9 and no subtype. it is opening stakes
+    if (ems_src && !ems_subsrc)
+    {
+        *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+        return true;
+    }
+
+    if (ems_subsrc && subsrc_tsd_size)
+    {
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAIN)==0)
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_OPEN;
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAINV2)==0)
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_OPEN;
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_HARVEST)==0) 
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD;
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_ADDLIQ)==0) 
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_EXTEND;
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_EMSFIX)==0) 
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_CHANGE;
+    
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_BONUS)==0) 
+            *a_action =  DAP_CHAIN_TX_TAG_ACTION_CHANGE;
+        
+
+        if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION)==0)
+            *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD;
+    
+        if (*a_action == DAP_CHAIN_TX_TAG_ACTION_UNKNOWN)
+        {
+            log_it(L_WARNING, "Unknown action for staking: %s", ems_subsrc);
+        }     
+        return true;
+    }
+
+    return false;
+}
+
+static bool s_tag_check_staking(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //staking native open: have SRV_STAKE_LOCK out
+    
+    if (a_items_grp->items_out_cond_srv_stake_lock) {
+        *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+        return true;
+    }
+    
+    //staking native close: have IN_COND linked with SRV_STAKE_LOCK out
+    if (a_items_grp->items_in_cond) 
+    {
+       for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
+            dap_chain_tx_in_cond_t *l_tx_in = it->data;
+            dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
+
+            if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) {
+                if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE;
+                return true;
+            }   
+        }
+    }
+
+    //m-token burn: have TSD-items with "STAKING type UNSTAKE subtype"
+    
+    if (a_items_grp->items_tsd) {
+        
+        bool src_staking = false;
+        bool subtype_unstake = false;
+        for (dap_list_t *it = a_items_grp->items_tsd; it; it = it->next) {
+            dap_chain_tx_tsd_t *l_tx_tsd = it->data;
+            int l_type;
+            size_t l_size;
+            byte_t *l_data = dap_chain_datum_tx_item_get_data(l_tx_tsd, &l_type, &l_size);
+            
+            
+            if (l_type == DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE && s_tsd_str_cmp(l_data, l_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING) == 0)
+                src_staking = true;
+            
+            if (l_type == DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE && s_tsd_str_cmp(l_data, l_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION) == 0)
+                subtype_unstake = true;
+        }
+        if (subtype_unstake && src_staking)
+        {
+            if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE;
+            return true;
+        }
+    }
+
+    //crosschain staking AUTH emissions 
+    if (!a_items_grp->items_in_ems)
+        return false;
+
+    dap_chain_tx_in_ems_t *l_tx_in_ems = a_items_grp->items_in_ems->data;
+    dap_hash_fast_t ems_hash = l_tx_in_ems->header.token_emission_hash;
+    dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(a_ledger, &ems_hash);
+    if(l_emission) {   
+        bool success = s_get_ems_staking_action(l_emission, a_action);
+        return success;
+    }
+
+    return false;
+}
+
 /**
  * @brief dap_chain_net_srv_external_stake_init
  * @return
@@ -132,6 +266,10 @@ int dap_chain_net_srv_stake_lock_init()
                 "-chain <chain>\n"
     );
     s_debug_more = dap_config_get_item_bool_default(g_config, "ledger", "debug_more", false);
+
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_LOCK_ID };
+    dap_ledger_service_add(l_uid, "staking", s_tag_check_staking);
+
     return 0;
 }
 
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 b464c68a9a..86c438f747 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
@@ -56,6 +56,32 @@ static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap
 
 static dap_list_t *s_srv_stake_list = NULL;
 
+static bool s_tag_check_key_delegation(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    // keydelegation open: have STAK_POS_DELEGATE out
+    
+    if (a_items_grp->items_out_cond_srv_stake_pos_delegate) {
+        if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+        return true;
+    }
+
+    //key delegation invalidation (close): have IN_COND linked with STAKE_POS_DELEGATE out
+    if (a_items_grp->items_in_cond) 
+    {
+       for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
+            dap_chain_tx_in_cond_t *l_tx_in = it->data;
+            dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
+
+            if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE) {
+                if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE;
+                return true;
+            }   
+        }
+    }
+
+    return false;
+}
+
 /**
  * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel
  * @return 0 if everything is okay, lesser then zero if errors
@@ -103,6 +129,8 @@ int dap_chain_net_srv_stake_pos_delegate_init()
          "\tCheck remote validator"
     );
 
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID };
+    dap_ledger_service_add(l_uid, "pos_delegate", s_tag_check_key_delegation);
     return 0;
 }
 
@@ -833,7 +861,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t
         dap_list_free_full(l_tsd_list, NULL);
         return NULL;
     }
-    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR;
+    l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR;
     l_tsd->size = sizeof(dap_chain_node_addr_t);
     *(dap_chain_node_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr;
     l_tsd_list = dap_list_append(l_tsd_list, l_tsd);
diff --git a/modules/service/voting/CMakeLists.txt b/modules/service/voting/CMakeLists.txt
new file mode 100644
index 0000000000..544179bc63
--- /dev/null
+++ b/modules/service/voting/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.10)
+project (dap_chain_net_srv_voting)
+
+file(GLOB DAP_SRV_VTNG_SRCS *.c)
+
+file(GLOB DAP_SRV_VTNG_HEADERS include/*.h)
+
+add_library(${PROJECT_NAME} STATIC ${DAP_SRV_VTNG_SRCS} ${DAP_SRV_VTNG_HEADERS})
+
+target_include_directories(${PROJECT_NAME} INTERFACE .)
+target_include_directories(${PROJECT_NAME} PUBLIC include)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_net dap_chain_net_srv)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../dap-sdk/3rdparty/json-c)
+
+if (INSTALL_SDK)
+set_target_properties(${PROJECT_NAME}  PROPERTIES PUBLIC_HEADER "${DAP_SRV_BRG_HEADERS}")
+INSTALL(TARGETS ${PROJECT_NAME} 
+        LIBRARY DESTINATION lib/modules/service/voting/
+        ARCHIVE DESTINATION lib/modules/service/voting/
+        PUBLIC_HEADER DESTINATION include/modules/service/voting/
+)
+endif()
\ No newline at end of file
diff --git a/modules/net/dap_chain_net_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c
similarity index 99%
rename from modules/net/dap_chain_net_voting.c
rename to modules/service/voting/dap_chain_net_srv_voting.c
index 9511e4c208..5cff28c808 100644
--- a/modules/net/dap_chain_net_voting.c
+++ b/modules/service/voting/dap_chain_net_srv_voting.c
@@ -30,7 +30,7 @@
 #include <errno.h>
 #include <pthread.h>
 
-#include "dap_chain_net_voting.h"
+#include "dap_chain_net_srv_voting.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_chain_net_tx.h"
 #include "dap_chain_mempool.h"
@@ -97,7 +97,24 @@ static int s_datum_tx_voting_coin_check_spent(dap_chain_net_t *a_net, dap_hash_f
 static bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in, bool a_apply);
 static int s_cli_voting(int argc, char **argv, void **a_str_reply);
 
-int dap_chain_net_voting_init()
+static bool s_tag_check_voting(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //voting open 
+    if (a_items_grp->items_voting) {
+        *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+        return true;
+    }
+
+    //voting use
+    if (a_items_grp->items_vote) {
+        *a_action = DAP_CHAIN_TX_TAG_ACTION_USE;
+        return true;
+    }
+
+    return false;
+}
+
+int dap_chain_net_srv_voting_init()
 {
     pthread_rwlock_init(&s_votings_rwlock, NULL);
     dap_chain_ledger_voting_verificator_add(s_datum_tx_voting_verification_callback);
@@ -106,9 +123,19 @@ int dap_chain_net_voting_init()
                             "voting vote -net <net_name> -hash <voting_hash> -option_idx <option_index> [-cert <delegate_cert_name>] -fee <value_datoshi> -w <fee_wallet_name>\n"
                             "voting list -net <net_name>\n"
                             "voting dump -net <net_name> -hash <voting_hash>\n");
+
+    
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VOTING_ID };
+    dap_ledger_service_add(l_uid, "voting", s_tag_check_voting);
+
     return 0;
 }
 
+void dap_chain_net_srv_voting_deinit()
+{
+
+}
+
 uint64_t* dap_chain_net_voting_get_result(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_voting_hash)
 {
     if(!a_voting_hash){
diff --git a/modules/net/include/dap_chain_net_voting.h b/modules/service/voting/include/dap_chain_net_srv_voting.h
similarity index 89%
rename from modules/net/include/dap_chain_net_voting.h
rename to modules/service/voting/include/dap_chain_net_srv_voting.h
index c045605f30..df90751a3e 100644
--- a/modules/net/include/dap_chain_net_voting.h
+++ b/modules/service/voting/include/dap_chain_net_srv_voting.h
@@ -28,6 +28,15 @@
 #include "dap_chain_common.h"
 #include "dap_chain_wallet.h"
 
+#define DAP_CHAIN_NET_SRV_VOTING_ID 0x06
+
+
+//typedef struct dap_chain_net_vote_info_result {
+//    uint64_t answer_idx;
+//    uint64_t votes_count;
+//}dap_chain_net_vote_result_t;
+
+
 typedef struct dap_chain_net_vote_info_option{
     uint64_t option_idx;
     uint64_t votes_count;
@@ -36,7 +45,6 @@ typedef struct dap_chain_net_vote_info_option{
     char *description;
     dap_list_t *hashes_tx_votes;
 }dap_chain_net_vote_info_option_t;
-
 typedef struct dap_chain_net_vote_info{
     dap_hash_fast_t hash;
     dap_chain_net_id_t net_id;
@@ -56,9 +64,8 @@ typedef struct dap_chain_net_vote_info{
     } options;
 }dap_chain_net_vote_info_t;
 
-
-int dap_chain_net_voting_init();
-
+int dap_chain_net_srv_voting_init();
+void dap_chain_net_srv_voting_deinit();
 
 uint64_t* dap_chain_net_voting_get_result(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_voting_hash);
 
@@ -80,9 +87,9 @@ enum DAP_CHAIN_NET_VOTE_CREATE_ERROR {
     DAP_CHAIN_NET_VOTE_CREATE_CAN_NOT_POOL_DATUM_IN_MEMPOOL
 };
 int dap_chain_net_vote_create(const char *a_question, dap_list_t *a_options, dap_time_t a_expire_vote,
-                              uint64_t a_max_vote, uint256_t a_fee, bool a_delegated_key_required,
-                              bool a_vote_changing_allowed, dap_chain_wallet_t *a_wallet,
-                              dap_chain_net_t *a_net, const char *a_hash_out_type, char **a_hash_output);
+                             uint64_t a_max_vote, uint256_t a_fee, bool a_delegated_key_required,
+                             bool a_vote_changing_allowed, dap_chain_wallet_t *a_wallet,
+                             dap_chain_net_t *a_net, const char *a_hash_out_type, char **a_hash_output);
 
 enum DAP_CHAIN_NET_VOTE_VOTING_ERROR{
     DAP_CHAIN_NET_VOTE_VOTING_OK,
@@ -111,3 +118,4 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal
 dap_list_t *dap_chain_net_vote_list(dap_chain_net_t *a_net);
 dap_chain_net_vote_info_t *dap_chain_net_vote_extract_info(dap_chain_net_t *a_net, dap_hash_fast_t *a_vote_hash);
 void dap_chain_net_vote_info_free(dap_chain_net_vote_info_t *a_info);
+
diff --git a/modules/service/vpn/CMakeLists.txt b/modules/service/vpn/CMakeLists.txt
index 04be24a936..8f5ffe7b7d 100644
--- a/modules/service/vpn/CMakeLists.txt
+++ b/modules/service/vpn/CMakeLists.txt
@@ -1,16 +1,20 @@
 cmake_minimum_required(VERSION 3.10)
 project (dap_chain_net_srv_vpn)
   
-file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *.c)
-
-file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*.h)
 
 if(WIN32)
+  file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *common.c)
+  file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*common.h)
+
   include_directories(../../../os/win32/)
   include_directories(../3rdparty/wepoll/include/)
   include_directories(../3rdparty/uthash/src/)
   include_directories(../../dap-sdk/3rdparty/json-c/)
   include_directories(../3rdparty/libmagic/src/)
+else()
+  file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *.c)
+  file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*.h)
+
 endif()
 
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS})
@@ -28,4 +32,4 @@ INSTALL(TARGETS ${PROJECT_NAME}
         ARCHIVE DESTINATION lib/modules/service/vpn/
         PUBLIC_HEADER DESTINATION include/modules/service/vpn/
 )
-endif()
\ No newline at end of file
+endif()
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_common.c b/modules/service/vpn/dap_chain_net_srv_vpn_common.c
new file mode 100644
index 0000000000..fbfdc2962b
--- /dev/null
+++ b/modules/service/vpn/dap_chain_net_srv_vpn_common.c
@@ -0,0 +1,44 @@
+
+#include "dap_chain_net_srv_vpn_common.h"
+#include "dap_chain_ledger.h"
+
+
+static bool s_tag_check_vpn(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,  dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    
+    //VPN  open: have SRV_PAY out with vpn uid
+    
+    if (a_items_grp->items_out_cond_srv_pay) {
+        dap_chain_tx_out_cond_t *l_cond_out = a_items_grp->items_out_cond_srv_pay->data; 
+        if (l_cond_out->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_VPN_ID)
+           if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+        return true;
+    }
+    
+    //VPN native use: have IN_COND linked with DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY out with vpn uid
+    
+    if (a_items_grp->items_in_cond) {
+       for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
+            dap_chain_tx_in_cond_t *l_tx_in = it->data;
+            dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
+
+            if (l_tx_out_cond && 
+                l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY &&
+                l_tx_out_cond->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_VPN_ID) {
+                    if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_USE;
+                    return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+
+
+int dap_chain_net_srv_vpn_pre_init()
+{
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
+    dap_ledger_service_add(l_uid, "vpn", s_tag_check_vpn);
+    return 0;
+}
diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn.h b/modules/service/vpn/include/dap_chain_net_srv_vpn.h
index 1fb31f7cb4..93698d8b18 100644
--- a/modules/service/vpn/include/dap_chain_net_srv_vpn.h
+++ b/modules/service/vpn/include/dap_chain_net_srv_vpn.h
@@ -28,6 +28,7 @@
 #include "dap_config.h"
 #include "dap_chain_net_srv.h"
 #include "dap_events.h"
+#include "dap_chain_net_srv_vpn_common.h"
 
 #define DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX "srv.vpn"
 
@@ -36,8 +37,6 @@
 
 #define DAP_STREAM_CH_NET_SRV_ID_VPN        'S'
 
-#define DAP_CHAIN_NET_SRV_VPN_ID            0x0000000000000001
-
 #define VPN_PACKET_OP_CODE_CONNECTED        0x000000a9
 #define VPN_PACKET_OP_CODE_CONNECT          0x000000aa
 #define VPN_PACKET_OP_CODE_DISCONNECT       0x000000ab
@@ -172,6 +171,7 @@ typedef struct dap_chain_net_srv_vpn
 
 int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config);
 
+int dap_chain_net_srv_vpn_pre_init();
 int dap_chain_net_srv_vpn_init(dap_config_t * g_config);
 void dap_chain_net_srv_vpn_deinit(void);
 
diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h
new file mode 100644
index 0000000000..abb3ad778b
--- /dev/null
+++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h
@@ -0,0 +1,4 @@
+
+#define DAP_CHAIN_NET_SRV_VPN_ID            0x0000000000000001
+
+int dap_chain_net_srv_vpn_pre_init();
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index f4b2d1436a..1dfb282546 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -56,13 +56,6 @@ typedef enum tx_opt_status {
     TX_STATUS_INACTIVE
 } tx_opt_status_t;
 
-typedef enum xchange_tx_type {
-    TX_TYPE_UNDEFINED=0,
-    TX_TYPE_ORDER,
-    TX_TYPE_EXCHANGE,
-    TX_TYPE_INVALIDATE
-} xchange_tx_type_t;
-
 static dap_chain_net_srv_fee_item_t *s_service_fees = NULL; // Governance statements for networks
 static pthread_rwlock_t s_service_fees_rwlock = PTHREAD_RWLOCK_INITIALIZER;
 
@@ -77,8 +70,6 @@ static int s_callback_requested(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id,
 static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
-
-static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item);
 static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx);
 static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, uint256_t *a_fee, bool a_ret_is_invalid);
@@ -86,6 +77,66 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
 static dap_chain_net_srv_xchange_t *s_srv_xchange;
 static bool s_debug_more = true;
 
+
+static bool s_tag_check_xchange(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
+{
+    //check if we have in or out for xchange
+    
+    bool have_xchange_out = false;
+    bool have_xchange_in = false;
+    if (a_items_grp->items_out_cond_srv_xchange) {
+        dap_chain_tx_out_cond_t *l_cond_out = a_items_grp->items_out_cond_srv_xchange->data; 
+        if (l_cond_out->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_XCHANGE_ID)
+            have_xchange_out = true;
+    }
+    
+    if (a_items_grp->items_in_cond) {
+       for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
+            dap_chain_tx_in_cond_t *l_tx_in = it->data;
+            dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
+
+            if (l_tx_out_cond && 
+                l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE &&
+                l_tx_out_cond->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_XCHANGE_ID) {
+                    have_xchange_in = true;
+            }
+        }
+    }
+
+    if (have_xchange_in || have_xchange_out) {
+        //xchange by xchange module
+        xchange_tx_type_t type = dap_chain_net_srv_xchange_tx_get_type(a_ledger, a_tx, NULL, NULL, NULL);
+        switch(type)
+        {
+            case TX_TYPE_ORDER:
+            { 
+                if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN;
+                return true;
+            }
+
+            case TX_TYPE_EXCHANGE:
+            { 
+                if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_USE;
+                return true;
+            }
+
+            case TX_TYPE_INVALIDATE:
+            { 
+                if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE;
+                return true;
+            } 
+            default:
+            {
+                if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
+                return false;
+            }
+        }
+    }
+
+    return false;
+    
+}
+
 /**
  * @brief dap_chain_net_srv_xchange_init Init actions for xchanger stream channel
  * @return 0 if everything is okay, lesser then zero if errors
@@ -136,6 +187,10 @@ int dap_chain_net_srv_xchange_init()
     l_srv_callbacks.receipt_next_success = s_callback_receipt_next_success;
     l_srv_callbacks.decree = s_callback_decree;
 
+    //register service for tagging
+    dap_ledger_service_add(l_uid, "xchange", s_tag_check_xchange);
+
+
     dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, "srv_xchange", &l_srv_callbacks);
     s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t);
     if (!s_srv_xchange || !l_srv) {
@@ -210,7 +265,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_
     byte_t * l_tx_item;
 
     dap_chain_addr_t l_service_fee_addr, *l_seller_addr = &a_tx_out_cond->subtype.srv_xchange.seller_addr;
-    uint16_t l_service_fee_type;
+    uint16_t l_service_fee_type = 0;
     dap_chain_net_t *l_net = a_ledger->net;
     bool l_service_fee_used = dap_chain_net_srv_xchange_get_fee(l_net->pub.id, &l_service_fee_val, &l_service_fee_addr, &l_service_fee_type);
     const char *l_native_ticker = l_net->pub.native_ticker;
@@ -834,7 +889,7 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_
         MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed);
     } else {
         dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
-        xchange_tx_type_t tx_type = s_xchange_tx_get_type(a_net, l_last_tx, NULL, NULL, &l_out_prev_cond_item);
+        xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, l_last_tx, NULL, NULL, &l_out_prev_cond_item);
         if (tx_type == TX_TYPE_EXCHANGE){
             SUBTRACT_256_256(l_out_cond->header.value, uint256_0, &l_percent_completed);
             DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
@@ -1328,7 +1383,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash(l_net, &l_order_tx_hash, TX_SEARCH_TYPE_NET);
                 
                 if( l_tx){
-                    xchange_tx_type_t l_tx_type = s_xchange_tx_get_type(l_net, l_tx, NULL, NULL, NULL);
+                    xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, NULL, NULL, NULL);
                     char *l_tx_hash = dap_chain_hash_fast_to_str_new(&l_order_tx_hash);
                     if(l_tx_type != TX_TYPE_ORDER){
                         dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum with hash %s is not order. Check hash.", l_tx_hash);
@@ -1531,6 +1586,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                                      l_cp_rate,
                                      l_price->net->pub.name);
 
+
+            DAP_DEL_Z(l_amount_coins_str);
+            DAP_DEL_Z(l_amount_datoshi_str);
             DAP_DEL_Z(l_cp_rate);
             DAP_DEL_Z(l_price);
         } break;
@@ -1582,7 +1640,7 @@ static bool s_filter_tx_list(dap_chain_datum_t *a_datum, dap_chain_t *a_chain, v
     return false;
 }
 
-static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item)
+xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item)
 {
     int l_tx_type = TX_TYPE_UNDEFINED;
 
@@ -1595,29 +1653,43 @@ static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_cha
     byte_t *l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL);
     dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL;
     int l_prev_cond_idx = 0;
-    dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL;
+    dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond->header.tx_prev_hash) : NULL;
     dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
                                                                                                 &l_prev_cond_idx) : NULL;
 
     if(l_out_prev_cond_item && l_out_prev_cond_item->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE)
         return l_tx_type;
-
+    
+    if (l_in_cond && l_prev_cond_idx >= 0 && (uint32_t)l_prev_cond_idx != l_in_cond->header.tx_out_prev_idx)
+        return l_tx_type;
+    
     if (l_out_cond_item && !l_out_prev_cond_item)
         l_tx_type = TX_TYPE_ORDER;
     else if (l_out_cond_item && l_out_prev_cond_item)
+    {
         l_tx_type = TX_TYPE_EXCHANGE;
-    else if (!l_out_cond_item && l_out_prev_cond_item){
+    }
+    else if (!l_out_cond_item && l_out_prev_cond_item)
+    {
         dap_chain_datum_tx_t * l_prev_tx_temp = a_tx;
         byte_t *l_tx_item_temp = NULL;
-        while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL){
+        while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL)
+        {
                 dap_chain_tx_in_cond_t * l_in_cond_temp = (dap_chain_tx_in_cond_t *) l_tx_item_temp;
-                l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_in_cond_temp->header.tx_prev_hash);
+                l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond_temp->header.tx_prev_hash);
         }
 
-        dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, TX_ITEM_TYPE_SIG, NULL);
-        dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
-        dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
-        dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
+        //have to find EXCHANGE tx_out_cond!
+        l_out_cond_item = NULL;
+        l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_prev_tx_temp, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
+                                                                               &l_cond_idx);
+        if (!l_out_cond_item) {
+            l_tx_type = TX_TYPE_UNDEFINED;
+        } else {
+            dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, TX_ITEM_TYPE_SIG, NULL);
+            dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
+            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL);
+            dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
 
         bool l_owner = false;
         l_owner = dap_sign_compare_pkeys(l_prev_sign,l_sign);
@@ -1625,14 +1697,16 @@ static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_cha
                 l_tx_type = TX_TYPE_INVALIDATE;
         else
                 l_tx_type = TX_TYPE_EXCHANGE;
-    }
+        }
 
-    if(a_out_cond_item)
-        *a_out_cond_item = l_out_cond_item;
-    if(a_out_prev_cond_item)
-        *a_out_prev_cond_item = l_out_prev_cond_item;
-    if (a_item_idx)
-        *a_item_idx = l_cond_idx;
+        if(a_out_cond_item)
+            *a_out_cond_item = l_out_cond_item;
+        if(a_out_prev_cond_item)
+            *a_out_prev_cond_item = l_out_prev_cond_item;
+        if (a_item_idx)
+            *a_item_idx = l_cond_idx;
+        return l_tx_type;
+    }
     return l_tx_type;
 }
 
@@ -1700,7 +1774,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
     dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
     int l_cond_idx = 0;
 
-    xchange_tx_type_t l_tx_type = s_xchange_tx_get_type(a_net, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item);
+    xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item);
 
     bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL);
     if ((a_filter_by_status == TX_STATUS_ACTIVE && l_is_closed) || (a_filter_by_status == TX_STATUS_INACTIVE && !l_is_closed))
@@ -1808,6 +1882,9 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
             dap_string_append_printf(a_reply_str, "  returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str);
             if(a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
+
+            DAP_DELETE(l_value_from_str);
+            DAP_DELETE(l_value_from_datoshi_str);
         } break;
         default: return false;
     }
@@ -2299,7 +2376,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                             int l_cond_idx = 0;
                             dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
 
-                            if (s_xchange_tx_get_type(l_net, l_tx, &l_out_cond_item, &l_cond_idx, NULL) != TX_TYPE_ORDER){
+                            if (dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, &l_out_cond_item, &l_cond_idx, NULL) != TX_TYPE_ORDER){
                                 l_cur = dap_list_next(l_cur);
                                 continue;
                             }
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index d9b155a072..9cff53d974 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -26,6 +26,7 @@
 
 #include "dap_chain_net_srv.h"
 #include "dap_chain_wallet.h"
+#include "dap_chain_datum_tx_out_cond.h"
 
 #define DAP_CHAIN_NET_SRV_XCHANGE_ID 0x2
 #define GROUP_LOCAL_XCHANGE "local.xchange"
@@ -77,7 +78,7 @@ typedef enum dap_chain_net_srv_xchange_create_error_list{
     XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
     XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
     XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL,
-}dap_chain_net_srv_xchange_create_error_t;
+} dap_chain_net_srv_xchange_create_error_t;
 dap_chain_net_srv_xchange_create_error_t dap_chain_net_srv_xchange_create(dap_chain_net_t *a_net, const char *a_token_buy,
                                      const char *a_token_sell, uint256_t a_datoshi_sell,
                                      uint256_t a_rate, uint256_t a_fee, dap_chain_wallet_t *a_wallet,
@@ -90,7 +91,7 @@ typedef enum dap_chain_net_srv_xchange_remove_error_list{
     XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX,
     XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE,
     XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX
-}dap_chain_net_srv_xchange_remove_error_t;
+} dap_chain_net_srv_xchange_remove_error_t;
 dap_chain_net_srv_xchange_remove_error_t dap_chain_net_srv_xchange_remove(dap_chain_net_t *a_net, dap_hash_fast_t *a_hash_tx, uint256_t a_fee,
                                      dap_chain_wallet_t *a_wallet, char **a_out_hash_tx);
 
@@ -103,7 +104,7 @@ typedef enum dap_chain_net_srv_xchange_purchase_error_list{
     XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND,
     XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE,
     XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX,
-}dap_chain_net_srv_xchange_purchase_error_t;
+} dap_chain_net_srv_xchange_purchase_error_t;
 dap_chain_net_srv_xchange_purchase_error_t dap_chain_net_srv_xchange_purchase(dap_chain_net_t *a_net, dap_hash_fast_t *a_order_hash, uint256_t a_value,
                                        uint256_t a_fee, dap_chain_wallet_t *a_wallet, char **a_hash_out);
 
@@ -113,6 +114,15 @@ typedef enum dap_chain_net_srv_xchange_order_status{
     XCHANGE_ORDER_STATUS_OPENED = 0,
     XCHANGE_ORDER_STATUS_CLOSED,
     XCHANGE_ORDER_STATUS_UNKNOWN,
-}dap_chain_net_srv_xchange_order_status_t;
+} dap_chain_net_srv_xchange_order_status_t;
+
+typedef enum xchange_tx_type{
+    TX_TYPE_UNDEFINED=0,
+    TX_TYPE_ORDER,
+    TX_TYPE_EXCHANGE,
+    TX_TYPE_INVALIDATE
+}   xchange_tx_type_t;
+
 dap_chain_net_srv_xchange_order_status_t dap_chain_net_srv_xchange_get_order_status(dap_chain_net_t *a_net, dap_hash_fast_t a_order_tx_hash);
 bool dap_chain_net_srv_xchange_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_fee, dap_chain_addr_t *a_addr, uint16_t *a_type);
+xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item);
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 8dbad5400d..2b1802af25 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -82,7 +82,7 @@ typedef struct dap_chain_cs_blocks_pvt
 #define PVT(a) ((dap_chain_cs_blocks_pvt_t *)(a)->_pvt )
 
 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(  dap_string_t * a_str_tmp, const char * a_meta_title, dap_chain_block_meta_t * a_meta);
+static void s_cli_meta_hash_print(  json_object* json_obj_a, const char * a_meta_title, dap_chain_block_meta_t * a_meta);
 static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply);
 
 // Setup BFT consensus and select the longest chunk
@@ -426,14 +426,14 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, voi
  * @param a_meta_title
  * @param a_meta
  */
-static void s_cli_meta_hash_print(dap_string_t *a_str_tmp, const char *a_meta_title, dap_chain_block_meta_t *a_meta)
+static void s_cli_meta_hash_print(json_object* json_obj_a, const char *a_meta_title, dap_chain_block_meta_t *a_meta)
 {
     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));
-        dap_string_append_printf(a_str_tmp, "\t\t%s: %s\n", a_meta_title, l_hash_str);
+        json_object_object_add(json_obj_a, a_meta_title, json_object_new_string(l_hash_str));
     } else
-        dap_string_append_printf(a_str_tmp,"\t\t\%s: Error, hash size is incorrect\n", a_meta_title);
+        json_object_object_add(json_obj_a, a_meta_title, json_object_new_string("Error, hash size is incorrect"));
 }
 
 /**
@@ -442,36 +442,45 @@ static void s_cli_meta_hash_print(dap_string_t *a_str_tmp, const char *a_meta_ti
  * @param a_meta_title
  * @param a_meta
  */
-static void s_cli_meta_hex_print(  dap_string_t * a_str_tmp, const char * a_meta_title, dap_chain_block_meta_t * a_meta)
+static void s_cli_meta_hex_print(json_object* json_obj_a, const char * a_meta_title, dap_chain_block_meta_t * a_meta)
 {
     char *l_data_hex = DAP_NEW_Z_SIZE(char, a_meta->hdr.data_size * 2 + 3);
     dap_bin2hex(l_data_hex, a_meta->data, a_meta->hdr.data_size);
-    dap_string_append_printf(a_str_tmp,"\t\t\%s: 0x%s\n", a_meta_title, l_data_hex);
+    char l_tmp_buff[70]={0};
+    sprintf(l_tmp_buff,"0x%s\n", l_data_hex);
+    json_object_object_add(json_obj_a, a_meta_title, json_object_new_string(l_tmp_buff));
     DAP_DELETE(l_data_hex);
 }
 
-static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_reply_str, const char *a_table_name)
+static void s_print_autocollect_table(dap_chain_net_t *a_net, json_object* json_obj_a, const char *a_table_name)
 {
     bool l_status = dap_chain_esbocs_get_autocollect_status(a_net->pub.id);
-    dap_string_append_printf(a_reply_str, "\nAutocollect status for %s in network %s is %s\n",
-                                         dap_strdown(a_table_name, -1), a_net->pub.name,
-                                         l_status ? "active" : "inactive, cause the network config or consensus starting problems");
+    char l_tmp_buff[150]={0};
+    sprintf(l_tmp_buff,"for %s in network %s is %s\n", a_table_name, a_net->pub.name,
+                                        l_status ? "active" : "inactive, cause the network config or consensus starting problems");
+    json_object_object_add(json_obj_a, "Autocollect status", json_object_new_string(l_tmp_buff));
     if (!l_status)
         return;
-    dap_string_append_printf(a_reply_str, "\nAutocollect tables content for:\n=== %s ===\n", a_table_name);
+    sprintf(l_tmp_buff,"\nAutocollect tables content for:\n=== %s ===\n", a_table_name);
+    json_object_object_add(json_obj_a, "Autocollect status", json_object_new_string(l_tmp_buff));
     size_t l_objs_count = 0;
     char *l_group = dap_strcmp(a_table_name, "Fees") ? dap_chain_cs_blocks_get_reward_group(a_net->pub.name)
                                                      : dap_chain_cs_blocks_get_fee_group(a_net->pub.name);
     dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_group, &l_objs_count);
     DAP_DELETE(l_group);
     uint256_t l_total_value = uint256_0;
+    json_object* json_arr_out = json_object_new_array();
     for (size_t i = 0; i < l_objs_count; i++) {
+        json_object* json_obj_t = json_object_new_object();
         dap_global_db_obj_t *l_obj_cur = l_objs + i;
         uint256_t l_cur_value = *(uint256_t*)l_obj_cur->value;
         const char *l_value_str; dap_uint256_to_char(l_cur_value, &l_value_str);
-        dap_string_append_printf(a_reply_str, "%s\t%s\n", l_obj_cur->key, l_value_str);
+        json_object_object_add(json_obj_t, "obj_key",json_object_new_string(l_obj_cur->key));
+        json_object_object_add(json_obj_t, "obj_val",json_object_new_string(l_value_str));
+        json_object_array_add(json_arr_out, json_obj_t);
         SUM_256_256(l_total_value, l_cur_value, &l_total_value);
     }
+    json_object_object_add(json_obj_a,"Autocollect tables",json_arr_out);
     if (l_objs_count) {
         dap_global_db_objs_delete(l_objs, l_objs_count);
         uint256_t l_collect_fee = dap_chain_esbocs_get_fee(a_net->pub.id);
@@ -493,11 +502,12 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re
         char *l_profit_str = dap_chain_balance_to_coins(l_collect_value);
         char *l_tax_str = dap_chain_balance_to_coins(l_collect_tax);
         char *l_fee_str = dap_chain_balance_to_coins(l_collect_fee);
-        dap_string_append_printf(a_reply_str, "\nTotal prepared value: %s %s, where\n\tprofit is %s, tax is %s, fee is %s\n",
+        sprintf(l_tmp_buff,"\nTotal prepared value: %s %s, where\n\tprofit is %s, tax is %s, fee is %s\n",
                                  l_total_str, a_net->pub.native_ticker, l_profit_str, l_tax_str, l_fee_str);
+        json_object_object_add(json_obj_a, "status",json_object_new_string(l_tmp_buff));
         DAP_DEL_MULTY(l_total_str, l_profit_str, l_tax_str, l_fee_str);
     } else
-        dap_string_append(a_reply_str, "Empty\n");
+        json_object_object_add(json_obj_a, "status",json_object_new_string("Empty\n"));
 }
 
 /**
@@ -510,6 +520,9 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re
  */
 static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
 {
+    json_object **json_arr_reply = (json_object **)a_str_reply;
+    //char ** a_str_reply = (char **) reply;
+    const char *l_hash_out_type = NULL;
     enum {
         SUBCMD_UNDEFINED =0,
         SUBCMD_NEW_FLUSH,
@@ -555,16 +568,15 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
     dap_chain_net_t * l_net = NULL;
 
     // Parse default values
-    if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0)
-        return -11;
+    if(dap_chain_node_cli_cmd_values_parse_net_chain_json(&arg_index, a_argc, a_argv, &l_chain, &l_net) < 0)
+        return -DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
 
     const char *l_chain_type = dap_chain_get_cs_type(l_chain);
 
     if (!strstr(l_chain_type, "block_") && strcmp(l_chain_type, "esbocs")){
-            dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Type of chain %s is not block. This chain with type %s is not supported by this command",
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR, "Type of chain %s is not block. This chain with type %s is not supported by this command",
                         l_chain->name, l_chain_type);
-            return -42;
+        return DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR;
     }
 
     l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
@@ -606,9 +618,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 s_cli_parse_cmd_hash(a_argv,arg_index,a_argc,a_str_reply,"-datum", &l_datum_hash );
                 l_blocks->block_new_size=dap_chain_block_datum_del_by_hash( &l_blocks->block_new, l_blocks->block_new_size, &l_datum_hash );
             }else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply,
-                          "Error! Can't delete datum from hash because no forming new block! Check pls you role, it must be MASTER NODE or greater");
-                ret = -12;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR, "Error! Can't delete datum from hash because no forming new block! Check pls you role, it must be MASTER NODE or greater");
+                ret = DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR;
             }
             pthread_rwlock_unlock( &PVT(l_blocks)->rwlock );
         }break;
@@ -618,9 +629,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_chain_datum_t ** l_datums = DAP_NEW_Z_SIZE(dap_chain_datum_t*,
                                                            sizeof(dap_chain_datum_t*)*l_datums_count);
             if (!l_datums) {
-        log_it(L_CRITICAL, "%s", g_error_memory_alloc);
-                dap_cli_server_cmd_set_reply_text(a_str_reply,"Out of memory in s_cli_blocks");
-                return -1;
+                log_it(L_CRITICAL, "%s", g_error_memory_alloc);
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR, "Out of memory in s_cli_blocks");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR;
             }
             size_t l_datum_size = 0;
 
@@ -630,16 +641,16 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             for (size_t i = 0; i < l_datums_count; i++) {
                 bool l_err = dap_chain_node_mempool_process(l_chain, l_datums[i], l_subcmd_str_arg);
                 if (l_err) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Error! Datum %s doesn't pass verifications, examine node log files",
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR, "Error! Datum %s doesn't pass verifications, examine node log files",
                                                       l_subcmd_str_arg);
-                    ret = -9;
+                    ret = DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR;
                 } else
                    log_it(L_INFO, "Pass datum %s from mempool to block in the new forming round ",
                                                      l_subcmd_str_arg);
                 if (l_err)
                     break;
             }
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "All datums processed");
+            dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "All datums processed");
             DAP_DELETE(l_gdb_group_mempool);
         } break;
 
@@ -654,94 +665,121 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
         case SUBCMD_DUMP:{
             dap_chain_hash_fast_t l_block_hash={0};
             if (!l_subcmd_str_arg) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Enter block hash ");
-                return -13;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash ");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR;
             }
             dap_chain_hash_fast_from_str(l_subcmd_str_arg, &l_block_hash); // Convert argument to hash
             dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash);
             if (!l_block_cache) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find block %s ", l_subcmd_str_arg);
-                return 10;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_subcmd_str_arg);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR;
             }
             dap_chain_block_t *l_block = l_block_cache->block;
-            dap_string_t *l_str_tmp = dap_string_new(NULL);
+            char l_tmp_buff[70]={0};
+
+            char l_time_buf[DAP_TIME_STR_SIZE];    
+            dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
             // Header
-            dap_string_append_printf(l_str_tmp, "Block number %"DAP_UINT64_FORMAT_U" hash %s:\n", l_block_cache->block_number, l_subcmd_str_arg);
-            dap_string_append_printf(l_str_tmp, "\t\t\tversion: 0x%04X\n", l_block->hdr.version);
-            dap_string_append_printf(l_str_tmp, "\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.cell_id.uint64);
-            dap_string_append_printf(l_str_tmp, "\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.chain_id.uint64);
-            char buf[DAP_TIME_STR_SIZE];
-            dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created);
-            dap_string_append_printf(l_str_tmp, "\t\t\tts_created: %s\n", buf);
+            json_object* json_obj_inf = json_object_new_object();
+            json_object_object_add(json_obj_inf, "Block number", json_object_new_uint64(l_block_cache->block_number));
+            json_object_object_add(json_obj_inf, "hash", json_object_new_string(l_subcmd_str_arg));
+            sprintf(l_tmp_buff,"0x%04X",l_block->hdr.version);
+            json_object_object_add(json_obj_inf, "version", json_object_new_string(l_tmp_buff));
+            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.cell_id.uint64);
+            json_object_object_add(json_obj_inf, "cell_id", json_object_new_string(l_tmp_buff));
+            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.chain_id.uint64);
+            json_object_object_add(json_obj_inf, "chain_id", json_object_new_string(l_tmp_buff));
+            json_object_object_add(json_obj_inf, "ts_created", json_object_new_string(l_time_buf));
 
             // Dump Metadata
             size_t l_offset = 0;
-            dap_string_append_printf(l_str_tmp,"\tMetadata. Count: %us\n",l_block->hdr.meta_count );
+            json_object_object_add(json_obj_inf, "Metadata: count", json_object_new_int(l_block->hdr.meta_count));
+            json_object* json_arr_meta_out = json_object_new_array();
+            json_object_array_add(*json_arr_reply, json_obj_inf);
             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:
-                    dap_string_append_printf(l_str_tmp, "\t\tGENESIS\n");
+                    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(l_str_tmp, "PREV", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta);
                     break;
                 case DAP_CHAIN_BLOCK_META_ANCHOR:
-                    s_cli_meta_hash_print(l_str_tmp, "ANCHOR", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta);
                     break;
                 case DAP_CHAIN_BLOCK_META_LINK:
-                    s_cli_meta_hash_print(l_str_tmp, "LINK", l_meta);
+                    s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta);
                     break;
                 case DAP_CHAIN_BLOCK_META_NONCE:
-                    s_cli_meta_hex_print(l_str_tmp, "NONCE", l_meta);
+                    s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta);
                     break;
                 case DAP_CHAIN_BLOCK_META_NONCE2:
-                    s_cli_meta_hex_print(l_str_tmp, "NONCE2", l_meta);
+                    s_cli_meta_hex_print(json_obj_meta, "NONCE2", l_meta);
                     break;
                 default: {
                         char * l_data_hex = DAP_NEW_Z_SIZE(char,l_meta->hdr.data_size*2+3);
                         dap_bin2hex(l_data_hex, l_meta->data, l_meta->hdr.data_size);
-                        dap_string_append_printf(l_str_tmp, "\t\t 0x%0X: 0x%s\n", i, l_data_hex );
+                        sprintf(l_tmp_buff,"0x%0X",i);
+                        json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_tmp_buff));
+                        sprintf(l_tmp_buff,"0x%s",l_data_hex);
+                        json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_tmp_buff));
                         DAP_DELETE(l_data_hex);
                     }
                 }
+                json_object_array_add(json_arr_meta_out, json_obj_meta);
                 l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size;
             }
-            dap_string_append_printf(l_str_tmp,"\t\tdatums:\tcount: %zu\n",l_block_cache->datum_count);
+            json_object_array_add(*json_arr_reply, json_arr_meta_out);
+            json_object* json_obj_datum = json_object_new_object();
+            json_object_object_add(json_obj_datum, "Datums: count", json_object_new_uint64(l_block_cache->datum_count));
+            json_object_array_add(*json_arr_reply, json_obj_datum);
+            json_object* json_arr_datum_out = json_object_new_array();
             for (uint32_t i=0; i < l_block_cache->datum_count ; i++){
+                char buf[70];
+                json_object* json_obj_tx = json_object_new_object();
                 dap_chain_datum_t * l_datum = l_block_cache->datum[i];
                 size_t l_datum_size =  dap_chain_datum_size(l_datum);
-                dap_string_append_printf(l_str_tmp,"\t\t\tdatum:\tdatum_size: %zu\n",l_datum_size);
+                json_object_object_add(json_obj_tx, "datum size ",json_object_new_uint64(l_datum_size));
                 if (l_datum_size < sizeof (l_datum->header) ){
-                    dap_string_append_printf(l_str_tmp,"\t\t\tERROR: datum size %zu is smaller than header size %zu \n",l_datum_size,
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu \n",l_datum_size,
                                             sizeof (l_datum->header));
                     break;
                 }
                 // Nested datums
-                dap_string_append_printf(l_str_tmp,"\t\t\t\tversion:=0x%02X\n", l_datum->header.version_id);
+                sprintf(l_tmp_buff,"0x%02X",l_datum->header.version_id);
+                json_object_object_add(json_obj_tx, "version",json_object_new_string(l_tmp_buff));
                 const char * l_datum_type_str="UNKNOWN";
                 DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str);
-                dap_string_append_printf(l_str_tmp,"\t\t\t\ttype_id:=%s\n", l_datum_type_str);
+                json_object_object_add(json_obj_tx, "type_id",json_object_new_string(l_datum_type_str));
                 dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create);
-                dap_string_append_printf(l_str_tmp,"\t\t\t\tts_create=%s\n", buf);
-                dap_string_append_printf(l_str_tmp,"\t\t\t\tdata_size=%u\n", l_datum->header.data_size);
-                dap_chain_datum_dump(l_str_tmp, l_datum, "hex", l_net->pub.id);
+                json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(buf));
+                json_object_object_add(json_obj_tx, "data_size",json_object_new_int(l_datum->header.data_size));
+                dap_chain_datum_dump_json(json_obj_tx,l_datum,l_hash_out_type,l_net->pub.id);
+                json_object_array_add(json_arr_datum_out, json_obj_tx);
             }
             // Signatures
-            dap_string_append_printf(l_str_tmp,"\t\tsignatures:\tcount: %zu\n", l_block_cache->sign_count );
+            json_object_array_add(*json_arr_reply, json_arr_datum_out);
+            // Signatures
+            json_object* json_obj_sig = json_object_new_object();
+            json_object_object_add(json_obj_sig, "signatures count", json_object_new_uint64(l_block_cache->sign_count));
+            json_object_array_add(*json_arr_reply, json_obj_sig);
+            json_object* json_arr_sign_out = json_object_new_array();
             for (uint32_t i=0; i < l_block_cache->sign_count ; i++) {
+                json_object* json_obj_sign = json_object_new_object();
                 dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, 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);
                 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));
-                dap_string_append_printf(l_str_tmp,"\t\t\ttype:%s size: %zd pkey_hash: %s \n"
-                                                "\t\t\t\n", dap_sign_type_to_str( l_sign->header.type ),
-                                                        l_sign_size, l_pkey_hash_str );
+                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_array_add(json_arr_sign_out, json_obj_sign);
             }
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);
-            dap_string_free(l_str_tmp, true);
+            json_object_array_add(*json_arr_reply, json_arr_sign_out);
         } break;
 
         case SUBCMD_LIST:{
@@ -751,6 +789,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_pkey_t * l_pub_key = NULL;
             dap_hash_fast_t l_from_hash = {}, l_to_hash = {}, l_pkey_hash = {};
             dap_time_t l_from_time = 0, l_to_time = 0;
+            char l_tmp_buff[150]={0};
 
             l_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "signed") > 0;
             l_first_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "first_signed") > 0;
@@ -767,30 +806,29 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
 
             if (l_signed_flag && l_first_signed_flag) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Choose only one option from 'singed' and 'first_signed'");
-                return -10;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Choose only one option from 'singed' and 'first_signed'");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
             if ((l_signed_flag || l_first_signed_flag) && !l_cert_name && !l_pkey_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Option from '%s' requires parameter '-cert' or 'pkey_hash'",
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Option from '%s' requires parameter '-cert' or 'pkey_hash'",
                                                                 l_first_signed_flag ? "first_signed" : "signed");
-                return -11;
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
             if (l_cert_name) {
                 dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
                 if (!l_cert) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
-                    return -18;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
                 }
                 l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key);
                 if (!l_pub_key) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,
-                            "Corrupted certificate \"%s\" have no public key data", l_cert_name);
-                    return -20;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR, "Corrupted certificate \"%s\" have no public key data", l_cert_name);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR;
                 }
             } else if (l_pkey_hash_str) {
                 if (dap_chain_hash_fast_from_str(l_pkey_hash_str, &l_pkey_hash)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_pkey_hash_str);
-                    return -12;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_pkey_hash_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR;
                 }
             }
             if (l_unspent_flag && l_signed_flag && !l_pkey_hash_str)
@@ -800,29 +838,29 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
 
             if (l_from_hash_str) {
                 if (dap_chain_hash_fast_from_str(l_from_hash_str, &l_from_hash)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_from_hash_str);
-                    return -13;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_from_hash_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR;
                 }
             }
             if (l_to_hash_str) {
                 if (dap_chain_hash_fast_from_str(l_to_hash_str, &l_to_hash)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_to_hash_str);
-                    return -14;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_to_hash_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR;
                 }
             }
 
             if (l_from_date_str) {
                 l_from_time = dap_time_from_str_simplified(l_from_date_str);
                 if (!l_from_time) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to date", l_from_date_str);
-                    return -21;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to date", l_from_date_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR;
                 }
             }
             if (l_to_date_str) {
                 l_to_time = dap_time_from_str_simplified(l_to_date_str);
                 if (!l_to_time) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to date", l_to_date_str);
-                    return -21;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to date", l_to_date_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR;
                 }
                 struct tm *l_localtime = localtime((time_t *)&l_to_time);
                 l_localtime->tm_mday += 1;  // + 1 day to end date, got it inclusive
@@ -830,21 +868,23 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             }
 
             pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock);
-            dap_string_t *l_str_tmp = dap_string_new(NULL);
+            json_object* json_arr_bl_cache_out = json_object_new_array();
+            json_object* json_obj_lim = json_object_new_object();
             size_t l_start_arr = 0;
             if(l_offset > 0) {
                 l_start_arr = l_offset;
-                dap_string_append_printf(l_str_tmp, "offset: %lu\n", l_start_arr);
+                json_object_object_add(json_obj_lim, "offset",json_object_new_uint64(l_start_arr));
             }
             size_t l_arr_end = PVT(l_blocks)->blocks_count;
             if (l_limit) {
-                dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_limit);
+                json_object_object_add(json_obj_lim, "limit",json_object_new_uint64(l_limit));
                 l_arr_end = l_start_arr + l_limit;
                 if (l_arr_end > PVT(l_blocks)->blocks_count)
                     l_arr_end = PVT(l_blocks)->blocks_count;
             }
+            json_object_array_add(json_arr_bl_cache_out, json_obj_lim);
             size_t i_tmp = 0;
-            for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) {
+            for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) {                
                 if (i_tmp < l_start_arr || i_tmp >= l_arr_end) {
                     i_tmp++;
                     continue;
@@ -911,25 +951,34 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                     }
                 }
                 char l_buf[DAP_TIME_STR_SIZE];
+                json_object* json_obj_bl_cache = json_object_new_object();
                 dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
-                dap_string_append_printf(l_str_tmp, "\t%zu\t - %s: ts_create=%s\n",i_tmp-1, l_block_cache->block_hash_str, l_buf);
+                json_object_object_add(json_obj_bl_cache, "block",json_object_new_uint64(i_tmp));
+                json_object_object_add(json_obj_bl_cache, "hash",json_object_new_string(l_block_cache->block_hash_str));
+                json_object_object_add(json_obj_bl_cache, "ts_create",json_object_new_string(l_buf));
+                json_object_array_add(json_arr_bl_cache_out, json_obj_bl_cache);
                 if (l_to_hash_str && dap_hash_fast_compare(&l_to_hash, &l_block_cache->block_hash))
                     break;
             }
             pthread_rwlock_unlock(&PVT(l_blocks)->rwlock);
+            json_object_array_add(*json_arr_reply, json_arr_bl_cache_out);
 
-            char *l_filtered_criteria = "";
+            char *l_filtered_criteria = "none";
+            json_object* json_obj_out = json_object_new_object();
             if (l_cert_name || l_pkey_hash_str || l_from_hash_str || l_to_hash_str || l_from_date_str || l_to_date_str)
                 l_filtered_criteria = " filtered according to the specified criteria";
-            dap_string_append_printf(l_str_tmp, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks%s\n",
-                                     l_net->pub.name, l_chain->name, i_tmp, l_filtered_criteria);
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);
-            dap_string_free(l_str_tmp, true);
+            sprintf(l_tmp_buff,"%s.%s with filter - %s, have blocks",l_net->pub.name,l_chain->name,l_filtered_criteria);
+            json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(i_tmp));
+            json_object_array_add(*json_arr_reply,json_obj_out);
         } break;
 
         case SUBCMD_COUNT: {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%zu blocks in %s.%s", PVT(l_blocks)->blocks_count,
-                                              l_net->pub.name, l_chain->name);
+            char l_tmp_buff[70]={0};
+            json_object* json_obj_out = json_object_new_object();
+            sprintf(l_tmp_buff,"%s.%s has blocks - ",l_net->pub.name,l_chain->name);
+            json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(PVT(l_blocks)->blocks_count));
+            json_object_array_add(*json_arr_reply, json_obj_out);
+
         } break;
 
         case SUBCMD_FEE:
@@ -939,6 +988,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             const char * l_addr_str = NULL;
             const char * l_hash_out_type = NULL;
             const char * l_hash_str = NULL;
+            char l_tmp_buff[70]={0};
 
             uint256_t               l_fee_value = {};
             size_t                  l_hashes_count = 0;
@@ -947,52 +997,54 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
 
             if (l_subcmd == SUBCMD_FEE) {
                 if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires subcommand 'collect'");
-                    return -14;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block fee' requires subcommand 'collect'");
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                 }
             } else { // l_sumcmd == SUBCMD_REWARD
                 if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "set") >= 0) {
                     const char *l_value_str = NULL;
                     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-poa_cert", &l_cert_name);
                     if(!l_cert_name) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward set' requires parameter '-poa_cert'");
-                        return -17;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward set' requires parameter '-poa_cert'");
+                        return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                     }
                     dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
                     if (!l_cert) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
-                        return -18;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name);
+                        return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
                     }
                     if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                "Certificate \"%s\" doesn't contains private key", l_cert_name);
-                        return -19;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR, "Certificate \"%s\" doesn't contains private key", l_cert_name);
+                        return DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR;
                     }
 
                     dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str);
                     uint256_t l_value = dap_chain_balance_scan(l_value_str);
                     if (!l_value_str || IS_ZERO_256(l_value)) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer");
-                        return -20;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer");
+                        return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                     }
                     char *l_decree_hash_str = s_blocks_decree_set_reward(l_net, l_chain, l_value, l_cert);
                     if (l_decree_hash_str) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
+                        //добавить вывод
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str);
                         DAP_DELETE(l_decree_hash_str);
                     } else {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Basic block sign reward setting failed. Examine log file for details");
-                        return -21;
+                        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR, "Basic block sign reward setting failed. Examine log file for details");
+                        return DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR;
                     }
                     break;
                 } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "show") >= 0) {
                     uint256_t l_cur_reward = dap_chain_net_get_reward(l_net, UINT64_MAX);
                     const char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str);
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_reward_str);
+                    json_object* json_obj_out = json_object_new_object();
+                    sprintf(l_tmp_buff,"Current base block reward is %s\n", l_reward_str);
+                    json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                    json_object_array_add(*json_arr_reply, json_obj_out);
                     break;
                 } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'");
-                    return -14;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'");
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                 }
             }
 
@@ -1001,8 +1053,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             if(!l_hash_out_type)
                 l_hash_out_type = "hex";
             if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
-                return -15;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "invalid parameter -H, valid values: -H <hex | base58>");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
 
             // Private certificate
@@ -1013,42 +1065,41 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_fee_value_str);
 
             if (!l_addr_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str);
-                return -16;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
             l_addr = dap_chain_addr_from_str(l_addr_str);
             if(!l_cert_name) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str);
-                return -17;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
             dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
             if (!l_cert) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
-                return -18;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
             }
             if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Certificate \"%s\" doesn't contains private key", l_cert_name);
-                return -19;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR,
+                                        "Certificate \"%s\" doesn't contains private key", l_cert_name);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
             }
 
             l_fee_value = dap_chain_balance_scan(l_fee_value_str);
             if (!l_fee_value_str || IS_ZERO_256(l_fee_value)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                                  "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str);
-                return -20;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
 
             if (!l_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'");
-                return -21;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block fee collect' requires parameter '-hashes'");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
             }
             // NOTE: This call will modify source string
             l_block_list = s_block_parse_str_list((char *)l_hash_str, &l_hashes_count, l_chain);            
             if (!l_block_list || !l_hashes_count) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply,
-                        "Block fee collection requires at least one hash to create a transaction");
-                return -22;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR,
+                                            "Block fee collection requires at least one hash to create a transaction");
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR;
             }
 
             char *l_hash_tx = NULL;
@@ -1057,11 +1108,15 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             else
                 l_hash_tx = dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type);
             if (l_hash_tx) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "TX for %s collection created succefully, hash=%s\n", l_subcmd_str, l_hash_tx);
+                json_object* json_obj_out = json_object_new_object();
+                sprintf(l_tmp_buff, "TX for %s collection created succefully, hash = %s\n", l_subcmd_str, l_hash_tx);
+                json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                json_object_array_add(*json_arr_reply, json_obj_out);
                 DAP_DELETE(l_hash_tx);
             } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create %s collect TX\n", l_subcmd_str);
-                ret = -24;
+                dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR,
+                                            "Can't create %s collect TX\n", l_subcmd_str);
+                return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR;
             }
             dap_list_free_full(l_block_list, NULL);
         }break;
@@ -1072,6 +1127,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             dap_hash_fast_t l_pkey_hash = {};
             dap_chain_addr_t *l_addr = NULL;
             size_t l_block_count = 0;
+            char l_tmp_buff[128]={0};
             int fl_renew = dap_cli_server_cmd_check_option(a_argv, arg_index,a_argc, "renew");
             if(fl_renew != -1)
             {
@@ -1079,23 +1135,26 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str);
                 l_addr = dap_chain_addr_from_str(l_addr_str);
                 if(!l_cert_name) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect renew' requires parameter '-cert'");
-                    return -20;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR,
+                                            "Command 'block autocollect renew' requires parameter '-cert'", l_subcmd_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                 }
                 if (!l_addr_str) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect renew' requires parameter '-addr'");
-                    return -20;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR,
+                                            "Command 'block autocollect renew' requires parameter '-addr'", l_subcmd_str);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                 }
                 dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
                 if (!l_cert) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name);
-                    return -20;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR,
+                                            "Can't find \"%s\" certificate", l_cert_name);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR;
                 }
                 l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key);
                 if (!l_pub_key) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,
-                            "Corrupted certificate \"%s\" have no public key data", l_cert_name);
-                    return -20;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR,
+                                            "Corrupted certificate \"%s\" have no public key data", l_cert_name);
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR;
                 }
                 dap_chain_esbocs_block_collect_t l_block_collect_params = (dap_chain_esbocs_block_collect_t){
                         .collecting_level = dap_chain_esbocs_get_collecting_level(l_chain),
@@ -1116,7 +1175,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                 if(l_objs_rew_count)dap_global_db_objs_delete(l_objs_rew,l_objs_rew_count);
                 DAP_DELETE(l_group_fee);
                 DAP_DELETE(l_group_rew);
-                dap_string_t *l_str_tmp = dap_string_new(NULL);
+                json_object* json_arr_bl_out = json_object_new_array();
 
                 for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) {
                     dap_time_t l_ts = l_block_cache->block->hdr.ts_created;
@@ -1136,10 +1195,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                         if (NULL == dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, &l_out_idx_tmp))
                             continue;
                         if (!dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) {
-                            dap_chain_esbocs_add_block_collect(l_block_cache->block, l_block_cache->block_size, &l_block_collect_params,1);
-                            char l_buf[50];
-                            dap_time_to_str_rfc822(l_buf, 50, l_ts);
-                            dap_string_append_printf(l_str_tmp, "fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
+                            dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_FEES);
+                            char l_buf[DAP_TIME_STR_SIZE];
+                            json_object* json_obj_bl = json_object_new_object();
+                            dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
+                            sprintf(l_tmp_buff, "fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
+                            json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff));
+                            json_object_array_add(json_arr_bl_out, json_obj_bl);
                             l_block_count++;
                             break;
                         }
@@ -1164,37 +1226,44 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
                         continue;
                     if (dap_ledger_is_used_reward(l_net->pub.ledger, &l_block_cache->block_hash, &l_pkey_hash))
                         continue;
-                    dap_chain_esbocs_add_block_collect(l_block_cache->block, l_block_cache->block_size, &l_block_collect_params,2);
-                    {   
-                        char l_buf[50];
-                        dap_time_to_str_rfc822(l_buf, 50, l_ts);
-                        dap_string_append_printf(l_str_tmp, "rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
-                        l_block_count++; 
-                    }                   
+                    dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_REWARDS);
+                    char l_buf[DAP_TIME_STR_SIZE];
+                    json_object* json_obj_bl = json_object_new_object();
+                    dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts);
+                    sprintf(l_tmp_buff, "rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf);
+                    json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff));
+                    json_object_array_add(json_arr_bl_out, json_obj_bl);
+                    l_block_count++;
                 }
-                dap_string_append_printf(l_str_tmp, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n",
+                json_object_array_add(*json_arr_reply, json_arr_bl_out);
+                json_object* json_obj_out = json_object_new_object();
+                sprintf(l_tmp_buff, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n",
                                      l_net->pub.name, l_chain->name, l_block_count);
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str);
-                dap_string_free(l_str_tmp, true);
+                json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+                json_object_array_add(*json_arr_reply, json_obj_out);
             }else{
                 if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "status") == -1) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect' requires subcommand 'status'");
-                    return -14;
+                    dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR,
+                                            "Command 'block autocollect' requires subcommand 'status'");
+                    return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
                 }
-                dap_string_t *l_reply_str = dap_string_new("");
-                s_print_autocollect_table(l_net, l_reply_str, "Fees");
-                s_print_autocollect_table(l_net, l_reply_str, "Rewards");                
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_reply_str->str);
-                dap_string_free(l_reply_str, true);
+                json_object* json_obj_out = json_object_new_object();
+                s_print_autocollect_table(l_net, json_obj_out, "Fees");
+                s_print_autocollect_table(l_net, json_obj_out, "Rewards");
+                json_object_array_add(*json_arr_reply, json_obj_out);
             }            
         } break;
 
         case SUBCMD_UNDEFINED:
         default: {
-            dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                              "Undefined block subcommand \"%s\" ",
+            char l_tmp_buff[70]={0};
+            json_object* json_obj_out = json_object_new_object();
+            snprintf(l_tmp_buff, sizeof(l_tmp_buff), "Undefined block subcommand \"%s\" ",
                                               l_subcmd_str);
-            ret=-11;
+            json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff));
+            json_object_array_add(*json_arr_reply, json_obj_out);
+            ret=DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN;
+
         } break;
     }
     return ret;
diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h
index ad4383280a..2c2e7de395 100644
--- a/modules/type/blocks/include/dap_chain_cs_blocks.h
+++ b/modules/type/blocks/include/dap_chain_cs_blocks.h
@@ -62,6 +62,27 @@ typedef struct dap_chain_cs_blocks
    void * _inheritor;
 } dap_chain_cs_blocks_t;
 
+typedef enum s_com_blocks_err{
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR,
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR,
+
+    /* add custom codes here */
+
+    DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN /* MAX */
+} s_com_blocks_err_t;
+
 #define DAP_CHAIN_CS_BLOCKS(a) ((dap_chain_cs_blocks_t *)(a)->_inheritor)
 typedef int (*dap_chain_blocks_block_callback_ptr_t)(dap_chain_cs_blocks_t *, dap_chain_block_t *);
 
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 9f0db5d074..bf86d7ebf6 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -695,8 +695,6 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_da
     return l_res;
 }
 
-
-
 /**
  * @brief dap_chain_cs_dag_find_event_by_hash
  * @param a_dag
@@ -737,8 +735,6 @@ static bool s_event_verify_size(dap_chain_cs_dag_event_t *a_event, size_t a_even
     return l_sign_offset == a_event_size;
 }
 
-
-
 /**
  * @brief s_chain_callback_atom_verify Verify atomic element
  * @param a_chain
@@ -1049,9 +1045,9 @@ static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_links( dap_chain_ato
                     (*a_links_size_array)[i] = l_link_item->event_size;
                 }else {
                     char l_err_str[256];
-                    unsigned l_off = dap_snprintf(l_err_str, sizeof(l_err_str), "Can't find %s -> ",
+                    unsigned l_off = snprintf(l_err_str, sizeof(l_err_str), "Can't find %s -> ",
                         dap_chain_hash_fast_to_str_static(l_link_hash));
-                    dap_snprintf(l_err_str + l_off, sizeof(l_err_str) - l_off, "%s links",
+                    snprintf(l_err_str + l_off, sizeof(l_err_str) - l_off, "%s links",
                         l_event_item ? dap_chain_hash_fast_to_str_static(&l_event_item->hash) : "<null>");
                     log_it(L_ERROR, "%s", l_err_str);
                     (*a_links_size_array)--;
@@ -1825,7 +1821,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                             i_tmp++;
                             char buf[DAP_TIME_STR_SIZE];
                             dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created);
-                            dap_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp - 1,
+                            dap_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp,
                                                      dap_chain_hash_fast_to_str_static(&l_event_item->hash),
                                                      buf);
                         }
@@ -1864,7 +1860,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
                         i_tmp++;
                         char buf[DAP_TIME_STR_SIZE];
                         dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created);
-                        dap_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp - 1,
+                        dap_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp,
                                                  dap_chain_hash_fast_to_str_static( &l_event_item->hash),
                                                  buf);
                     }
-- 
GitLab