diff --git a/CMakeLists.txt b/CMakeLists.txt
index 426811025385c726a2170500dfb712a3dedd516c..eb4b01fd89578a2f97d44cacc1d97f1b63908165 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,12 +49,11 @@ if(WIN32)
   add_definitions ("-D_POSIX")
   add_definitions ("-D_POSIX_")
   add_definitions ("-D_POSIX_THREAD_SAFE_FUNCTIONS")
-  add_definitions ("-DNODE_NETNAME=\"kelvin\"")
+  add_definitions ("-DNODE_NETNAME=\"cellframe\"")
   include_directories(../libdap/src/win32/)
   include_directories(../3rdparty/wepoll/include/)
   include_directories(../3rdparty/uthash/src/)
   include_directories(../3rdparty/libjson-c/)
-  include_directories(../3rdparty/libmagic/src/)
   include_directories(../3rdparty/curl/include/)
   include_directories(../3rdparty/libsqlite3/)
 endif()
@@ -62,7 +61,7 @@ endif()
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
 
 if(WIN32)
-  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain dap_chain_gdb dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_net_srv_vpn dap_chain_mempool dap_chain_global_db )
+  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain dap_chain_gdb dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db )
 endif()
 
 if(UNIX)
diff --git a/dap_chain_net.c b/dap_chain_net.c
index a106848e7ad167fb5dcfb30ee1ed1a05fc78587f..9fda000d9d70f7cc7cc1972b4bebf59770eda358 100755
--- a/dap_chain_net.c
+++ b/dap_chain_net.c
@@ -630,6 +630,7 @@ lb_proc_state:
             }
         }
             break;
+        default: log_it (L_DEBUG, "Unprocessed state");
     }
     pthread_mutex_unlock(&PVT(l_net)->state_mutex );
     return ret;
@@ -845,6 +846,13 @@ void dap_chain_net_load_all()
                 continue;
             }
             DAP_DELETE(l_full_path);
+            // search only ".cfg" files
+            if(strlen(l_dir_entry->d_name) > 4) { // It has non zero name excluding file extension
+                if(strncmp(l_dir_entry->d_name + strlen(l_dir_entry->d_name) - 4, ".cfg", 4) != 0) {
+                    // its not .cfg file
+                    continue;
+                }
+            }
             log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name);
             //char* l_dot_pos = rindex(l_dir_entry->d_name,'.');
             char* l_dot_pos = strchr(l_dir_entry->d_name,'.');
@@ -1066,6 +1074,23 @@ static int s_cli_net( int argc, char **argv, char **a_str_reply)
     return  ret;
 }
 
