diff --git a/CMakeLists.txt b/CMakeLists.txt
index e76fe08b19986df15fac42097b39de210b864318..d5845470692e5e312a80ba25df6dfeff4ad3d5a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,11 +58,11 @@ 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_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_net_srv_vpn dap_chain_mempool dap_chain_global_db )
 endif()
 
 if(UNIX)
-  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_chain_gdb dap_stream_ch_chain_net dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db -lresolv)
+  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_chain_gdb dap_stream_ch_chain_net dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_net_srv_vpn dap_chain_mempool dap_chain_global_db -lresolv)
 endif()
 
 target_include_directories(dap_chain_net INTERFACE . PUBLIC ${IPUTILS_INCLUDE_DIRS})
diff --git a/dap_chain_net.c b/dap_chain_net.c
index c5b23d2a10da93a920a8a26668ce36d702443ee0..604e6c05f4fb4eb2d97658e3dc7863ede8b06482 100644
--- a/dap_chain_net.c
+++ b/dap_chain_net.c
@@ -278,6 +278,7 @@ lb_proc_state:
                     // If we haven't any assigned shard - connect to root-0
                 if(l_net->pub.cell_id.uint64 == 0) {
 
+                    dap_chain_net_pvt_t *pvt_debug = PVT(l_net);
                     // get current node address
                     dap_chain_node_addr_t l_address;
                     l_address.uint64 = dap_chain_net_get_cur_addr(l_net) ?
@@ -307,9 +308,12 @@ lb_proc_state:
                     }
                     // add root nodes for connect
                     if(!PVT(l_net)->links_addrs_count){
+                        // use no more then 4 root node
+                        int l_use_root_nodes = min(4, PVT(l_net)->seed_aliases_count);
                         PVT(l_net)->links_addrs = DAP_NEW_Z_SIZE(dap_chain_node_addr_t,
-                                min(1, PVT(l_net)->seed_aliases_count) * sizeof(dap_chain_node_addr_t));
-                        for(uint16_t i = 0; i < min(1, PVT(l_net)->seed_aliases_count); i++) {
+                                l_use_root_nodes * sizeof(dap_chain_node_addr_t));
+
+                        for(uint16_t i = 0; i < l_use_root_nodes; i++) {
                             dap_chain_node_addr_t * l_node_addr = dap_chain_node_alias_find(l_net, PVT(l_net)->seed_aliases[i]);
                             if(l_node_addr) {
                                 PVT(l_net)->links_addrs[PVT(l_net)->links_addrs_count].uint64 = l_node_addr->uint64;
@@ -617,7 +621,7 @@ static void *s_net_proc_thread ( void *a_net )
 
         struct timespec l_to;
         clock_gettime( CLOCK_MONOTONIC, &l_to );
-        int64_t l_nsec_new = l_to.tv_nsec + l_timeout_ms * 1000000ll;
+        int64_t l_nsec_new = l_to.tv_nsec + l_timeout_ms * 10000000ll;
 
         // if the new number of nanoseconds is more than a second
         if(l_nsec_new > (long) 1e9) {
@@ -1116,6 +1120,7 @@ int s_net_load(const char * a_net_name)
         const char * l_node_alias_str = dap_config_get_item_str(l_cfg , "general" , "node-alias");
         log_it (L_DEBUG, "Read %u aliases, %u address and %u ipv4 addresses, check them",
                 PVT(l_net)->seed_aliases_count,l_seed_nodes_addrs_len, l_seed_nodes_ipv4_len );
+        // save new nodes from cfg file to db
         for ( size_t i = 0; i < PVT(l_net)->seed_aliases_count &&
                             i < l_seed_nodes_addrs_len &&
                             i < l_seed_nodes_ipv4_len
@@ -1137,8 +1142,10 @@ int s_net_load(const char * a_net_name)
                 if( l_seed_node_addr ){
                     inet_pton( AF_INET, l_seed_nodes_ipv4[i],&l_node_info->hdr.ext_addr_v4);
                     l_node_info->hdr.address.uint64 = l_seed_node_addr->uint64;
-                    if(l_seed_nodes_port_len >= i)
+                    if(l_seed_nodes_port_len && l_seed_nodes_port_len >= i)
                         l_node_info->hdr.ext_port = strtoul(l_seed_nodes_port[i], NULL, 10);
+                    else
+                        l_node_info->hdr.ext_port = 8079;
                     int l_ret;
                     if ( (l_ret = dap_chain_node_info_save(l_net, l_node_info)) ==0 ){
                         if (dap_chain_node_alias_register(l_net,PVT(l_net)->seed_aliases[i],l_seed_node_addr))
@@ -1204,6 +1211,13 @@ int s_net_load(const char * a_net_name)
 
 
          }
+/*        // if present 'l_node_ipv4_str' and no 'l_node_addr_str' and 'l_node_alias_str'
+        if(!PVT(l_net)->node_info && l_node_ipv4_str) {
+            dap_chain_node_info_t *l_node_info = DAP_NEW_Z(dap_chain_node_info_t);
+            inet_pton( AF_INET, l_node_ipv4_str, &l_node_info->hdr.ext_addr_v4);
+            PVT(l_net)->node_info = l_node_info;
+        }*/
+
         // Init chains
         //size_t l_chains_path_size =strlen(dap_config_path())+1+strlen(l_net->pub.name)+1+strlen("network")+1;
         //char * l_chains_path = DAP_NEW_Z_SIZE (char,l_chains_path_size);
diff --git a/dap_chain_node_cli.c b/dap_chain_node_cli.c
index ad4d2a0c99cf5fd0d070c80be2795d8242790820..b798cb3833b383c6dec8496a80706961a316da4c 100644
--- a/dap_chain_node_cli.c
+++ b/dap_chain_node_cli.c
@@ -847,6 +847,12 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
     // Transaction history
     dap_chain_node_cli_cmd_item_create("tx_history", com_tx_history, "Transaction history (for address or by hash)",
             "tx_history  [-addr <addr> | -w <wallet name> | -tx <tx_hash>] -net <net name> -chain <chain name>\n");
+
+    // vpn client
+    dap_chain_node_cli_cmd_item_create ("vpn_client", com_vpn_client, "VPN client control",
+    "vpn_client [start | stop | status]\n");
+
+
     // Log
     dap_chain_node_cli_cmd_item_create ("print_log", com_print_log, "Print log info",
                 "print_log [ts_after <timestamp >] [limit <line numbers>]\n" );
diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index c1e9ca101223ee102cb1b4e5833514881aad36b9..9b46b0446070e84edeb070333854403df54a6e23 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -94,14 +94,15 @@
  *
  * return addr, NULL if not found
  */
-dap_chain_node_addr_t* dap_chain_node_addr_get_by_alias( dap_chain_net_t * a_net, const char *a_alias)
+dap_chain_node_addr_t* dap_chain_node_addr_get_by_alias(dap_chain_net_t * a_net, const char *a_alias)
 {
     dap_chain_node_addr_t *l_addr = NULL;
     if(!a_alias)
         return NULL;
     const char *a_key = a_alias;
     size_t l_addr_size = 0;
-    l_addr = (dap_chain_node_addr_t*) (void*) dap_chain_global_db_gr_get(a_key, &l_addr_size, a_net->pub.gdb_nodes_aliases);
+    l_addr = (dap_chain_node_addr_t*) (void*) dap_chain_global_db_gr_get(a_key, &l_addr_size,
+            a_net->pub.gdb_nodes_aliases);
     if(l_addr_size != sizeof(dap_chain_node_addr_t)) {
 //        l_addr = DAP_NEW_Z(dap_chain_node_addr_t);
 //        if(hex2bin((char*) l_addr, (const unsigned char *) addr_str, sizeof(dap_chain_node_addr_t) * 2) == -1) {
@@ -159,7 +160,8 @@ static dap_chain_node_addr_t* node_info_get_addr(dap_chain_net_t * a_net, dap_ch
 /**
  * Read node from base
  */
-static dap_chain_node_info_t* node_info_read_and_reply(dap_chain_net_t * a_net, dap_chain_node_addr_t *a_address, char **a_str_reply)
+static dap_chain_node_info_t* node_info_read_and_reply(dap_chain_net_t * a_net, dap_chain_node_addr_t *a_address,
+        char **a_str_reply)
 {
     char *l_key = dap_chain_node_addr_to_hash_str(a_address);
     if(!l_key)
@@ -177,6 +179,8 @@ static dap_chain_node_info_t* node_info_read_and_reply(dap_chain_net_t * a_net,
         DAP_DELETE(l_key);
         return NULL;
     }
+    if(!node_info->hdr.ext_port)
+        node_info->hdr.ext_port = 8079;
     size_t node_info_size_must_be = dap_chain_node_info_get_size(node_info);
     if(node_info_size_must_be != node_info_size) {
         dap_chain_node_cli_set_reply_text(a_str_reply, "node has bad size in base=%u (must be %u)", node_info_size,
@@ -212,7 +216,7 @@ static bool node_info_save_and_reply(dap_chain_net_t * a_net, dap_chain_node_inf
     }
     //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(a_key, (const uint8_t *) node_info, node_info_size,a_net->pub.gdb_nodes);
+    bool res = dap_chain_global_db_gr_set(a_key, (const uint8_t *) node_info, node_info_size, a_net->pub.gdb_nodes);
     DAP_DELETE(a_key);
     //DAP_DELETE(a_value);
     return res;
@@ -224,7 +228,8 @@ static bool node_info_save_and_reply(dap_chain_net_t * a_net, dap_chain_node_inf
  * str_reply[out] for reply
  * return 0 Ok, -1 error
  */
-static int node_info_add_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info, const char *a_alias_str,
+static int node_info_add_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info,
+        const char *a_alias_str,
         const char *a_cell_str, const char *a_ipv4_str, const char *a_ipv6_str, char **a_str_reply)
 {
 
@@ -249,7 +254,7 @@ static int node_info_add_with_reply(dap_chain_net_t * a_net, dap_chain_node_info
      }*/
     if(a_alias_str) {
         // add alias
-        if(!dap_chain_node_alias_register( a_net, a_alias_str, &a_node_info->hdr.address)) {
+        if(!dap_chain_node_alias_register(a_net, a_alias_str, &a_node_info->hdr.address)) {
             log_it(L_WARNING, "can't save alias %s", a_alias_str);
             dap_chain_node_cli_set_reply_text(a_str_reply, "alias '%s' can't be mapped to addr=0x%lld",
                     a_alias_str, a_node_info->hdr.address.uint64);
@@ -258,7 +263,7 @@ static int node_info_add_with_reply(dap_chain_net_t * a_net, dap_chain_node_info
     }
 
     // write to base
-    bool res = node_info_save_and_reply(a_net,a_node_info, a_str_reply);
+    bool res = node_info_save_and_reply(a_net, a_node_info, a_str_reply);
     if(res)
         dap_chain_node_cli_set_reply_text(a_str_reply, "node added");
     else
@@ -274,7 +279,8 @@ static int node_info_add_with_reply(dap_chain_net_t * a_net, dap_chain_node_info
  * str_reply[out] for reply
  * return 0 Ok, -1 error
  */
-static int node_info_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info, const char *alias_str, char **str_reply)
+static int node_info_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info, const char *alias_str,
+        char **str_reply)
 {
     if(!a_node_info->hdr.address.uint64 && !alias_str) {
         dap_chain_node_cli_set_reply_text(str_reply, "addr not found");
@@ -334,7 +340,8 @@ static int node_info_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_info
  * str_reply[out] for reply
  * return 0 Ok, -1 error
  */
-static int link_add_or_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info, const char *cmd, const char *a_alias_str,
+static int link_add_or_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_info_t *a_node_info, const char *cmd,
+        const char *a_alias_str,
         dap_chain_node_addr_t *link, char **a_str_reply)
 {
     if(!a_node_info->hdr.address.uint64 && !a_alias_str) {
@@ -442,7 +449,8 @@ static int link_add_or_del_with_reply(dap_chain_net_t * a_net, dap_chain_node_in
  * str_reply[out] for reply
  * return 0 Ok, -1 error
  */
-static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_addr_t * a_addr, bool a_is_full, const char *a_alias, char **a_str_reply)
+static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_addr_t * a_addr, bool a_is_full,
+        const char *a_alias, char **a_str_reply)
 {
     int l_ret = 0;
     dap_string_t *l_string_reply = dap_string_new("Node dump:");
@@ -462,7 +470,7 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
         }
         // read node
         dap_chain_node_info_t *node_info_read = node_info_read_and_reply(a_net, l_addr, a_str_reply);
-        if(!node_info_read){
+        if(!node_info_read) {
             DAP_DELETE(l_addr);
             dap_string_free(l_string_reply, true);
             return -2;
@@ -524,13 +532,12 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
         DAP_DELETE(l_addr);
         DAP_DELETE(node_info_read);
 
-
-    }else { // Dump list
+    } else { // Dump list
         dap_global_db_obj_t *l_objs = NULL;
         size_t l_nodes_count = 0;
         dap_string_append(l_string_reply, "\n");
         // read all node
-        l_objs = dap_chain_global_db_gr_load( a_net->pub.gdb_nodes, &l_nodes_count);
+        l_objs = dap_chain_global_db_gr_load(a_net->pub.gdb_nodes, &l_nodes_count);
 
         if(!l_nodes_count || !l_objs) {
             dap_string_append_printf(l_string_reply, "No records\n");
@@ -538,13 +545,14 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
             dap_string_free(l_string_reply, true);
             dap_chain_global_db_objs_delete(l_objs, l_nodes_count);
             return -1;
-        }else {
+        } else {
             size_t l_nodes_count_real = 0;
-            dap_string_append_printf(l_string_reply,"Got %u records:\n",l_nodes_count);
+            dap_string_append_printf(l_string_reply, "Got %u records:\n", l_nodes_count);
             for(size_t i = 0; i < l_nodes_count; i++) {
-                dap_chain_node_info_t *l_node_info =  (dap_chain_node_info_t *) l_objs[i].value;
+                dap_chain_node_info_t *l_node_info = (dap_chain_node_info_t *) l_objs[i].value;
                 // find addr by alias or addr_str
-                dap_chain_node_addr_t *address = node_info_get_addr(a_net, l_node_info, &l_node_info->hdr.address, a_alias);
+                dap_chain_node_addr_t *address = node_info_get_addr(a_net, l_node_info, &l_node_info->hdr.address,
+                        a_alias);
                 if(!address) {
                     dap_chain_node_cli_set_reply_text(a_str_reply, "alias not found");
                     dap_string_free(l_string_reply, true);
@@ -552,7 +560,7 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
                     return -1;
                 }
                 // read node
-                dap_chain_node_info_t *node_info_read = node_info_read_and_reply( a_net, address, NULL);
+                dap_chain_node_info_t *node_info_read = node_info_read_and_reply(a_net, address, NULL);
                 if(!node_info_read) {
                     DAP_DELETE(address);
                     continue;
@@ -572,7 +580,7 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
 
                 // get aliases in form of string
                 dap_string_t *aliases_string = dap_string_new(NULL);
-                dap_list_t *list_aliases = get_aliases_by_name(a_net,address);
+                dap_list_t *list_aliases = get_aliases_by_name(a_net, address);
                 if(list_aliases)
                 {
                     dap_list_t *list = list_aliases;
@@ -592,7 +600,7 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
                 for(unsigned int i = 0; i < node_info_read->hdr.links_number; i++) {
                     dap_chain_node_addr_t link_addr = node_info_read->links[i];
                     dap_string_append_printf(links_string, "\nlink%02d address : " NODE_ADDR_FP_STR, i,
-                                             NODE_ADDR_FP_ARGS_S(link_addr) );
+                            NODE_ADDR_FP_ARGS_S(link_addr));
                 }
 
                 if(i)
@@ -619,14 +627,13 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
                 DAP_DELETE(node_info_read);
             }
         }
-    dap_chain_global_db_objs_delete(l_objs, l_nodes_count);
+        dap_chain_global_db_objs_delete(l_objs, l_nodes_count);
     }
     dap_chain_node_cli_set_reply_text(a_str_reply, l_string_reply->str);
     dap_string_free(l_string_reply, true);
     return l_ret;
 }
 
-
 /**
  * global_db command
  *
@@ -636,9 +643,10 @@ static int node_info_dump_with_reply(dap_chain_net_t * a_net, dap_chain_node_add
 int com_global_db(int a_argc, char ** a_argv, char **a_str_reply)
 {
     enum {
-        CMD_NONE, CMD_NAME_CELL, CMD_ADD };
+        CMD_NONE, CMD_NAME_CELL, CMD_ADD
+    };
     int arg_index = 1;
-    int cmd_name =  CMD_NONE;
+    int cmd_name = CMD_NONE;
     // find 'cells' as first parameter only
     arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "cells", NULL);
     if(arg_index)
@@ -689,17 +697,17 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply)
             dap_chain_cell_t *l_cell = dap_chain_cell_create();
             l_cell->chain = l_chain;
             l_cell->id.uint64 = l_cell_id.uint64;
-            l_cell->file_storage_path = dap_strdup_printf("%0llx.dchaincell",l_cell->id.uint64);
+            l_cell->file_storage_path = dap_strdup_printf("%0llx.dchaincell", l_cell->id.uint64);
             int l_ret = dap_chain_cell_file_update(l_cell);
             if(!l_ret)
                 dap_chain_node_cli_set_reply_text(a_str_reply, "cell added successfully");
             else
                 dap_chain_node_cli_set_reply_text(a_str_reply, "can't create file for cell 0x%016X ( %s )",
-                        l_cell->id.uint64,l_cell->file_storage_path);
+                        l_cell->id.uint64, l_cell->file_storage_path);
             dap_chain_cell_delete(l_cell);
             return l_ret;
 
-        //case CMD_NONE:
+            //case CMD_NONE:
         default:
             dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]);
             return -1;
@@ -709,147 +717,147 @@ int com_global_db(int a_argc, char ** a_argv, char **a_str_reply)
 }
 
 /*
-int com_global_db_prev(int a_argc, char ** a_argv, char **a_str_reply)
-{
-    enum {
-        CMD_NONE, CMD_NAME_NODE, CMD_NAME_CELL, CMD_ADD, CMD_DEL, CMD_LINK    };
-    //printf("com_global_db\n");
-    int arg_index = 1;
-    int cmd_name =  CMD_NONE;
-    // find 'node' as first parameter only
-    arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "node", NULL);
-    if(arg_index)
-                cmd_name =  CMD_NAME_NODE;
-    // find 'cells' as first parameter only
-    if(!arg_index) {
-        arg_index = 1;
-        arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "cells", NULL);
-        if(arg_index)
-            cmd_name =  CMD_NAME_CELL;
-    }
-    if(!arg_index || a_argc < 3) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "parameters are not valid");
-        return -1;
-    }
-    dap_chain_t * l_chain = NULL;
-    dap_chain_net_t * l_net = NULL;
-
-    if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0)
-        return -11;
-
-    int arg_index_n = ++arg_index;
-    // find command (add, delete, etc) as second parameter only
-    int cmd_num = CMD_NONE;
-    switch(cmd_name){
-    case CMD_NAME_NODE:
-        if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
-                != 0) {
-            cmd_num = CMD_ADD;
-        }
-        else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del",
-        NULL))
-                != 0) {
-            cmd_num = CMD_DEL;
-        }
-        else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "link",
-        NULL))
-                != 0) {
-            cmd_num = CMD_LINK;
-        }
-        break;
-
-    case CMD_NAME_CELL:
-        if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
-                != 0) {
-            cmd_num = CMD_ADD;
-        }
-    }
-
-    if(cmd_num == CMD_NONE) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]);
-        return -1;
-    }
-    //arg_index = arg_index_n; // no need, they are already equal must be
-    assert(arg_index == arg_index_n);
-    arg_index++;
-    const char *l_addr_str = NULL, *alias_str = NULL, *l_cell_str = NULL, *l_chain_str = NULL, *l_link_str = NULL;
-    const char *a_ipv4_str = NULL, *a_ipv6_str = NULL;
-    // find addr, alias
-
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-alias", &alias_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-cell", &l_cell_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv4", &a_ipv4_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv6", &a_ipv6_str);
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-link", &l_link_str);
-
-    // struct to write to the global db
-    dap_chain_node_addr_t l_link = { 0 };
-    dap_chain_node_info_t *l_node_info;
-    size_t l_node_info_size = sizeof(l_node_info->hdr) + sizeof(l_link);
-    l_node_info = DAP_NEW_Z_SIZE(dap_chain_node_info_t, l_node_info_size);
-
-    if(l_addr_str) {
-        dap_digit_from_string(l_addr_str, l_node_info->hdr.address.raw, sizeof(l_node_info->hdr.address.raw));
-    }
-    if(l_cell_str) {
-        dap_digit_from_string(l_cell_str, l_node_info->hdr.cell_id.raw, sizeof(l_node_info->hdr.cell_id.raw)); //DAP_CHAIN_CELL_ID_SIZE);
-    }
-    if(l_link_str) {
-        dap_digit_from_string(l_link_str, l_link.raw, sizeof(l_link.raw));
-    }
-
-    switch (cmd_num)
-    {
-    // add new node to global_db
-    case CMD_ADD:
-        if(cmd_name == CMD_NAME_NODE) {
-            if(!arg_index || a_argc < 8) {
-                dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
-                return -1;
-            }
-            // handler of command 'global_db node add'
-            return node_info_add_with_reply(l_net, l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str,
-                    a_str_reply);
-        }
-        else if(cmd_name == CMD_NAME_CELL) {
-            if(!arg_index || a_argc < 7) {
-                dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
-                return -1;
-            }
-            dap_chain_cell_t *l_cell = dap_chain_cell_create();
-            l_cell->chain = l_chain;
-            l_cell->id.uint64 = l_node_info->hdr.cell_id.uint64;
-            l_cell->file_storage_path = "234";
-            dap_chain_cell_file_update(l_cell);
-            DAP_DELETE(l_cell);
-
-        }
-        break;
-
-    case CMD_DEL:
-        // handler of command 'global_db node del'
-        return node_info_del_with_reply(l_net,l_node_info, alias_str, a_str_reply);
-    case CMD_LINK:
-        if(dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
-            // handler of command 'global_db node link add -addr <node address> -link <node address>'
-            return link_add_or_del_with_reply(l_net, l_node_info, "add", alias_str, &l_link, a_str_reply);
-        else if(dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del", NULL))
-            // handler of command 'global_db node link del -addr <node address> -link <node address>'
-            return link_add_or_del_with_reply(l_net, l_node_info, "del", alias_str, &l_link, a_str_reply);
-        else {
-            dap_chain_node_cli_set_reply_text(a_str_reply, "command not recognize, supported format:\n"
-                    "global_db node link <add|del] [-addr <node address>  | -alias <node alias>] -link <node address>");
-            DAP_DELETE(l_node_info);
-            return -1;
-        }
-
-    default:
-        dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]);
-        return -1;
-    }
-}
+ int com_global_db_prev(int a_argc, char ** a_argv, char **a_str_reply)
+ {
+ enum {
+ CMD_NONE, CMD_NAME_NODE, CMD_NAME_CELL, CMD_ADD, CMD_DEL, CMD_LINK    };
+ //printf("com_global_db\n");
+ int arg_index = 1;
+ int cmd_name =  CMD_NONE;
+ // find 'node' as first parameter only
+ arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "node", NULL);
+ if(arg_index)
+ cmd_name =  CMD_NAME_NODE;
+ // find 'cells' as first parameter only
+ if(!arg_index) {
+ arg_index = 1;
+ arg_index = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "cells", NULL);
+ if(arg_index)
+ cmd_name =  CMD_NAME_CELL;
+ }
+ if(!arg_index || a_argc < 3) {
+ dap_chain_node_cli_set_reply_text(a_str_reply, "parameters are not valid");
+ return -1;
+ }
+ dap_chain_t * l_chain = NULL;
+ dap_chain_net_t * l_net = NULL;
+
+ if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0)
+ return -11;
+
+ int arg_index_n = ++arg_index;
+ // find command (add, delete, etc) as second parameter only
+ int cmd_num = CMD_NONE;
+ switch(cmd_name){
+ case CMD_NAME_NODE:
+ if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
+ != 0) {
+ cmd_num = CMD_ADD;
+ }
+ else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del",
+ NULL))
+ != 0) {
+ cmd_num = CMD_DEL;
+ }
+ else if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "link",
+ NULL))
+ != 0) {
+ cmd_num = CMD_LINK;
+ }
+ break;
+
+ case CMD_NAME_CELL:
+ if((arg_index_n = dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
+ != 0) {
+ cmd_num = CMD_ADD;
+ }
+ }
+
+ if(cmd_num == CMD_NONE) {
+ dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]);
+ return -1;
+ }
+ //arg_index = arg_index_n; // no need, they are already equal must be
+ assert(arg_index == arg_index_n);
+ arg_index++;
+ const char *l_addr_str = NULL, *alias_str = NULL, *l_cell_str = NULL, *l_chain_str = NULL, *l_link_str = NULL;
+ const char *a_ipv4_str = NULL, *a_ipv6_str = NULL;
+ // find addr, alias
+
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-alias", &alias_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-cell", &l_cell_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv4", &a_ipv4_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-ipv6", &a_ipv6_str);
+ dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-link", &l_link_str);
+
+ // struct to write to the global db
+ dap_chain_node_addr_t l_link = { 0 };
+ dap_chain_node_info_t *l_node_info;
+ size_t l_node_info_size = sizeof(l_node_info->hdr) + sizeof(l_link);
+ l_node_info = DAP_NEW_Z_SIZE(dap_chain_node_info_t, l_node_info_size);
+
+ if(l_addr_str) {
+ dap_digit_from_string(l_addr_str, l_node_info->hdr.address.raw, sizeof(l_node_info->hdr.address.raw));
+ }
+ if(l_cell_str) {
+ dap_digit_from_string(l_cell_str, l_node_info->hdr.cell_id.raw, sizeof(l_node_info->hdr.cell_id.raw)); //DAP_CHAIN_CELL_ID_SIZE);
+ }
+ if(l_link_str) {
+ dap_digit_from_string(l_link_str, l_link.raw, sizeof(l_link.raw));
+ }
+
+ switch (cmd_num)
+ {
+ // add new node to global_db
+ case CMD_ADD:
+ if(cmd_name == CMD_NAME_NODE) {
+ if(!arg_index || a_argc < 8) {
+ dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
+ return -1;
+ }
+ // handler of command 'global_db node add'
+ return node_info_add_with_reply(l_net, l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str,
+ a_str_reply);
+ }
+ else if(cmd_name == CMD_NAME_CELL) {
+ if(!arg_index || a_argc < 7) {
+ dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
+ return -1;
+ }
+ dap_chain_cell_t *l_cell = dap_chain_cell_create();
+ l_cell->chain = l_chain;
+ l_cell->id.uint64 = l_node_info->hdr.cell_id.uint64;
+ l_cell->file_storage_path = "234";
+ dap_chain_cell_file_update(l_cell);
+ DAP_DELETE(l_cell);
+
+ }
+ break;
+
+ case CMD_DEL:
+ // handler of command 'global_db node del'
+ return node_info_del_with_reply(l_net,l_node_info, alias_str, a_str_reply);
+ case CMD_LINK:
+ if(dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "add", NULL))
+ // handler of command 'global_db node link add -addr <node address> -link <node address>'
+ return link_add_or_del_with_reply(l_net, l_node_info, "add", alias_str, &l_link, a_str_reply);
+ else if(dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), "del", NULL))
+ // handler of command 'global_db node link del -addr <node address> -link <node address>'
+ return link_add_or_del_with_reply(l_net, l_node_info, "del", alias_str, &l_link, a_str_reply);
+ else {
+ dap_chain_node_cli_set_reply_text(a_str_reply, "command not recognize, supported format:\n"
+ "global_db node link <add|del] [-addr <node address>  | -alias <node alias>] -link <node address>");
+ DAP_DELETE(l_node_info);
+ return -1;
+ }
+
+ default:
+ dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]);
+ return -1;
+ }
+ }
  */
 
 /**
@@ -939,7 +947,8 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
             return -1;
         }
         // handler of command 'global_db node add'
-        int l_ret = node_info_add_with_reply(l_net, l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str, a_str_reply);
+        int l_ret = node_info_add_with_reply(l_net, l_node_info, alias_str, l_cell_str, a_ipv4_str, a_ipv6_str,
+                a_str_reply);
         DAP_DELETE(l_node_info);
         return l_ret;
         //break;
@@ -976,7 +985,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         bool l_is_full = dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-full", NULL);
         return node_info_dump_with_reply(l_net, &l_node_addr, l_is_full, alias_str, a_str_reply);
     }
-    // add alias
+        // add alias
     case CMD_ALIAS:
         if(alias_str) {
             if(l_addr_str) {
@@ -1017,7 +1026,6 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
             return -1;
         }
 
-
         dap_chain_node_info_t *l_remote_node_info = node_info_read_and_reply(l_net, &l_node_addr, a_str_reply);
         if(!l_remote_node_info) {
             return -1;
@@ -1032,8 +1040,8 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         // wait connected
         int timeout_ms = 5000; //5 sec = 5000 ms
         int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms);
-        if(res ) {
-            dap_chain_node_cli_set_reply_text(a_str_reply, "no response from node: code %d",res);
+        if(res) {
+            dap_chain_node_cli_set_reply_text(a_str_reply, "no response from node: code %d", res);
             // clean client struct
             dap_chain_node_client_close(l_node_client);
             DAP_DELETE(l_remote_node_info);
@@ -1078,11 +1086,11 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
         timeout_ms = 120000; // 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 ){
+        if(res < 0) {
             dap_chain_node_client_close(l_node_client);
             DAP_DELETE(l_remote_node_info);
             dap_chain_node_cli_set_reply_text(a_str_reply, "Error: can't sync with node "NODE_ADDR_FP_STR,
-                                              NODE_ADDR_FP_ARGS_S(l_node_client->remote_node_addr));
+                    NODE_ADDR_FP_ARGS_S(l_node_client->remote_node_addr));
 
             return -2;
 
@@ -1123,7 +1131,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
     case CMD_HANDSHAKE: {
         // get address from alias if addr not defined
         if(alias_str && !l_node_addr.uint64) {
-            dap_chain_node_addr_t *address_tmp = dap_chain_node_addr_get_by_alias(l_net,alias_str);
+            dap_chain_node_addr_t *address_tmp = dap_chain_node_addr_get_by_alias(l_net, alias_str);
             if(address_tmp) {
                 memcpy(&l_node_addr, address_tmp, sizeof(*address_tmp));
                 DAP_DELETE(address_tmp);
@@ -1138,7 +1146,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply)
             return -5;
         }
 
-        dap_chain_node_info_t *node_info = node_info_read_and_reply(l_net,&l_node_addr, a_str_reply);
+        dap_chain_node_info_t *node_info = node_info_read_and_reply(l_net, &l_node_addr, a_str_reply);
         if(!node_info)
             return -6;
         int timeout_ms = 10000; //10 sec = 10000 ms
@@ -1256,7 +1264,7 @@ int com_traceroute(int argc, char** argv, char **str_reply)
     }
     return res;
 #endif
-return 0;
+    return 0;
 }
 
 /**
@@ -1330,7 +1338,7 @@ int com_tracepath(int argc, char** argv, char **str_reply)
     }
     return res;
 #endif
-  return 0;
+    return 0;
 }
 
 /**
@@ -1392,7 +1400,7 @@ int com_ping(int argc, char** argv, char **str_reply)
     }
     return res;
 #endif
-return 0;
+    return 0;
 }
 
 /**
@@ -1434,7 +1442,7 @@ int com_help(int argc, char ** argv, char **str_reply)
  *
  * Wallet info
  */
-int com_tx_wallet(int argc,  char ** argv, char **str_reply)
+int com_tx_wallet(int argc, char ** argv, char **str_reply)
 {
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
     // Get address of wallet
@@ -1562,10 +1570,10 @@ int com_tx_wallet(int argc,  char ** argv, char **str_reply)
             for(size_t i = 0; i < l_addr_tokens_size; i++) {
                 if(l_addr_tokens[i]) {
                     uint64_t l_balance = dap_chain_ledger_calc_balance(l_ledger, l_addr, l_addr_tokens[i]);
-                    long  double l_balance_coins = (long double) l_balance / 1000000000000.0L;
+                    long double l_balance_coins = (long double) l_balance / 1000000000000.0L;
                     //dap_string_append_printf(l_string_ret, "          %.3Lf (%llu) %s\n", l_balance_coins,
                     dap_string_append_printf(l_string_ret, "\t\u00a0%.3Lf (%llu) %s", l_balance_coins,
-                                             l_balance, l_addr_tokens[i]);
+                            l_balance, l_addr_tokens[i]);
                     if(i < l_addr_tokens_size - 1)
                         dap_string_append_printf(l_string_ret, "\n");
 
@@ -1657,7 +1665,7 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int argc, ch
  * @param str_reply
  * @return
  */
-int com_token_decl_sign(int argc,  char ** argv, char ** a_str_reply)
+int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply)
 {
     int arg_index = 1;
 
@@ -1692,7 +1700,7 @@ int com_token_decl_sign(int argc,  char ** argv, char ** a_str_reply)
         }
         size_t l_certs_count = l_certs_size / sizeof(dap_chain_cert_t *);
 
-        char * l_gdb_group_mempool;// = dap_chain_net_get_gdb_group_mempool(l_chain);
+        char * l_gdb_group_mempool; // = dap_chain_net_get_gdb_group_mempool(l_chain);
         if(l_gdb_group_mempool) {
             l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain);
         }
@@ -1777,7 +1785,7 @@ int com_token_decl_sign(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, (uint8_t*) &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
@@ -1860,15 +1868,15 @@ int com_mempool_list(int argc, char ** argv, char ** a_str_reply)
     }
 
     if(l_net) {
-        char * l_gdb_group_mempool = NULL, * l_gdb_group_mempool_tmp;
-        if(l_chain){
+        char * l_gdb_group_mempool = NULL, *l_gdb_group_mempool_tmp;
+        if(l_chain) {
             l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain);
             l_gdb_group_mempool_tmp = l_gdb_group_mempool;
         }
         dap_string_t * l_str_tmp = dap_string_new(NULL);
 
-        for(dap_chain_type_t i = CHAIN_TYPE_FIRST+1; i < CHAIN_TYPE_LAST; i++) {
-            if(!l_gdb_group_mempool){
+        for(dap_chain_type_t i = CHAIN_TYPE_FIRST + 1; i < CHAIN_TYPE_LAST; i++) {
+            if(!l_gdb_group_mempool) {
                 l_chain = dap_chain_net_get_chain_by_chain_type(l_net, i);
                 if(!l_chain)
                     continue;
@@ -1876,7 +1884,7 @@ int com_mempool_list(int argc, char ** argv, char ** a_str_reply)
             }
             size_t l_objs_size = 0;
             dap_global_db_obj_t * l_objs = dap_chain_global_db_gr_load(l_gdb_group_mempool_tmp, &l_objs_size);
-            if(l_objs_size>0)
+            if(l_objs_size > 0)
                 dap_string_append_printf(l_str_tmp, "%s.%s: Found %u records :\n", l_net->pub.name, l_chain->name,
                         l_objs_size);
             else
@@ -1972,7 +1980,7 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply)
         }
     }
     char * l_gdb_group_mempool = NULL, *l_gdb_group_mempool_tmp;
-    if(l_chain){
+    if(l_chain) {
         l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain);
         l_gdb_group_mempool_tmp = l_gdb_group_mempool;
     }
@@ -2168,18 +2176,18 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
                 sizeof(l_datum_token->header),
                 0);
         size_t l_sign_size = dap_chain_sign_get_size(l_sign);
-        l_datum_token=DAP_REALLOC(l_datum_token,sizeof (l_datum_token->header)+l_signs_offset +l_sign_size);
+        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;
         DAP_DELETE(l_sign);
     }
     dap_chain_datum_t * l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_DECL, l_datum_token,
-            sizeof(l_datum_token->header) + l_signs_offset );
+            sizeof(l_datum_token->header) + l_signs_offset);
     size_t l_datum_size = dap_chain_datum_size(l_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_hash_fast(l_datum, l_datum_size, (uint8_t*) &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
@@ -2192,7 +2200,8 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply)
 
     }
     if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, l_datum_size, l_gdb_group_mempool)) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "datum %s with token %s is placed in datum pool ", l_key_str, l_ticker);
+        dap_chain_node_cli_set_reply_text(a_str_reply, "datum %s with token %s is placed in datum pool ", l_key_str,
+                l_ticker);
         DAP_DELETE(l_datum);
         DAP_DELETE(l_datum_token);
         DAP_DELETE(l_gdb_group_mempool);
@@ -2312,9 +2321,9 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
 
     // Select chain emission
     /*if(!l_chain_emission_str) {
-        dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter '-chain_emission'");
-        return -44;
-    } */
+     dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter '-chain_emission'");
+     return -44;
+     } */
     if(l_chain_emission_str) {
         if((l_chain_emission = dap_chain_net_get_chain_by_name(l_net, l_chain_emission_str)) == NULL) { // Can't find such chain
             dap_chain_node_cli_set_reply_text(str_reply,
@@ -2327,9 +2336,9 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
 
     // Select chain emission
     /*if(!l_chain_base_tx_str) {
-        dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'chain_base_tx'");
-        return -46;
-    }*/
+     dap_chain_node_cli_set_reply_text(str_reply, "token_create requires parameter 'chain_base_tx'");
+     return -46;
+     }*/
     if(l_chain_base_tx_str) {
         if((l_chain_base_tx = dap_chain_net_get_chain_by_name(l_net, l_chain_base_tx_str)) == NULL) { // Can't find such chain
             dap_chain_node_cli_set_reply_text(str_reply,
@@ -2341,7 +2350,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
     }
 
     // Get groups for the chains
-    char * l_gdb_group_mempool_emission, * l_gdb_group_mempool_base_tx;
+    char * l_gdb_group_mempool_emission, *l_gdb_group_mempool_base_tx;
     if(l_chain_emission) {
         l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool(l_chain_emission);
     }
@@ -2360,23 +2369,24 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
     // Create emission datum
     // then create datum in memory
     dap_chain_datum_token_emission_t * l_token_emission;
-    size_t l_token_emission_size = sizeof (l_token_emission->hdr) +
-            sizeof (l_token_emission->data.type_auth.signs_count);
+    size_t l_token_emission_size = sizeof(l_token_emission->hdr) +
+            sizeof(l_token_emission->data.type_auth.signs_count);
 
     l_token_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_token_emission_size);
     strncpy(l_token_emission->hdr.ticker, l_ticker, sizeof(l_token_emission->hdr.ticker));
     l_token_emission->hdr.value = l_emission_value;
     l_token_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH;
-    memcpy(&l_token_emission->hdr.address, l_addr, sizeof (l_token_emission->hdr.address));
+    memcpy(&l_token_emission->hdr.address, l_addr, sizeof(l_token_emission->hdr.address));
     // 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, sizeof(l_token_emission->hdr),0 );
+    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,
+                sizeof(l_token_emission->hdr), 0);
         size_t l_sign_size = dap_chain_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);
-        l_offset+= 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);
+        l_offset += l_sign_size;
         DAP_DELETE(l_sign);
     }
 
@@ -2391,7 +2401,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply)
 
     // Calc datum's hash
     dap_chain_hash_fast_t l_datum_emission_hash;
-    dap_hash_fast(l_datum_emission, l_datum_emission_size, (uint8_t*)&l_datum_emission_hash);
+    dap_hash_fast(l_datum_emission, l_datum_emission_size, (uint8_t*) &l_datum_emission_hash);
     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_datum_emission_hash);
 
     // Add to mempool emission token
@@ -2444,7 +2454,7 @@ 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, (uint8_t*) &l_datum_tx_hash);
     l_key_str = dap_chain_hash_fast_to_str_new(&l_datum_tx_hash);
     DAP_DELETE(l_tx);
 
@@ -2485,7 +2495,7 @@ int com_tx_cond_create(int argc, char ** argv, char **str_reply)
     {
 //        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);
+        //      char *addr = dap_chain_addr_to_str(l_addr_tesla);
 //        addr = 0;
     }
 
@@ -2532,7 +2542,7 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
     const char * l_net_name = NULL;
     const char * l_chain_name = NULL;
     const char * l_tx_num_str = NULL;
-    size_t l_tx_num =0;
+    size_t l_tx_num = 0;
 
     uint64_t value = 0;
     uint64_t value_fee = 0;
@@ -2543,8 +2553,8 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
     dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-chain", &l_chain_name);
     dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-tx_num", &l_tx_num_str);
 
-    if ( l_tx_num_str )
-        l_tx_num = strtoul(l_tx_num_str,NULL,10);
+    if(l_tx_num_str)
+        l_tx_num = strtoul(l_tx_num_str, NULL, 10);
 
     if(dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-fee", &addr_base58_fee)) {
         if(dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-value_fee", &str_tmp)) {
@@ -2567,7 +2577,8 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
         return -1;
     }
     if(addr_base58_fee && !value_fee) {
-        dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-value_fee' if '-fee' is specified");
+        dap_chain_node_cli_set_reply_text(str_reply,
+                "tx_create requires parameter '-value_fee' if '-fee' is specified");
         return -1;
     }
 
@@ -2576,22 +2587,23 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
         return -1;
     }
     dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name);
-    dap_ledger_t *l_ledger = l_net? l_net->pub.ledger : NULL ;
+    dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL;
     if((l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) {
         dap_chain_node_cli_set_reply_text(str_reply, "not found net by name '%s'", l_net_name);
         return -1;
     }
 
-/*    if(!l_chain_name) {
-        dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-chain'");
-        return -1;
-    }*/
+    /*    if(!l_chain_name) {
+     dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-chain'");
+     return -1;
+     }*/
     dap_chain_t * l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name);
-    if ( !l_chain ){
+    if(!l_chain) {
         l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX);
     }
-    if ( !l_chain ){
-        dap_chain_node_cli_set_reply_text(str_reply, "not found chain name '%s', try use parameter '-chain'", l_chain_name);
+    if(!l_chain) {
+        dap_chain_node_cli_set_reply_text(str_reply, "not found chain name '%s', try use parameter '-chain'",
+                l_chain_name);
         return -1;
     }
 
@@ -2623,10 +2635,15 @@ int com_tx_create(int argc, char ** argv, char **str_reply)
     //g_string_printf(string_ret, "from=%s\nto=%s\nval=%lld\nfee=%s\nval_fee=%lld\n\n",
     //        addr_base58_from, addr_base58_to, value, addr_base58_fee, value_fee);
 
-    int res = l_tx_num? dap_chain_mempool_tx_create_massive( l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, addr_to, addr_fee,
-                                                     l_token_ticker, value, value_fee, l_tx_num)
-              :dap_chain_mempool_tx_create( l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, addr_to, addr_fee,
-            l_token_ticker, value, value_fee);
+    int res =
+            l_tx_num ?
+                       dap_chain_mempool_tx_create_massive(l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from,
+                               addr_to, addr_fee,
+                               l_token_ticker, value, value_fee, l_tx_num)
+                               :
+                       dap_chain_mempool_tx_create(l_chain, dap_chain_wallet_get_key(l_wallet, 0), addr_from, addr_to,
+                               addr_fee,
+                               l_token_ticker, value, value_fee);
     dap_string_append_printf(string_ret, "transfer=%s\n",
             (res == 0) ? "Ok" : (res == -2) ? "False, not enough funds for transfer" : "False");
 
@@ -2655,7 +2672,6 @@ int com_tx_verify(int argc, char ** argv, char **str_reply)
     return -1;
 }
 
-
 /**
  * tx_history command
  *
@@ -2711,7 +2727,7 @@ int com_tx_history(int argc, char ** argv, char **str_reply)
     //const char *l_chain_group = dap_chain_gdb_get_group(l_chain);
 
     dap_chain_hash_fast_t l_tx_hash;
-    if(l_tx_hash_str){
+    if(l_tx_hash_str) {
         if(dap_chain_str_to_hash_fast(l_tx_hash_str, &l_tx_hash) < 0) {
             l_tx_hash_str = NULL;
             dap_chain_node_cli_set_reply_text(str_reply, "tx hash not recognized");
@@ -2793,7 +2809,7 @@ int com_print_log(int argc, char ** argv, char **str_reply)
     }
 
     // get logs from list
-    char *l_str_ret = dap_log_get_item(l_ts_after,(int) l_limit);
+    char *l_str_ret = dap_log_get_item(l_ts_after, (int) l_limit);
     if(!l_str_ret) {
         dap_chain_node_cli_set_reply_text(str_reply, "no logs");
         return -1;
@@ -2803,3 +2819,85 @@ int com_print_log(int argc, char ** argv, char **str_reply)
     return 0;
 }
 
+/**
+ * vpn_client command
+ *
+ * VPN client control
+ */
+int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply)
+{
+    enum {
+        CMD_NONE, CMD_START, CMD_STOP, CMD_STATUS
+    };
+    int l_arg_index = 1;
+    // find net
+    dap_chain_net_t *l_net = NULL;
+    if(dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0)
+        return -2;
+
+    int cmd_num = CMD_NONE;
+    if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "start", NULL)) {
+        cmd_num = CMD_START;
+    }
+    else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "stop", NULL)) {
+        cmd_num = CMD_STOP;
+    }
+    else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "status", NULL)) {
+        cmd_num = CMD_STATUS;
+    }
+    if(cmd_num == CMD_NONE) {
+        if(!a_argv[1])
+            dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
+        else
+            dap_chain_node_cli_set_reply_text(a_str_reply, "parameter %s not recognized", a_argv[1]);
+        return -1;
+    }
+
+    switch (cmd_num)
+    {
+    case CMD_START: {
+        int l_res = 0;//dap_chain_net_vpn_client_start(l_net, "192.168.100.93", NULL, 8079);
+        switch (l_res) {
+        case 0:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client started successfully");
+            break;
+        case 1:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client already started");
+            break;
+        case -2:
+        case -3:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't connect to VPN server");
+            break;
+        default:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't start VPN client");
+            break;
+        }
+        return l_res;
+    }
+        break;
+    case CMD_STOP: {
+        int res = 0;//dap_chain_net_vpn_client_stop();
+        if(!res)
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client stopped successfully");
+        else
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client not stopped");
+        return res;
+    }
+        //break;
+    case CMD_STATUS:
+        //switch (dap_chain_net_vpn_client_status()) {
+        switch (0){
+        case 0:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client stopped");
+            return 0;
+        case 1:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client started");
+            return 0;
+        case -1:
+            dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get VPN state");
+            return -1;
+        }
+        break;
+    }
+    return 0;
+}
diff --git a/dap_chain_node_cli_cmd.h b/dap_chain_node_cli_cmd.h
index ccea01fd45bb318a8fc1f137227dc6cfcc784dd6..dd5225f4742d2d6614a551baa81e21674f61fbbf 100644
--- a/dap_chain_node_cli_cmd.h
+++ b/dap_chain_node_cli_cmd.h
@@ -126,6 +126,9 @@ int com_tx_history(int argc, char ** argv, char **str_reply);
 // Print log info
 int com_print_log(int argc, char ** argv, char **str_reply);
 
