diff --git a/dap-sdk b/dap-sdk
index 1f0c4caf7a9cec9ddee67e9019e337c4c9278168..66bb11721a6f5726b9f2479b361fd95da62319b9 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit 1f0c4caf7a9cec9ddee67e9019e337c4c9278168
+Subproject commit 66bb11721a6f5726b9f2479b361fd95da62319b9
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 7dbf04b51274ef029b745509fa14f186eb41158e..44fe70e5886e581aed4c1eaa83e100cd0b42cf2f 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -1449,7 +1449,7 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg)
  * @param sh HTTP server instance
  * @param url URL string
  */
-void dap_chain_mempool_add_proc(dap_http_t * a_http_server, const char * a_url)
+void dap_chain_mempool_add_proc(dap_http_server_t * a_http_server, const char * a_url)
 {
     dap_http_simple_proc_add(a_http_server, a_url, 4096, chain_mempool_proc);
 }
diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h
index d18df1e803e53ec819a4f0635fe31e00efb368d9..a2221296a2a3e5de36bd2360878f659bcb4b53a9 100644
--- a/modules/mempool/include/dap_chain_mempool.h
+++ b/modules/mempool/include/dap_chain_mempool.h
@@ -4,7 +4,7 @@
 #include "dap_chain_net.h"
 #include "dap_chain_datum.h"
 #include "dap_chain_ledger.h"
-#include "dap_http.h"
+#include "dap_http_server.h"
 #include "dap_cert.h"
 #include "dap_chain_block_cache.h"
 /*
@@ -56,7 +56,7 @@ dap_datum_mempool_t * dap_datum_mempool_deserialize(uint8_t *datum_mempool_str,
 void dap_datum_mempool_clean(dap_datum_mempool_t *datum);
 void dap_datum_mempool_free(dap_datum_mempool_t *datum);
 
-void dap_chain_mempool_add_proc(dap_http_t * a_http_server, const char * a_url);
+void dap_chain_mempool_add_proc(dap_http_server_t * a_http_server, const char * a_url);
 
 void dap_chain_mempool_filter(dap_chain_t *a_chain, int *a_removed);
 
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 227d5c0bd2c7d138c07e75a955ec20bdee7ca103..bc549582557f87509b80b4e74fcf1188a543bc3a 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -4783,6 +4783,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c
  */
 void dap_ledger_purge(dap_ledger_t *a_ledger, bool a_preserve_db)
 {
+    dap_return_if_fail(a_ledger);
     dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
     pthread_rwlock_wrlock(&l_ledger_pvt->ledger_rwlock);
     pthread_rwlock_wrlock(&l_ledger_pvt->tokens_rwlock);
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index d85f0058f2441c2996521ad0e88c8f71bcf2ed8b..0f5ca1b87e4100f4ab84a3dc0d0bec60538d25ef 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -181,6 +181,9 @@ typedef struct dap_chain_net_pvt{
     uint16_t permanent_links_count;
     dap_stream_node_addr_t *permanent_links; // TODO realize permanent links from config
 
+    uint16_t poa_nodes_count;
+    dap_stream_node_addr_t *poa_nodes_addrs;
+
     uint16_t seed_nodes_count;
     struct sockaddr_in *seed_nodes_ipv4;
     struct sockaddr_in6 *seed_nodes_ipv6;       // TODO
@@ -577,6 +580,7 @@ static void s_fill_links_from_root_aliases(dap_chain_net_t * a_net)
         dap_chain_node_info_t l_link_node_info = {};
         l_link_node_info.hdr.ext_addr_v4 = l_net_pvt->seed_nodes_ipv4[i].sin_addr;
         l_link_node_info.hdr.ext_port = l_net_pvt->seed_nodes_ipv4[i].sin_port;
+        l_link_node_info.hdr.address = l_net_pvt->poa_nodes_addrs[i];
         if (s_net_link_add(a_net, &l_link_node_info) > 0)    // Maximum links count reached
             break;
     }
@@ -2414,11 +2418,14 @@ void dap_chain_net_delete(dap_chain_net_t *a_net)
     }
     if (PVT(a_net)->main_timer)
         dap_interval_timer_delete(PVT(a_net)->main_timer);
+    DAP_DEL_Z(PVT(a_net)->poa_nodes_addrs);
     DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv4);
     DAP_DEL_Z(PVT(a_net)->seed_nodes_ipv6);
     DAP_DEL_Z(PVT(a_net)->node_info);
-    dap_ledger_purge(a_net->pub.ledger, true);
-    dap_ledger_handle_free(a_net->pub.ledger);
+    if (a_net->pub.ledger) {
+        dap_ledger_purge(a_net->pub.ledger, true);
+        dap_ledger_handle_free(a_net->pub.ledger);
+    }
     DAP_DELETE(a_net);
 }
 
@@ -2506,6 +2513,28 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
     // Wait time before reconnect attempt with same link
     l_net_pvt->reconnect_delay = dap_config_get_item_int16_default(l_cfg, "general", "reconnect_delay", 10);
 
+    char **l_poa_nodes_addrs = dap_config_get_array_str(l_cfg, "general", "seed_nodes_addrs", &l_net_pvt->poa_nodes_count);
+    if (!l_net_pvt->poa_nodes_count) {
+        log_it(L_ERROR, "Can't read seed nodes addresses");
+        dap_chain_net_delete(l_net);
+        dap_config_close(l_cfg);
+        return -15;
+    }
+    l_net_pvt->poa_nodes_addrs = DAP_NEW_SIZE(dap_stream_node_addr_t, l_net_pvt->poa_nodes_count * sizeof(dap_stream_node_addr_t));
+    if (!l_net_pvt->poa_nodes_addrs) {
+        log_it(L_CRITICAL, g_error_memory_alloc);
+        dap_chain_net_delete(l_net);
+        dap_config_close(l_cfg);
+        return -1;
+    }
+    for (uint16_t i = 0; i < l_net_pvt->poa_nodes_count; i++) {
+        if (dap_stream_node_addr_from_str(l_net_pvt->poa_nodes_addrs + i, l_poa_nodes_addrs[i])) {
+            log_it(L_ERROR, "Incorrect format for address #%hu", i);
+            dap_chain_net_delete(l_net);
+            dap_config_close(l_cfg);
+            return -16;
+        }
+    }
     uint16_t l_seed_nodes_ipv4_len = 0;
     char **l_seed_nodes_ipv4 = dap_config_get_array_str(l_cfg, "general", "seed_nodes_ipv4", &l_seed_nodes_ipv4_len);
     uint16_t l_seed_nodes_ipv6_len = 0;
@@ -2519,9 +2548,12 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
     if (l_seed_nodes_port_len) {
         if ((l_seed_nodes_ipv4_len && l_seed_nodes_ipv4_len != l_seed_nodes_port_len) ||
                 (l_seed_nodes_ipv6_len && l_seed_nodes_ipv6_len != l_seed_nodes_port_len) ||
-                (l_seed_nodes_hostnames_len && l_seed_nodes_hostnames_len != l_seed_nodes_port_len)) {
+                (l_seed_nodes_hostnames_len && l_seed_nodes_hostnames_len != l_seed_nodes_port_len) ||
+                (!l_seed_nodes_ipv4_len && !l_seed_nodes_ipv6_len && !l_seed_nodes_hostnames_len)) {
             log_it (L_ERROR, "Configuration mistake for seed nodes");
-
+            dap_chain_net_delete(l_net);
+            dap_config_close(l_cfg);
+            return -6;
         }
         l_net_pvt->seed_nodes_count = l_seed_nodes_port_len;
     } else {
@@ -2530,8 +2562,23 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
         l_net_pvt->seed_nodes_count = l_bootstrap_nodes_len;
     }
     log_it (L_DEBUG, "Read %u seed nodes params", l_net_pvt->seed_nodes_count);
-    l_net_pvt->seed_nodes_ipv4 = DAP_NEW_SIZE(struct sockaddr_in, l_net_pvt->seed_nodes_count * sizeof(struct sockaddr_in));
-    l_net_pvt->seed_nodes_ipv6 = DAP_NEW_SIZE(struct sockaddr_in6, l_net_pvt->seed_nodes_count * sizeof(struct sockaddr_in6));
+    if (l_seed_nodes_ipv6_len) {
+        l_net_pvt->seed_nodes_ipv6 = DAP_NEW_SIZE(struct sockaddr_in6, l_net_pvt->seed_nodes_count * sizeof(struct sockaddr_in6));
+        if (!l_net_pvt->seed_nodes_ipv6) {
+            log_it(L_CRITICAL, g_error_memory_alloc);
+            dap_chain_net_delete(l_net);
+            dap_config_close(l_cfg);
+            return -1;
+        }
+    } else {   // Just only IPv4 can be resolved for now
+        l_net_pvt->seed_nodes_ipv4 = DAP_NEW_SIZE(struct sockaddr_in, l_net_pvt->seed_nodes_count * sizeof(struct sockaddr_in));
+        if (!l_net_pvt->seed_nodes_ipv4) {
+            log_it(L_CRITICAL, g_error_memory_alloc);
+            dap_chain_net_delete(l_net);
+            dap_config_close(l_cfg);
+            return -1;
+        }
+    }
     // Load seed nodes from cfg file
     for (uint16_t i = 0; i < l_net_pvt->seed_nodes_count; i++) {
         char *l_node_hostname = NULL;
@@ -2551,16 +2598,16 @@ int s_net_init(const char * a_net_name, uint16_t a_acl_idx)
                 l_node_port = atoi(l_bootstrap_port_str);
             l_node_hostname = l_bootstrap_nodes[i];
         }