+// for sequential loading chains
+typedef struct list_priority_{
+    uint16_t prior;
+    char * chains_path;
+}list_priority;
+
+static int callback_compare_prioritity_list(const void * a_item1, const void * a_item2)
+{
+    list_priority *l_item1 = (list_priority*) a_item1;
+    list_priority *l_item2 = (list_priority*) a_item2;
+    if(!l_item1 || !l_item2 || l_item1->prior == l_item2->prior)
+        return 0;
+    if(l_item1->prior > l_item2->prior)
+        return 1;
+    return -1;
+}
+
 /**
  * @brief s_net_load
  * @param a_net_name
@@ -1312,6 +1337,9 @@ int s_net_load(const char * a_net_name)
         DIR * l_chains_dir = opendir(l_chains_path);
         DAP_DELETE (l_chains_path);
         if ( l_chains_dir ){
+            // for sequential loading chains
+            dap_list_t *l_prior_list = NULL;
+
             struct dirent * l_dir_entry;
             while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){
                 if (l_dir_entry->d_name[0]=='\0')
@@ -1322,20 +1350,48 @@ int s_net_load(const char * a_net_name)
                         l_entry_name [strlen(l_entry_name)-4] = 0;
                         log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name);
                         l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name);
-                        // Create chain object
-                        dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name,
-                                l_net->pub.id, l_chains_path);
-                        if(l_chain) {
-                            DL_APPEND(l_net->pub.chains, l_chain);
-                            if(l_chain->callback_created)
-                                l_chain->callback_created(l_chain, l_cfg);
+                        dap_config_t * l_cfg = dap_config_open(l_chains_path);
+                        if(l_cfg) {
+                            list_priority *l_chain_prior = DAP_NEW_Z(list_priority);
+                            l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100);
+                            l_chain_prior->chains_path = l_chains_path;
+                            // add chain to load list;
+                            l_prior_list = dap_list_append(l_prior_list, l_chain_prior);
                         }
-                        DAP_DELETE (l_chains_path);
+                        // Create chain object
+//                        dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name,
+//                                l_net->pub.id, l_chains_path);
+//                        if(l_chain) {
+//                            DL_APPEND(l_net->pub.chains, l_chain);
+//                            if(l_chain->callback_created)
+//                                l_chain->callback_created(l_chain, l_cfg);
+//                        }
+//                        DAP_DELETE (l_chains_path);
                     }
                 }
                 DAP_DELETE (l_entry_name);
             }
             closedir(l_chains_dir);
+
+            // sort list with chains names by priority
+            l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list);
+            // load chains by priority
+            dap_list_t *l_list = l_prior_list;
+            while(l_list){
+                list_priority *l_chain_prior = l_list->data;
+                // Create chain object
+                dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name,
+                        l_net->pub.id, l_chain_prior->chains_path);
+                if(l_chain) {
+                    DL_APPEND(l_net->pub.chains, l_chain);
+                    if(l_chain->callback_created)
+                        l_chain->callback_created(l_chain, l_cfg);
+                }
+                DAP_DELETE (l_chain_prior->chains_path);
+                l_list = dap_list_next(l_list);
+            }
+            dap_list_free(l_prior_list);
+
         } else {
             log_it(L_ERROR,"Can't any chains for network %s",l_net->pub.name);
             PVT(l_net)->load_mode = false;
@@ -1485,7 +1541,7 @@ dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const ch
 {
    dap_chain_t * l_chain;
    DL_FOREACH(l_net->pub.chains, l_chain){
-        if(strcmp(l_chain->name,a_name) == 0)
+        if(dap_strcmp(l_chain->name,a_name) == 0)
             return  l_chain;
    }
    return NULL;
@@ -1561,3 +1617,42 @@ void dap_chain_net_proc_datapool (dap_chain_net_t * a_net)
 {
 
 }
+
+/**
+ * @brief dap_chain_net_tx_get_by_hash
+ * @param a_net
+ * @param a_tx_hash
+ * @param a_search_type
+ * @return
+ */
+dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash,
+                                                     dap_chain_net_tx_search_type_t a_search_type)
+{
+    dap_ledger_t * l_ledger = dap_chain_ledger_by_net_name( a_net->pub.name );
+    dap_chain_datum_tx_t * l_tx = NULL;
+
+    switch (a_search_type) {
+        case TX_SEARCH_TYPE_NET:
+        case TX_SEARCH_TYPE_CELL:
+        case TX_SEARCH_TYPE_LOCAL:{
+            if ( ! l_tx ){
+                // pass all chains
+                for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){
+                    if ( l_chain->callback_tx_find_by_hash ){
+                        // try to find transaction in chain ( inside shard )
+                        l_tx = l_chain->callback_tx_find_by_hash( l_chain, a_tx_hash );
+                        if (l_tx)
+                            break;
+                    }
+                }
+            }
+        }break;
+
+        case TX_SEARCH_TYPE_NET_UNSPENT:
+        case TX_SEARCH_TYPE_CELL_UNSPENT:{
+            l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger, a_tx_hash );
+        }break;
+    }
+    return l_tx;
+}
+
diff --git a/dap_chain_net.h b/dap_chain_net.h
index 05d9e73f13bd4e687299c83e89e91d342501908a..99cd058fc8b01ce4cb06cfe68619c38a61deeb8e 100644
--- a/dap_chain_net.h
+++ b/dap_chain_net.h
@@ -1,27 +1,28 @@
 /*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * Alexander Lysikov <alexander.lysikov@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * 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/>.
+* Authors:
+* Dmitriy Gerasimov <naeper@demlabs.net>
+* Aleksandr Lysikov <alexander.lysikov@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2019
+* All rights reserved.
+
+This file is part of CellFrame SDK the open source project
+
+CellFrame SDK 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.
+
+CellFrame SDK 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 CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
 */
+
 #pragma once
 
 #ifndef _WIN32
@@ -107,6 +108,21 @@ dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net);
 
 void dap_chain_net_links_connect(dap_chain_net_t * a_net);
 