+// vpn_client command
+int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply);
+
 int com_mempool_delete(int argc, char ** argv, char ** a_str_reply);
 int com_mempool_list(int argc, char ** argv, char ** a_str_reply);
 int com_mempool_proc(int argc, char ** argv, char ** a_str_reply);
diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c
index fe3bb648caf0a2043a5fe72f2eea2945e5de84ae..b3ecfe3ed4b89f5f27c73e2737d69d3ae3b520c4 100644
--- a/dap_chain_node_client.c
+++ b/dap_chain_node_client.c
@@ -1,6 +1,7 @@
 /*
  * Authors:
  * Dmitriy A. Gearasimov <naeper@demlabs.net>
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
  * DeM Labs Inc.   https://demlabs.net
 
  This file is part of DAP (Deus Applications Prototypes) the open source project
@@ -65,11 +66,11 @@
 
 static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg);
 static void s_ch_chain_callback_notify_packet_out(dap_stream_ch_chain_t*, uint8_t a_pkt_type,
-                                                      dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
-                                                      void * a_arg);
+        dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
+        void * a_arg);
 static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_chain, uint8_t a_pkt_type,
-                                                      dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
-                                                      void * a_arg);
+        dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
+        void * a_arg);
 
 /**
  * @brief dap_chain_node_client_init
@@ -84,9 +85,9 @@ int dap_chain_node_client_init(void)
         return -1;
     }
     /*else {
-        const char *port_str = dap_config_get_item_str(g_config, "server", "listen_port_tcp");
-        listen_port_tcp = (port_str) ? atoi(port_str) : 8079;
-    }*/
+     const char *port_str = dap_config_get_item_str(g_config, "server", "listen_port_tcp");
+     listen_port_tcp = (port_str) ? atoi(port_str) : 8079;
+     }*/
     if(g_config)
         dap_config_close(g_config);
     return 0;