-        if (!l_node_port)
-            l_node_port = dap_config_get_item_uint16_default(g_config, "server", "listen_port_tcp", 8079);
         if (!l_node_port) {
             log_it(L_ERROR, "Can't find port for seed node #%hu", i);
             dap_chain_net_delete(l_net);
             dap_config_close(l_cfg);
             return -12;
         } else {
-            l_net_pvt->seed_nodes_ipv4[i].sin_port = l_node_port;
-            l_net_pvt->seed_nodes_ipv6[i].sin6_port = l_node_port;
+            if (l_seed_nodes_ipv6_len)
+                l_net_pvt->seed_nodes_ipv6[i].sin6_port = l_node_port;
+            else
+                l_net_pvt->seed_nodes_ipv4[i].sin_port = l_node_port;
         }
         if (l_node_hostname) {
             struct in_addr l_res = {};
@@ -2845,7 +2892,7 @@ int s_net_load(dap_chain_net_t *a_net)
         }
         dap_chain_net_add_poa_certs_to_cluster(l_net, l_cluster);
         DAP_DELETE(l_gdb_groups_mask);
-        if (l_net->pub.chains == l_chain)
+        if (l_net->pub.chains == l_chain)   // Pointer for first mempool cluster in global double-linked list of clusters
             l_net_pvt->mempool_clusters = l_cluster;
     }
     // Service orders cluster
@@ -3042,11 +3089,8 @@ void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_sto
 int dap_chain_net_add_poa_certs_to_cluster(dap_chain_net_t *a_net, dap_global_db_cluster_t *a_cluster)
 {
     dap_return_val_if_fail(a_net && a_cluster, -1);
-    for (dap_list_t *it = a_net->pub.keys; it; it = it->next) {
-        dap_pkey_t *l_pkey = it->data;
-        dap_stream_node_addr_t l_poa_addr = dap_stream_node_addr_from_pkey(l_pkey);
-        dap_global_db_cluster_member_add(a_cluster, &l_poa_addr, DAP_GDB_MEMBER_ROLE_ROOT);
-    }
+    for (uint16_t i = 0; i < PVT(a_net)->poa_nodes_count; i++)
+        dap_global_db_cluster_member_add(a_cluster, PVT(a_net)->poa_nodes_addrs + i, DAP_GDB_MEMBER_ROLE_ROOT);
     return 0;
 }
 
diff --git a/modules/net/dap_chain_net_news.h b/modules/net/dap_chain_net_news.h
deleted file mode 100644
index d3c82ce4658987c30e207472e51015d55c326c0f..0000000000000000000000000000000000000000
--- a/modules/net/dap_chain_net_news.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Authors:
- * Alexander Lysikov <alexander.lysikov@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 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 "dap_http.h"
-
-int dap_chain_net_news_init(dap_http_t * a_http);
-void dap_chain_net_srv_vpn_cdb_news_cache_reset(void);
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index 324ca95a2dd52c2aab94d105091bbe22319c5fec..36574892638d87ff2c1d59f90004da326799e391 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -256,7 +256,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
                             "-addr <addr> [-chain_emission <chain_name>] -net <net_name> -certs <cert list>\n");
 
     dap_cli_server_cmd_add("mempool", com_mempool, "Command for working with mempool",
-                           "mempool list -net <net_name> [-chain <chain_name>] [-addr <addr>] [-fast]\n"
+                           "mempool list -net <net_name> [-chain <chain_name>] [-addr <addr>] [-brief]\n"
                            "\tList mempool (entries or transaction) for (selected chain network or wallet)\n"
                            "mempool check -net <net_name> [-chain <chain_name>] -datum <datum_hash>\n"
                            "\tCheck mempool entrie for presence in selected chain network\n"
@@ -269,7 +269,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
                            "\tDelete datum with hash <datum hash> for selected chain network\n"
                            "mempool dump -net <net_name> -chain <chain_name> -datum <datum_hash>\n"
                            "\tOutput information about datum in mempool\n"
-                           "mempool add_ca -net <net_name> [-chain <chain_name>] -ca_name <priv_cert_name>\n"
+                           "mempool add_ca -net <net_name> [-chain <chain_name>] -ca_name <pub_cert_name>\n"
                            "\tAdd pubic certificate into the mempool to prepare its way to chains\n"
                            "mempool count -net <net_name> [-chain <chain_name>]\n"
                            "\tDisplays the number of elements in the mempool of a given network.");
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 29f121c2a5052a73fb274d223f19a081571c6c4d..330cc816a1973c3215b8590be5fdb172a19ab155 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -82,12 +82,8 @@
 #include "dap_chain_block.h"
 #include "dap_chain_cs_blocks.h"
 
-#ifndef _WIN32
-#include "dap_chain_net_news.h"
-#endif
 #include "dap_chain_cell.h"
 
-
 #include "dap_enc_base64.h"
 #include "json.h"
 #ifdef DAP_OS_UNIX
@@ -102,6 +98,7 @@
 #include "dap_chain_mempool.h"
 #include "dap_global_db.h"
 #include "dap_global_db_cluster.h"
+#include "dap_global_db_pkt.h"
 
 #include "dap_stream_ch_chain_net.h"
 #include "dap_chain_ch.h"
@@ -2413,7 +2410,8 @@ typedef enum dap_chain_node_cli_cmd_values_parse_net_chain_err_to_json {
     DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CHAIN_NOT_FOUND = 104,
     DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CHAIN_STR_IS_NULL = 105,
     DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CONFIG_DEFAULT_DATUM = 106,
-    DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CONVERT_BASE58_TO_ADDR_WALLET = 107
+    DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CONVERT_BASE58_TO_ADDR_WALLET = 107,
+    DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_FAST_AND_BASE58_ADDR
 } dap_chain_node_cli_cmd_values_parse_net_chain_err_to_json;
 int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int a_argc,
                                                            char **a_argv,
@@ -2929,11 +2927,18 @@ const char* s_tx_get_main_ticker(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_
  * @param a_str_tmp
  * @param a_hash_out_type
  */
-void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a_chain, const char * a_add, json_object *a_json_obj, const char *a_hash_out_type) {
+void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a_chain, const char * a_add, json_object *a_json_obj, const char *a_hash_out_type, bool a_fast) {
     dap_chain_addr_t *l_wallet_addr = dap_chain_addr_from_str(a_add);
     if (a_add && !l_wallet_addr) {
         dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CONVERT_BASE58_TO_ADDR_WALLET, "Cannot convert "
-                               "string '%s' to binary address.\n", a_add);
+                                                                                                 "string '%s' to binary address.\n", a_add);
+        return;
+    }
+    if (l_wallet_addr && a_fast) {
+        dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_FAST_AND_BASE58_ADDR,
+                               "In fast mode, it is impossible to count the number of transactions and emissions "
+                               "for a specific address. The -brief and -addr options are mutually exclusive.\n");
+        DAP_DELETE(l_wallet_addr);
         return;
     }
     char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(a_chain);
@@ -2977,7 +2982,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
         dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value;
         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",
-                    a_net->pub.name, a_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len);
+                   a_net->pub.name, a_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len);
             dap_global_db_del_sync(l_gdb_group_mempool, l_objs[i].key);
             continue;
         }
@@ -3058,256 +3063,438 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
         json_object_object_add(l_jobj_datum, "type", l_jobj_type);
         json_object_object_add(l_jobj_datum, "created", l_jobj_ts_created);
         bool datum_is_accepted_addr = false;