+typedef enum dap_chain_net_tx_search_type {
+    /// Search local, in memory, possible load data from drive to memory
+    TX_SEARCH_TYPE_LOCAL,
+    /// Do the request to the network if its not full node, search inside shard
+    TX_SEARCH_TYPE_CELL,
+    /// Do the request for unspent txs in cell
+    TX_SEARCH_TYPE_CELL_UNSPENT,
+    /// Do the search in whole network and request tx from others cells if need
+    TX_SEARCH_TYPE_NET,
+    /// Do the search in whole network but search only unspent
+    TX_SEARCH_TYPE_NET_UNSPENT
+}dap_chain_net_tx_search_type_t;
+
+dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash,
+                                                     dap_chain_net_tx_search_type_t a_search_type);
 
 /**
  * @brief dap_chain_net_get_gdb_group_mempool
diff --git a/dap_chain_node.c b/dap_chain_node.c
index 68436d22441b736aeefc2a47cee8b17486fff6ef..1fb9ae970c2cd5b2eda0b3bc9e9e4cfe6385f54c 100644
--- a/dap_chain_node.c
+++ b/dap_chain_node.c
@@ -86,12 +86,12 @@ bool dap_chain_node_check_addr(dap_chain_net_t * a_net,dap_chain_node_addr_t *ad
  */
 bool dap_chain_node_alias_register(dap_chain_net_t * a_net,const char *alias, dap_chain_node_addr_t *addr)
 {
-    const char *a_key = alias;
+    char *a_key = strdup(alias);
 //    char a_value[2 * sizeof(dap_chain_node_addr_t) + 1];
 //    if(bin2hex(a_value, (const unsigned char *) addr, sizeof(dap_chain_node_addr_t)) == -1)
 //        return false;
 //    a_value[2 * sizeof(dap_chain_node_addr_t)] = '\0';
-    bool res = dap_chain_global_db_gr_set(a_key, (const uint8_t*) addr, sizeof(dap_chain_node_addr_t)
+    bool res = dap_chain_global_db_gr_set(a_key,  addr, sizeof(dap_chain_node_addr_t)
                                           , a_net->pub.gdb_nodes_aliases);
     return res;
 }
@@ -114,7 +114,7 @@ dap_chain_node_addr_t * dap_chain_node_alias_find(dap_chain_net_t * a_net,const
  */
 bool dap_chain_node_alias_delete(dap_chain_net_t * a_net,const char *a_alias)
 {
-    const char *a_key = a_alias;
+    char *a_key = strdup(a_alias);
     bool res = dap_chain_global_db_gr_del(a_key, a_net->pub.gdb_nodes_aliases);
     return res;
 }
@@ -153,7 +153,7 @@ int dap_chain_node_info_save(dap_chain_net_t * a_net, dap_chain_node_info_t *nod
     }
     //char *a_value = dap_chain_node_info_serialize(node_info, NULL);
     size_t node_info_size = dap_chain_node_info_get_size(node_info);
-    bool res = dap_chain_global_db_gr_set(l_key, (const uint8_t *) node_info, node_info_size, a_net->pub.gdb_nodes);
+    bool res = dap_chain_global_db_gr_set(l_key, node_info, node_info_size, a_net->pub.gdb_nodes);
     DAP_DELETE(l_key);
     //DAP_DELETE(a_value);
     return res?0:-3;
diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index 216067c774d268d014380bb460ccd9eee8b77d21..8ae4d435ec1287844df1348ff3611867331300a7 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -63,7 +63,7 @@
 #include "dap_strfuncs.h"
 #include "dap_list.h"
 #include "dap_string.h"
-#include "dap_chain_cert.h"
+#include "dap_cert.h"
 #include "dap_chain_wallet.h"
 #include "dap_chain_node.h"
 #include "dap_chain_global_db.h"
@@ -1183,7 +1183,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         }
         dap_stream_ch_set_ready_to_write(l_ch_chain, true);
         // wait for finishing of request
-        timeout_ms = 120000; // 20 min = 1200 sec = 1 200 000 ms
+        timeout_ms = 1200000; // 20 min = 1200 sec = 1 200 000 ms
         // TODO add progress info to console
         res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms);
         if(res < 0) {
@@ -1199,12 +1199,14 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         dap_chain_t *l_chain = NULL;
         DL_FOREACH(l_net->pub.chains, l_chain)
         {
+            // reset state NODE_CLIENT_STATE_SYNCED
+            l_node_client->state = NODE_CLIENT_STATE_CONNECTED;
             // send request
             dap_stream_ch_chain_sync_request_t l_sync_request = { { 0 } };
             if(0 == dap_stream_ch_chain_pkt_write(l_ch_chain, DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_CHAINS,
                     l_net->pub.id, l_chain->id, l_remote_node_info->hdr.cell_id, &l_sync_request,
                     sizeof(l_sync_request))) {
-                dap_chain_node_cli_set_reply_text(a_str_reply, "Error: Cant send sync chains request");
+                dap_chain_node_cli_set_reply_text(a_str_reply, "Error: Can't send sync chains request");
                 // clean client struct
                 dap_chain_node_client_close(l_node_client);
                 DAP_DELETE(l_remote_node_info);
@@ -1217,6 +1219,9 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
             timeout_ms = 120000; // 2 min = 120 sec = 120 000 ms
             // TODO add progress info to console
             res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms);
+            if(res < 0) {
+                log_it(L_ERROR, "Error: Can't sync chain %s", l_chain->name);
+            }
         }
         log_it(L_INFO, "Chains and gdb are synced");
         DAP_DELETE(l_remote_node_info);
@@ -1575,6 +1580,8 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
     dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-w", &wallet_name);
     dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-net", &l_net_name); // for
 
+    dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name( l_net_name) : NULL;
+
     dap_string_t *l_string_ret = dap_string_new(NULL);
     switch (cmd_num) {
     // new wallet
@@ -1584,18 +1591,18 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
                     "wallet name option <-w>  not defined");
             return -1;
         }