@@ -106,7 +107,7 @@ void dap_chain_node_client_deinit()
  * @param a_client
  * @param a_arg
  */
-static void stage_status_callback(dap_client_t *a_client, void *a_arg)
+static void s_stage_status_callback(dap_client_t *a_client, void *a_arg)
 {
     (void) a_client;
     (void) a_arg;
@@ -123,14 +124,14 @@ static void s_stage_status_error_callback(dap_client_t *a_client, void *a_arg)
 {
     (void) a_arg;
     dap_chain_node_client_t *l_node_client = DAP_CHAIN_NODE_CLIENT(a_client);
-    if ( l_node_client && l_node_client->keep_connection &&
-         ( ( dap_client_get_stage(a_client) != STAGE_STREAM_STREAMING )||
-           ( dap_client_get_stage_status(a_client) == STAGE_STATUS_ERROR  ) ) ){
+    if(l_node_client && l_node_client->keep_connection &&
+            ((dap_client_get_stage(a_client) != STAGE_STREAM_STREAMING) ||
+                    (dap_client_get_stage_status(a_client) == STAGE_STATUS_ERROR))) {
         log_it(L_NOTICE,"Some errors happends, current state is %s but we need to return back to STAGE_STREAM_STREAMING",
-                 dap_client_get_stage_str(a_client) ) ;
+                dap_client_get_stage_str(a_client) );
 
         pthread_mutex_unlock(&l_node_client->wait_mutex);
-        log_it(L_DEBUG,"Wakeup all who waits");
+        log_it(L_DEBUG, "Wakeup all who waits");
         l_node_client->state = NODE_CLIENT_STATE_ERROR;
 
 #ifndef _WIN32
@@ -153,26 +154,26 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg)
     dap_chain_node_client_t *l_node_client = a_client->_inheritor;
     //assert(l_node_client);
     if(l_node_client) {
-        log_it(L_NOTICE,"Stream connection with node " NODE_ADDR_FP_STR " established",
-               NODE_ADDR_FP_ARGS_S( l_node_client->remote_node_addr) );
+        log_it(L_NOTICE, "Stream connection with node " NODE_ADDR_FP_STR " established",
+                NODE_ADDR_FP_ARGS_S( l_node_client->remote_node_addr));
         pthread_mutex_lock(&l_node_client->wait_mutex);
         l_node_client->state = NODE_CLIENT_STATE_CONNECTED;
 
-        dap_stream_ch_t * l_ch = dap_client_get_stream_ch( a_client , dap_stream_ch_chain_get_id() );
-        if (l_ch){
+        dap_stream_ch_t * l_ch = dap_client_get_stream_ch(a_client, dap_stream_ch_chain_get_id());
+        if(l_ch) {
             dap_stream_ch_chain_t * l_ch_chain = DAP_STREAM_CH_CHAIN(l_ch);
             l_ch_chain->callback_notify_packet_out = s_ch_chain_callback_notify_packet_out;
             l_ch_chain->callback_notify_packet_in = s_ch_chain_callback_notify_packet_in;
             l_ch_chain->callback_notify_arg = l_node_client;
-        }else {
-            log_it(L_WARNING,"No ch_chain channel, can't init notify callback for pkt type CH_CHAIN");
+        } else {
+            log_it(L_WARNING, "No ch_chain channel, can't init notify callback for pkt type CH_CHAIN");
         }
 
         pthread_mutex_unlock(&l_node_client->wait_mutex);
-        if ( l_node_client->callback_connected )
-            l_node_client->callback_connected(l_node_client,a_arg);
+        if(l_node_client->callback_connected)
+            l_node_client->callback_connected(l_node_client, a_arg);
         l_node_client->keep_connection = true;
-        log_it(L_DEBUG,"Wakeup all who waits");
+        log_it(L_DEBUG, "Wakeup all who waits");
 
 #ifndef _WIN32
         pthread_cond_signal(&l_node_client->wait_cond);
@@ -191,94 +192,95 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg)
  * @param a_arg
  */
 static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_chain, uint8_t a_pkt_type,
-                                                      dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
-                                                      void * a_arg)
+        dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
+        void * a_arg)
 {
     dap_chain_node_client_t * l_node_client = (dap_chain_node_client_t *) a_arg;
     switch (a_pkt_type) {
-        case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR:
-            pthread_mutex_lock(&l_node_client->wait_mutex);
-            l_node_client->state = NODE_CLIENT_STATE_ERROR ;
-            dap_snprintf(l_node_client->last_error,sizeof (l_node_client->last_error),
-                     "%s", (char*) a_pkt->data );
-            log_it(L_WARNING,"Received packet DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR with error \"%s\"",
-                   l_node_client->last_error);
-            pthread_mutex_unlock(&l_node_client->wait_mutex);
+    case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR:
+        pthread_mutex_lock(&l_node_client->wait_mutex);
+        l_node_client->state = NODE_CLIENT_STATE_ERROR;
+        dap_snprintf(l_node_client->last_error, sizeof(l_node_client->last_error),
+                "%s", (char*) a_pkt->data);
+        log_it(L_WARNING, "Received packet DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR with error \"%s\"",
+                l_node_client->last_error);
+        pthread_mutex_unlock(&l_node_client->wait_mutex);
 
 #ifndef _WIN32
-            pthread_cond_signal(&l_node_client->wait_cond);
+        pthread_cond_signal(&l_node_client->wait_cond);
 #else
             SetEvent( l_node_client->wait_cond );
 #endif
 
-        case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_LEASE:
-            pthread_mutex_lock(&l_node_client->wait_mutex);
-            l_node_client->state = NODE_CLIENT_STATE_NODE_ADDR_LEASED;
-            pthread_mutex_unlock(&l_node_client->wait_mutex);
+    case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_LEASE:
+        pthread_mutex_lock(&l_node_client->wait_mutex);
+        l_node_client->state = NODE_CLIENT_STATE_NODE_ADDR_LEASED;
+        pthread_mutex_unlock(&l_node_client->wait_mutex);
 #ifndef _WIN32
-            pthread_cond_signal(&l_node_client->wait_cond);
+        pthread_cond_signal(&l_node_client->wait_cond);
 #else
             SetEvent( l_node_client->wait_cond );
 #endif
         break;
-        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL:
+    case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL:
         case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_GLOBAL_DB:
-        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS:{
-            dap_stream_ch_chain_sync_request_t * l_request = NULL;
-            if ( a_pkt_data_size == sizeof ( *l_request))
-                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() ){
-                    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();
-                    dap_list_t *l_list = dap_db_log_get_list((time_t) l_request->id_start);
-
-                    if ( l_list ) {
-                        // Add it to outgoing list
-                        l_list->prev = a_ch_chain->request_global_db_trs;
-                        a_ch_chain->request_global_db_trs = l_list;
-                        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 ;
-
-                        dap_chain_node_addr_t l_node_addr = { 0 };
-                        l_node_addr.uint64 = dap_db_get_cur_node_addr();
-                        dap_stream_ch_chain_pkt_write(a_ch_chain->ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB,
-                                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));
-
-                        log_it(L_INFO, "Sync for remote tr_count=%d",dap_list_length(l_list));
-                        dap_stream_ch_set_ready_to_write(a_ch_chain->ch, true);
-                    }
-                }else {
-                    log_it(L_INFO, "Remote node has lastes ts for us");
-                    pthread_mutex_lock(&l_node_client->wait_mutex);
-                    l_node_client->state = NODE_CLIENT_STATE_SYNCED;
-                    pthread_mutex_unlock(&l_node_client->wait_mutex);
-#ifndef _WIN32
-                    pthread_cond_signal(&l_node_client->wait_cond);
-#else
-                    SetEvent( l_node_client->wait_cond );
-#endif
-
+        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS: {
+        dap_stream_ch_chain_sync_request_t * l_request = NULL;
+        if(a_pkt_data_size == sizeof(*l_request))
+            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()) {
+                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();
+                dap_list_t *l_list = dap_db_log_get_list((time_t) l_request->id_start);
+
+                if(l_list) {
+                    // Add it to outgoing list
+                    l_list->prev = a_ch_chain->request_global_db_trs;
+                    a_ch_chain->request_global_db_trs = l_list;
+                    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;
+
+                    dap_chain_node_addr_t l_node_addr = { 0 };
+                    l_node_addr.uint64 = dap_db_get_cur_node_addr();
+                    dap_stream_ch_chain_pkt_write(a_ch_chain->ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB,
+                            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));
+
+                    log_it(L_INFO, "Sync for remote tr_count=%d", dap_list_length(l_list));
+                    dap_stream_ch_set_ready_to_write(a_ch_chain->ch, true);
                 }
-            }else {
-                log_it(L_INFO, "Sync notify without request to sync back, stay in SYNCED state");
+            } else {
+                log_it(L_INFO, "Remote node has lastes ts for us");
                 pthread_mutex_lock(&l_node_client->wait_mutex);
                 l_node_client->state = NODE_CLIENT_STATE_SYNCED;
                 pthread_mutex_unlock(&l_node_client->wait_mutex);
 #ifndef _WIN32
                 pthread_cond_signal(&l_node_client->wait_cond);
 #else
-                SetEvent( l_node_client->wait_cond );
+                    SetEvent( l_node_client->wait_cond );
 #endif
-            }
 
+            }
+        } else {
+            log_it(L_INFO, "Sync notify without request to sync back, stay in SYNCED state");
+            pthread_mutex_lock(&l_node_client->wait_mutex);
+            l_node_client->state = NODE_CLIENT_STATE_SYNCED;
+            pthread_mutex_unlock(&l_node_client->wait_mutex);
+#ifndef _WIN32
+            pthread_cond_signal(&l_node_client->wait_cond);
+#else
+                SetEvent( l_node_client->wait_cond );
+#endif
         }