-        switch (l_datum->header.type_id) {
-            case DAP_CHAIN_DATUM_TX: {
-                dap_chain_addr_t l_addr_from;
-                dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data;
-                const char *l_main_token = s_tx_get_main_ticker(l_tx, a_net, NULL);
-                dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL);
-                if (!l_list_sig_item) {
-                    json_object *l_jobj_wgn = json_object_new_string("An item with a type TX_ITEM_TYPE_SIG for the "
-                                                                     "transaction was not found, the transaction may "
-                                                                     "be corrupted.");
-                    json_object_object_add(l_jobj_datum, "warning", l_jobj_wgn);
-                    break;
-                }
-                dap_chain_tx_sig_t *l_sig = l_list_sig_item->data;
-                dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig);
-                dap_chain_addr_fill_from_sign(&l_addr_from, l_sign, a_net->pub.id);
-                if (l_wallet_addr && dap_chain_addr_compare(l_wallet_addr, &l_addr_from)) {
-                    datum_is_accepted_addr = true;
-                }
-                dap_list_free(l_list_sig_item);
-                char *l_addr_from_str = dap_chain_addr_to_str(&l_addr_from);
-                if (!l_addr_from_str) {
-                    json_object_put(l_jobj_datum);
-                    json_object_put(l_jobj_datums);
-                    json_object_put(l_obj_chain);
-                    dap_global_db_objs_delete(l_objs, l_objs_count);
-                    dap_json_rpc_allocation_error;
-                    return;
-                }
-                json_object *l_jobj_addr_from = json_object_new_string(l_addr_from_str);
-                DAP_DELETE(l_addr_from_str);
-                if (!l_jobj_addr_from) {
-                    json_object_put(l_jobj_datum);
-                    json_object_put(l_jobj_datums);
-                    json_object_put(l_obj_chain);
-                    dap_global_db_objs_delete(l_objs, l_objs_count);
-                    dap_json_rpc_allocation_error;
-                    return;
-                }
-                json_object_object_add(l_jobj_datum, "from", l_jobj_addr_from);
-                dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-                json_object *l_jobj_to_list = json_object_new_array();
-                json_object *l_jobj_change_list = json_object_new_array();
-                json_object *l_jobj_fee_list = json_object_new_array();
-                if (!l_jobj_to_list || !l_jobj_change_list || !l_jobj_fee_list) {
-                    json_object_put(l_jobj_to_list);
-                    json_object_put(l_jobj_change_list);
-                    json_object_put(l_jobj_fee_list);
-                    json_object_put(l_jobj_datum);
-                    json_object_put(l_jobj_datums);
-                    json_object_put(l_obj_chain);
-                    dap_global_db_objs_delete(l_objs, l_objs_count);
-                    dap_json_rpc_allocation_error;
-                    return;
-                }
-                for (dap_list_t *it = l_list_out_items; it; it = it->next) {
-                    dap_chain_addr_t *l_dist_addr = NULL;
-                    uint256_t l_value = uint256_0;
-                    const char *l_dist_token = NULL;
-                    uint8_t l_type = *(uint8_t*)it->data;
-                    switch (l_type) {
-                        case TX_ITEM_TYPE_OUT: {
-                            l_value = ((dap_chain_tx_out_t*)it->data)->header.value;
-                            l_dist_token = l_main_token;
-                            l_dist_addr = &((dap_chain_tx_out_t*)it->data)->addr;
-                        } break;
-                        case TX_ITEM_TYPE_OUT_EXT: {
-                            l_value = ((dap_chain_tx_out_ext_t*)it->data)->header.value;
-                            l_dist_token = ((dap_chain_tx_out_ext_t*)it->data)->token;
-                            l_dist_addr = &((dap_chain_tx_out_ext_t*)it->data)->addr;
-                        } break;
-                        case TX_ITEM_TYPE_OUT_COND: {
-                            l_value = ((dap_chain_tx_out_cond_t*)it->data)->header.value;
-                            if (((dap_chain_tx_out_cond_t*)it->data)->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) {
-                                l_dist_token = a_net->pub.native_ticker;
-                            }
-                        } break;
-                        default: break;
+        if (!a_fast) {
+            switch (l_datum->header.type_id) {
+                case DAP_CHAIN_DATUM_TX: {
+                    dap_chain_addr_t l_addr_from;
+                    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data;
+                    const char *l_main_token = s_tx_get_main_ticker(l_tx, a_net, NULL);
+                    if (l_main_token) {
+                        json_object *l_jobj_main_ticker = json_object_new_string(l_main_token);
+                        if (!l_jobj_main_ticker) {
+                            json_object_put(l_jobj_datum);
+                            json_object_put(l_jobj_datums);
+                            json_object_put(l_obj_chain);
+                            dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
+                            return;
+                        }
+                        json_object_object_add(l_jobj_datum, "main_ticker", l_jobj_main_ticker);
                     }
-                    json_object *l_jobj_money = json_object_new_object();
-                    if (!l_jobj_money){
-                        json_object_put(l_jobj_to_list);
-                        json_object_put(l_jobj_change_list);
-                        json_object_put(l_jobj_fee_list);
-                        json_object_put(l_jobj_datum);
-                        json_object_put(l_jobj_datums);
-                        json_object_put(l_obj_chain);
-                        dap_global_db_objs_delete(l_objs, l_objs_count);
-                        return;
+                    dap_list_t *l_list_sig_item = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL);
+                    dap_list_t *l_list_in_ems = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_EMS, NULL);
+                    if (!l_list_sig_item) {
+                        json_object *l_jobj_wgn = json_object_new_string("An item with a type TX_ITEM_TYPE_SIG for the "
+                                                                         "transaction was not found, the transaction may "
+                                                                         "be corrupted.");
+                        json_object_object_add(l_jobj_datum, "warning", l_jobj_wgn);
+                        break;
                     }
-                    char *l_value_str = dap_chain_balance_print(l_value);
-                    if (!l_value_str) {
-                        json_object_put(l_jobj_to_list);
-                        json_object_put(l_jobj_change_list);
-                        json_object_put(l_jobj_fee_list);
-                        json_object_put(l_jobj_money);
-                        json_object_put(l_jobj_datum);
-                        json_object_put(l_jobj_datums);
-                        json_object_put(l_obj_chain);
-                        dap_global_db_objs_delete(l_objs, l_objs_count);
-                        return;
+                    dap_chain_tx_sig_t *l_sig = l_list_sig_item->data;
+                    dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig);
+                    dap_chain_addr_fill_from_sign(&l_addr_from, l_sign, a_net->pub.id);
+                    if (l_wallet_addr && dap_chain_addr_compare(l_wallet_addr, &l_addr_from)) {
+                        datum_is_accepted_addr = true;
                     }
-                    char *l_value_coins_str = dap_chain_balance_to_coins(l_value);
-                    if (!l_value_coins_str) {
-                        json_object_put(l_jobj_to_list);
-                        json_object_put(l_jobj_change_list);
-                        json_object_put(l_jobj_fee_list);
-                        DAP_DELETE(l_value_str);
-                        json_object_put(l_jobj_money);
+                    dap_list_free(l_list_sig_item);
+                    char *l_addr_from_str = dap_chain_addr_to_str(&l_addr_from);
+                    if (!l_addr_from_str) {
                         json_object_put(l_jobj_datum);
                         json_object_put(l_jobj_datums);
                         json_object_put(l_obj_chain);
                         dap_global_db_objs_delete(l_objs, l_objs_count);
+                        dap_json_rpc_allocation_error;
                         return;
                     }
-                    json_object *l_jobj_value = json_object_new_string(l_value_str);
-                    if (!l_jobj_value) {
-                        json_object_put(l_jobj_to_list);
-                        json_object_put(l_jobj_change_list);
-                        json_object_put(l_jobj_fee_list);
-                        DAP_DELETE(l_value_str);
-                        DAP_DELETE(l_value_coins_str);
-                        json_object_put(l_jobj_money);
-                        json_object_put(l_jobj_datum);
-                        json_object_put(l_jobj_datums);
-                        json_object_put(l_obj_chain);
-                        dap_global_db_objs_delete(l_objs, l_objs_count);
-                        return;
+                    dap_list_t *l_list_in_reward = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_REWARD, NULL);
+                    if (l_list_in_reward) {
+                        json_object *l_obj_in_reward_arary = json_object_new_array();
+                        if (!l_obj_in_reward_arary) {
+                            dap_list_free(l_list_in_reward);
+                            json_object_put(l_jobj_datum);
+                            json_object_put(l_jobj_datums);
+                            json_object_put(l_obj_chain);
+                            dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
+                            return;
+                        }
+                        for (dap_list_t *it = l_list_in_reward; it; it = it->next) {
+                            dap_chain_tx_in_reward_t *l_in_reward = (dap_chain_tx_in_reward_t *) it->data;
+                            char *l_block_hash = dap_chain_hash_fast_to_str_new(&l_in_reward->block_hash);
+                            json_object *l_jobj_block_hash = json_object_new_string(l_block_hash);
+                            if (!l_jobj_block_hash) {
+                                DAP_DELETE(l_block_hash);
+                                json_object_put(l_obj_in_reward_arary);
+                                dap_list_free(l_list_in_reward);
+                                json_object_put(l_jobj_datum);
+                                json_object_put(l_jobj_datums);
+                                json_object_put(l_obj_chain);
+                                dap_global_db_objs_delete(l_objs, l_objs_count);
+                                dap_json_rpc_allocation_error;
+                                return;
+                            }
+                            json_object_array_add(l_obj_in_reward_arary, l_jobj_block_hash);
+                            DAP_DELETE(l_block_hash);
+                        }
+                    } else {
+                        json_object *l_jobj_addr_from = json_object_new_string(l_addr_from_str);
+                        if (!l_jobj_addr_from) {
+                            json_object_put(l_jobj_datum);
+                            json_object_put(l_jobj_datums);
+                            json_object_put(l_obj_chain);
+                            dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
+                            return;
+                        }
+                        json_object_object_add(l_jobj_datum, "from", l_jobj_addr_from);
                     }
-                    json_object_object_add(l_jobj_money, "value", l_jobj_value);
-                    json_object *l_jobj_value_coins = json_object_new_string(l_value_coins_str);
-                    if (!l_jobj_value_coins){
+                    DAP_DELETE(l_addr_from_str);
+                    dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
+                    json_object *l_jobj_to_list = json_object_new_array();
+                    json_object *l_jobj_change_list = json_object_new_array();
+                    json_object *l_jobj_to_from_emi = json_object_new_array();
+                    json_object *l_jobj_fee_list = json_object_new_array();
+                    json_object *l_jobj_stake_lock_list = json_object_new_array();
+                    json_object *l_jobj_xchange_list = json_object_new_array();
+                    json_object *l_jobj_stake_pos_delegate_list = json_object_new_array();
+                    json_object *l_jobj_pay_list = json_object_new_array();
+                    if (!l_jobj_to_list || !l_jobj_change_list || !l_jobj_fee_list || !l_jobj_stake_lock_list ||
+                        !l_jobj_xchange_list || !l_jobj_stake_pos_delegate_list || !l_jobj_pay_list) {
                         json_object_put(l_jobj_to_list);
                         json_object_put(l_jobj_change_list);
+                        json_object_put(l_jobj_to_from_emi);
                         json_object_put(l_jobj_fee_list);
-                        DAP_DELETE(l_value_str);
-                        DAP_DELETE(l_value_coins_str);
-                        json_object_put(l_jobj_money);
+                        json_object_put(l_jobj_stake_lock_list);
+                        json_object_put(l_jobj_xchange_list);
+                        json_object_put(l_jobj_stake_pos_delegate_list);
+                        json_object_put(l_jobj_pay_list);
                         json_object_put(l_jobj_datum);
                         json_object_put(l_jobj_datums);
                         json_object_put(l_obj_chain);
                         dap_global_db_objs_delete(l_objs, l_objs_count);
+                        dap_json_rpc_allocation_error;
                         return;
                     }
-                    json_object_object_add(l_jobj_money, "coins", l_jobj_value_coins);
-                    if (l_dist_token) {
-                        json_object *l_jobj_token = json_object_new_string(l_dist_token);
-                        if (!l_jobj_token) {
+                    enum {
+                        OUT_COND_TYPE_UNKNOWN,
+                        OUT_COND_TYPE_PAY,
+                        OUT_COND_TYPE_FEE,
+                        OUT_COND_TYPE_STAKE_LOCK,
+                        OUT_COND_TYPE_XCHANGE,
+                        OUT_COND_TYPE_POS_DELEGATE
+                    }l_out_cond_subtype={0};
+                    for (dap_list_t *it = l_list_out_items; it; it = it->next) {
+                        dap_chain_addr_t *l_dist_addr = NULL;
+                        uint256_t l_value = uint256_0;
+                        const char *l_dist_token = NULL;
+                        uint8_t l_type = *(uint8_t *) it->data;
+                        switch (l_type) {
+                            case TX_ITEM_TYPE_OUT: {
+                                l_value = ((dap_chain_tx_out_t *) it->data)->header.value;
+                                l_dist_token = l_main_token;
+                                l_dist_addr = &((dap_chain_tx_out_t *) it->data)->addr;
+                            }
+                                break;
+                            case TX_ITEM_TYPE_OUT_EXT: {
+                                l_value = ((dap_chain_tx_out_ext_t *) it->data)->header.value;
+                                l_dist_token = ((dap_chain_tx_out_ext_t *) it->data)->token;
+                                l_dist_addr = &((dap_chain_tx_out_ext_t *) it->data)->addr;
+                            }
+                                break;
+                            case TX_ITEM_TYPE_OUT_COND: {
+                                dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*)it->data;
+                                l_value = ((dap_chain_tx_out_cond_t *) it->data)->header.value;
+                                switch (l_out_cond->header.subtype) {
+                                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: {
+                                        l_dist_token = a_net->pub.native_ticker;
+                                        l_out_cond_subtype = OUT_COND_TYPE_FEE;
+                                    } break;
+                                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: {
+                                        l_dist_token = l_main_token;
+                                        l_out_cond_subtype = OUT_COND_TYPE_STAKE_LOCK;
+                                    } break;
+                                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
+                                        l_dist_token = l_main_token;
+                                        l_out_cond_subtype = OUT_COND_TYPE_XCHANGE;
+                                    } break;
+                                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: {
+                                        l_dist_token = l_main_token;
+                                        l_out_cond_subtype = OUT_COND_TYPE_POS_DELEGATE;
+                                    } break;
+                                    case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
+                                        l_dist_token = l_main_token;
+                                        l_out_cond_subtype = OUT_COND_TYPE_PAY;
+                                    } break;
+                                    default:
+                                        break;
+                                }
+                            }
+                                break;
+                            default:
+                                break;
+                        }
+                        json_object *l_jobj_money = json_object_new_object();
+                        if (!l_jobj_money) {
                             json_object_put(l_jobj_to_list);
                             json_object_put(l_jobj_change_list);
+                            json_object_put(l_jobj_to_from_emi);
+                            json_object_put(l_jobj_fee_list);
+                            json_object_put(l_jobj_datum);
+                            json_object_put(l_jobj_datums);
+                            json_object_put(l_obj_chain);
+                            dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
+                            return;
+                        }
+                        char *l_value_str = dap_chain_balance_print(l_value);
+                        if (!l_value_str) {
+                            json_object_put(l_jobj_to_list);
+                            json_object_put(l_jobj_change_list);
+                            json_object_put(l_jobj_to_from_emi);
                             json_object_put(l_jobj_fee_list);
                             json_object_put(l_jobj_money);
                             json_object_put(l_jobj_datum);
                             json_object_put(l_jobj_datums);
                             json_object_put(l_obj_chain);
-                            DAP_DELETE(l_value_str);
-                            DAP_DELETE(l_value_coins_str);
                             dap_global_db_objs_delete(l_objs, l_objs_count);
                             dap_json_rpc_allocation_error;
                             return;
                         }
-                        json_object_object_add(l_jobj_money, "token", l_jobj_token);
-                    }
-
-                    if (l_dist_addr) {
-                        char *l_addr_str = dap_chain_addr_to_str(l_dist_addr);
-                        if (!l_addr_str) {
+                        char *l_value_coins_str = dap_chain_balance_to_coins(l_value);
+                        if (!l_value_coins_str) {
                             json_object_put(l_jobj_to_list);
                             json_object_put(l_jobj_change_list);
+                            json_object_put(l_jobj_to_from_emi);
                             json_object_put(l_jobj_fee_list);
                             DAP_DELETE(l_value_str);
-                            DAP_DELETE(l_value_coins_str);
                             json_object_put(l_jobj_money);
                             json_object_put(l_jobj_datum);
                             json_object_put(l_jobj_datums);
                             json_object_put(l_obj_chain);
                             dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
                             return;
-                        }                    
-                        json_object *l_jobj_addr = json_object_new_string(l_addr_str);
-                        if (!l_jobj_addr) {
+                        }
+                        json_object *l_jobj_value = json_object_new_string(l_value_str);
+                        if (!l_jobj_value) {
                             json_object_put(l_jobj_to_list);
                             json_object_put(l_jobj_change_list);
+                            json_object_put(l_jobj_to_from_emi);
                             json_object_put(l_jobj_fee_list);
                             DAP_DELETE(l_value_str);
                             DAP_DELETE(l_value_coins_str);
-                            DAP_DELETE(l_addr_str);
                             json_object_put(l_jobj_money);
                             json_object_put(l_jobj_datum);
                             json_object_put(l_jobj_datums);
                             json_object_put(l_obj_chain);
                             dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
                             return;
                         }
-                        if (!datum_is_accepted_addr && l_wallet_addr) {
-                            datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr);
-                        }
-                        json_object *l_jobj_f = json_object_new_object();
-                        if (!l_jobj_f) {
+                        json_object_object_add(l_jobj_money, "value", l_jobj_value);
+                        json_object *l_jobj_value_coins = json_object_new_string(l_value_coins_str);
+                        if (!l_jobj_value_coins) {
                             json_object_put(l_jobj_to_list);
                             json_object_put(l_jobj_change_list);
+                            json_object_put(l_jobj_to_from_emi);
                             json_object_put(l_jobj_fee_list);
                             DAP_DELETE(l_value_str);
                             DAP_DELETE(l_value_coins_str);
-                            DAP_DELETE(l_addr_str);
-                            json_object_put(l_jobj_addr);
                             json_object_put(l_jobj_money);
                             json_object_put(l_jobj_datum);
                             json_object_put(l_jobj_datums);
                             json_object_put(l_obj_chain);
                             dap_global_db_objs_delete(l_objs, l_objs_count);
+                            dap_json_rpc_allocation_error;
                             return;
                         }
-                        json_object_object_add(l_jobj_f, "money", l_jobj_money);
-                        if (dap_chain_addr_compare(&l_addr_from, l_dist_addr)) {
-                            json_object_array_add(l_jobj_change_list, l_jobj_f);
+                        json_object_object_add(l_jobj_money, "coins", l_jobj_value_coins);
+                        if (l_dist_token) {
+                            json_object *l_jobj_token = json_object_new_string(l_dist_token);
+                            if (!l_jobj_token) {
+                                json_object_put(l_jobj_to_list);
+                                json_object_put(l_jobj_change_list);
+                                json_object_put(l_jobj_to_from_emi);
+                                json_object_put(l_jobj_fee_list);
+                                json_object_put(l_jobj_money);
+                                json_object_put(l_jobj_datum);
+                                json_object_put(l_jobj_datums);
+                                json_object_put(l_obj_chain);
+                                DAP_DELETE(l_value_str);
+                                DAP_DELETE(l_value_coins_str);
+                                dap_global_db_objs_delete(l_objs, l_objs_count);
+                                dap_json_rpc_allocation_error;
+                                return;
+                            }
+                            json_object_object_add(l_jobj_money, "token", l_jobj_token);
+                        }
+
+                        if (l_dist_addr) {
+                            char *l_addr_str = dap_chain_addr_to_str(l_dist_addr);
+                            if (!l_addr_str) {
+                                json_object_put(l_jobj_to_list);
+                                json_object_put(l_jobj_change_list);
+                                json_object_put(l_jobj_to_from_emi);
+                                json_object_put(l_jobj_fee_list);
+                                DAP_DELETE(l_value_str);
+                                DAP_DELETE(l_value_coins_str);
+                                json_object_put(l_jobj_money);
+                                json_object_put(l_jobj_datum);
+                                json_object_put(l_jobj_datums);
+                                json_object_put(l_obj_chain);
+                                dap_global_db_objs_delete(l_objs, l_objs_count);
+                                dap_json_rpc_allocation_error;
+                                return;
+                            }
+                            json_object *l_jobj_addr = json_object_new_string(l_addr_str);
+                            if (!l_jobj_addr) {
+                                json_object_put(l_jobj_to_list);
+                                json_object_put(l_jobj_change_list);
+                                json_object_put(l_jobj_to_from_emi);
+                                json_object_put(l_jobj_fee_list);
+                                DAP_DELETE(l_value_str);
+                                DAP_DELETE(l_value_coins_str);
+                                DAP_DELETE(l_addr_str);
+                                json_object_put(l_jobj_money);
+                                json_object_put(l_jobj_datum);
+                                json_object_put(l_jobj_datums);
+                                json_object_put(l_obj_chain);
+                                dap_global_db_objs_delete(l_objs, l_objs_count);
+                                dap_json_rpc_allocation_error;
+                                return;
+                            }
+                            if (!datum_is_accepted_addr && l_wallet_addr) {
+                                datum_is_accepted_addr = dap_chain_addr_compare(l_wallet_addr, l_dist_addr);
+                            }
+                            json_object *l_jobj_f = json_object_new_object();
+                            if (!l_jobj_f) {
+                                json_object_put(l_jobj_to_list);
+                                json_object_put(l_jobj_change_list);
+                                json_object_put(l_jobj_to_from_emi);
+                                json_object_put(l_jobj_fee_list);
+                                DAP_DELETE(l_value_str);
+                                DAP_DELETE(l_value_coins_str);
+                                DAP_DELETE(l_addr_str);
+                                json_object_put(l_jobj_addr);
+                                json_object_put(l_jobj_money);
+                                json_object_put(l_jobj_datum);
+                                json_object_put(l_jobj_datums);
+                                json_object_put(l_obj_chain);
+                                dap_global_db_objs_delete(l_objs, l_objs_count);
+                                dap_json_rpc_allocation_error;
+                                return;
+                            }
+                            json_object_object_add(l_jobj_f, "money", l_jobj_money);
+                            if (dap_chain_addr_compare(&l_addr_from, l_dist_addr)) {
+                                bool l_in_from_emi = false;
+                                for (dap_list_t *it_ems = l_list_in_ems; it_ems; it_ems = it_ems->next) {
+                                    dap_chain_tx_in_ems_t *l_in_ems = (dap_chain_tx_in_ems_t*)it_ems->data;
+                                    if (!dap_strcmp(l_in_ems->header.ticker, l_dist_token)) {
+                                        l_in_from_emi = true;
+                                        dap_hash_fast_t l_ems_hash = l_in_ems->header.token_emission_hash;
+                                        char l_ems_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+                                        dap_hash_fast_to_str(&l_ems_hash, l_ems_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
+                                        json_object * l_obj_ems_hash = json_object_new_string(l_ems_hash_str);
+                                        if (!l_obj_ems_hash) {
+                                            json_object_put(l_jobj_to_list);
+                                            json_object_put(l_jobj_change_list);
+                                            json_object_put(l_jobj_to_from_emi);
+                                            json_object_put(l_jobj_fee_list);
+                                            DAP_DELETE(l_value_str);
+                                            DAP_DELETE(l_value_coins_str);
+                                            DAP_DELETE(l_addr_str);
+                                            json_object_put(l_jobj_addr);
+                                            json_object_put(l_jobj_money);
+                                            json_object_put(l_jobj_datum);
+                                            json_object_put(l_jobj_datums);
+                                            json_object_put(l_obj_chain);
+                                            json_object_put(l_jobj_f);
+                                            dap_global_db_objs_delete(l_objs, l_objs_count);
+                                            dap_json_rpc_allocation_error;
+                                            return;
+                                        }
+                                        json_object_object_add(l_jobj_f, "token_emission_hash", l_obj_ems_hash);
+                                        break;
+                                    }
+                                }
+                                if (l_in_from_emi)
+                                    json_object_array_add(l_jobj_to_from_emi, l_jobj_f);
+                                else
+                                    json_object_array_add(l_jobj_change_list, l_jobj_f);
+                            } else {
+                                json_object_object_add(l_jobj_f, "addr", l_jobj_addr);
+                                json_object_array_add(l_jobj_to_list, l_jobj_f);
+                            }
+                            DAP_DELETE(l_addr_str);
                         } else {
-                            json_object_object_add(l_jobj_f, "addr", l_jobj_addr);
-                            json_object_array_add(l_jobj_to_list, l_jobj_f);
+                            switch (l_out_cond_subtype) {
+                                case OUT_COND_TYPE_PAY:
+                                    json_object_array_add(l_jobj_pay_list, l_jobj_money);
+                                    break;
+                                case OUT_COND_TYPE_FEE:
+                                    json_object_array_add(l_jobj_fee_list, l_jobj_money);
+                                    break;
+                                case OUT_COND_TYPE_STAKE_LOCK:
+                                    json_object_array_add(l_jobj_stake_lock_list, l_jobj_money);
+                                    break;
+                                case OUT_COND_TYPE_XCHANGE:
+                                    json_object_array_add(l_jobj_xchange_list, l_jobj_money);
+                                    break;
+                                case OUT_COND_TYPE_POS_DELEGATE:
+                                    json_object_array_add(l_jobj_stake_pos_delegate_list, l_jobj_money);
+                                    break;
+                                default:
+                                    log_it(L_ERROR, "An unknown subtype output was found in a transaction in the mempool list.");
+                                    break;
+                            }
                         }
-                    
                         DAP_DELETE(l_value_str);
                         DAP_DELETE(l_value_coins_str);
-                        DAP_DELETE(l_addr_str);
-                    } else {
-                        json_object_array_add(l_jobj_fee_list, l_jobj_money);
                     }
+                    json_object_object_add(l_jobj_datum, "to", l_jobj_to_list);
+                    json_object_object_add(l_jobj_datum, "change", l_jobj_change_list);
+                    json_object_object_add(l_jobj_datum, "fee", l_jobj_fee_list);
+                    json_object_array_length(l_jobj_pay_list) > 0 ?
+                    json_object_object_add(l_jobj_datum, "srv_pay", l_jobj_pay_list) : json_object_put(l_jobj_pay_list);
+                    json_object_array_length(l_jobj_xchange_list) > 0 ?
+                    json_object_object_add(l_jobj_datum, "srv_xchange", l_jobj_xchange_list) : json_object_put(l_jobj_xchange_list);
+                    json_object_array_length(l_jobj_stake_lock_list) > 0 ?
+                    json_object_object_add(l_jobj_datum, "srv_stake_lock", l_jobj_stake_lock_list) : json_object_put(l_jobj_stake_lock_list);
+                    json_object_array_length(l_jobj_stake_pos_delegate_list) > 0 ?
+                    json_object_object_add(l_jobj_datum, "srv_stake_pos_delegate", l_jobj_stake_pos_delegate_list) : json_object_put(l_jobj_stake_pos_delegate_list);
+                    json_object_array_length(l_jobj_to_from_emi) > 0 ?
+                    json_object_object_add(l_jobj_datum, "from_emission", l_jobj_to_from_emi) : json_object_put(l_jobj_to_from_emi);
+                    dap_list_free(l_list_out_items);
                 }
-                json_object_object_add(l_jobj_datum, "to", l_jobj_to_list);
-                json_object_object_add(l_jobj_datum, "change", l_jobj_change_list);
-                json_object_object_add(l_jobj_datum, "fee", l_jobj_fee_list);
-                dap_list_free(l_list_out_items);
-            } break;
-            case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
-                size_t l_emi_size = l_datum->header.data_size;
-                dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_read(l_datum->data, &l_emi_size);
-                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));
-            } break;
-            default:
-                json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
+                    break;
+                case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
+                    size_t l_emi_size = l_datum->header.data_size;
+                    dap_chain_datum_token_emission_t *l_emi = dap_chain_datum_emission_read(l_datum->data, &l_emi_size);
+                    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));
+                }
+                    break;
+                default:
+                    json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
+            }
         }