-        dap_chain_sign_type_t l_sign_type = { SIG_TYPE_BLISS };
-        dap_chain_net_id_t l_net_id = { 0x1 };
+        dap_sign_type_t l_sign_type = { SIG_TYPE_BLISS };
         // Creates new wallet
-        dap_chain_wallet_t *l_wallet = dap_chain_wallet_create(wallet_name, c_wallets_path, l_net_id, l_sign_type);
-        dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
-        if(!l_wallet || !l_addr) {
+        dap_chain_wallet_t *l_wallet = dap_chain_wallet_create(wallet_name, c_wallets_path,  l_sign_type);
+        dap_chain_addr_t *l_addr = l_net? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL;
+        if(!l_wallet ) {
             dap_chain_node_cli_set_reply_text(str_reply, "wallet is not created");
             return -1;
         }
-        char *l_addr_str = dap_chain_addr_to_str(l_addr);
+        char *l_addr_str = l_addr? dap_chain_addr_to_str(l_addr) : NULL;
         dap_string_append_printf(l_string_ret, "wallet '%s' successfully created\n", l_wallet->name);
-        dap_string_append_printf(l_string_ret, "new address %s", l_addr_str);
+        if ( l_addr_str )
+            dap_string_append_printf(l_string_ret, "new address %s", l_addr_str);
         DAP_DELETE(l_addr_str);
         dap_chain_wallet_close(l_wallet);
     }
@@ -1612,11 +1619,13 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
                     char *l_file_path_tmp = dap_strdup_printf("%s/%s", c_wallets_path, l_file_name);
                     dap_chain_wallet_t *l_wallet = dap_chain_wallet_open_file(l_file_path_tmp);
                     if(l_wallet) {
-                        dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(l_wallet);
+                        dap_chain_addr_t *l_addr = l_net? dap_chain_wallet_get_addr(l_wallet, l_net->pub.id) : NULL;
                         char *l_addr_str = dap_chain_addr_to_str(l_addr);
                         dap_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name);
-                        dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
-                        DAP_DELETE(l_addr_str);
+                        if ( l_addr_str){
+                            dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-");
+                            DAP_DELETE(l_addr_str);
+                        }
                         dap_chain_wallet_close(l_wallet);
                     }
                     DAP_DELETE(l_file_path_tmp);
@@ -1634,7 +1643,8 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
 
         if(wallet_name) {
             l_wallet = dap_chain_wallet_open(wallet_name, c_wallets_path);
-            l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
+            if ( l_net )
+                l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id );
         }
         if(!l_addr && addr_str)
             l_addr = dap_chain_addr_from_str(addr_str);