-        default:{}
+
+    }
+    default: {
+    }
     }
 }
 
@@ -291,27 +293,29 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
  * @param a_arg
  */
 static void s_ch_chain_callback_notify_packet_out(dap_stream_ch_chain_t* a_ch_chain, uint8_t a_pkt_type,
-                                                      dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
-                                                      void * a_arg)
+        dap_stream_ch_chain_pkt_t *a_pkt, size_t a_pkt_data_size,
+        void * a_arg)
 {
     (void) a_pkt;
     (void) a_pkt_data_size;
     (void) a_ch_chain;
     dap_chain_node_client_t * l_node_client = (dap_chain_node_client_t *) a_arg;
     switch (a_pkt_type) {
-        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL:
+    case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL:
         case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_GLOBAL_DB:
-        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS:{
-            pthread_mutex_lock(&l_node_client->wait_mutex);
-            l_node_client->state = NODE_CLIENT_STATE_SYNCED;
-            pthread_mutex_unlock(&l_node_client->wait_mutex);
+        case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS: {
+        pthread_mutex_lock(&l_node_client->wait_mutex);
+        l_node_client->state = NODE_CLIENT_STATE_SYNCED;
+        pthread_mutex_unlock(&l_node_client->wait_mutex);
 #ifndef _WIN32
-            pthread_cond_signal(&l_node_client->wait_cond);
+        pthread_cond_signal(&l_node_client->wait_cond);
 #else
             SetEvent( l_node_client->wait_cond );
 #endif
-        }break;
-        default:{}
+    }
+        break;
+    default: {
+    }
     }
 }
 