-        json_object_array_add(l_jobj_datums, l_jobj_datum);
+        if (l_wallet_addr) {
+            if (datum_is_accepted_addr) {
+                json_object_array_add(l_jobj_datums, l_jobj_datum);
+            } else
+                json_object_put(l_jobj_datum);
+        } else
+            json_object_array_add(l_jobj_datums, l_jobj_datum);
     }
-    dap_global_db_objs_delete(l_objs, l_objs_count);
+
     json_object_object_add(l_obj_chain, "datums", l_jobj_datums);
-    
+
+    dap_global_db_objs_delete(l_objs, l_objs_count);
+
     char l_net_chain_count_total[64] = {0};
+
     sprintf(l_net_chain_count_total, "%s.%s: %zu", a_net->pub.name, a_chain->name, l_objs_count);
     json_object * l_object_total = json_object_new_string(l_net_chain_count_total);
     if (!l_object_total) {
@@ -3325,7 +3512,11 @@ static int mempool_delete_for_chain(dap_chain_t *a_chain, const char * a_datum_h
         char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(a_chain);
         uint8_t *l_data_tmp = dap_global_db_get_sync(l_gdb_group_mempool, a_datum_hash_str,
                                                      NULL, NULL, NULL);
-        if(l_data_tmp && dap_global_db_del_sync(l_gdb_group_mempool, a_datum_hash_str) == 0) {
+        if (!l_data_tmp) {
+            DAP_DELETE(l_gdb_group_mempool);
+            return 1;
+        }
+        if (dap_global_db_del_sync(l_gdb_group_mempool, a_datum_hash_str) == 0) {
             char *l_msg_str = dap_strdup_printf("Datum %s deleted", a_datum_hash_str);
             json_object *l_msg = json_object_new_string(l_msg_str);
             DAP_DELETE(l_msg_str);
@@ -3342,7 +3533,7 @@ static int mempool_delete_for_chain(dap_chain_t *a_chain, const char * a_datum_h
         } else {
             DAP_DELETE(l_gdb_group_mempool);
             DAP_DELETE(l_data_tmp);
-            return 1;
+            return 2;
         }
 }
 
@@ -3378,7 +3569,7 @@ int _cmd_mempool_delete(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
         res = mempool_delete_for_chain(a_chain, a_datum_hash, a_json_reply);
     }
     if (res) {
-        char *l_msg_str = dap_strdup_printf("Error! Can't find datum %s", a_datum_hash);
+        char *l_msg_str = dap_strdup_printf("Error! Can't %s datum %s", res == 1 ? "find" : "delete", a_datum_hash);
         if (!l_msg_str) {
             dap_json_rpc_allocation_error;
             return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
@@ -3529,7 +3720,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
                 return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
             }
             json_object_object_add(l_obj_atom, "hash", l_jobj_atom_hash);
-            json_object_object_add(l_obj_atom, "err", l_jobj_atom_err);
+            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);
@@ -3953,11 +4144,12 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply)
                 dap_json_rpc_allocation_error;
                 return -1;
             }
+            bool l_fast = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false;
             if(l_chain) {
-                s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type);
+                s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast);
             } else {
                 DL_FOREACH(l_net->pub.chains, l_chain) {
-                    s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type);
+                    s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast);
                 }
             }
             json_object_object_add(obj_ret, "chains", l_jobj_chains);