@@ -1774,7 +1784,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
 
     if(l_datum_hash_str) {
         const char * l_certs_str = NULL;
-        dap_chain_cert_t ** l_certs = NULL;
+        dap_cert_t ** l_certs = NULL;
         size_t l_certs_count = 0;
         dap_chain_t * l_chain;
 
@@ -1795,7 +1805,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
 
         // Load certs lists
         if (l_certs_str)
-            dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count);
+            dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count);
 
         if(!l_certs_count) {
             dap_chain_node_cli_set_reply_text(a_str_reply,
@@ -1826,9 +1836,9 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
                 size_t l_signs_count = 0;
 
                 for(size_t l_offset = 0; l_offset < l_signs_size; l_signs_count++) {
-                    dap_chain_sign_t * l_sign = (dap_chain_sign_t *) l_datum_token->signs + l_offset;
-                    l_offset += dap_chain_sign_get_size(l_sign);
-                    if( dap_chain_sign_verify(l_sign, l_datum_token, sizeof(l_datum_token->header)) != 1) {
+                    dap_sign_t * l_sign = (dap_sign_t *) l_datum_token->signs + l_offset;
+                    l_offset += dap_sign_get_size(l_sign);
+                    if( dap_sign_verify(l_sign, l_datum_token, sizeof(l_datum_token->header)) != 1) {
                         log_it(L_WARNING, "Wrong signature %u for datum_token with key %s in mempool!", l_signs_count, l_datum_hash_str);
                         dap_chain_node_cli_set_reply_text(a_str_reply,
                                 "Datum %s with datum token has wrong signature %u, break process and exit",
@@ -1865,10 +1875,10 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
                 else if(l_datum_token->header.signs_total >= l_signs_count + l_certs_count) {
                     size_t l_offset = 0;
                     for(size_t i = 0; i < l_certs_count; i++) {
-                        dap_chain_sign_t * l_sign = dap_chain_sign_create(l_certs[i]->enc_key,
+                        dap_sign_t * l_sign = dap_sign_create(l_certs[i]->enc_key,
                                 l_datum_token,
                                 sizeof(l_datum_token->header), 0);
-                        size_t l_sign_size = dap_chain_sign_get_size(l_sign);
+                        size_t l_sign_size = dap_sign_get_size(l_sign);
 
 
                         l_signs_size+= l_sign_size;
@@ -1894,14 +1904,15 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
                     // Recalc hash, string and place new datum
 
                     // Calc datum's hash
-                    dap_chain_hash_fast_t l_key_hash;
-                    dap_hash_fast(l_datum, l_datum_size, (uint8_t*) &l_key_hash);
+                    dap_chain_hash_fast_t l_key_hash={0};
+                    dap_hash_fast(l_datum, l_datum_size, &l_key_hash);
                     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
 
                     // Add datum to mempool with datum_token hash as a key
                     if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, l_datum_size, l_gdb_group_mempool)) {
+                        char* l_hash_str = strdup(l_datum_hash_str);
                         // Remove old datum from pool
-                        if(dap_chain_global_db_gr_del(l_datum_hash_str, l_gdb_group_mempool)) {
+                        if(dap_chain_global_db_gr_del( l_hash_str, l_gdb_group_mempool)) {
                             dap_chain_node_cli_set_reply_text(a_str_reply,
                                     "datum %s produced from %s is replacing the %s in datum pool",
                                     l_key_str, l_datum_hash_str, l_datum_hash_str);
@@ -1919,6 +1930,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
                             DAP_DELETE(l_gdb_group_mempool);
                             return 1;
                         }
+                        DAP_DELETE(l_hash_str);
 
                     }
                     else {
@@ -2056,12 +2068,15 @@ int com_mempool_delete(int argc, char ** argv, char ** a_str_reply)
         const char * l_datum_hash_str = NULL;
         dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-datum", &l_datum_hash_str);
         if(l_datum_hash_str) {
+            char * l_datum_hash_str2 = strdup(l_datum_hash_str);
             char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain);
-            if(dap_chain_global_db_gr_del(l_datum_hash_str, l_gdb_group_mempool)) {
+            if(dap_chain_global_db_gr_del(l_datum_hash_str2, l_gdb_group_mempool)) {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Datum %s deleted", l_datum_hash_str);
+                DAP_DELETE( l_datum_hash_str2);
                 return 0;
             } else {
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Can't find datum %s", l_datum_hash_str);
+                DAP_DELETE( l_datum_hash_str2);
                 return -4;
             }
         } else {
@@ -2146,10 +2161,13 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply)
             if(l_objs_processed > 15) {
                 dap_string_append_printf(l_str_tmp, "...\n");
             }
+            if(l_objs_processed < l_datums_size)
+                dap_string_append_printf(l_str_tmp, "%s.%s: %d records not processed\n", l_net->pub.name, l_chain->name,
+                        l_datums_size - l_objs_processed);
             dap_chain_global_db_objs_delete(l_objs, l_objs_size);
         }
         else {
-            dap_string_append_printf(l_str_tmp, "%s.%s: No records in mempool\n", l_net->pub.name, l_chain->name);
+            dap_string_append_printf(l_str_tmp, "%s.%s: No records in mempool\n", l_net->pub.name, l_chain ? l_chain->name : "[no chain]");
         }
         DAP_DELETE(l_gdb_group_mempool);
         // only one time if group defined
@@ -2184,7 +2202,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
 
     const char * l_certs_str = NULL;
 
-    dap_chain_cert_t ** l_certs = NULL;
+    dap_cert_t ** l_certs = NULL;
     size_t l_certs_size = 0;
 
     dap_chain_t * l_chain = NULL;
@@ -2266,7 +2284,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
     }
 
     // Load certs lists
-    dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size);
+    dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size);
     if(!l_certs_size) {
         dap_chain_node_cli_set_reply_text(a_str_reply,
                 "token_create command requres at least one valid certificate to sign the basic transaction of emission");
@@ -2289,11 +2307,11 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
     // Sign header with all certificates in the list and add signs to the end of ticker declaration
     // Important:
     for(size_t i = 0; i < l_certs_size; i++) {
-        dap_chain_sign_t * l_sign = dap_chain_cert_sign(l_certs[i],
+        dap_sign_t * l_sign = dap_cert_sign(l_certs[i],
                 l_datum_token,
                 sizeof(l_datum_token->header),
                 0);
-        size_t l_sign_size = dap_chain_sign_get_size(l_sign);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
         l_datum_token = DAP_REALLOC(l_datum_token, sizeof(l_datum_token->header) + l_signs_offset + l_sign_size);
         memcpy(l_datum_token->signs + l_signs_offset, l_sign, l_sign_size);
         l_signs_offset += l_sign_size;
@@ -2305,7 +2323,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
 
     // Calc datum's hash
     dap_chain_hash_fast_t l_key_hash;
-    dap_hash_fast(l_datum, l_datum_size, (uint8_t*) &l_key_hash);
+    dap_hash_fast(l_datum, l_datum_size, &l_key_hash);
     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
 
     // Add datum to mempool with datum_token hash as a key
@@ -2355,7 +2373,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
 
     const char * l_certs_str = NULL;
 
-    dap_chain_cert_t ** l_certs = NULL;
+    dap_cert_t ** l_certs = NULL;
     size_t l_certs_size = 0;
 
     const char * l_chain_emission_str = NULL;
@@ -2402,7 +2420,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
     }
 
     // Load certs
-    dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size);
+    dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size);
 
     if(!l_certs_size) {
         dap_chain_node_cli_set_reply_text(str_reply,
@@ -2498,9 +2516,9 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
     // Then add signs
     size_t l_offset = 0;
     for(size_t i = 0; i < l_certs_size; i++) {
-        dap_chain_sign_t * l_sign = dap_chain_cert_sign(l_certs[i], &l_token_emission->hdr,
+        dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_token_emission->hdr,
                 sizeof(l_token_emission->hdr), 0);
-        size_t l_sign_size = dap_chain_sign_get_size(l_sign);
+        size_t l_sign_size = dap_sign_get_size(l_sign);
         l_token_emission_size += l_sign_size;
         l_token_emission = DAP_REALLOC(l_token_emission, l_token_emission_size);
         memcpy(l_token_emission->data.type_auth.signs + l_offset, l_sign, l_sign_size);
@@ -2516,7 +2534,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
 
     // Calc token's hash
     dap_chain_hash_fast_t l_token_emission_hash;
-    dap_hash_fast(l_token_emission, l_token_emission_size, (uint8_t*) &l_token_emission_hash);
+    dap_hash_fast(l_token_emission, l_token_emission_size, &l_token_emission_hash);
     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_token_emission_hash);
 
     // Delete token emission
@@ -2577,12 +2595,12 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
     //dap_hash_fast(l_tx, l_tx_size, &l_key_hash); //dap_hash_fast(l_datum_tx, l_datum_tx_size, &l_key_hash);
     // calc datum hash
     dap_chain_hash_fast_t l_datum_tx_hash;
-    dap_hash_fast(l_datum_tx, l_datum_tx_size, (uint8_t*) &l_datum_tx_hash);
+    dap_hash_fast(l_datum_tx, l_datum_tx_size,  &l_datum_tx_hash);
     l_key_str = dap_chain_hash_fast_to_str_new(&l_datum_tx_hash);
     DAP_DELETE(l_tx);
 
     // Add to mempool tx token
-    if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum_tx, l_datum_tx_size
+    if(dap_chain_global_db_gr_set(l_key_str, l_datum_tx, l_datum_tx_size
             , l_gdb_group_mempool_base_tx)) {
         dap_chain_node_cli_set_reply_text(str_reply, "%s\ndatum tx %s is placed in datum pool ", str_reply_tmp,
                 l_key_str);
@@ -2608,19 +2626,12 @@ int com_tx_cond_create(int argc, char ** argv, char **str_reply)
 {
     (void) argc;
     // test
+    /*
     const char * l_token_ticker = NULL;
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
     const char *c_wallet_name_from = "w_tesla"; // where to take coins for service
     const char *c_wallet_name_cond = "w_picnic"; // who will be use service, usually the same address (addr_from)
-//    const char *c_net_name = "kelvin-testnet";
     uint64_t l_value = 50;
-    //debug
-    {
-//        dap_chain_wallet_t * l_wallet_tesla = dap_chain_wallet_open("w_picnic", c_wallets_path);
-//        const dap_chain_addr_t *l_addr_tesla = dap_chain_wallet_get_addr(l_wallet_tesla);
-        //      char *addr = dap_chain_addr_to_str(l_addr_tesla);
-//        addr = 0;
-    }
 
     dap_chain_wallet_t *l_wallet_from = dap_chain_wallet_open(c_wallet_name_from, c_wallets_path);
     dap_enc_key_t *l_key = dap_chain_wallet_get_key(l_wallet_from, 0);
@@ -2645,6 +2656,8 @@ int com_tx_cond_create(int argc, char ** argv, char **str_reply)
     dap_chain_node_cli_set_reply_text(str_reply, "cond create=%s\n",
             (res == 0) ? "Ok" : (res == -2) ? "False, not enough funds for service fee" : "False");
     return res;
+    */
+    return  -1;
 }
 
 /**
@@ -2737,7 +2750,7 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
         dap_chain_node_cli_set_reply_text(str_reply, "wallet %s does not exist", l_from_wallet_name);
         return -1;
     }
-    const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
+    const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
     dap_chain_addr_t *addr_to = dap_chain_addr_from_str(addr_base58_to);
     dap_chain_addr_t *addr_fee = dap_chain_addr_from_str(addr_base58_fee);
 
@@ -2867,7 +2880,7 @@ int com_tx_history(int argc, char ** argv, char **str_reply)
             const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
             dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path);
             if(l_wallet) {
-                dap_chain_addr_t *l_addr_tmp = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet);
+                dap_chain_addr_t *l_addr_tmp = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
                 l_addr = DAP_NEW_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t));
                 memcpy(l_addr, l_addr_tmp, sizeof(dap_chain_addr_t));
                 dap_chain_wallet_close(l_wallet);
@@ -2949,6 +2962,7 @@ int com_print_log(int argc, char ** argv, char **str_reply)
  */
 int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply)
 {
+#ifndef _WIN32
     enum {
         CMD_NONE, CMD_START, CMD_STOP, CMD_STATUS
     };
@@ -3037,5 +3051,6 @@ int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply)
         }
         break;
     }
+#endif
     return 0;
 }
diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c
index ee356a4b046cdb440ddf3e73aa464f9685243348..0ece420862ece432ad250fe4330e35a779efa46e 100644
--- a/dap_chain_node_client.c
+++ b/dap_chain_node_client.c
@@ -46,8 +46,10 @@
 #include "dap_client.h"
 #include "dap_config.h"
 #include "dap_events.h"
+#include "dap_hash.h"
 #include "dap_http_client_simple.h"
 #include "dap_client_pvt.h"
+#include "dap_chain_global_db_remote.h"
 #include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_chain.h"
 #include "dap_stream_ch_chain_pkt.h"
@@ -292,7 +294,11 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
             l_request = (dap_stream_ch_chain_sync_request_t*) a_pkt->data;
 
         if(l_request) {
-            if(l_request->id_start < (uint64_t) dap_db_log_get_last_id()) {
+            uint64_t l_id_last_here = 1;
+            // for sync chain not used time
+            if(a_pkt_type != DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS)
+                l_id_last_here =(uint64_t) dap_db_log_get_last_id();
+            if(l_request->id_start < l_id_last_here) {
                 log_it(L_INFO, "Remote is synced but we have updates for it");
                 // Get log diff
                 a_ch_chain->request_last_ts = dap_db_log_get_last_id();
@@ -305,12 +311,44 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
                     a_ch_chain->request_net_id.uint64 = a_pkt->hdr.net_id.uint64;
                     a_ch_chain->request_cell_id.uint64 = a_pkt->hdr.cell_id.uint64;
                     a_ch_chain->request_chain_id.uint64 = a_pkt->hdr.chain_id.uint64;
-                    a_ch_chain->state = CHAIN_STATE_SYNC_GLOBAL_DB;
-
+                    a_ch_chain->state = dap_stream_ch_chain_pkt_type_to_dap_stream_ch_chain_state(a_pkt_type);//CHAIN_STATE_SYNC_CHAINS;//GLOBAL_DB;
+
+                    // type of first packet
+                    uint8_t l_type =
+                            (a_pkt_type != DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS) ?
+                                    DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB :
+                                    DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_CHAIN;
+                    if(l_type == DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_CHAIN)
+                    {
+                        dap_chain_t * l_chain = dap_chain_find_by_id(a_pkt->hdr.net_id, a_pkt->hdr.chain_id);
+                        dap_chain_atom_iter_t* l_iter = l_chain ? l_chain->callback_atom_iter_create(l_chain) : NULL;
+                        //a_ch_chain->request_atom_iter = l_iter;
+
+                        dap_chain_atom_ptr_t * l_lasts = NULL;
+                        size_t l_lasts_size = 0;
+                        l_lasts = l_chain->callback_atom_iter_get_lasts(l_iter, &l_lasts_size);
+                        for(size_t i = 0; i < l_lasts_size; i++) {
+                            dap_chain_atom_item_t * l_item = NULL;
+                            dap_chain_hash_fast_t l_atom_hash;
+                            dap_hash_fast(l_lasts[i], l_chain->callback_atom_get_size(l_lasts[i]),
+                                    &l_atom_hash);
+                            HASH_FIND(hh, a_ch_chain->request_atoms_lasts, &l_atom_hash, sizeof(l_atom_hash), l_item);
+                            if(l_item == NULL) { // Not found, add new lasts
+                                l_item = DAP_NEW_Z(dap_chain_atom_item_t);
+                                l_item->atom = l_lasts[i];
+                                memcpy(&l_item->atom_hash, &l_atom_hash, sizeof(l_atom_hash));
+                                HASH_ADD(hh, a_ch_chain->request_atoms_lasts, atom_hash, sizeof(l_atom_hash), l_item);
+                            }
+                            else
+                                DAP_DELETE(l_lasts[i]);
+                        }
+                        DAP_DELETE(l_lasts);
+                        DAP_DELETE(l_iter);
+                    }
                     dap_chain_node_addr_t l_node_addr = { 0 };
                     dap_chain_net_t *l_net = dap_chain_net_by_id(a_ch_chain->request_net_id);
-                    l_node_addr.uint64 = dap_db_get_cur_node_addr(l_net->pub.name);
-                    dap_stream_ch_chain_pkt_write(a_ch_chain->ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB,
+                    l_node_addr.uint64 = l_net ? dap_db_get_cur_node_addr(l_net->pub.name) : 0;
+                    dap_stream_ch_chain_pkt_write(a_ch_chain->ch, l_type,
                             a_ch_chain->request_net_id, a_ch_chain->request_chain_id,
                             a_ch_chain->request_cell_id, &l_node_addr, sizeof(dap_chain_node_addr_t));