@@ -320,10 +324,11 @@ static void s_ch_chain_callback_notify_packet_out(dap_stream_ch_chain_t* a_ch_ch
  *
  * return a connection handle, or NULL, if an error
  */
-dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *a_node_info)
+dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info, dap_client_stage_t a_stage_target,
+        const char *a_active_channels)
 {
-    if(!a_node_info){
-        log_it(L_ERROR,"Can't connect to the node: null object node_info");
+    if(!a_node_info) {
+        log_it(L_ERROR, "Can't connect to the node: null object node_info");
         return NULL;
     }
     dap_chain_node_client_t *l_node_client = DAP_NEW_Z(dap_chain_node_client_t);
@@ -340,10 +345,11 @@ dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *a_
 
     pthread_mutex_init(&l_node_client->wait_mutex, NULL);
     l_node_client->events = NULL; //dap_events_new();
-    l_node_client->client = dap_client_new(l_node_client->events, stage_status_callback, s_stage_status_error_callback);
+    l_node_client->client = dap_client_new(l_node_client->events, s_stage_status_callback,
+            s_stage_status_error_callback);
     l_node_client->client->_inheritor = l_node_client;
     l_node_client->remote_node_addr.uint64 = a_node_info->hdr.address.uint64;
-    dap_client_set_active_channels(l_node_client->client,"CN");
+    dap_client_set_active_channels(l_node_client->client, a_active_channels);
 
     int hostlen = 128;
     char host[hostlen];
@@ -368,10 +374,22 @@ dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *a_
 
     l_node_client->state = NODE_CLIENT_STATE_CONNECT;
     // Handshake & connect
-    dap_client_go_stage(l_node_client->client, l_stage_target, s_stage_connected_callback);
+    dap_client_go_stage(l_node_client->client, a_stage_target, s_stage_connected_callback);
     return l_node_client;
 }
 
+/**
+ * Create connection to server
+ *
+ * return a connection handle, or NULL, if an error
+ */
+dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *a_node_info)
+{
+    dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING;
+    const char *l_active_channels = "CN";
+    return dap_chain_client_connect(a_node_info, l_stage_target, l_active_channels);
+}
+
 /**
  * Close connection to server, delete chain_node_client_t *client
  */