@@ -6907,19 +7099,25 @@ int cmd_gdb_export(int a_argc, char **a_argv, void **a_str_reply)
 
         for (size_t i = 0; i < l_store_obj_count; ++i) {
             size_t l_out_size = DAP_ENC_BASE64_ENCODE_SIZE((int64_t)l_store_obj[i].value_len) + 1;
+            dap_sign_t *l_sign = l_store_obj[i].sign;
+            size_t l_sign_size = DAP_ENC_BASE64_ENCODE_SIZE(dap_sign_get_size(l_sign))+1;
             char *l_value_enc_str = DAP_NEW_Z_SIZE(char, l_out_size);
+            char *l_sign_str = DAP_NEW_Z_SIZE(char, l_sign_size);
             if(!l_value_enc_str) {
                 log_it(L_CRITICAL, "Memory allocation error");
                 return -1;
             }
             dap_enc_base64_encode(l_store_obj[i].value, l_store_obj[i].value_len, l_value_enc_str, DAP_ENC_DATA_TYPE_B64);
+            dap_enc_base64_encode(l_sign, dap_sign_get_size(l_sign), l_sign_str, DAP_ENC_DATA_TYPE_B64);
             struct json_object *jobj = json_object_new_object();
-            // TODO export sign and CRC and flags
             //json_object_object_add(jobj, "id",      json_object_new_int64((int64_t)l_store_obj[i].id));
             json_object_object_add(jobj, "key",     json_object_new_string(l_store_obj[i].key));
             json_object_object_add(jobj, "value",   json_object_new_string(l_value_enc_str));
             json_object_object_add(jobj, "value_len", json_object_new_int64((int64_t)l_store_obj[i].value_len));
+            json_object_object_add(jobj, "flags", json_object_new_uint64((uint64_t)l_store_obj[i].flags));
+            json_object_object_add(jobj, "sign", json_object_new_string(l_sign_str));
             json_object_object_add(jobj, "timestamp", json_object_new_int64((int64_t)l_store_obj[i].timestamp));
+            json_object_object_add(jobj, "crc", json_object_new_uint64(l_store_obj[i].crc));
             json_object_array_add(l_json_group, jobj);
 
             DAP_DELETE(l_value_enc_str);
@@ -7006,9 +7204,9 @@ int cmd_gdb_import(int a_argc, char **a_argv, void **a_str_reply)
             //l_id        = json_object_object_get(l_record, "id");
             l_key       = json_object_object_get(l_record, "key");
             l_value     = json_object_object_get(l_record, "value");
+            size_t l_record_size = json_object_object_length(l_record);
             l_value_len = json_object_object_get(l_record, "value_len");
             l_ts        = json_object_object_get(l_record, "timestamp");
-            // TODO import sign and CRC and flags
             // l_group_store[j].id     = (uint64_t)json_object_get_int64(l_id);
             l_group_store[j].key    = dap_strdup(json_object_get_string(l_key));
             l_group_store[j].group  = dap_strdup(l_group_name);
@@ -7025,6 +7223,26 @@ int cmd_gdb_import(int a_argc, char **a_argv, void **a_str_reply)
             }
             dap_enc_base64_decode(l_value_str, strlen(l_value_str), l_val, DAP_ENC_DATA_TYPE_B64);
             l_group_store[j].value  = (uint8_t*)l_val;
+            if (l_record_size > 5) {
+                json_object *l_jobj_crc = json_object_object_get(l_record, "crc");
+                json_object *l_jobj_sign = json_object_object_get(l_record, "sign");
+                json_object *l_jobj_flags = json_object_object_get(l_record, "flags");
+                uint8_t l_flags = (uint8_t)json_object_get_uint64(l_jobj_flags);
+                uint64_t l_crc = json_object_get_uint64(l_jobj_crc);
+                const char *l_sign_str = json_object_get_string(l_jobj_sign);
+                dap_sign_t *l_sign = DAP_NEW_Z_SIZE(dap_sign_t, dap_strlen(l_sign_str) + 1);
+                size_t l_sign_decree_size = dap_enc_base64_decode(l_sign_str, dap_strlen(l_sign_str), l_sign, DAP_ENC_DATA_TYPE_B64);
+                if (dap_sign_get_size(l_sign) != l_sign_decree_size) {
+                    log_it(L_ERROR, "Can't reade signature from record with key %s", l_group_store[j].key);
+                }
+                l_group_store[j].sign = l_sign;
+                l_group_store[j].flags = l_flags;
+                l_group_store[j].crc = l_crc;
+            } else {
+                //Loading old record
+                dap_cert_t *l_cert_record = dap_cert_find_by_name(DAP_STREAM_NODE_ADDR_CERT_NAME);
+                l_group_store[j].sign = dap_store_obj_sign(&l_group_store[j], l_cert_record->enc_key, &l_group_store[j].crc);
+            }
         }
         if (dap_global_db_driver_apply(l_group_store, l_records_count)) {
             log_it(L_CRITICAL, "An error occured on importing group %s...", l_group_name);
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 1c9f797c54955bbad513f3f2d0cac1fb7a1d3000..077af7ad71f2dd7ff8c1b9a4e3811895156b2fec 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -551,6 +551,9 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
                 DAP_DELETE(l_coins_str);
             }
         }
+        if (json_object_array_length(j_arr_data) > 0) {
+            json_object_object_add(j_obj_tx, "data", j_arr_data);
+        }
         dap_list_free(l_list_out_items);
         if (l_is_need_correction) {
             SUM_256_256(l_corr_value, l_fee_sum, &l_corr_value);
@@ -563,10 +566,6 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
             DAP_DELETE(l_coins_str);
             l_is_need_correction = false;
         }
-        if (json_object_array_length(j_arr_data) > 0) {
-            json_object_object_add(j_obj_tx, "data", j_arr_data);
-            json_object_array_add(json_obj_datum, j_obj_tx);
-        }
     }
     a_chain->callback_datum_iter_delete(l_datum_iter);
     // delete hashes
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index fadccfe53697b5ff48d867299c1c51717c43c5b9..eac80ec86b27bd2f7ef3182264e0eaaf13ec123c 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -268,8 +268,17 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg)
             l_node_client->callbacks.connected(l_node_client, l_node_client->callbacks_arg);
         dap_stream_ch_chain_net_pkt_hdr_t l_announce = { .version = DAP_STREAM_CH_CHAIN_NET_PKT_VERSION,
                                                          .net_id  = l_node_client->net->pub.id };
+        // Announce net on downlink
         dap_client_write_unsafe(a_client, 'N', DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ANNOUNCE,
                                          &l_announce, sizeof(l_announce));
+        // Add uplink to clusters
+        dap_stream_node_addr_t *l_uplink_addr = &l_node_client->info->hdr.address;
+        dap_global_db_cluster_t *it;
+        DL_FOREACH(dap_global_db_instance_get_default()->clusters, it)
+            if (dap_cluster_member_find_unsafe(it->role_cluster, l_uplink_addr))
+                dap_cluster_member_add(it->links_cluster, l_uplink_addr, 0, NULL);
+        dap_chain_net_add_cluster_link(l_node_client->net, l_uplink_addr);
+
         pthread_mutex_lock(&l_node_client->wait_mutex);
         l_node_client->state = NODE_CLIENT_STATE_ESTABLISHED;
         if (s_stream_ch_chain_debug_more)
diff --git a/modules/net/include/dap_chain_net_bugreport.h b/modules/net/include/dap_chain_net_bugreport.h
index c930015f0b79897ba7502452b74da80595b89872..d4ca32a594bfc38129acb7504ea0dfe72fde2ade 100644
--- a/modules/net/include/dap_chain_net_bugreport.h
+++ b/modules/net/include/dap_chain_net_bugreport.h
@@ -22,6 +22,6 @@
  along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "dap_http.h"
+#include "dap_http_server.h"
 
-int dap_chain_net_bugreport_init(dap_http_t * a_http);
+int dap_chain_net_bugreport_init(dap_http_server_t * a_http);
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index a8b7d359f67a776e4e9d73f7d63dcc38a8a75c13..be4dc5d5c7db959bbf037181267497274b9cf6d6 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -865,7 +865,7 @@ dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net
     }
 
     uint64_t l_max_price_cfg = dap_config_get_item_uint64_default(g_config, a_config_section, "max_price", 0xFFFFFFFFFFFFFFF);
-    if (l_order->node_addr.uint64 != l_node_addr->uint64 &&
+    if (l_order->node_addr.uint64 != g_node_addr.uint64 &&
         l_order->srv_uid.uint64 != a_srv->uid.uint64) {
         DAP_DELETE(l_price);
         DAP_DEL_Z(l_order);
@@ -962,9 +962,14 @@ int dap_chain_net_srv_price_apply_from_my_order(dap_chain_net_srv_t *a_srv, cons
     uint64_t l_max_price_cfg = dap_config_get_item_uint64_default(g_config, a_config_section, "max_price", 0xFFFFFFFFFFFFFFF);
     char *l_gdb_order_group = dap_chain_net_srv_order_get_gdb_group(l_net);
     dap_global_db_obj_t *l_orders = dap_global_db_get_all_sync(l_gdb_order_group, &l_orders_count);
+    log_it(L_INFO, "Found %"DAP_UINT64_FORMAT_U" orders.", l_orders_count);
     for (size_t i=0; i < l_orders_count; i++){
         l_err_code = -4;
         dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_read(l_orders[i].value, l_orders[i].value_len);
+        if(!l_order){
+            log_it(L_ERROR, "Invalid order: NULL. Skip order.");
+            continue;
+        }
         if (l_order->node_addr.uint64 == g_node_addr.uint64 &&
             l_order->srv_uid.uint64 == a_srv->uid.uint64) {
             l_err_code = 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 d448dfa7877f708e65e56fbca106fe53e04aae14..0d49e1cbf4a280689545bf7531f2aeff27bb3731 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
@@ -2547,7 +2547,8 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply)
                     char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
                     dap_chain_hash_fast_to_str(&l_datum_hash, l_hash_str, sizeof(l_hash_str));
                     dap_string_append_printf(l_str_tmp,"%s \n",spaces);
-                    dap_string_append_printf(l_str_tmp, "%s \n", dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum_tx->header.ts_created));
+                    dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum_tx->header.ts_created);
+                    dap_string_append_printf(l_str_tmp, "%s \n", buf);
                     dap_string_append_printf(l_str_tmp,"tx_hash:\t%s \n",l_hash_str);
 
                     l_signing_addr_str = dap_chain_addr_to_str(&l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr);
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 1dca52acb800f8eb6a43637acfe6156478bff9a2..3e0630c055cfac649bb14a19887b240afc3ddd91 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1023,19 +1023,11 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -token_sell");
                 return -5;
             }
-            if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_sell_str)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_sell_str);
-                return -6;
-            }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-token_buy", &l_token_buy_str);
             if (!l_token_buy_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -token_buy");
                 return -5;
             }