@@ -380,12 +398,12 @@ void dap_chain_node_client_close(dap_chain_node_client_t *a_client)
     if(a_client) {
 
         pthread_mutex_lock(&a_client->wait_mutex);
-        a_client->client->_inheritor = NULL;// because client->_inheritor == a_client
+        a_client->client->_inheritor = NULL; // because client->_inheritor == a_client
         pthread_mutex_unlock(&a_client->wait_mutex);
 
         // clean client
-        //dap_client_delete(a_client->client);
-        //a_client->client = NULL;
+        dap_client_delete(a_client->client);
+        a_client->client = NULL;
 
 #ifndef _WIN32
         pthread_cond_destroy(&a_client->wait_cond);
@@ -397,7 +415,6 @@ void dap_chain_node_client_close(dap_chain_node_client_t *a_client)
     }
 }
 
-
 /**
  * Send stream request to server
  */
@@ -409,17 +426,16 @@ int dap_chain_node_client_send_ch_pkt(dap_chain_node_client_t *a_client, uint8_t
 
 //    dap_stream_t *l_stream = dap_client_get_stream(a_client->client);
     dap_stream_ch_t * l_ch = dap_client_get_stream_ch(a_client->client, a_ch_id);
-    if(l_ch){
+    if(l_ch) {
 //        dap_stream_ch_chain_net_t * l_ch_chain = DAP_STREAM_CH_CHAIN_NET(l_ch);
 
         dap_stream_ch_pkt_write(l_ch, a_type, a_pkt_data, a_pkt_data_size);
         dap_stream_ch_set_ready_to_write(l_ch, true);
         return 0;
-    }else
+    } else
         return -1;
 }
 