-            if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_buy_str)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str);
-                return -6;
-            }
             const char *l_val_sell_str = NULL, *l_val_rate_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_val_sell_str);
             if (!l_val_sell_str) {
@@ -1043,20 +1035,12 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 return -8;
             }
             uint256_t l_datoshi_sell = dap_chain_balance_scan(l_val_sell_str);
-            if (IS_ZERO_256(l_datoshi_sell)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned integer 256>");
-                return -9;
-            }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
             if (!l_val_rate_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -rate");
                 return -8;
             }
             uint256_t l_rate = dap_chain_coins_to_balance(l_val_rate_str);
-            if (IS_ZERO_256(l_rate)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -rate n.n = buy / sell (eg: 1.0, 1.135)");
-                return -9;
-            }
             const char *l_fee_str = NULL;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
@@ -1064,10 +1048,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 return -20;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
-            if (IS_ZERO_256(l_fee)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -fee <unsigned integer 256>");
-                return -21;
-            }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
             if (!l_wallet_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -w");
@@ -1081,27 +1061,78 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             } else {
                 l_sign_str = dap_chain_wallet_check_sign(l_wallet);
             }
-            uint256_t l_value = dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_token_sell_str);
-            uint256_t l_value_sell = l_datoshi_sell;
-            if (!dap_strcmp(l_net->pub.native_ticker, l_token_sell_str)) {
-                if (SUM_256_256(l_value_sell, l_fee, &l_value_sell)) {
-                    dap_chain_wallet_close(l_wallet);
+            char *l_hash_ret = NULL;
+            int ret_code = dap_chain_net_srv_xchange_create(l_net, l_token_buy_str, l_token_sell_str, l_datoshi_sell, l_rate, l_fee, l_wallet, &l_hash_ret);
+            dap_chain_wallet_close(l_wallet);
+            switch (ret_code) {
+                case XCHANGE_CREATE_ERROR_OK: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSuccessfully created order %s", l_sign_str, l_hash_ret);
+                    DAP_DELETE(l_hash_ret);
+                    return 0;
+                }
+                case XCHANGE_CREATE_ERROR_INVALID_ARGUMENT: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Some parameters could not be set during a function call");
+                    DAP_DELETE(l_hash_ret);
+                    return -24;
+                }
+                case XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_sell_str);
+                    DAP_DELETE(l_hash_ret);
+                    return -6;
+                }
+                case XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_buy_str);
+                    DAP_DELETE(l_hash_ret);
+                    return -6;
+                }
+                case XCHANGE_CREATE_ERROR_RATE_IS_ZERO: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -rate n.n = buy / sell (eg: 1.0, 1.135)");
+                    DAP_DELETE(l_hash_ret);
+                    return -9;
+                }
+                case XCHANGE_CREATE_ERROR_FEE_IS_ZERO: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned integer 256>");
+                    DAP_DELETE(l_hash_ret);
+                    return -21;
+                }
+                case XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned integer 256>");
+                    DAP_DELETE(l_hash_ret);
+                    return -9;
+                }
+                case XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE: {
                     log_it(L_ERROR, "Integer overflow with sum of value and fee");
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Integer overflow with sum of value and fee");
+                    DAP_DELETE(l_hash_ret);
                     return -22;
                 }
-            } else { // sell non-native ticker
-                uint256_t l_fee_value = dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_net->pub.native_ticker);
-                if (compare256(l_fee_value, l_fee) == -1) {
+                case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET: {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nNot enough cash for fee in specified wallet", l_sign_str);
-                    dap_chain_wallet_close(l_wallet);
+                    DAP_DELETE(l_hash_ret);
                     return -23;
                 }
+                case XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nNot enough cash in specified wallet", l_sign_str);
+                    DAP_DELETE(l_hash_ret);
+                    return -12;
+                }
+                case XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Out of memory");
+                    DAP_DELETE(l_hash_ret);
+                    return -1;
+                }
+                case XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't compose the conditional transaction", l_sign_str);
+                    DAP_DELETE(l_hash_ret);
+                    return -14;
+                }
+                case XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't compose the conditional transaction", l_sign_str);
+                    DAP_DELETE(l_hash_ret);
+                    return -15;
+                }
             }
-            if (compare256(l_value, l_value_sell) == -1) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nNot enough cash in specified wallet", l_sign_str);
-                dap_chain_wallet_close(l_wallet);
-                return -12;
-            }
+
             // Create the price
             dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t);
             if (!l_price) {
@@ -1110,7 +1141,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 dap_chain_wallet_close(l_wallet);
                 return -1;
             }
-            l_price->wallet_str = dap_strdup(l_wallet_str);
             dap_stpcpy(l_price->token_sell, l_token_sell_str);
             l_price->net = l_net;
             dap_stpcpy(l_price->token_buy, l_token_buy_str);
@@ -1121,7 +1151,6 @@ 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 = s_xchange_tx_create_request(l_price, l_wallet);
             if (!l_tx) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't compose the conditional transaction", l_sign_str);
-                DAP_DELETE(l_price->wallet_str);
                 DAP_DELETE(l_price);
                 dap_chain_wallet_close(l_wallet);
                 return -14;
@@ -1131,7 +1160,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             char* l_ret = NULL;
             if(!(l_ret = s_xchange_tx_put(l_tx, l_net))) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't put transaction to mempool", l_sign_str);
-                DAP_DELETE(l_price->wallet_str);
                 DAP_DELETE(l_price);
                 return -15;
             }
@@ -1262,41 +1290,39 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 return -12;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
-            if(IS_ZERO_256(l_fee)){
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get fee value.");
-                return -13;
-            }
             dap_hash_fast_t l_tx_hash = {};
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash);
-            dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
-            if (!l_cond_tx) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSpecified order not found", l_sign_str);
-                return -13;
-            }
-            dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_fee, false);
-            if (!l_price) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't create price object from order", l_sign_str);
-                return -13;
-            }
-
-            if (l_cmd_num == CMD_REMOVE) {
-                dap_string_t *l_str_reply = dap_string_new(l_sign_str);
-                char*  l_ret = s_xchange_tx_invalidate(l_price, l_wallet);
-                dap_chain_wallet_close(l_wallet);
-                if (!l_ret) {
-                    if (!l_price) {
-                        dap_string_append_printf(l_str_reply, "Can't get price for order %s\n", l_order_hash_str);
-                    } else {
-                        char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
-                        dap_string_append_printf(l_str_reply, "Can't invalidate transaction %s\n", l_tx_hash_str);
-                        DAP_DELETE(l_tx_hash_str);
-                    }
-                } else
-                    dap_string_append_printf(l_str_reply, "Order successfully removed. Created inactivate tx with hash %s", l_ret);
-                DAP_DELETE(l_price);
-                DAP_DEL_Z(l_ret);
-                *a_str_reply = dap_string_free(l_str_reply, false);
+            dap_chain_wallet_close(l_wallet);
+            char *l_tx_hash_ret = NULL;
+            int l_ret_code = dap_chain_net_srv_xchange_remove(l_net, &l_tx_hash, l_fee, l_wallet, &l_tx_hash_ret);
+            switch (l_ret_code) {
+                case XCHANGE_REMOVE_ERROR_OK:
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Order successfully removed. Created inactivate tx with hash %s", l_tx_hash_ret);
+                    DAP_DELETE(l_tx_hash_ret);
+                    break;
+                case XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX:
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSpecified order not found", l_sign_str);
+                    break;
+                case XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE:
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't create price object from order", l_sign_str);
+                    break;
+                case XCHANGE_REMOVE_ERROR_FEE_IS_ZERO:
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get fee value.");
+                    break;
+                case XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX: {
+                    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
+                    dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_fee, false);
+                    char *l_finaly_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_price->tx_hash);
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create invalidate transaction from: %s\n", l_finaly_tx_hash_str);
+                    DAP_DELETE(l_price);
+                    DAP_DELETE(l_finaly_tx_hash_str);
+                } break;
+                default:
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "An error occurred with an unknown code: %d.", l_ret_code);
+                    break;
             }
+            DAP_DELETE(l_sign_str);
+            return l_ret_code;
         } break;
 
         case CMD_STATUS: {
@@ -1968,47 +1994,39 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 return -8;
             }
             uint256_t l_datoshi_buy = dap_chain_balance_scan(l_val_buy_str);
-            if (IS_ZERO_256(l_datoshi_buy)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <unsigned int256>");
-                return -9;
-            }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_val_fee_str);
             if (!l_val_fee_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'purchase' requires parameter -fee");
                 return  -8;
             }
             uint256_t  l_datoshi_fee = dap_chain_balance_scan(l_val_fee_str);
-            if (IS_ZERO_256(l_datoshi_fee)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -fee <unsigned int256>");
-                return -9;
-            }
             dap_hash_fast_t l_tx_hash = {};
             dap_chain_hash_fast_from_str(l_order_hash_str, &l_tx_hash);
-            dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash);
-
-            if (l_cond_tx) {
-                dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_datoshi_fee, false);
-                if(!l_price){
+            char *l_str_ret_hash = NULL;
+            int l_ret_code = dap_chain_net_srv_xchange_purchase(l_net, &l_tx_hash, l_datoshi_buy, l_datoshi_fee,
+                                                                l_wallet, &l_str_ret_hash);
+            switch (l_ret_code) {
+                case XCHANGE_PURCHASE_ERROR_OK: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Exchange transaction has done. tx hash: %s", l_str_ret_hash);
+                    DAP_DELETE(l_str_ret_hash);
+                    return 0;
+                }
+                case XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found");
+                    return -13;
+                }
+                case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE: {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create price from order");
                     return -13;
                 }
-                // Create conditional transaction
-                dap_chain_hash_fast_from_str(l_order_hash_str, &l_price->order_hash);
-                char *l_ret = NULL;
-                dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_exchange(l_price, l_wallet, l_datoshi_buy, l_datoshi_fee);
-                if (l_tx && (l_ret = s_xchange_tx_put(l_tx, l_net)) &&
-                        dap_hash_fast_is_blank(&l_price->order_hash))
-                    dap_chain_net_srv_order_delete_by_hash_str_sync(l_price->net, l_order_hash_str);
-                DAP_DELETE(l_price);
-                if (l_tx && l_ret){
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Exchange transaction has done. tx hash: %s", l_ret);
-                } else
+                case XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX: {
                     dap_cli_server_cmd_set_reply_text(a_str_reply,  "Exchange transaction error");
-
-                DAP_DEL_Z(l_ret);
-            } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found");
-                return -13;
+                    return -13;
+                }
+                default: {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "An error occurred with an unknown code: %d.", l_ret_code);
+                    return -14;
+                }
             }
         } break;
         case CMD_ENABLE: {
@@ -2419,3 +2437,151 @@ void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a
                                                "\t\tThe xchanger service has not announced a commission fee.\n");
     }
 }
+
+dap_list_t *dap_chain_net_srv_xchange_get_prices(dap_chain_net_t *a_net) {
+    dap_list_t *l_list_prices = NULL;
+    dap_list_t *l_list_tx =  dap_chain_net_get_tx_cond_all_by_srv_uid(a_net, c_dap_chain_net_srv_xchange_uid, 0, 0,TX_SEARCH_TYPE_NET);
+    dap_list_t *l_temp = l_list_tx;
+    while(l_temp)
+    {
+        dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_temp->data;
+
+        dap_chain_net_srv_xchange_price_t * l_price = NULL;
+        l_price = s_xchange_price_from_order(a_net, l_tx, NULL, true);
+        if(!l_price ){
+            log_it(L_WARNING,"Can't create price from order");
+            l_temp = l_temp->next;
+            continue;
+        }
+        l_list_prices = dap_list_append(l_list_prices, l_price);
+        l_temp = l_temp->next;
+    }
+    dap_list_free(l_list_tx);
+    return l_list_prices;
+}
+
+int 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,
+                                     char **a_out_tx_hash){
+    if (!a_net || !a_token_buy || !a_token_sell || !a_wallet || !a_out_tx_hash) {
+        return XCHANGE_CREATE_ERROR_INVALID_ARGUMENT;
+    }
+    if (!dap_ledger_token_ticker_check(a_net->pub.ledger, a_token_sell)) {
+        return XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER;
+    }
+    if (!dap_ledger_token_ticker_check(a_net->pub.ledger, a_token_buy)) {
+        return XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER;
+    }
+    if (IS_ZERO_256(a_rate)) {
+        return XCHANGE_CREATE_ERROR_RATE_IS_ZERO;
+    }
+    if (IS_ZERO_256(a_fee)) {
+        return XCHANGE_CREATE_ERROR_FEE_IS_ZERO;
+    }
+    if (IS_ZERO_256(a_datoshi_sell)) {
+        return XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO;
+    }
+    const char* l_sign_str = dap_chain_wallet_check_sign(a_wallet);
+    uint256_t l_value = dap_chain_wallet_get_balance(a_wallet, a_net->pub.id, a_token_sell);
+    uint256_t l_value_sell = a_datoshi_sell;
+    if (!dap_strcmp(a_net->pub.native_ticker, a_token_sell)) {
+        if (SUM_256_256(l_value_sell, a_fee, &l_value_sell)) {
+            log_it(L_ERROR, "Integer overflow with sum of value and fee");
+            return XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE;
+        }
+    } else { // sell non-native ticker
+        uint256_t l_fee_value = dap_chain_wallet_get_balance(a_wallet, a_net->pub.id, a_net->pub.native_ticker);
+        if (compare256(l_fee_value, a_fee) == -1) {
+            return XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET;
+        }
+    }
+    if (compare256(l_value, l_value_sell) == -1) {
+        return XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET;
+    }
+    // Create the price
+    dap_chain_net_srv_xchange_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_xchange_price_t);
+    if (!l_price) {
+        log_it(L_CRITICAL, "Memory allocation error");
+        return XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED;
+    }
+    dap_stpcpy(l_price->token_sell, a_token_sell);
+    l_price->net = a_net;
+    dap_stpcpy(l_price->token_buy, a_token_buy);
+    l_price->datoshi_sell = a_datoshi_sell;
+    l_price->rate = a_rate;
+    l_price->fee = a_fee;
+    // Create conditional transaction
+    dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_request(l_price, a_wallet);
+    if (!l_tx) {
+        DAP_DELETE(l_price);
+        return XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION;
+    }
+    dap_hash_fast_t l_tx_hash ={};
+    dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
+    char* l_ret = NULL;
+    if(!(l_ret = s_xchange_tx_put(l_tx, a_net))) {
+        DAP_DELETE(l_price);
+        return XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL;
+    }
+    // To avoid confusion, the term "order" will apply to the original conditional exchange offer transactions.
+    *a_out_tx_hash = l_ret;
+    return XCHANGE_CREATE_ERROR_OK;
+}
+
+int 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) {
+    if (!a_net || !a_hash_tx || !a_wallet) {
+        return XCHANGE_REMOVE_ERROR_INVALID_ARGUMENT;
+    }
+    if(IS_ZERO_256(a_fee)){
+        return XCHANGE_REMOVE_ERROR_FEE_IS_ZERO;
+    }
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_hash_tx);
+    if (!l_cond_tx) {
+        return XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX;
+    }
+    dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(a_net, l_cond_tx, &a_fee, false);
+    if (!l_price) {
+        return XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE;
+    }
+    char*  l_ret = s_xchange_tx_invalidate(l_price, a_wallet);
+    if (!l_ret){
+        DAP_DELETE(l_price);
+        return XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX;
+    }
+    *a_out_hash_tx = l_ret;
+    DAP_DELETE(l_price);
+    return XCHANGE_REMOVE_ERROR_OK;
+}
+
+int 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){
+    if (!a_net || !a_order_hash || !a_wallet || !a_hash_out) {
+        return XCHANGE_PURCHASE_ERROR_INVALID_ARGUMENT;
+    }
+    dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_order_hash);
+    if (l_cond_tx) {
+        dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(a_net, l_cond_tx, &a_fee, false);
+        if(!l_price){
+            return XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE;
+        }
+        // Create conditional transaction
+        char *l_ret = NULL;
+        dap_chain_datum_tx_t *l_tx = s_xchange_tx_create_exchange(l_price, a_wallet, a_value, a_fee);
+        if (l_tx && (l_ret = s_xchange_tx_put(l_tx, a_net)) &&
+            dap_hash_fast_is_blank(&l_price->order_hash)) {
+            char *l_order_hash_str = dap_hash_fast_to_str_new(a_order_hash);
+            dap_chain_net_srv_order_delete_by_hash_str_sync(l_price->net, l_order_hash_str);
+            DAP_DELETE(l_order_hash_str);
+        }
+        DAP_DELETE(l_price);
+        if (l_tx && l_ret){
+            *a_hash_out = l_ret;
+            return XCHANGE_PURCHASE_ERROR_OK;
+        } else
+            return XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX;
+    } else {
+        return XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND;
+    }
+}
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 1d8ac20c694eb2f847b2ec197c8b25d8eedb3369..0cd59476943d77e14e1a4e96fc3c71c660013a0e 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -31,7 +31,6 @@
 #define GROUP_LOCAL_XCHANGE "local.xchange"
 
 typedef struct dap_chain_net_srv_xchange_price {
-    char *wallet_str;
     char token_sell[DAP_CHAIN_TICKER_SIZE_MAX];
     uint256_t datoshi_sell;
     dap_chain_net_t *net;
@@ -62,3 +61,47 @@ void dap_chain_net_srv_xchange_deinit();
 
 json_object *dap_chain_net_srv_xchange_print_fee_json(dap_chain_net_t *a_net);
 void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a_string_ret);
+
+enum dap_chain_net_srv_xchange_create_error_list{
+    XCHANGE_CREATE_ERROR_OK = 0,
+    XCHANGE_CREATE_ERROR_INVALID_ARGUMENT,
+    XCHANGE_CREATE_ERROR_TOKEN_TICKER_SELL_IS_NOT_FOUND_LEDGER,
+    XCHANGE_CREATE_ERROR_TOKEN_TICKER_BUY_IS_NOT_FOUND_LEDGER,
+    XCHANGE_CREATE_ERROR_RATE_IS_ZERO,
+    XCHANGE_CREATE_ERROR_FEE_IS_ZERO,
+    XCHANGE_CREATE_ERROR_VALUE_SELL_IS_ZERO,
+    XCHANGE_CREATE_ERROR_INTEGER_OVERFLOW_WITH_SUM_OF_VALUE_AND_FEE,
+    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_FOR_FEE_IN_SPECIFIED_WALLET,
+    XCHANGE_CREATE_ERROR_NOT_ENOUGH_CASH_IN_SPECIFIED_WALLET,
+    XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED,
+    XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION,
+    XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL,
+};
+int 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,
+                                     char **a_out_tx_hash);
+
+enum dap_chain_net_srv_xchange_remove_error_list{
+    XCHANGE_REMOVE_ERROR_OK = 0,
+    XCHANGE_REMOVE_ERROR_INVALID_ARGUMENT,
+    XCHANGE_REMOVE_ERROR_FEE_IS_ZERO,
+    XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX,
+    XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE,
+    XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX
+};
+int 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);
+
+dap_list_t *dap_chain_net_srv_xchange_get_tx_xchange(dap_chain_net_t *a_net);
+dap_list_t *dap_chain_net_srv_xchange_get_prices(dap_chain_net_t *a_net);
+
+enum dap_chain_net_srv_xchange_purchase_error_list{
+    XCHANGE_PURCHASE_ERROR_OK = 0,
+    XCHANGE_PURCHASE_ERROR_INVALID_ARGUMENT,
+    XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND,
+    XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE,
+    XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX,
+};
+int 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);