-
 /**
  * wait for the complete of request
  *
@@ -427,27 +443,27 @@ int dap_chain_node_client_send_ch_pkt(dap_chain_node_client_t *a_client, uint8_t
  * waited_state state which we will wait, sample NODE_CLIENT_STATE_CONNECT or NODE_CLIENT_STATE_SENDED
  * return -2 false, -1 timeout, 0 end of connection or sending data
  */
-int dap_chain_node_client_wait( dap_chain_node_client_t *a_client, int a_waited_state, int a_timeout_ms )
+int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_state, int a_timeout_ms)
 {
     int ret = -1;
-    if( !a_client )
+    if(!a_client)
         return -3;
 
-    pthread_mutex_lock( &a_client->wait_mutex );
+    pthread_mutex_lock(&a_client->wait_mutex);
     // have waited
-    if ( a_client->state == a_waited_state ) {
-        pthread_mutex_unlock( &a_client->wait_mutex );
+    if(a_client->state == a_waited_state) {
+        pthread_mutex_unlock(&a_client->wait_mutex);
         return 0;
     }
 
 #ifndef _WIN32
     // prepare for signal waiting
     struct timespec to;
-    clock_gettime( CLOCK_MONOTONIC, &to );
+    clock_gettime( CLOCK_MONOTONIC, &to);
     int64_t nsec_new = to.tv_nsec + a_timeout_ms * 1000000ll;
     // if the new number of nanoseconds is more than a second
 
-    if ( nsec_new > (long) 1e9 ) {
+    if(nsec_new > (long) 1e9) {
         to.tv_sec += nsec_new / (long) 1e9;
         to.tv_nsec = nsec_new % (long) 1e9;
     }
@@ -461,11 +477,11 @@ int dap_chain_node_client_wait( dap_chain_node_client_t *a_client, int a_waited_
     do {
 
 #ifndef _WIN32
-        int wait = pthread_cond_timedwait( &a_client->wait_cond, &a_client->wait_mutex, &to);
+        int wait = pthread_cond_timedwait(&a_client->wait_cond, &a_client->wait_mutex, &to);
         if(wait == 0 && (
-                    a_client->state == a_waited_state ||
-                    a_client->state == NODE_CLIENT_STATE_ERROR )
-          ) {
+                a_client->state == a_waited_state ||
+                        a_client->state == NODE_CLIENT_STATE_ERROR)
+                ) {
             ret = a_client->state == a_waited_state ? 0 : -2;
             break;
         }
@@ -490,8 +506,8 @@ int dap_chain_node_client_wait( dap_chain_node_client_t *a_client, int a_waited_
         }
 #endif
 
-    } while( 1 );
+    } while(1);
 
-    pthread_mutex_unlock( &a_client->wait_mutex );
+    pthread_mutex_unlock(&a_client->wait_mutex);
     return ret;
 }
diff --git a/dap_chain_node_client.h b/dap_chain_node_client.h
index 1ec69226d4b4a398af461ee61bf2c4abb310e27a..2787f63311c61002da7d2c653fb67036e07b27a5 100644
--- a/dap_chain_node_client.h
+++ b/dap_chain_node_client.h
@@ -1,6 +1,7 @@
 /*
  * Authors:
  * Dmitriy A. Gearasimov <naeper@demlabs.net>
+ * Alexander Lysikov <alexander.lysikov@demlabs.net>
  * DeM Labs Inc.   https://demlabs.net
 
  This file is part of DAP (Deus Applications Prototypes) the open source project
@@ -29,25 +30,25 @@
 #include "dap_chain_node.h"
 
 // connection states
-typedef enum dap_chain_node_client_state{
+typedef enum dap_chain_node_client_state {
     NODE_CLIENT_STATE_ERROR = -1,
-    NODE_CLIENT_STATE_DISCONNECTED=0,
-    NODE_CLIENT_STATE_GET_NODE_ADDR=1,
-    NODE_CLIENT_STATE_NODE_ADDR_LEASED=2,
-    NODE_CLIENT_STATE_PING=3,
-    NODE_CLIENT_STATE_PONG=4,
-    NODE_CLIENT_STATE_CONNECT=5,
-    NODE_CLIENT_STATE_CONNECTED=100,
+    NODE_CLIENT_STATE_DISCONNECTED = 0,
+    NODE_CLIENT_STATE_GET_NODE_ADDR = 1,
+    NODE_CLIENT_STATE_NODE_ADDR_LEASED = 2,
+    NODE_CLIENT_STATE_PING = 3,
+    NODE_CLIENT_STATE_PONG = 4,
+    NODE_CLIENT_STATE_CONNECT = 5,
+    NODE_CLIENT_STATE_CONNECTED = 100,
     //NODE_CLIENT_STATE_SEND,
     //NODE_CLIENT_STATE_SENDED,
-    NODE_CLIENT_STATE_SYNC_GDB=101,
-    NODE_CLIENT_STATE_SYNC_CHAINS=102,
-    NODE_CLIENT_STATE_SYNCED=103
+    NODE_CLIENT_STATE_SYNC_GDB = 101,
+    NODE_CLIENT_STATE_SYNC_CHAINS = 102,
+    NODE_CLIENT_STATE_SYNCED = 103
 } dap_chain_node_client_state_t;
 
 typedef struct dap_chain_node_client dap_chain_node_client_t;
 
-typedef void (*dap_chain_node_client_callback_t) (dap_chain_node_client_t *, void*);
+typedef void (*dap_chain_node_client_callback_t)(dap_chain_node_client_t *, void*);
 
 // state for a client connection
 typedef struct dap_chain_node_client {
@@ -58,9 +59,9 @@ typedef struct dap_chain_node_client {
     char last_error[128];
 
     dap_chain_node_client_callback_t callback_connected;
-#ifndef _WIN32
+    #ifndef _WIN32
     pthread_cond_t wait_cond;
-#else
+    #else
     HANDLE wait_cond;
 #endif
     pthread_mutex_t wait_mutex;
@@ -75,11 +76,12 @@ typedef struct dap_chain_node_client {
 } dap_chain_node_client_t;
 #define DAP_CHAIN_NODE_CLIENT(a) ( (dap_chain_node_client_t *) (a)->_inheritor )
 
-
 int dap_chain_node_client_init(void);
 
 void dap_chain_node_client_deinit(void);
 
+dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info, dap_client_stage_t a_stage_target,
+        const char *a_active_channels);
 /**
  * Create handshake to server
  *
@@ -87,8 +89,6 @@ void dap_chain_node_client_deinit(void);
  */
 dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *node_info);
 
-
-
 /**
  * Close connection to server, delete chain_node_client_t *client
  */