diff --git a/dap-sdk/core/src/dap_strfuncs.c b/dap-sdk/core/src/dap_strfuncs.c
index 109d459eafb1f0a82de57e884097be4b492dfb4f..80336d36c92f1f2498bdf29ebe7f38ab2d854c37 100755
--- a/dap-sdk/core/src/dap_strfuncs.c
+++ b/dap-sdk/core/src/dap_strfuncs.c
@@ -26,7 +26,7 @@ bool dap_isstralnum(const char *c)
 
     for (size_t i = 0; i < str_len; i++)
     {
-        if (!isalnum(c[i]))
+        if (!isalnum(c[i]) && c[i] != '_' && c[i] != '-')
             return false;
     }
 
diff --git a/dap-sdk/crypto/include/dap_pkey.h b/dap-sdk/crypto/include/dap_pkey.h
index 93040b6a0617ccb2b2178826787c81ff27ac6c4e..50256f7eca6e726b06a03a61c621d6c65f816ea6 100755
--- a/dap-sdk/crypto/include/dap_pkey.h
+++ b/dap-sdk/crypto/include/dap_pkey.h
@@ -68,13 +68,4 @@ typedef struct dap_pkey{
     uint8_t pkey[]; /// @param pkey @brief raw pkey dat
 } DAP_ALIGN_PACKED dap_pkey_t;
 
-static dap_pkey_t m_dap_pkey_null; // For sizeof nothing more
-
 dap_pkey_t *dap_pkey_from_enc_key(dap_enc_key_t *a_key);
-static inline size_t dap_pkey_from_enc_key_output_calc(dap_enc_key_t *a_key)
-{
-    return sizeof(m_dap_pkey_null.header)+ a_key->pub_key_data_size;
-}
-
-int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output);
-
diff --git a/dap-sdk/crypto/src/dap_cert.c b/dap-sdk/crypto/src/dap_cert.c
index 2e5ce262c397431093ec5c44cd52ad857c8f028a..b9e24a29d656c1b4ceb8c591a6150147e6cb7c5c 100755
--- a/dap-sdk/crypto/src/dap_cert.c
+++ b/dap-sdk/crypto/src/dap_cert.c
@@ -295,29 +295,28 @@ void dap_cert_delete_by_name(const char * a_cert_name)
  */
 dap_cert_t * dap_cert_find_by_name(const char * a_cert_name)
 {
-	if (!a_cert_name) return NULL;
-    dap_cert_item_t * l_cert_item = NULL;
-    HASH_FIND_STR(s_certs,a_cert_name,l_cert_item);
-    if ( l_cert_item ){
-        return l_cert_item->cert ;
+    dap_cert_item_t *l_cert_item = NULL;
+    dap_cert_t *l_ret = NULL;
+    HASH_FIND_STR(s_certs, a_cert_name, l_cert_item);
+    if (l_cert_item ) {
+        l_ret = l_cert_item->cert ;
     } else {
-            dap_cert_t *l_cert = NULL;
-            uint16_t l_ca_folders_size = 0;
-            char **l_ca_folders;
-            char *l_cert_path = NULL;
-            l_ca_folders = dap_config_get_array_str(g_config, "resources", "ca_folders", &l_ca_folders_size);
-            for (uint16_t i = 0; i < l_ca_folders_size; ++i) {
-                l_cert_path = dap_strjoin("", l_ca_folders[i], "/", a_cert_name, ".dcert", (char*)NULL);
-                l_cert = dap_cert_file_load(l_cert_path);
-                if (l_cert) {
-                    goto ret;
-                }
-            }
-    ret:
-            if (l_cert_path)
-                DAP_DELETE(l_cert_path);
-            return l_cert;
+        uint16_t l_ca_folders_size = 0;
+        char **l_ca_folders;
+        char *l_cert_path = NULL;
+        l_ca_folders = dap_config_get_array_str(g_config, "resources", "ca_folders", &l_ca_folders_size);
+        for (uint16_t i = 0; i < l_ca_folders_size; ++i) {
+            l_cert_path = dap_strjoin("", l_ca_folders[i], "/", a_cert_name, ".dcert", (char *)NULL);
+            l_ret = dap_cert_file_load(l_cert_path);
+            DAP_DELETE(l_cert_path);
+            if (l_ret)
+                break;
         }
+    }
+    if (!l_ret)
+        log_it(L_DEBUG, "Can't load cert '%s'", a_cert_name);
+    return l_ret;
+
 }
 
 dap_list_t *dap_cert_get_all_mem()
diff --git a/dap-sdk/crypto/src/dap_pkey.c b/dap-sdk/crypto/src/dap_pkey.c
index a8a40a9ecbce9576cad556911291cc4965543abe..0c0164b581cc113175c43df104aae77ce78a66a9 100755
--- a/dap-sdk/crypto/src/dap_pkey.c
+++ b/dap-sdk/crypto/src/dap_pkey.c
@@ -35,58 +35,38 @@
  * @param a_key dap_enc_key_t encryption key
  * @return dap_pkey_t* 
  */
-dap_pkey_t* dap_pkey_from_enc_key(dap_enc_key_t *a_key)
+dap_pkey_t *dap_pkey_from_enc_key(dap_enc_key_t *a_key)
 {
-    if (a_key->pub_key_data_size > 0 ){
-        dap_pkey_t * l_ret = NULL;
-        l_ret = DAP_NEW_Z_SIZE(dap_pkey_t,dap_pkey_from_enc_key_output_calc(a_key));
-        if( dap_pkey_from_enc_key_output(a_key,l_ret) != 0 ) {
-            DAP_DELETE(l_ret);
-            return NULL;
-        }else
-            return l_ret;
-    }
-
-    return NULL;
-}
-
-/**
- * @brief dap_pkey_from_enc_key_output
- * convert encryption key to public key and placed it in output buffer
- * @param a_key dap_enc_key_t encryption key object
- * @param a_output output data
- * @return result
- */
-int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output)
-{
-    dap_pkey_t * l_output = (dap_pkey_t *) a_output;
+    dap_pkey_type_t l_type;
     if (a_key->pub_key_data_size > 0 ){
         switch (a_key->type) {
             case DAP_ENC_KEY_TYPE_SIG_BLISS:
-                l_output->header.type.type = PKEY_TYPE_SIGN_BLISS ;
-            break;
+                l_type.type = PKEY_TYPE_SIGN_BLISS; break;
             case DAP_ENC_KEY_TYPE_SIG_TESLA:
-                l_output->header.type.type = PKEY_TYPE_SIGN_TESLA ;
-            break;
+                l_type.type = PKEY_TYPE_SIGN_TESLA; break;
             case DAP_ENC_KEY_TYPE_SIG_PICNIC:
-                l_output->header.type.type = PKEY_TYPE_SIGN_PICNIC ;
-            break;
+                l_type.type = PKEY_TYPE_SIGN_PICNIC; break;
             case DAP_ENC_KEY_TYPE_SIG_DILITHIUM:
-                l_output->header.type.type = PKEY_TYPE_SIGN_DILITHIUM;
-            break;
-
+                l_type.type = PKEY_TYPE_SIGN_DILITHIUM; break;
             default:
                 log_it(L_WARNING,"No serialization preset");
-                return -1;
+                return NULL;
+        }
+        size_t l_pub_key_size;
+        uint8_t *l_pkey = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size);
+        if (!l_pkey) {
+            log_it(L_WARNING,"Serialization failed");
+            return NULL;
         }
-        l_output->header.size = a_key->pub_key_data_size;
-        memcpy(l_output->pkey,a_key->pub_key_data,a_key->pub_key_data_size);
-        return 0;
+        dap_pkey_t *l_ret = DAP_NEW_SIZE(dap_pkey_t, sizeof(dap_pkey_t) + l_pub_key_size);
+        l_ret->header.type = l_type;
+        l_ret->header.size = (uint32_t)l_pub_key_size;
+        memcpy(&l_ret->pkey, l_pkey, l_pub_key_size);
+        DAP_DELETE(l_pkey);
+        return l_ret;
     }else{
         log_it(L_WARNING, "No public key in the input enc_key object");
-        return -2;
+        return NULL;
     }
-    return -3;
+    return NULL;
 }
-
-
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 2f6429690bc109696e37bd27b9bb19a2c6016e9c..9d9fdeddc31e5ae17054ff5de277fea916cdd492 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -82,7 +82,7 @@
 static int s_max_attempts = 3;
 static int s_timeout = 20;
 static bool s_debug_more = false;
-static time_t s_client_timeout_read_after_connect_seconds = 5;
+static time_t s_client_timeout_active_after_connect_seconds = 15;
 
 
 static bool s_stage_status_after(dap_client_pvt_t * a_client_internal);
@@ -127,9 +127,8 @@ int dap_client_pvt_init()
     s_max_attempts = dap_config_get_item_int32_default(g_config, "dap_client", "max_tries", s_max_attempts);
     s_timeout = dap_config_get_item_int32_default(g_config, "dap_client", "timeout", s_timeout);
     s_debug_more = dap_config_get_item_bool_default(g_config, "dap_client", "debug_more", false);
-    s_client_timeout_read_after_connect_seconds = (time_t) dap_config_get_item_uint32_default(g_config,
-                                                  "dap_client","timeout_read_after_connect", s_client_timeout_read_after_connect_seconds);
-
+    s_client_timeout_active_after_connect_seconds = (time_t) dap_config_get_item_uint32_default(g_config,
+                                                  "dap_client","timeout_active_after_connect", s_client_timeout_active_after_connect_seconds);
     return 0;
 }
 
@@ -216,7 +215,7 @@ static void s_stream_connected(dap_client_pvt_t * a_client_pvt)
     dap_events_socket_uuid_t * l_es_uuid_ptr = DAP_NEW_Z(dap_events_socket_uuid_t);
     assert(a_client_pvt->stream_es);
     *l_es_uuid_ptr = a_client_pvt->stream_es->uuid;
-    if( dap_timerfd_start_on_worker(a_client_pvt->stream_es->worker, s_client_timeout_read_after_connect_seconds * 1000, s_stream_timer_timeout_after_connected_check ,l_es_uuid_ptr) == NULL ){
+    if( dap_timerfd_start_on_worker(a_client_pvt->stream_es->worker, s_client_timeout_active_after_connect_seconds * 1000, s_stream_timer_timeout_after_connected_check ,l_es_uuid_ptr) == NULL ){
         log_it(L_ERROR,"Can't run timer for stream after connect check for esocket uuid %"DAP_UINT64_FORMAT_U, *l_es_uuid_ptr);
         DAP_DEL_Z(l_es_uuid_ptr);
     }
@@ -237,7 +236,7 @@ static bool s_stream_timer_timeout_check(void * a_arg)
     dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
     if(l_es){
         if (l_es->flags & DAP_SOCK_CONNECTING ){
-            dap_client_pvt_t * l_client_pvt = (dap_client_pvt_t *)l_es->_inheritor;
+            dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
             if (dap_client_pvt_find(l_client_pvt->uuid)) {
                 log_it(L_WARNING,"Connecting timeout for stream uplink request http://%s:%u/, possible network problems or host is down",
                        l_client_pvt->uplink_addr, l_client_pvt->uplink_port);
@@ -278,10 +277,9 @@ static bool s_stream_timer_timeout_after_connected_check(void * a_arg)
 
     dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
     if( l_es ){
-        dap_client_pvt_t * l_client_pvt = (dap_client_pvt_t *)l_es->_inheritor;
+        dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
         if (dap_client_pvt_find(l_client_pvt->uuid)) {
-            if ( time(NULL)- l_client_pvt->ts_last_read >= s_client_timeout_read_after_connect_seconds){
-
+            if (time(NULL) - l_client_pvt->ts_last_active >= s_client_timeout_active_after_connect_seconds) {
                 log_it(L_WARNING,"Activity timeout for streaming uplink http://%s:%u/, possible network problems or host is down",
                        l_client_pvt->uplink_addr, l_client_pvt->uplink_port);
                 l_client_pvt->is_closed_by_timeout = true;
@@ -319,7 +317,7 @@ static bool s_enc_init_delay_before_request_timer_callback(void * a_arg)
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default());
     dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
     if(l_es){
-        dap_client_pvt_t * l_client_pvt =(dap_client_pvt_t*) l_es->_inheritor;
+        dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
         s_stage_status_after(l_client_pvt);
     }
     DAP_DEL_Z(l_es_uuid_ptr);
@@ -525,7 +523,7 @@ static bool s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                             assert(a_client_pvt->stream_es);
                             dap_events_socket_uuid_t * l_stream_es_uuid_ptr = DAP_NEW_Z(dap_events_socket_uuid_t);
                             *l_stream_es_uuid_ptr  = a_client_pvt->stream_es->uuid;
-                            dap_timerfd_start_on_worker(a_client_pvt->worker, (unsigned long)s_client_timeout_read_after_connect_seconds * 1000,
+                            dap_timerfd_start_on_worker(a_client_pvt->worker, (unsigned long)s_client_timeout_active_after_connect_seconds * 1000,
                                                         s_stream_timer_timeout_check,l_stream_es_uuid_ptr);
                         }
                         else if (l_err != EINPROGRESS && l_err != -1){
@@ -554,7 +552,7 @@ static bool s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                             dap_worker_add_events_socket( a_client_pvt->stream_es, l_worker);
                             dap_events_socket_uuid_t * l_stream_es_uuid_ptr = DAP_NEW_Z(dap_events_socket_uuid_t);
                             *l_stream_es_uuid_ptr = a_client_pvt->stream_es->uuid;
-                            dap_timerfd_start_on_worker(a_client_pvt->worker, (unsigned long)s_client_timeout_read_after_connect_seconds * 1000,
+                            dap_timerfd_start_on_worker(a_client_pvt->worker, (unsigned long)s_client_timeout_active_after_connect_seconds * 1000,
                                                         s_stream_timer_timeout_check,l_stream_es_uuid_ptr);
                         }
                     }
@@ -1218,7 +1216,7 @@ static void s_stage_stream_streaming(dap_client_t * a_client, void* arg)
  */
 static void s_stream_es_callback_connected(dap_events_socket_t * a_es)
 {
-    dap_client_pvt_t * l_client_pvt =(dap_client_pvt_t*) a_es->_inheritor;
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_es);
     s_stream_connected(l_client_pvt);
 }
 
@@ -1232,7 +1230,7 @@ static void s_stream_es_callback_delete(dap_events_socket_t *a_es, void *arg)
     (void) arg;
     log_it(L_INFO, "Stream delete callback");
 
-    dap_client_pvt_t *l_client_pvt = (dap_client_pvt_t *)a_es->_inheritor;
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_es);
     a_es->_inheritor = NULL; // To prevent delete in reactor
 
     if(l_client_pvt == NULL) {
@@ -1267,9 +1265,9 @@ static void s_stream_es_callback_delete(dap_events_socket_t *a_es, void *arg)
 static void s_stream_es_callback_read(dap_events_socket_t * a_es, void * arg)
 {
     (void) arg;
-    dap_client_pvt_t * l_client_pvt =(dap_client_pvt_t *) a_es->_inheritor;
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_es);
 
-    l_client_pvt->ts_last_read = time(NULL);
+    l_client_pvt->ts_last_active = time(NULL);
     switch (l_client_pvt->stage) {
         case STAGE_STREAM_SESSION:
             dap_client_go_stage(l_client_pvt->client, STAGE_STREAM_STREAMING, s_stage_stream_streaming);
@@ -1313,7 +1311,7 @@ static void s_stream_es_callback_read(dap_events_socket_t * a_es, void * arg)
 static void s_stream_es_callback_write(dap_events_socket_t * a_es, void * arg)
 {
     (void) arg;
-    dap_client_pvt_t * l_client_pvt = a_es->_inheritor;
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_es);
 
     if (l_client_pvt->stage_status == STAGE_STATUS_ERROR || !l_client_pvt->stream)
         return;
@@ -1348,7 +1346,7 @@ static void s_stream_es_callback_write(dap_events_socket_t * a_es, void * arg)
  */
 static void s_stream_es_callback_error(dap_events_socket_t * a_es, int a_error)
 {
-    dap_client_pvt_t *l_client_pvt = (dap_client_pvt_t *) a_es->_inheritor;
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_es);
     if (!l_client_pvt)
         return;
     l_client_pvt = dap_client_pvt_find(l_client_pvt->uuid);
diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h
index 81af1d0618fc580d240688e23caef24267d39c4c..d8b9c20b65e611ac745c17c005d39f3a2d354471 100644
--- a/dap-sdk/net/client/include/dap_client_pvt.h
+++ b/dap-sdk/net/client/include/dap_client_pvt.h
@@ -91,7 +91,7 @@ typedef struct dap_client_internal
     bool is_encrypted_headers;
     bool is_close_session;// the last request in session, in the header will be added "SessionCloseAfterRequest: true"
     bool is_closed_by_timeout;
-    time_t ts_last_read;
+    time_t ts_last_active;
 
     bool is_always_reconnect; // Always reconnect ever number of tries are over
     dap_client_callback_data_size_t request_response_callback;
@@ -100,6 +100,7 @@ typedef struct dap_client_internal
 } dap_client_pvt_t;
 
 #define DAP_CLIENT_PVT(a) (a ? (dap_client_pvt_t*) a->_internal : NULL)
+#define DAP_ESOCKET_CLIENT_PVT(a) (a ? (dap_client_pvt_t *)a->_inheritor : NULL)
 
 int dap_client_pvt_init();
 void dap_client_pvt_deinit();
diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c
index 30346a117f9296bdfea71277fbd36b7374e02f10..8a4c33262e70a537e63cc0557051df3f407c9b1d 100644
--- a/dap-sdk/net/core/dap_events_socket.c
+++ b/dap-sdk/net/core/dap_events_socket.c
@@ -1217,10 +1217,10 @@ int dap_events_socket_queue_ptr_send_to_input(dap_events_socket_t * a_es_input,
             l_ret=kevent(l_es->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
         else
             l_ret=-100;
-        if(l_ret ==0 ){
+        if(l_ret != -1 ){
             return 0;
         }else{
-            log_it(L_ERROR,"Can't send message in queue, code %d", l_ret);
+            log_it(L_ERROR,"Can't send message in queue, code %d", errno);
             DAP_DELETE(l_es_w_data);
             return l_ret;
         }
@@ -1351,7 +1351,7 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t *a_es, void *a_arg)
         DAP_DELETE(l_es_w_data);
     }
 
-    if(l_n == 0 ){
+    if(l_n != -1 ){
         l_ret = sizeof (a_arg);
     }else{
         l_errno = errno;
@@ -1430,7 +1430,7 @@ int dap_events_socket_event_signal( dap_events_socket_t * a_es, uint64_t a_value
     else
         l_n = -1;
 
-    if(l_n != 0){
+    if(l_n == -1){
         log_it(L_ERROR,"Haven't sent pointer in pipe out queue, code %d", l_n);
         DAP_DELETE(l_es_w_data);
     }
@@ -1570,7 +1570,7 @@ void dap_events_socket_worker_poll_update_unsafe(dap_events_socket_t * a_esocket
         int l_errno=0;
         if (a_esocket->type == DESCRIPTOR_TYPE_EVENT ){
             EV_SET(l_event, a_esocket->socket, EVFILT_USER,EV_ADD| EV_CLEAR ,0,0, &a_esocket->kqueue_event_catched_data );
-            if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL)!=0){
+            if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
                 l_is_error = true;
                 l_errno = errno;
             }
@@ -1578,7 +1578,7 @@ void dap_events_socket_worker_poll_update_unsafe(dap_events_socket_t * a_esocket
             EV_SET(l_event, a_esocket->socket, l_filter,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
             if( a_esocket->flags & DAP_SOCK_READY_TO_READ ){
                 EV_SET(l_event, a_esocket->socket, EVFILT_READ,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-                if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) != 1 ){
+                if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1 ){
                     l_is_error = true;
                     l_errno = errno;
                 }
@@ -1586,7 +1586,7 @@ void dap_events_socket_worker_poll_update_unsafe(dap_events_socket_t * a_esocket
             if( !l_is_error){
                 if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING ){
                     EV_SET(l_event, a_esocket->socket, EVFILT_WRITE,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-                    if(kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) != 1){
+                    if(kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
                         l_is_error = true;
                         l_errno = errno;
                     }
@@ -1641,7 +1641,7 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *a_esocket, bool
         if( l_kqueue_fd>0 ){
             int l_kevent_ret = kevent(l_kqueue_fd,&l_event,1,NULL,0,NULL);
             int l_errno = errno;
-            if ( l_kevent_ret !=1 && l_errno != EINPROGRESS ){
+            if ( l_kevent_ret == -1 && l_errno != EINPROGRESS ){
                 char l_errbuf[128];
                 l_errbuf[0]=0;
                 strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -1709,7 +1709,7 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *a_esocket, bool
         if( l_kqueue_fd>0 ){
             int l_kevent_ret=kevent(l_kqueue_fd,&l_event,1,NULL,0,NULL);
             int l_errno = errno;
-            if ( l_kevent_ret!=l_expected_reply && l_errno != EINPROGRESS && l_errno != ENOENT ){
+            if ( l_kevent_ret == -1 && l_errno != EINPROGRESS && l_errno != ENOENT ){
                 char l_errbuf[128];
                 l_errbuf[0]=0;
                 strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -1873,7 +1873,7 @@ void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap
         struct kevent * l_event = &a_es->kqueue_event;
         if (a_es->kqueue_base_filter){
             EV_SET(l_event, a_es->socket, a_es->kqueue_base_filter ,EV_DELETE, 0,0,a_es);
-            if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) != 1 ) {
+            if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                 int l_errno = errno;
                 char l_errbuf[128];
                 strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -1887,7 +1887,7 @@ void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap
 
             if(a_es->flags & DAP_SOCK_READY_TO_WRITE){
                 EV_SET(l_event, a_es->socket, EVFILT_WRITE ,EV_DELETE, 0,0,a_es);
-                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) != 0 ) {
+                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                     int l_errno = errno;
                     char l_errbuf[128];
                     strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -1897,7 +1897,7 @@ void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap
             }
             if(a_es->flags & DAP_SOCK_READY_TO_READ){
                 EV_SET(l_event, a_es->socket, EVFILT_READ ,EV_DELETE, 0,0,a_es);
-                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) != 0 ) {
+                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                     int l_errno = errno;
                     char l_errbuf[128];
                     strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/net/core/dap_worker.c
index f5281d3ed4e767c786312105e45b7f5216b19e58..81b1818d591c41e9daaa18cfbc8117c0e5401329 100644
--- a/dap-sdk/net/core/dap_worker.c
+++ b/dap-sdk/net/core/dap_worker.c
@@ -329,7 +329,7 @@ void *dap_worker_thread(void *arg)
                 }
                 default:
                     if(s_debug_reactor)
-                        log_it(L_INFO,"RDHUP event on esocket %p (%"DAP_FORMAT_SOCKET") type %d", l_cur, l_cur->socket, l_cur->type );
+                        log_it(L_WARNING, "HUP event on esocket %p (%"DAP_FORMAT_SOCKET") type %d", l_cur, l_cur->socket, l_cur->type );
                 }
             }
 
@@ -575,7 +575,7 @@ void *dap_worker_thread(void *arg)
                     default:{}
                 }
                 if(s_debug_reactor)
-                    log_it(L_INFO,"RDHUP event on esocket %p (%"DAP_FORMAT_SOCKET") type %d", l_cur, l_cur->socket, l_cur->type );
+                    log_it(L_DEBUG, "RDHUP event on esocket %p (%"DAP_FORMAT_SOCKET") type %d", l_cur, l_cur->socket, l_cur->type);
             }
 
             // If its outgoing connection
diff --git a/dap-sdk/net/core/include/dap_proc_queue.h b/dap-sdk/net/core/include/dap_proc_queue.h
index f3e6635c2a769733bdb56dc49a3a1e5e93004b7a..0f66a08e92fba60267f3b676eca792640d114b9e 100644
--- a/dap-sdk/net/core/include/dap_proc_queue.h
+++ b/dap-sdk/net/core/include/dap_proc_queue.h
@@ -25,7 +25,7 @@
 
 typedef struct dap_proc_thread dap_proc_thread_t;
 
-typedef int (*dap_proc_queue_callback_t)(dap_proc_thread_t*,void* );        // Callback for processor. Returns true if
+typedef bool (*dap_proc_queue_callback_t)(dap_proc_thread_t *, void *);     // Callback for processor. Returns true if
                                                                             // we want to stop callback execution and
                                                                             // not to go on next loop
 enum    {
diff --git a/dap-sdk/net/server/http_server/dap_http_simple.c b/dap-sdk/net/server/http_server/dap_http_simple.c
index b69ad02f3bbacd61d546bb0e2033822ccd0509e2..0dddbf1d3a9af2ece290067b915613b1ad8fe399 100644
--- a/dap-sdk/net/server/http_server/dap_http_simple.c
+++ b/dap-sdk/net/server/http_server/dap_http_simple.c
@@ -69,7 +69,7 @@ static void s_http_simple_delete( dap_http_simple_t *a_http_simple);
 static void s_http_client_headers_read( dap_http_client_t *cl_ht, void *arg );
 static void s_http_client_data_read( dap_http_client_t * cl_ht, void *arg );
 static void s_http_client_data_write( dap_http_client_t * a_http_client, void *a_arg );
-static int  s_proc_queue_callback(dap_proc_thread_t * a_thread, void *a_arg );
+static bool s_proc_queue_callback(dap_proc_thread_t * a_thread, void *a_arg );
 
 typedef struct dap_http_simple_url_proc {
 
@@ -279,7 +279,7 @@ inline static void s_write_response_bad_request( dap_http_simple_t * a_http_simp
  * @brief dap_http_simple_proc Execute procession callback and switch to write state
  * @param cl_sh HTTP simple client instance
  */
-static int  s_proc_queue_callback(dap_proc_thread_t * a_thread, void * a_arg )
+static bool s_proc_queue_callback(dap_proc_thread_t * a_thread, void * a_arg )
 {
     (void) a_thread;
      dap_http_simple_t *l_http_simple = (dap_http_simple_t*) a_arg;
diff --git a/dap-sdk/net/server/http_server/http_client/dap_http_header.c b/dap-sdk/net/server/http_server/http_client/dap_http_header.c
index 4e5bb1c44e544e6dd7950c3470db9c027a6d9dba..7b647dea75912ba0cd7274d6d98e9e1d398f5f48 100644
--- a/dap-sdk/net/server/http_server/http_client/dap_http_header.c
+++ b/dap-sdk/net/server/http_server/http_client/dap_http_header.c
@@ -138,17 +138,14 @@ int dap_http_header_parse(struct dap_http_client * cl_ht, const char * str)
  * @param value Header's value
  * @return Pointer to the new HTTP header's structure
  */
-dap_http_header_t* dap_http_header_add(dap_http_header_t ** top, const char*name, const char * value)
-{
-    dap_http_header_t * nh = (dap_http_header_t*) calloc(1,sizeof(dap_http_header_t));
-  //  log_it(L_DEBUG,"Added header %s",name);
-    nh->name=strdup(name);
-    nh->value=strdup(value);
-    nh->next=*top;
-    if(*top)
-        (*top)->prev=nh;
-    *top=nh;
-    return nh;
+dap_http_header_t *dap_http_header_add(dap_http_header_t **a_top, const char *a_name, const char *a_value)
+{ 
+    dap_http_header_t *l_new_header = DAP_NEW_Z(dap_http_header_t);
+    l_new_header->name = dap_strdup(a_name);
+    l_new_header->value = dap_strdup(a_value);
+    DL_APPEND(*a_top, l_new_header);
+    return l_new_header;
+
 }
 
 
@@ -182,17 +179,13 @@ dap_http_header_t * dap_http_out_header_add_f(dap_http_client_t * ht, const char
  * @brief dap_http_header_remove Removes header from the list
  * @param dap_hdr HTTP header
  */
-void dap_http_header_remove(dap_http_header_t ** top, dap_http_header_t * hdr )
+void dap_http_header_remove(dap_http_header_t **a_top, dap_http_header_t *a_hdr)
 {
-    if(hdr->prev)
-        hdr->prev=hdr->next;
-    else
-        *top=hdr->next;
-
-    if(hdr->next)
-        hdr->next->prev=hdr->prev;
-    free(hdr->name);
-    free(hdr->value);
+    DL_DELETE(*a_top, a_hdr);
+    DAP_DELETE(a_hdr->name);
+    DAP_DELETE(a_hdr->value);
+    DAP_DELETE(a_hdr);
+
 }
 
 void print_dap_http_headers(dap_http_header_t * top)
diff --git a/dap-sdk/net/server/http_server/http_client/include/dap_http_header.h b/dap-sdk/net/server/http_server/http_client/include/dap_http_header.h
index f3b1e8e2845095c193aab2d5a42279dfc5a38d47..500c6bcd2bea4f70949f084af082a4cc998957e9 100644
--- a/dap-sdk/net/server/http_server/http_client/include/dap_http_header.h
+++ b/dap-sdk/net/server/http_server/http_client/include/dap_http_header.h
@@ -37,7 +37,7 @@ void dap_http_header_deinit(); // Deinit module
 
 int dap_http_header_parse(struct dap_http_client * cl_ht, const char * str);
 
-dap_http_header_t * dap_http_header_add(dap_http_header_t ** top, const char*name, const char * value);
+dap_http_header_t *dap_http_header_add(dap_http_header_t **a_top, const char *a_name, const char *a_value);
 
 dap_http_header_t * dap_http_out_header_add(struct dap_http_client * ht, const char*name, const char * value);
 dap_http_header_t * dap_http_out_header_add_f(struct dap_http_client * ht, const char*name, const char * value,...);
@@ -46,7 +46,7 @@ dap_http_header_t * dap_http_header_find(dap_http_header_t * top, const char*nam
 
 dap_http_header_t * dap_http_headers_dup(dap_http_header_t * a_top);
 
-void dap_http_header_remove(dap_http_header_t ** top,dap_http_header_t * hdr );
+void dap_http_header_remove(dap_http_header_t **a_top,dap_http_header_t *a_hdr);
 
 // For debug output
 void print_dap_http_headers(dap_http_header_t * top);
diff --git a/dap-sdk/net/stream/stream/CMakeLists.txt b/dap-sdk/net/stream/stream/CMakeLists.txt
index 16fb98fc4e6b8f0e6e25053a63756b6cd19b418b..11d4b6896a85fa96512ad37d6a9c72cf06a36831 100755
--- a/dap-sdk/net/stream/stream/CMakeLists.txt
+++ b/dap-sdk/net/stream/stream/CMakeLists.txt
@@ -7,7 +7,7 @@ file(GLOB STREAM_HDRS include/*.h)
 add_library(${PROJECT_NAME} STATIC ${STREAM_SRCS} ${STREAM_HDRS})
 
 target_link_libraries(dap_stream dap_core dap_server_core dap_crypto
-    dap_http_server dap_enc_server dap_session dap_stream_ch)
+    dap_http_server dap_enc_server dap_session dap_stream_ch dap_client)
 
 target_include_directories(dap_stream INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
diff --git a/dap-sdk/net/stream/stream/dap_stream.c b/dap-sdk/net/stream/stream/dap_stream.c
index a36776d86067c6d1fe429f41fab013a70d2ce65b..144a4ad6c88e92784ba4e12023247da0fec1a933 100644
--- a/dap-sdk/net/stream/stream/dap_stream.c
+++ b/dap-sdk/net/stream/stream/dap_stream.c
@@ -52,6 +52,7 @@
 #include "dap_http_client.h"
 #include "dap_http_header.h"
 #include "dap_stream_worker.h"
+#include "dap_client_pvt.h"
 
 #define LOG_TAG "dap_stream"
 #define HEADER_WITH_SIZE_FIELD 12  //This count of bytes enough for allocate memory for stream packet
@@ -67,6 +68,8 @@ static void s_http_client_data_read(dap_http_client_t * a_http_client, void * a_
 
 static void s_esocket_callback_worker_assign(dap_events_socket_t * a_esocket, dap_worker_t * a_worker);
 static void s_esocket_callback_worker_unassign(dap_events_socket_t * a_esocket, dap_worker_t * a_worker);
+static void s_client_callback_worker_assign(dap_events_socket_t *a_esocket, dap_worker_t *a_worker);
+static void s_client_callback_worker_unassign(dap_events_socket_t *a_esocket, dap_worker_t *a_worker);
 
 static void s_esocket_data_read(dap_events_socket_t* a_esocket, void * a_arg);
 static void s_esocket_write(dap_events_socket_t* a_esocket, void * a_arg);
@@ -75,10 +78,11 @@ static void s_udp_esocket_new(dap_events_socket_t* a_esocket,void * a_arg);
 
 // Internal functions
 static dap_stream_t * s_stream_new(dap_http_client_t * a_http_client); // Create new stream
-static void s_http_client_new(dap_http_client_t * a_esocket, void * a_arg);
+static void s_http_client_new(dap_http_client_t * a_esocket, void * a_arg) { }
 static void s_http_client_delete(dap_http_client_t * a_esocket, void * a_arg);
 
-static bool s_callback_keepalive( void * a_arg);
+static bool s_callback_server_keepalive(void *a_arg);
+static bool s_callback_client_keepalive(void *a_arg);
 
 static bool s_dump_packet_headers = false;
 static bool s_debug = false;
@@ -257,23 +261,45 @@ void check_session( unsigned int a_id, dap_events_socket_t *a_esocket )
  * @brief stream_new Create new stream instance for HTTP client
  * @return New stream_t instance
  */
-dap_stream_t * s_stream_new(dap_http_client_t * a_http_client)
+dap_stream_t *s_stream_new(dap_http_client_t *a_http_client)
 {
-    dap_stream_t * ret= DAP_NEW_Z(dap_stream_t);
-
-    ret->esocket = a_http_client->esocket;
-    ret->stream_worker = (dap_stream_worker_t*) a_http_client->esocket->worker->_inheritor;
-    ret->conn_http=a_http_client;
-    ret->buf_defrag_size = 0;
-    ret->seq_id = 0;
-    ret->client_last_seq_id_packet = (size_t)-1;
-
-    a_http_client->_inheritor=ret;
-
+    dap_stream_t *l_ret = DAP_NEW_Z(dap_stream_t);
+
+    l_ret->esocket = a_http_client->esocket;
+    l_ret->stream_worker = (dap_stream_worker_t *)a_http_client->esocket->worker->_inheritor;
+    l_ret->conn_http = a_http_client;
+    l_ret->buf_defrag_size = 0;
+    l_ret->seq_id = 0;
+    l_ret->client_last_seq_id_packet = (size_t)-1;
+    // Start server keep-alive timer
+    dap_events_socket_uuid_t *l_es_uuid = DAP_NEW_Z(dap_events_socket_uuid_t);
+    *l_es_uuid = l_ret->esocket->uuid;
+    l_ret->keepalive_timer = dap_timerfd_start_on_worker(l_ret->esocket->worker,
+                                                         STREAM_KEEPALIVE_TIMEOUT * 1000,
+                                                         (dap_timerfd_callback_t)s_callback_server_keepalive,
+                                                         l_es_uuid);
+    l_ret->esocket->callbacks.worker_assign_callback = s_esocket_callback_worker_assign;
+    l_ret->esocket->callbacks.worker_unassign_callback = s_esocket_callback_worker_unassign;
+    a_http_client->_inheritor = l_ret;
     log_it(L_NOTICE,"New stream instance");
-    return ret;
+    return l_ret;
 }
 
+/**
+ * @brief dap_stream_new_es
+ * @param a_es
+ * @return
+ */
+dap_stream_t* dap_stream_new_es_client(dap_events_socket_t * a_esocket)
+{
+    dap_stream_t *l_ret = DAP_NEW_Z(dap_stream_t);
+    l_ret->esocket = a_esocket;
+    l_ret->esocket_uuid = a_esocket->uuid;
+    l_ret->is_client_to_uplink = true;
+    l_ret->esocket->callbacks.worker_assign_callback = s_client_callback_worker_assign;
+    l_ret->esocket->callbacks.worker_unassign_callback = s_client_callback_worker_unassign;
+    return l_ret;
+}
 
 /**
  * @brief dap_stream_delete
@@ -314,23 +340,6 @@ static void s_esocket_callback_delete(dap_events_socket_t* a_esocket, void * a_a
     dap_stream_delete(l_stream);
 }
 
-
-/**
- * @brief dap_stream_new_es
- * @param a_es
- * @return
- */
-dap_stream_t* dap_stream_new_es_client(dap_events_socket_t * a_esocket)
-{
-    dap_stream_t * ret= DAP_NEW_Z(dap_stream_t);
-    ret->esocket = a_esocket;
-    ret->esocket_uuid = a_esocket->uuid;
-    ret->buf_defrag_size=0;
-    ret->is_client_to_uplink = true;
-    return ret;
-}
-
-
 /**
  * @brief stream_header_read Read headers callback for HTTP
  * @param a_http_client HTTP client structure
@@ -412,16 +421,6 @@ static void s_http_client_headers_write(dap_http_client_t * a_http_client, void
 
         a_http_client->state_read=DAP_HTTP_CLIENT_STATE_DATA;
         dap_events_socket_set_readable_unsafe(a_http_client->esocket,true);
-        // Connection is established, setting up keepalive timer
-        if (!l_stream->keepalive_timer) {
-            dap_events_socket_uuid_t * l_es_uuid= DAP_NEW_Z(dap_events_socket_uuid_t);
-            *l_es_uuid = a_http_client->esocket->uuid;
-            l_stream->keepalive_timer = dap_timerfd_start_on_worker(a_http_client->esocket->worker,
-                                                                    STREAM_KEEPALIVE_TIMEOUT * 1000,
-                                                                    s_callback_keepalive,
-                                                                    l_es_uuid);
-        }
-
     }
 }
 
@@ -452,16 +451,14 @@ static void s_esocket_callback_worker_assign(dap_events_socket_t * a_esocket, da
     assert(l_http_client);
     dap_stream_t * l_stream = DAP_STREAM(l_http_client);
     assert(l_stream);
-    if (a_esocket->type == DESCRIPTOR_TYPE_SOCKET_UDP ||
-            (l_http_client->state_read == DAP_HTTP_CLIENT_STATE_DATA && l_http_client->state_write == DAP_HTTP_CLIENT_STATE_DATA )) {
-        if (!l_stream->keepalive_timer) {
-            dap_events_socket_uuid_t * l_es_uuid= DAP_NEW_Z(dap_events_socket_uuid_t);
-            *l_es_uuid = a_esocket->uuid;
-            l_stream->keepalive_timer = dap_timerfd_start_on_worker(a_worker,
-                                                                    STREAM_KEEPALIVE_TIMEOUT * 1000,
-                                                                    (dap_timerfd_callback_t)s_callback_keepalive,
-                                                                    l_es_uuid);
-        }
+    // Restart server keepalive timer if it was unassigned before
+    if (!l_stream->keepalive_timer) {
+        dap_events_socket_uuid_t * l_es_uuid= DAP_NEW_Z(dap_events_socket_uuid_t);
+        *l_es_uuid = a_esocket->uuid;
+        l_stream->keepalive_timer = dap_timerfd_start_on_worker(a_worker,
+                                                                STREAM_KEEPALIVE_TIMEOUT * 1000,
+                                                                (dap_timerfd_callback_t)s_callback_server_keepalive,
+                                                                l_es_uuid);
     }
 }
 
@@ -482,6 +479,34 @@ static void s_esocket_callback_worker_unassign(dap_events_socket_t * a_esocket,
     l_stream->keepalive_timer = NULL;
 }
 
+static void s_client_callback_worker_assign(dap_events_socket_t * a_esocket, dap_worker_t * a_worker)
+{
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_esocket);
+    assert(l_client_pvt);
+    dap_stream_t *l_stream = l_client_pvt->stream;
+    assert(l_stream);
+    // Start client keepalive timer or restart it, if it was unassigned before
+    if (!l_stream->keepalive_timer) {
+        dap_events_socket_uuid_t * l_es_uuid= DAP_NEW_Z(dap_events_socket_uuid_t);
+        *l_es_uuid = a_esocket->uuid;
+        l_stream->keepalive_timer = dap_timerfd_start_on_worker(a_worker,
+                                                                STREAM_KEEPALIVE_TIMEOUT * 1000,
+                                                                (dap_timerfd_callback_t)s_callback_client_keepalive,
+                                                                l_es_uuid);
+    }
+}
+
+static void s_client_callback_worker_unassign(dap_events_socket_t * a_esocket, dap_worker_t * a_worker)
+{
+    UNUSED(a_worker);
+    dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(a_esocket);
+    assert(l_client_pvt);
+    dap_stream_t *l_stream = l_client_pvt->stream;
+    assert(l_stream);
+    DAP_DEL_Z(l_stream->keepalive_timer->callback_arg);
+    dap_timerfd_delete(l_stream->keepalive_timer);
+    l_stream->keepalive_timer = NULL;
+}
 
 /**
  * @brief s_data_read
@@ -551,18 +576,6 @@ static void s_http_client_data_read(dap_http_client_t * a_http_client, void * ar
     s_esocket_data_read(a_http_client->esocket,arg);
 }
 
-/**
- * @brief s_http_client_new
- * @param a_http_client
- * @param arg
- */
-static void s_http_client_new(dap_http_client_t * a_http_client, void * arg)
-{
-    a_http_client->esocket->callbacks.worker_assign_callback = s_esocket_callback_worker_assign;
-    a_http_client->esocket->callbacks.worker_unassign_callback = s_esocket_callback_worker_unassign;
-}
-
-
 /**
  * @brief stream_delete Delete stream and free its resources
  * @param sid Stream id
@@ -760,6 +773,7 @@ size_t dap_stream_data_proc_read (dap_stream_t *a_stream)
  */
 static void s_stream_proc_pkt_in(dap_stream_t * a_stream)
 {
+    a_stream->is_active = true;
     dap_stream_pkt_t * l_pkt = a_stream->pkt_buf_in;
     size_t l_pkt_size = a_stream->pkt_buf_in_data_size;
     a_stream->pkt_buf_in=NULL;
@@ -771,7 +785,7 @@ static void s_stream_proc_pkt_in(dap_stream_t * a_stream)
 
         size_t l_dec_pkt_size = dap_stream_pkt_read_unsafe(a_stream, l_pkt, l_ch_pkt, sizeof(a_stream->pkt_cache));
         if (l_dec_pkt_size == 0) {
-            log_it(L_WARNING, "Input: can't decode packet size=%zu",l_pkt_size);
+            log_it(L_WARNING, "Input: can't decode packet size = %zu", l_pkt_size);
             DAP_DELETE(l_pkt);
             return;
         }
@@ -825,6 +839,7 @@ static void s_stream_proc_pkt_in(dap_stream_t * a_stream)
         }
     } break;
     case STREAM_PKT_TYPE_ALIVE:
+        a_stream->is_active = false; // To prevent keep-alive concurrency
         //log_it(L_DEBUG, "Keep alive response recieved");
         break;
     default:
@@ -868,14 +883,29 @@ static bool s_detect_loose_packet(dap_stream_t * a_stream)
  * @param a_arg
  * @return
  */
-static bool s_callback_keepalive( void * a_arg)
+static bool s_callback_keepalive(void *a_arg, bool a_server_side)
 {
     if (!a_arg)
         return false;
     dap_events_socket_uuid_t * l_es_uuid = (dap_events_socket_uuid_t*) a_arg;
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default());
     dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid);
-    if( l_es){
+    if(l_es) {
+        dap_stream_t *l_stream = NULL;
+        if (a_server_side) {
+            dap_http_client_t *l_http_client = DAP_HTTP_CLIENT(l_es);
+            assert(l_http_client);
+            l_stream = DAP_STREAM(l_http_client);
+        } else {
+            dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
+            assert(l_client_pvt);
+            l_stream = l_client_pvt->stream;
+        }
+        assert(l_stream);
+        if (l_stream->is_active) {
+            l_stream->is_active = false;
+            return true;
+        }
         if(s_debug)
             log_it(L_DEBUG,"Keepalive for sock fd %"DAP_FORMAT_SOCKET" uuid 0x%016"DAP_UINT64_FORMAT_x, l_es->socket, *l_es_uuid);
         dap_stream_pkt_hdr_t l_pkt = {};
@@ -890,3 +920,13 @@ static bool s_callback_keepalive( void * a_arg)
         return false; // Socket is removed from worker
     }
 }
+
+static bool s_callback_client_keepalive(void *a_arg)
+{
+    return s_callback_keepalive(a_arg, false);
+}
+
+static bool s_callback_server_keepalive(void *a_arg)
+{
+    return s_callback_keepalive(a_arg, true);
+}
diff --git a/dap-sdk/net/stream/stream/dap_stream_pkt.c b/dap-sdk/net/stream/stream/dap_stream_pkt.c
index 38d14061d3e072b87f5908a7f0596b20f4b059f1..5031551bd08450b3ad17b6a3c5db7a5c22b3af91 100644
--- a/dap-sdk/net/stream/stream/dap_stream_pkt.c
+++ b/dap-sdk/net/stream/stream/dap_stream_pkt.c
@@ -138,6 +138,7 @@ size_t dap_stream_pkt_read_unsafe( dap_stream_t * a_stream, dap_stream_pkt_t * a
 
 size_t dap_stream_pkt_write_unsafe(dap_stream_t * a_stream, const void * a_data, size_t a_data_size)
 {
+    a_stream->is_active = true;
     size_t ret=0;
     dap_stream_pkt_hdr_t pkt_hdr;
 
diff --git a/dap-sdk/net/stream/stream/include/dap_stream.h b/dap-sdk/net/stream/stream/include/dap_stream.h
index b6685a93c473da560e390b0bee0ec031698962a9..a26e14cfc4406a7612ee6bf6506e0d8f91e551f0 100644
--- a/dap-sdk/net/stream/stream/include/dap_stream.h
+++ b/dap-sdk/net/stream/stream/include/dap_stream.h
@@ -53,16 +53,14 @@ typedef struct dap_stream {
     int id;
     dap_stream_session_t * session;
     dap_events_socket_t * esocket; // Connection
-    // uint128_t esocket_uuid;
-    uint64_t esocket_uuid;
+    dap_events_socket_uuid_t esocket_uuid;
     dap_stream_worker_t * stream_worker;
     struct dap_http_client * conn_http; // HTTP-specific
 
     dap_timerfd_t *keepalive_timer;
+    bool is_active;
 
     char * service_key;
-
-    bool is_live;
     bool is_client_to_uplink ;
 
     struct dap_stream_pkt * in_pkt;
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 54911037d8407c96bd12f174c89ce2cac0760609..cb0696b9018919fcc3ec8100f38776eddb210c7e 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -1824,11 +1824,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         if (l_is_blank){
             if(s_debug_more)
                 log_it(L_DEBUG, "Tx check: blank prev hash ");
-           dap_snprintf(l_tx_prev_hash_str,sizeof( l_tx_prev_hash_str),"BLANK");
+            dap_snprintf(l_tx_prev_hash_str,sizeof( l_tx_prev_hash_str),"BLANK");
         }else{
             dap_chain_hash_fast_to_str(&l_tx_prev_hash,l_tx_prev_hash_str,sizeof(l_tx_prev_hash_str));
-            if(s_debug_more)
-                log_it(L_DEBUG, "Tx check:  tx prev hash %s",l_tx_prev_hash_str);
         }
 
         if(l_is_blank || l_is_first_transaction) {
@@ -1855,9 +1853,9 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
         dap_chain_datum_tx_t *l_tx_prev =
                 s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out); // dap_chain_datum_tx_t *l_tx_prev = (dap_chain_datum_tx_t*) dap_chain_node_datum_tx_cache_find(&tx_prev_hash);
         bound_item->item_out = l_item_out;
-        if(!l_tx_prev) { // First transaction
-            if(s_debug_more)
-                log_it(L_DEBUG,"No previous transaction was found for hash %s",l_tx_prev_hash_str);
+        if(!l_tx_prev) { // Unchained transaction
+            //if(s_debug_more)  // Too many messages with thresholds processing
+            //    log_it(L_DEBUG,"No previous transaction was found for hash %s",l_tx_prev_hash_str);
             l_err_num = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS;
             break;
         }
@@ -1971,11 +1969,6 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 l_err_num = -8;
                 break;
             }
-            if (! l_token_item){
-                l_err_num = -16;
-                log_it(L_ERROR,"Can't find token item for conditioned tx out");
-                break;
-            }
             // 5a. Check for condition owner
             dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_prev, NULL, TX_ITEM_TYPE_SIG, NULL);
             dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig);
@@ -2646,10 +2639,12 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
         dap_list_t *l_tist_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_item_tmp->cache_data.n_outs);
         // If debug mode dump the UTXO
         if (dap_log_level_get() == L_DEBUG && s_debug_more) {
-            for (size_t i =0; i < (size_t) l_item_tmp->cache_data.n_outs; i++){
-                dap_chain_tx_out_t * l_tx_out = l_tist_tmp->data;
+            for (size_t i =0; i < (size_t) l_item_tmp->cache_data.n_outs; i++){               
+                dap_chain_tx_out_t *l_tx_out = l_tist_tmp->data;
+                if (l_tx_out->header.type != TX_ITEM_TYPE_OUT)
+                    continue;
                 char * l_tx_out_addr_str = dap_chain_addr_to_str( &l_tx_out->addr );
-                log_it(L_DEBUG,"Added tx out to %s",l_tx_out_addr_str );
+                log_it(L_DEBUG, "Added tx out to %s", l_tx_out_addr_str);
                 DAP_DELETE (l_tx_out_addr_str);
             }
         }
@@ -2668,7 +2663,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
 
         size_t l_tx_size = dap_chain_datum_tx_get_size(a_tx);
         memcpy(l_item_tmp->tx, a_tx, l_tx_size);
-        pthread_rwlock_wrlock(&l_ledger_priv->ledger_rwlock);
+        pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
         HASH_ADD(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t), l_item_tmp); // tx_hash_fast: name of key field
         pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
         // Count TPS
@@ -3191,10 +3186,7 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led
     bool is_search_enable = is_null_hash;
     dap_chain_ledger_tx_item_t *l_iter_current, *l_item_tmp;
     pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
-    HASH_ITER(hh, l_ledger_priv->ledger_items , l_iter_current, l_item_tmp)
-    {
-        pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
-
+    HASH_ITER(hh, l_ledger_priv->ledger_items , l_iter_current, l_item_tmp) {
         dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
         dap_chain_hash_fast_t *l_tx_hash_tmp = &l_iter_current->tx_hash_fast;
         // start searching from the next hash after a_tx_first_hash
@@ -3217,7 +3209,6 @@ const dap_chain_datum_tx_t* dap_chain_ledger_tx_find_by_pkey(dap_ledger_t *a_led
                 break;
             }
         }
-        pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
     }
     pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
     return l_cur_tx;
@@ -3241,9 +3232,7 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le
     dap_chain_tx_out_cond_t *l_tx_out_cond = NULL;
     int l_tx_out_cond_idx;
     pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
-    HASH_ITER(hh, l_ledger_priv->ledger_items, l_iter_current, l_item_tmp)
-    {
-        pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
+    HASH_ITER(hh, l_ledger_priv->ledger_items, l_iter_current, l_item_tmp) {
         dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
         dap_chain_hash_fast_t *l_tx_hash_tmp = &l_iter_current->tx_hash_fast;
         // start searching from the next hash after a_tx_first_hash
@@ -3263,7 +3252,6 @@ dap_chain_datum_tx_t* dap_chain_ledger_tx_cache_find_out_cond(dap_ledger_t *a_le
             }
             break;
         }
-        pthread_rwlock_rdlock(&l_ledger_priv->ledger_rwlock);
     }
     pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
     if (a_out_cond) {
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
index c14c975de1e166da78f188a1723b8f489c438f9b..eb6a5f64fe110dca772346c89ac5098126082661 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c
@@ -38,7 +38,6 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_mempool.h"
 
 #include "dap_chain_net_srv.h"
-#include "dap_chain_net_srv_common.h"
 #include "dap_chain_net_srv_stream_session.h"
 
 
@@ -83,16 +82,6 @@ void dap_stream_ch_chain_net_srv_deinit(void)
 
 }
 
-/**
- * @brief Set srv uid - for client
- */
-void dap_stream_ch_chain_net_srv_set_srv_uid(dap_stream_ch_t* a_ch, dap_chain_net_srv_uid_t a_srv_uid)
-{
-    // save srv id
-    dap_stream_ch_chain_net_srv_t * l_ch_chain_net_srv = DAP_STREAM_CH_CHAIN_NET_SRV(a_ch);
-    l_ch_chain_net_srv->srv_uid.uint64 = a_srv_uid.uint64;
-}
-
 /**
  * @brief s_stream_ch_new
  * @param a_ch
@@ -103,8 +92,9 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch , void* arg)
     (void ) arg;
     a_ch->internal=DAP_NEW_Z(dap_stream_ch_chain_net_srv_t);
     dap_stream_ch_chain_net_srv_t * l_ch_chain_net_srv = DAP_STREAM_CH_CHAIN_NET_SRV(a_ch);
-    pthread_mutex_init( &l_ch_chain_net_srv->mutex,NULL);
-    if (a_ch->stream->session->_inheritor == NULL && a_ch->stream->session != NULL)
+    l_ch_chain_net_srv->ch_uuid = a_ch->uuid;
+    l_ch_chain_net_srv->ch = a_ch;
+    if (a_ch->stream->session && !a_ch->stream->session->_inheritor)
         dap_chain_net_srv_stream_session_create( a_ch->stream->session );
     else if ( a_ch->stream->session == NULL)
         log_it( L_ERROR, "No session at all!");
@@ -144,6 +134,7 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
     dap_stream_ch_chain_net_srv_pkt_error_t l_err;
     memset(&l_err, 0, sizeof(l_err));
     dap_chain_net_srv_t * l_srv = NULL;
+    dap_chain_net_srv_usage_t *l_usage = NULL;
     dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(a_grace->stream_worker, a_grace->ch_uuid);
 
     if (l_ch== NULL )
@@ -212,12 +203,11 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
             }
         }
     }
-    dap_chain_net_srv_usage_t *l_usage = NULL;
     if (!a_grace->usage) {
         l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, l_srv);
-        if ( !l_usage ){ // Usage can't add
-            log_it( L_WARNING, "Usage can't add");
-            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_USAGE_CANT_ADD;
+        if ( !l_usage ){ // Usage can't add          
+            log_it( L_WARNING, "Can't add usage");
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE;
             goto free_exit;
         }
 
@@ -237,7 +227,6 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
         l_usage->tx_cond = l_tx;
     }
     dap_chain_net_srv_price_t * l_price = NULL;
-    dap_chain_datum_tx_receipt_t * l_receipt = NULL;
     const char * l_ticker = NULL;
     if (l_srv->pricelist && !l_grace_start) {
         l_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_request->hdr.tx_cond );
@@ -279,11 +268,10 @@ static bool s_grace_period_control(dap_chain_net_srv_grace_t *a_grace)
                 memcpy(l_price, l_srv->pricelist, sizeof(*l_price));
                 l_price->value_datoshi = 0;
             }
-            l_usage->price = l_price;
-            // TODO extend callback to pass ext and ext size from service callbacks
-            l_receipt = dap_chain_net_srv_issue_receipt( l_usage->service, l_usage, l_usage->price,NULL,0 );
-            dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST, l_receipt, l_receipt->size);
-            DAP_DELETE(l_receipt);
+            l_usage->price = l_price;         
+            l_usage->receipt = dap_chain_net_srv_issue_receipt(l_usage->service, l_usage->price, NULL, 0);
+            dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
+                                           l_usage->receipt, l_usage->receipt->size);
         }else{
             l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND ;
             goto free_exit;
@@ -366,15 +354,20 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
     dap_stream_ch_chain_net_srv_pkt_error_t l_err;
     memset(&l_err,0,sizeof (l_err));
 
-    if(l_ch_pkt ) {
+    if (l_ch_pkt ) {
+        if (l_ch_chain_net_srv->notify_callback) {
+            l_ch_chain_net_srv->notify_callback(l_ch_chain_net_srv, l_ch_pkt->hdr.type, l_ch_pkt, l_ch_chain_net_srv->notify_callback_arg);
+            return; // It's a client behind this
+        }
         switch (l_ch_pkt->hdr.type) {
             // for send test data
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST:{
-                int l_err_code = 0;
                 dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_test_t*) l_ch_pkt->data;
                 size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
-                if(l_ch_pkt->hdr.size != l_request_size) {
-                    log_it(L_WARNING, "Wrong request size, less or more than required");
+                if (l_ch_pkt->hdr.size != l_request_size) {
+                    log_it(L_WARNING, "Wrong response size %u, required %zu", l_ch_pkt->hdr.size, l_request_size);
+                    l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_SIZE;
+                    dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
                     break;
                 }
                 struct timeval l_recvtime2;
@@ -383,52 +376,33 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 //printf("\n%lu.%06lu \n", (unsigned long) l_request->recv_time2.tv_sec, (unsigned long) l_request->recv_time2.tv_usec);
                 dap_chain_hash_fast_t l_data_hash;
                 dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
-                if(l_request->data_size>0 && !dap_hash_fast_compare(&l_data_hash, &(l_request->data_hash))){
-                    l_err_code+=2;
+                if (l_request->data_size > 0 && !dap_hash_fast_compare(&l_data_hash, &l_request->data_hash)) {
+                    l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_HASH;
+                    dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err));
+                    break;
                 }
-
                 // create data to send back
                 dap_stream_ch_chain_net_srv_pkt_test_t *l_request_out = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_test_t, sizeof(dap_stream_ch_chain_net_srv_pkt_test_t) + l_request->data_size_recv);
                 // copy info from recv message
                 memcpy(l_request_out,l_request, sizeof(dap_stream_ch_chain_net_srv_pkt_test_t));
-                l_request_out->data_size = l_request->data_size_recv;
-                randombytes(l_request_out->data, l_request_out->data_size);
-                l_request_out->err_code = l_err_code;
-                dap_hash_fast(l_request_out->data, l_request_out->data_size, &l_request_out->data_hash);
-                strncpy(l_request_out->ip_send,a_ch->stream->esocket->hostaddr  , sizeof(l_request_out->ip_send)-1);
-
+                if (l_request->data_size_recv) {
+                    l_request_out->data_size = l_request->data_size_recv;
+                    randombytes(l_request_out->data, l_request_out->data_size);
+                    dap_hash_fast(l_request_out->data, l_request_out->data_size, &l_request_out->data_hash);
+                }
+                l_request_out->err_code = 0;
+                strncpy(l_request_out->ip_send, a_ch->stream->esocket->hostaddr, sizeof(l_request_out->ip_send) - 1);
                 // Thats to prevent unaligned pointer
                 struct timeval l_tval;
                 gettimeofday(&l_tval, NULL);
                 l_request_out->send_time2.tv_sec = l_tval.tv_sec;
                 l_request_out->send_time2.tv_usec = l_tval.tv_usec;
-
                 // send response
                 dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE, l_request_out,
                                                l_request_out->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t));
                 DAP_DELETE(l_request_out);
             } break;
 
-            // for receive test data.
-            case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE: {
-                dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_test_t *) l_ch_pkt->data;
-                size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
-                if(l_ch_pkt->hdr.size != l_request_size) {
-                    log_it(L_WARNING, "Wrong request size, less or more than required");
-                    break;
-                }
-                struct timeval l_recv_time;
-                gettimeofday(&l_recv_time, NULL);
-                l_request->recv_time1 = l_recv_time;
-                dap_chain_hash_fast_t l_data_hash;
-                dap_hash_fast(l_request->data, l_request->data_size, &l_data_hash);
-                if(!dap_hash_fast_compare(&l_data_hash, &(l_request->data_hash))) {
-                    l_request->err_code += 4;
-                }
-                dap_stream_ch_set_ready_to_write_unsafe(a_ch, false);
-            } break;
-
-            // only for server
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST:{
                 if (l_ch_pkt->hdr.size < sizeof(dap_stream_ch_chain_net_srv_pkt_request_hdr_t) ){
                     log_it( L_WARNING, "Wrong request size, less than minimum");
@@ -438,49 +412,24 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 // Parse the request
                 l_grace->request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_request_t, l_ch_pkt->hdr.size);
                 memcpy(l_grace->request, l_ch_pkt->data, l_ch_pkt->hdr.size);
+                l_ch_chain_net_srv->srv_uid.uint64 = l_grace->request->hdr.srv_uid.uint64;
                 l_grace->request_size = l_ch_pkt->hdr.size;
                 l_grace->ch_uuid = a_ch->uuid;
                 l_grace->stream_worker = a_ch->stream_worker;
                 s_grace_period_control(l_grace);
             } break;
 
-            // only for client
-            case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST:{
-                log_it( L_NOTICE, "Requested smth to sign");
-                dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data;
-                size_t l_receipt_size = l_ch_pkt->hdr.size;
-                // create receipt copy, because l_receipt may be reallocated inside dap_chain_datum_tx_receipt_create()!
-                dap_chain_datum_tx_receipt_t *l_receipt_new = dap_chain_datum_tx_receipt_create(l_receipt->receipt_info.srv_uid,
-                        l_receipt->receipt_info.units_type,
-                        l_receipt->receipt_info.units,
-                        l_receipt->receipt_info.value_datoshi,
-                        l_receipt->exts_n_signs, l_receipt->exts_size);
-                //l_srv_session->usages
-                ///l_usage->service->uid.uint64;
-                //dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find( l_srv_session, l_pkt->hdr.usage_id );
-                dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_ch_chain_net_srv->srv_uid);
-                if(l_srv && l_srv->callback_client_sign_request) {
-                    // Sign receipt
-                    l_srv->callback_client_sign_request(l_srv, 0, NULL, &l_receipt_new, l_receipt_size);
-                    dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE,
-                                                   l_receipt_new, l_receipt_new->size);
-                }
-                DAP_DELETE(l_receipt_new);
-                // TODO sign smth
-            } break;
-
-            // only for server
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE:{
-                if (l_ch_pkt->hdr.size <= sizeof(dap_chain_receipt_info_t) + 1) {
+                 if (l_ch_pkt->hdr.size < sizeof(dap_chain_receipt_info_t)) {
                     log_it(L_ERROR, "Wrong sign response size, %u when expected at least %zu with smth", l_ch_pkt->hdr.size,
-                           sizeof(dap_chain_receipt_info_t)+1 );
+                           sizeof(dap_chain_receipt_info_t));
                     break;
                 }
                 dap_chain_datum_tx_receipt_t * l_receipt = (dap_chain_datum_tx_receipt_t *) l_ch_pkt->data;
                 size_t l_receipt_size = l_ch_pkt->hdr.size;
                 dap_chain_net_srv_usage_t * l_usage= NULL, *l_tmp= NULL;
                 bool l_is_found = false;
-                pthread_mutex_lock(& l_srv_session->parent->mutex );
+                pthread_mutex_lock(& l_srv_session->parent->mutex );        // TODO rework it with packet usage_id
                 HASH_ITER(hh, l_srv_session->usages, l_usage, l_tmp){
                     if ( l_usage->receipt_next ){ // If we have receipt next
                         if ( memcmp(&l_usage->receipt_next->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){
@@ -571,14 +520,12 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 if (! l_usage->receipt_next && l_usage->receipt){
                     DAP_DELETE(l_usage->receipt);
                     l_usage->receipt = DAP_NEW_SIZE(dap_chain_datum_tx_receipt_t,l_receipt_size);
-                    l_usage->receipt_size = l_receipt_size;
                     l_is_first_sign = true;
                     l_usage->is_active = true;
                     memcpy( l_usage->receipt, l_receipt, l_receipt_size);
                 } else if (l_usage->receipt_next ){
                     DAP_DELETE(l_usage->receipt_next);
                     l_usage->receipt_next = DAP_NEW_SIZE(dap_chain_datum_tx_receipt_t,l_receipt_size);
-                    l_usage->receipt_next_size = l_receipt_size;
                     l_usage->is_active = true;
                     memcpy( l_usage->receipt_next, l_receipt, l_receipt_size);
                 }
@@ -587,20 +534,21 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 dap_chain_hash_fast_t l_receipt_hash={0};
                 dap_hash_fast(l_receipt,l_receipt_size,&l_receipt_hash);
 
-                char * l_receipt_hash_str = dap_chain_hash_fast_to_str_new(&l_receipt_hash);
-                dap_chain_global_db_gr_set( l_receipt_hash_str,l_receipt,l_receipt_size,"local.receipts");
+                char *l_receipt_hash_str = dap_chain_hash_fast_to_str_new(&l_receipt_hash);
+                dap_chain_global_db_gr_set(l_receipt_hash_str, l_receipt, l_receipt_size, "local.receipts");
                 DAP_DELETE(l_receipt_hash_str);
 
                 size_t l_success_size;
                 dap_chain_hash_fast_t *l_tx_in_hash  = NULL;
                 if (!l_usage->is_grace) {
                     // Form input transaction
-                    dap_chain_addr_t *l_wallet_addr = dap_chain_wallet_get_addr(l_usage->wallet, l_usage->net->pub.id);
+                    dap_chain_addr_t *l_wallet_addr = dap_chain_wallet_get_addr(l_usage->price->wallet, l_usage->net->pub.id);
                     l_tx_in_hash = dap_chain_mempool_tx_create_cond_input(l_usage->net, &l_usage->tx_cond_hash, l_wallet_addr,
-                                                                          dap_chain_wallet_get_key(l_usage->wallet, 0),
-                                                                          l_receipt, l_receipt_size);
-                    if ( l_tx_in_hash){
-                        char * l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(l_tx_in_hash);
+                                                                          dap_chain_wallet_get_key(l_usage->price->wallet, 0),
+                                                                          l_receipt);
+                    if (l_tx_in_hash) {
+                        memcpy(&l_usage->tx_cond_hash, l_tx_in_hash, sizeof(dap_chain_hash_fast_t));
+                        char *l_tx_in_hash_str = dap_chain_hash_fast_to_str_new(l_tx_in_hash);
                         log_it(L_NOTICE, "Formed tx %s for input with active receipt", l_tx_in_hash_str);
                         DAP_DELETE(l_tx_in_hash_str);
                     }else
@@ -632,42 +580,18 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 if ( l_is_first_sign && l_usage->service->callback_response_success){
                     if( l_usage->service->callback_response_success(l_usage->service,l_usage->id,  l_usage->client,
                                                                 l_receipt, l_receipt_size ) !=0 ){
-                        log_it(L_NOTICE, "No success by service callback, inactivating service usage");
+                        log_it(L_NOTICE, "No success by service success callback, inactivating service usage");
                         l_usage->is_active = false;
                     }
-                    // issue receipt next
-                    l_usage->receipt_next = dap_chain_net_srv_issue_receipt( l_usage->service, l_usage, l_usage->price ,NULL,0);
-                    l_usage->receipt_next_size = l_usage->receipt_next->size;
-                    dap_stream_ch_pkt_write_unsafe( a_ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST ,
-                                             l_usage->receipt_next, l_usage->receipt_next->size);
-
-                }else if ( l_usage->service->callback_receipt_next_success){
-                    if (l_usage->service->callback_receipt_next_success(l_usage->service,l_usage->id,  l_usage->client,
+                } else if (l_usage->service->callback_receipt_next_success) {
+                    if (l_usage->service->callback_receipt_next_success(l_usage->service, l_usage->id, l_usage->client,
                                                                 l_receipt, l_receipt_size ) != 0 ){
-                        log_it(L_NOTICE, "No success by service callback, inactivating service usage");
+                        log_it(L_NOTICE, "No success by service receipt_next callback, inactivating service usage");
                         l_usage->is_active = false;
                     }
                 }
             } break;
 
-            case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS:{
-                log_it( L_NOTICE, "Responsed with success");
-                // TODO code for service client mode
-                dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*)l_ch_pkt->data;
-                size_t l_success_size = l_ch_pkt->hdr.size;
-                dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get(l_success->hdr.srv_uid);
-                if ( l_srv && l_srv->callback_client_success){
-                    // Create client for client)
-                    dap_chain_net_srv_client_remote_t *l_client = DAP_NEW_Z(dap_chain_net_srv_client_remote_t);
-                    l_client->ch = a_ch;
-                    l_client->stream_worker = a_ch->stream_worker;
-                    l_client->ts_created = time(NULL);
-                    l_client->session_id = a_ch->stream->session->id;
-                    l_srv->callback_client_success(l_srv, l_success->hdr.usage_id,  l_client, l_success, l_success_size );
-                    //l_success->hdr.net_id, l_success->hdr.srv_uid, l_success->hdr.usage_id
-                }
-            } break;
-
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_DATA:{
                 if (l_ch_pkt->hdr.size < sizeof(dap_stream_ch_chain_net_srv_pkt_data_hdr_t) ){
                     log_it( L_WARNING, "Wrong request size, less than minimum");
@@ -678,7 +602,6 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                 size_t l_pkt_size = l_ch_pkt->hdr.size - sizeof (dap_stream_ch_chain_net_srv_pkt_data_t);
                 dap_chain_net_srv_t * l_srv = dap_chain_net_srv_get( l_pkt->hdr.srv_uid);
                 dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find_unsafe( l_srv_session, l_pkt->hdr.usage_id );
-
                 // If service not found
                 if ( l_srv == NULL){
                     l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND ;
@@ -686,18 +609,21 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch , void* a_arg)
                     dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err) );
                     break;
                 }
-                // Check if callback is not present
-                if ( l_srv->callback_stream_ch_read == NULL ){
-                    l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_CH_NOT_FOUND ;
-                    l_err.srv_uid = l_pkt->hdr.srv_uid;
-                    dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof (l_err) );
+                if (!l_srv->callback_custom_data)
                     break;
+                size_t l_out_data_size = 0;
+                void *l_out_data = l_srv->callback_custom_data(l_srv, l_usage, l_pkt->data, l_pkt_size, &l_out_data_size);
+                if (l_out_data && l_out_data_size) {
+                    dap_stream_ch_chain_net_srv_pkt_data_t *l_data = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_data_t,
+                                                                                    sizeof(dap_stream_ch_chain_net_srv_pkt_data_t) + l_out_data_size);
+                    l_data->hdr.version = 1;
+                    l_data->hdr.srv_uid = l_srv->uid;
+                    l_data->hdr.usage_id = l_pkt->hdr.usage_id;
+                    l_data->hdr.data_size = l_out_data_size;
+                    memcpy(l_data->data, l_out_data, l_out_data_size);
+                    dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_DATA, l_data, sizeof(dap_stream_ch_chain_net_srv_pkt_data_t)+l_out_data_size);
+                    DAP_DELETE(l_data);
                 }
-                // Call callback if present
-
-                l_srv->callback_stream_ch_read( l_srv,l_usage->id, l_usage->client, l_pkt->data, l_pkt_size );
-
-
             } break;
 
             case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR:{
diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h
index 1d8b3ed468dcf22c6ae07acd3738c7280275f24a..53490cc0c59594dc5215bceb4549146935108c6c 100644
--- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h
+++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.h
@@ -25,7 +25,7 @@
 #pragma once
 
 #include <pthread.h>
-#include "dap_stream_ch.h"
+#include "dap_stream_worker.h"
 #include "dap_stream_ch_pkt.h"
 #include "dap_chain_common.h"
 
@@ -35,14 +35,14 @@ typedef void (*dap_stream_ch_chain_net_srv_callback_packet_t)(dap_stream_ch_chai
         dap_stream_ch_pkt_t *, void *);
 
 typedef struct dap_stream_ch_chain_net_srv {
-    pthread_mutex_t mutex;
     dap_chain_net_srv_uid_t srv_uid;
+    dap_stream_ch_t *ch;
+    dap_stream_ch_uuid_t ch_uuid;
     dap_stream_ch_chain_net_srv_callback_packet_t notify_callback;
     void *notify_callback_arg;
 } dap_stream_ch_chain_net_srv_t;
 
 #define DAP_STREAM_CH_CHAIN_NET_SRV(a) ((dap_stream_ch_chain_net_srv_t *) ((a)->internal) )
 
-void dap_stream_ch_chain_net_srv_set_srv_uid(dap_stream_ch_t* a_ch, dap_chain_net_srv_uid_t a_srv_uid);
 uint8_t dap_stream_ch_chain_net_srv_get_id();
 int dap_stream_ch_chain_net_srv_init(void);
diff --git a/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv_pkt.h b/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv_pkt.h
index aec3d53789164949aee756891c54ea0e226cfc27..0b78c06d446b2b3ba73f912ce85048485346acf9 100644
--- a/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv_pkt.h
+++ b/modules/channel/chain-net-srv/include/dap_stream_ch_chain_net_srv_pkt.h
@@ -31,7 +31,6 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include <stddef.h>
 #include <stdint.h>
 
-#include "dap_chain_net_srv_common.h"
 #include "dap_chain_net_srv_stream_session.h"
 
 
diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c
index 325d3ac2bf2b6bcc00c3e92f6d082b666c791c69..b60d4678d704dd116c7ae5bd1357aee09f1c5d14 100644
--- a/modules/channel/chain/dap_stream_ch_chain.c
+++ b/modules/channel/chain/dap_stream_ch_chain.c
@@ -132,7 +132,6 @@ int dap_stream_ch_chain_init()
     s_update_pack_size = dap_config_get_item_int16_default(g_config,"stream_ch_chain","update_pack_size",100);
     s_list_ban_groups = dap_config_get_array_str(g_config, "stream_ch_chain", "ban_list_sync_groups", &s_size_ban_groups);
     s_list_white_groups = dap_config_get_array_str(g_config, "stream_ch_chain", "white_list_sync_groups", &s_size_white_groups);
-
     return 0;
 }
 
@@ -184,20 +183,9 @@ static void s_sync_request_delete(struct sync_request * a_sync_request)
 static bool s_stream_ch_delete_in_proc(dap_proc_thread_t * a_thread, void * a_arg)
 {
     (void) a_thread;
-    dap_stream_ch_chain_t * l_ch_chain=(dap_stream_ch_chain_t*) a_arg;
-    dap_stream_ch_chain_hash_item_t * l_item = NULL, *l_tmp = NULL;
-
-    // Clear remote atoms
-    HASH_ITER(hh, l_ch_chain->remote_atoms, l_item, l_tmp){
-        HASH_DEL(l_ch_chain->remote_atoms, l_item);
-        DAP_DELETE(l_item);
-    }
-    // Clear remote gdbs
-    HASH_ITER(hh, l_ch_chain->remote_gdbs, l_item, l_tmp){
-        HASH_DEL(l_ch_chain->remote_gdbs, l_item);
-        DAP_DELETE(l_item);
-    }
-    DAP_DELETE(l_ch_chain);
+    dap_stream_ch_chain_go_idle((dap_stream_ch_chain_t *)a_arg);
+    s_free_log_list_gdb((dap_stream_ch_chain_t *)a_arg);
+    DAP_DELETE(a_arg);
     return true;
 }
 
@@ -700,9 +688,8 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg)
         const char *l_last_group = l_store_obj->group;
         int l_last_type = l_store_obj->type;
         bool l_group_changed = false;
-
-
-
+        uint32_t l_time_store_lim = dap_config_get_item_uint32_default(g_config, "resources", "dap_global_db_time_store_limit", 72);
+        uint64_t l_limit_time = l_time_store_lim ? (uint64_t)time(NULL) - l_time_store_lim * 3600 : 0;
 
         for (size_t i = 0; i < l_data_obj_count; i++) {
             // obj to add
@@ -754,7 +741,8 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg)
             }
             // check the applied object newer that we have stored or erased
             if (l_obj->timestamp > global_db_gr_del_get_timestamp(l_obj->group, l_obj->key) &&
-                    l_obj->timestamp > l_timestamp_cur) {
+                    l_obj->timestamp > l_timestamp_cur &&
+                    (l_obj->type != 'd' || l_obj->timestamp > l_limit_time)) {
                 l_apply = true;
             }
             if (s_debug_more){
@@ -844,7 +832,7 @@ static bool s_chain_timer_callback(void *a_arg)
         return false;
     }
     dap_stream_ch_chain_t *l_ch_chain = DAP_STREAM_CH_CHAIN(l_ch);
-    if (!l_ch_chain->was_active) {
+    if (l_ch_chain->timer_shots++ >= 3) {
         if (l_ch_chain->state != CHAIN_STATE_IDLE) {
             dap_stream_ch_chain_go_idle(l_ch_chain);
         }
@@ -856,7 +844,6 @@ static bool s_chain_timer_callback(void *a_arg)
         l_ch_chain->activity_timer = NULL;
         return false;
     }
-    l_ch_chain->was_active = false;
     // Sending dumb packet with nothing to inform remote thats we're just skiping atoms of GDB's, nothing freezed
     if (l_ch_chain->state == CHAIN_STATE_SYNC_CHAINS)
         dap_stream_ch_chain_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_UPDATE_CHAINS_TSD,
@@ -882,8 +869,8 @@ static void s_chain_timer_reset(dap_stream_ch_chain_t *a_ch_chain)
         dap_stream_ch_uuid_t *l_uuid = DAP_DUP(&DAP_STREAM_CH(a_ch_chain)->uuid);
         a_ch_chain->activity_timer = dap_timerfd_start_on_worker(DAP_STREAM_CH(a_ch_chain)->stream_worker->worker,
                                                                  3000, s_chain_timer_callback, (void *)l_uuid);
-    } else
-        a_ch_chain->was_active = true;
+    }
+    a_ch_chain->timer_shots = 0;
 }
 
 /**
@@ -1295,14 +1282,6 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                     else
                         log_it(L_INFO, "In: SYNC_CHAINS pkt");
                 }
-                if ((l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_PKT_TYPE_UPDATE_CHAINS_END) &&
-                        HASH_COUNT(l_ch_chain->remote_atoms) > 5000) {
-                    // TODO remove this after chains will come in order
-                    s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64,
-                                                        l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64,
-                                                        "ERROR_SYNC_REQUEST_IS_TOO_LARGE");
-                    break;
-                }
                 struct sync_request *l_sync_request = dap_stream_ch_chain_create_sync_request(l_chain_pkt, a_ch);
                 l_ch_chain->stats_request_atoms_processed = 0;
                 if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_CHAINS) {
diff --git a/modules/channel/chain/include/dap_stream_ch_chain.h b/modules/channel/chain/include/dap_stream_ch_chain.h
index fa63d53c2657cbb7ecd3e26ffdf8d2a49f0fbdea..45fb3c6c749275aa71310dcda4728e462386bff6 100644
--- a/modules/channel/chain/include/dap_stream_ch_chain.h
+++ b/modules/channel/chain/include/dap_stream_ch_chain.h
@@ -75,7 +75,7 @@ typedef struct dap_stream_ch_chain {
     dap_stream_ch_chain_pkt_hdr_t request_hdr;
     dap_list_t *request_db_iter;
 
-    bool was_active;
+    int timer_shots;
     dap_timerfd_t *activity_timer;
 
     dap_stream_ch_chain_callback_packet_t callback_notify_packet_out;
diff --git a/modules/common/dap_chain_datum_tx.c b/modules/common/dap_chain_datum_tx.c
index ef4b6934d2219b23a8389f909f6f64a49f689651..e73cdc334cdde6774d50571b0dde95916e5bdbb2 100644
--- a/modules/common/dap_chain_datum_tx.c
+++ b/modules/common/dap_chain_datum_tx.c
@@ -75,7 +75,7 @@ int dap_chain_datum_tx_add_item(dap_chain_datum_tx_t **a_tx, const uint8_t *a_it
     if(!size)
         return -1;
     dap_chain_datum_tx_t *tx_cur = *a_tx;
-    tx_cur = (dap_chain_datum_tx_t*) realloc(tx_cur, dap_chain_datum_tx_get_size(tx_cur) + size);
+    tx_cur = (dap_chain_datum_tx_t *)DAP_REALLOC(tx_cur, dap_chain_datum_tx_get_size(tx_cur) + size);
     memcpy((uint8_t*) tx_cur->tx_items + tx_cur->header.tx_items_size, a_item, size);
     tx_cur->header.tx_items_size += size;
     *a_tx = tx_cur;
@@ -179,7 +179,7 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c
  *
  * return 1 Ok, -1 Error
  */
-int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_pkey_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
         uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size)
 {
     dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_pay(
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index e69e951c0b833fd7bc9f5b4185232ca5155ab982..8723a48914e2171355311548ad57193f2fa22574 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -85,9 +85,9 @@ static size_t dap_chain_tx_pkey_get_size(const dap_chain_tx_pkey_t *a_item)
     return size;
 }
 
-static size_t dap_chain_tx_sig_get_size(const dap_chain_tx_sig_t *item)
+static size_t dap_chain_tx_sig_get_size(const dap_chain_tx_sig_t *a_item)
 {
-    size_t size = sizeof(dap_chain_tx_sig_t) + item->header.sig_size;
+    size_t size = sizeof(dap_chain_tx_sig_t) + a_item->header.sig_size;
     return size;
 }
 
@@ -98,6 +98,12 @@ static size_t dap_chain_tx_token_get_size(const dap_chain_tx_token_t *a_item)
     return size;
 }
 
+static size_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t *a_item)
+{
+    size_t size = a_item->size;
+    return size;
+}
+
 /**
  * Get item type
  *
@@ -133,7 +139,8 @@ size_t dap_chain_datum_item_tx_get_size(const uint8_t *a_item)
         size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item);
         break;
     case TX_ITEM_TYPE_RECEIPT: // Receipt
-        size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t*) a_item);
+        size = dap_chain_datum_tx_receipt_get_size((const dap_chain_datum_tx_receipt_t *)a_item);
+        break;
     case TX_ITEM_TYPE_IN_COND: // Transaction inputs with condition
         size = dap_chain_tx_in_cond_get_size((const dap_chain_tx_in_cond_t*) a_item);
         break;
@@ -244,16 +251,13 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a
  *
  * return item, NULL Error
  */
-dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_pkey_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
                                                                              uint256_t a_value, uint256_t a_value_max_per_unit,
                                                                              dap_chain_net_srv_price_unit_uid_t a_unit,
                                                                              const void *a_params, size_t a_params_size)
 {
-    if(!a_key || !a_params)
+    if (!a_key || !a_key->pkey)
         return NULL;
-    size_t l_pub_key_size = 0;
-    uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size);
-
 
     dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size);
     if(l_item == NULL)
@@ -261,13 +265,15 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc
 
     l_item->header.item_type = TX_ITEM_TYPE_OUT_256_COND;
     l_item->header.value = a_value;
-    l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY; // By default creatre cond for service pay. Rework with smth more flexible
+    l_item->header.subtype = DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY;
     l_item->subtype.srv_pay.srv_uid = a_srv_uid;
     l_item->subtype.srv_pay.unit = a_unit;
     l_item->subtype.srv_pay.unit_price_max_datoshi = a_value_max_per_unit;
-    dap_hash_fast( l_pub_key, l_pub_key_size, & l_item->subtype.srv_pay.pkey_hash);
-    l_item->params_size = (uint32_t)a_params_size;
-    memcpy(l_item->params, a_params, a_params_size);
+    dap_hash_fast(a_key->pkey, a_key->header.size, &l_item->subtype.srv_pay.pkey_hash);
+    if (a_params && a_params_size) {
+        l_item->params_size = (uint32_t)a_params_size;
+        memcpy(l_item->params, a_params, a_params_size);
+    }
     return l_item;
 }
 
diff --git a/modules/common/dap_chain_datum_tx_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c
index 5e374016d46fb98952c1f535ecbcfd39b89d64bf..b7251c970e9257359c11f1beeeda68f816d144ba 100644
--- a/modules/common/dap_chain_datum_tx_receipt.c
+++ b/modules/common/dap_chain_datum_tx_receipt.c
@@ -45,42 +45,41 @@ dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_
                                                                     uint64_t a_units, uint256_t a_value_datoshi,
                                                                   const void * a_ext, size_t a_ext_size)
 {
-    dap_chain_datum_tx_receipt_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_datum_tx_receipt_t, dap_chain_datum_tx_receipt_get_size_hdr() +a_ext_size );
+
+    dap_chain_datum_tx_receipt_t *l_ret = DAP_NEW_Z_SIZE(dap_chain_datum_tx_receipt_t,
+                                                         sizeof(dap_chain_datum_tx_receipt_t) + a_ext_size);
     l_ret->type = TX_ITEM_TYPE_RECEIPT;
     l_ret->receipt_info.units_type = a_units_type;
     l_ret->receipt_info.srv_uid = a_srv_uid;
     l_ret->receipt_info.units = a_units;
     l_ret->receipt_info.value_datoshi = a_value_datoshi;
-    l_ret->size = dap_chain_datum_tx_receipt_get_size_hdr()+a_ext_size;
+    l_ret->size = sizeof(dap_chain_datum_tx_receipt_t) + a_ext_size;
 
-    if( a_ext_size && a_ext){
+    if (a_ext_size && a_ext) {
         l_ret->exts_size = a_ext_size;
         memcpy(l_ret->exts_n_signs, a_ext, a_ext_size);
     }
     return  l_ret;
 }
 
-size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key )
+dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t *a_receipt, dap_enc_key_t *a_key)
 {
-    dap_chain_datum_tx_receipt_t *l_receipt = *a_receipt;
-    if ( ! *a_receipt ){
-        log_it( L_ERROR, "NULL receipt, can't add sign");
-        return 0;
+    if (!a_receipt) {
+        log_it(L_ERROR, "NULL receipt, can't add sign");
+        return NULL;
     }
-    dap_sign_t * l_sign = dap_sign_create(a_key,&l_receipt->receipt_info,sizeof (l_receipt->receipt_info),0);
-    size_t l_sign_size = l_sign? dap_sign_get_size( l_sign ) : 0;
-    if ( ! l_sign || ! l_sign_size ){
-        log_it( L_ERROR, "Can't sign the receipt, may be smth with key?");
-        return 0;
+    dap_sign_t *l_sign = dap_sign_create(a_key, &a_receipt->receipt_info, sizeof(a_receipt->receipt_info), 0);
+    size_t l_sign_size = l_sign ? dap_sign_get_size(l_sign) : 0;
+    if (!l_sign || !l_sign_size) {
+        log_it(L_ERROR, "Can't sign the receipt, may be smth with key?");
+        return NULL;
     }
-    l_receipt= (dap_chain_datum_tx_receipt_t*) DAP_REALLOC(l_receipt, a_receipt_size+l_sign_size);
-    memcpy(l_receipt->exts_n_signs + l_receipt->exts_size, l_sign, l_sign_size);
-    a_receipt_size += l_sign_size;
-    l_receipt->size = a_receipt_size;
-    l_receipt->exts_size += l_sign_size;
-    DAP_DELETE( l_sign );
-    *a_receipt = l_receipt;
-    return a_receipt_size;
+    dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t *)
+                                                DAP_REALLOC(a_receipt, a_receipt->size + l_sign_size);
+    memcpy((byte_t *)l_receipt + l_receipt->size, l_sign, l_sign_size);
+    l_receipt->size += l_sign_size;
+    DAP_DELETE(l_sign);
+    return l_receipt;
 }
 
 /**
@@ -91,17 +90,21 @@ size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_rec
  */
 dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size, uint16_t a_sign_position)
 {
-    if ( !l_receipt ||  l_receipt_size != l_receipt->size || l_receipt_size <= sizeof (l_receipt->receipt_info)+1)
+    if (!l_receipt ||  l_receipt_size != l_receipt->size ||
+            l_receipt->size == sizeof(dap_chain_datum_tx_receipt_t) + l_receipt->exts_size)
         return NULL;
-    dap_sign_t * l_sign = (dap_sign_t *)l_receipt->exts_n_signs;//+l_receipt->exts_size);
-    for ( ; a_sign_position && l_receipt_size > (size_t) ( (byte_t *) l_sign - (byte_t *) l_receipt ) ; a_sign_position-- ){
-        l_sign =(dap_sign_t *) (((byte_t*) l_sign)+  dap_sign_get_size( l_sign ));
+    dap_sign_t *l_sign = (dap_sign_t *)l_receipt->exts_n_signs + l_receipt->exts_size;
+    uint16_t l_sign_position;
+    for (l_sign_position = a_sign_position;
+             l_sign_position && l_receipt_size > (size_t)((byte_t *)l_sign - (byte_t *)l_receipt);
+             l_sign_position--) {
+        l_sign = (dap_sign_t *)((byte_t *)l_sign + dap_sign_get_size(l_sign));
     }
     // not enough signs in receipt
-    if(a_sign_position>0)
+    if (l_sign_position > 0)
         return NULL;
     // too big sign size
-    if((l_sign->header.sign_size + ((byte_t*) l_sign - (byte_t*) l_receipt->exts_n_signs)) >= l_receipt->exts_size)
+    if((l_sign->header.sign_size + ((byte_t*) l_sign - (byte_t*) l_receipt->exts_n_signs)) >= l_receipt->size)
         return NULL;
     return l_sign;
 }
diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h
index f0050efad9427c58f7509a063ce310ca2719fab1..c7623b2df662cca6d67f252fe73acf484d6586b9 100644
--- a/modules/common/include/dap_chain_common.h
+++ b/modules/common/include/dap_chain_common.h
@@ -211,14 +211,19 @@ enum dap_chain_tx_item_type {
     TX_ITEM_TYPE_OUT_ALL = 0xfe,
     TX_ITEM_TYPE_ANY = 0xff
 };
-typedef uint32_t dap_chain_tx_item_type_t;
+typedef byte_t dap_chain_tx_item_type_t;
 
-
-typedef struct dap_chain_receipt{
+typedef struct dap_chain_receipt_info {
     dap_chain_net_srv_uid_t srv_uid; // Service UID
+#if DAP_CHAIN_NET_SRV_UID_SIZE == 8
+    uint64_t addition;
+#endif
     dap_chain_net_srv_price_unit_uid_t units_type;
     uint64_t units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT
-    uint256_t value_datoshi; // Receipt value
+    union {
+        uint256_t value_datoshi; // Receipt value
+        uint64_t value_64;       // Old receipts compliance
+    };
 } dap_chain_receipt_info_t;
 
 #ifdef __cplusplus
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index c6b9c79f3d4e87c4fa817ab9586eea1d93714067..f07af98f8a19f8c74b72b484a80d6244df116018 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -119,7 +119,8 @@ int dap_chain_datum_tx_add_out_ext_item(dap_chain_datum_tx_t **a_tx, const dap_c
  *
  * return 1 Ok, -1 Error
  */
-int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+
+int dap_chain_datum_tx_add_out_cond_item(dap_chain_datum_tx_t **a_tx, dap_pkey_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
         uint256_t a_value, uint256_t a_value_max_per_unit, dap_chain_net_srv_price_unit_uid_t a_unit, const void *a_cond, size_t a_cond_size);
 
 /**
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index fb43da77230d11e14fc23f82898b36c16f8ea9c3..5f1f85ee0f5d683c8860ee0c841af80203005f20 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -111,7 +111,7 @@ dap_chain_tx_out_ext_t* dap_chain_datum_tx_item_out_ext_create(const dap_chain_a
  *
  * return item, NULL Error
  */
-dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_enc_key_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
+dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_out_cond_create_srv_pay(dap_pkey_t *a_key, dap_chain_net_srv_uid_t a_srv_uid,
                                                                              uint256_t a_value, uint256_t a_value_max_per_unit,
                                                                              dap_chain_net_srv_price_unit_uid_t a_unit,
                                                                              const void *a_params, size_t a_params_size);
diff --git a/modules/common/include/dap_chain_datum_tx_receipt.h b/modules/common/include/dap_chain_datum_tx_receipt.h
index be45c6405239fb1435ed2e4a376ec52735b40346..464973febbce36ce4f24a9691876f62db258e12a 100644
--- a/modules/common/include/dap_chain_datum_tx_receipt.h
+++ b/modules/common/include/dap_chain_datum_tx_receipt.h
@@ -34,8 +34,8 @@
 typedef struct dap_chain_datum_tx_receipt {
     dap_chain_tx_item_type_t type; // Transaction item type
     dap_chain_receipt_info_t receipt_info; // Receipt itself
-    uint16_t size;
-    uint16_t exts_size;
+    uint64_t size;
+    uint64_t exts_size;
     byte_t exts_n_signs[]; // Signatures, first from provider, second from client
 }DAP_ALIGN_PACKED dap_chain_datum_tx_receipt_t;
 
@@ -44,19 +44,13 @@ typedef struct dap_chain_datum_tx_receipt {
 extern "C" {
 #endif
 
-static inline size_t dap_chain_datum_tx_receipt_get_size_hdr(){ return 1+sizeof (dap_chain_receipt_info_t)+sizeof (uint16_t) +sizeof (uint16_t); }
-
 dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create(dap_chain_net_srv_uid_t srv_uid,
                                                                   dap_chain_net_srv_price_unit_uid_t units_type,
                                                                     uint64_t units, uint256_t value_datoshi, const void * a_ext, size_t a_ext_size);
-size_t dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t ** a_receipt, size_t a_receipt_size, dap_enc_key_t *a_key );
+
+dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datum_tx_receipt_t *a_receipt, dap_enc_key_t *a_key);
 dap_sign_t* dap_chain_datum_tx_receipt_sign_get(dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size , uint16_t sign_position);
 uint16_t dap_chain_datum_tx_receipt_signs_count(dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size);
-static inline uint16_t dap_chain_datum_tx_receipt_get_size(const dap_chain_datum_tx_receipt_t * l_receipt)
-{
-    return l_receipt->size;
-}
-
 
 #ifdef __cplusplus
 }
diff --git a/modules/global-db/dap_chain_global_db.c b/modules/global-db/dap_chain_global_db.c
index 6f9f8025be5f1a7331740f41585a93a3e3b4203e..f2ebde4d2ec2da45708707e73559dfc28b98c9fd 100644
--- a/modules/global-db/dap_chain_global_db.c
+++ b/modules/global-db/dap_chain_global_db.c
@@ -538,7 +538,7 @@ void dap_global_db_obj_track_history(dap_store_obj_t *a_store_data)
                         l_obj->group, l_obj->key,
                         l_obj->value, l_obj->value_len);
         }
-        if (!s_track_history) {
+        if (s_track_history) {
             lock();
             dap_db_history_add(l_obj->type, l_obj, 1, l_sync_group_item->group_name_for_history);
             unlock();
@@ -551,7 +551,7 @@ void dap_global_db_obj_track_history(dap_store_obj_t *a_store_data)
                         l_obj->type, l_obj->group, l_obj->key,
                         l_obj->value, l_obj->value_len);
             }
-            if (!s_track_history) {
+            if (s_track_history) {
                 lock();
                 dap_db_history_add(l_obj->type, l_obj, 1, l_sync_extra_group_item->group_name_for_history);
                 unlock();
diff --git a/modules/global-db/dap_chain_global_db_driver.c b/modules/global-db/dap_chain_global_db_driver.c
index a7dc81923ba4964f67159b9f2896359c2fbd2087..d3157eee24b3d8c5863c10e24939c9ccbe67d831 100644
--- a/modules/global-db/dap_chain_global_db_driver.c
+++ b/modules/global-db/dap_chain_global_db_driver.c
@@ -279,7 +279,7 @@ dap_store_obj_t *l_store_obj_cur;
     return l_ret;
 }
 
-static int s_dap_driver_req_exec (struct dap_proc_thread *a_dap_thd __attribute__((unused)),
+static bool s_dap_driver_req_exec (struct dap_proc_thread *a_dap_thd __attribute__((unused)),
                                    void *arg __attribute__((unused)) )
 {
 int l_ret;
@@ -316,7 +316,7 @@ size_t l_store_obj_cnt;
         /* Enqueue "Exec Complete" callback routine */
         l_dap_worker = dap_events_worker_get_auto ();
 
-        if ( (l_ret = dap_proc_queue_add_callback(l_dap_worker, l_store_obj_cur->cb, l_store_obj_cur->cb_arg)) )
+        if ( (l_ret = dap_proc_queue_add_callback(l_dap_worker, l_store_obj_cur->cb, (void *)l_store_obj_cur->cb_arg)) )
             log_it(L_ERROR, "[%p] Enqueue completion callback for item %s/%s (code %d)", l_store_obj_cur,
                    l_store_obj_cur->group, l_store_obj_cur->key, l_ret);
         }
diff --git a/modules/global-db/dap_chain_global_db_hist.c b/modules/global-db/dap_chain_global_db_hist.c
index 83f33885d3a0e407b7dd3579a2e149e2f2091756..53897051bc51399e27d5e1d362be35e1fcaa25a7 100644
--- a/modules/global-db/dap_chain_global_db_hist.c
+++ b/modules/global-db/dap_chain_global_db_hist.c
@@ -190,6 +190,8 @@ uint64_t dap_db_log_get_last_id(void)
 static void *s_list_thread_proc(void *arg)
 {
     dap_db_log_list_t *l_dap_db_log_list = (dap_db_log_list_t *)arg;
+    uint32_t l_time_store_lim = dap_config_get_item_uint32_default(g_config, "resources", "dap_global_db_time_store_limit", 72);
+    uint64_t l_limit_time = l_time_store_lim ? (uint64_t)time(NULL) - l_time_store_lim * 3600 : 0;
     for (dap_list_t *l_groups = l_dap_db_log_list->groups; l_groups && l_dap_db_log_list->is_process; l_groups = dap_list_next(l_groups)) {
         dap_db_log_list_group_t *l_group_cur = (dap_db_log_list_group_t *)l_groups->data;
         char *l_del_group_name_replace = NULL;
@@ -205,7 +207,7 @@ static void *s_list_thread_proc(void *arg)
         }
         uint64_t l_item_start = l_group_cur->last_id_synced + 1;
         while (l_group_cur->count && l_dap_db_log_list->is_process) { // Number of records to be synchronized
-            size_t l_item_count = min(32, l_group_cur->count);
+            size_t l_item_count = min(64, l_group_cur->count);
             dap_store_obj_t *l_objs = dap_chain_global_db_cond_load(l_group_cur->name, l_item_start, &l_item_count);
             // go to next group
             if (!l_objs)
@@ -218,6 +220,12 @@ static void *s_list_thread_proc(void *arg)
                 dap_store_obj_t *l_obj_cur = l_objs + i;
                 l_obj_cur->type = l_obj_type;
                 if (l_obj_type == 'd') {
+                    if (l_limit_time && l_obj_cur->timestamp < l_limit_time) {
+                        char *l_key_dup = dap_strdup(l_obj_cur->key);
+                        dap_chain_global_db_driver_delete(l_obj_cur, 1);
+                        l_obj_cur->key = l_key_dup;
+                        continue;
+                    }
                     DAP_DELETE((char *)l_obj_cur->group);
                     l_obj_cur->group = l_del_group_name_replace;
                 }
diff --git a/modules/global-db/include/dap_chain_global_db_driver.h b/modules/global-db/include/dap_chain_global_db_driver.h
index 6f5e4f5ef19d39a69f4fa2996099beade5370ca7..443ca4aced62806f699514778aa791b3c1238b0c 100644
--- a/modules/global-db/include/dap_chain_global_db_driver.h
+++ b/modules/global-db/include/dap_chain_global_db_driver.h
@@ -28,6 +28,7 @@
 #include <stdint.h>
 #include "dap_common.h"
 #include "dap_list.h"
+#include "dap_proc_thread.h"
 
 enum    {
     DAP_DB$K_OPTYPE_ADD  = 'a',                 /* Operation Type = INSERT/ADD */
@@ -46,8 +47,7 @@ typedef struct dap_store_obj {
     const uint8_t *value;
     uint64_t value_len;
 
-
-    void (*cb) (const void *a_arg);             /* (Async mode only!) A call back to be called on request completion */
+    dap_proc_queue_callback_t cb;               /* (Async mode only!) A call back to be called on request completion */
     const void *cb_arg;                         /* (Async mode only!) An argument of the callback rotine */
 
 } DAP_ALIGN_PACKED dap_store_obj_t, *pdap_store_obj_t;
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 796eb74e0cd1715d29d3c7057f3cef961662effe..a4e0ce9e4d1e4bc9b8d90f95b0116d45363cfaed 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -356,11 +356,10 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
 
 }
 
-dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net,dap_chain_hash_fast_t *a_tx_prev_hash,
-                                                              const dap_chain_addr_t* a_addr_to, dap_enc_key_t *l_key_tx_sign,
-                                                              dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size)
+dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash,
+                                                              const dap_chain_addr_t* a_addr_to, dap_enc_key_t *a_key_tx_sign,
+                                                              dap_chain_datum_tx_receipt_t * a_receipt)
 {
-    UNUSED(l_receipt_size);
     dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL;
     if ( ! a_net || ! l_ledger || ! a_addr_to )
         return NULL;
@@ -373,15 +372,16 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *
     dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
 
     uint16_t pos = 0;
-    dap_chain_datum_tx_add_item(&l_tx, (byte_t*) l_receipt);
+    dap_chain_datum_tx_add_item(&l_tx, (byte_t*)a_receipt);
     pos++;
-    uint256_t l_value_send = l_receipt->receipt_info.value_datoshi;
+    uint256_t l_value_send = a_receipt->receipt_info.value_datoshi;
 
     // add 'in_cond' items
-    dap_chain_datum_tx_t *l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_ledger, a_tx_prev_hash);
+    dap_chain_hash_fast_t *l_tx_prev_hash = a_tx_prev_hash;
+    dap_chain_datum_tx_t *l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_ledger, l_tx_prev_hash);
     int l_prev_cond_idx;
-    dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cond, &l_prev_cond_idx);
-    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, a_tx_prev_hash, l_prev_cond_idx)) {
+    dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_cond, &l_prev_cond_idx);  
+    if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, l_tx_prev_hash, l_prev_cond_idx)) { // TX already spent
         dap_chain_datum_tx_t *l_tx_tmp;
         dap_chain_hash_fast_t l_tx_cur_hash = { 0 }; // start hash
         dap_chain_tx_out_cond_t *l_tmp_cond;
@@ -411,8 +411,11 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *
             log_it(L_WARNING, "Requested conditional transaction is already used out");
             return NULL;
         }
+        l_prev_cond_idx = l_tmp_cond_idx;
+        l_out_cond = l_tmp_cond;
+        l_tx_prev_hash = dap_chain_node_datum_tx_calc_hash(l_tx_tmp);
     }
-    if (dap_chain_datum_tx_add_in_cond_item(&l_tx, a_tx_prev_hash, l_prev_cond_idx, pos - 1) != 0 ){
+    if (dap_chain_datum_tx_add_in_cond_item(&l_tx, l_tx_prev_hash, l_prev_cond_idx, pos - 1)) {
         dap_chain_datum_tx_delete(l_tx);
         log_it( L_ERROR, "Cant add tx cond input");
         return NULL;
@@ -425,17 +428,14 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *
         return NULL;
     }
 
-    //add 'out_cond' item
-    size_t l_size = dap_chain_datum_item_tx_get_size((uint8_t *)l_out_cond);
-    dap_chain_tx_out_cond_t *l_out_cond_new = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, l_size);
-    memcpy(l_out_cond_new, l_out_cond, l_size);
-    SUBTRACT_256_256(l_out_cond_new->header.value, l_value_send, &l_out_cond_new->header.value);
-    dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond_new);
-    DAP_DELETE(l_out_cond_new);
+    uint256_t l_old_val = l_out_cond->header.value;
+    SUBTRACT_256_256(l_out_cond->header.value, l_value_send, &l_out_cond->header.value);
+    dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)&l_out_cond);
+    l_out_cond->header.value = l_old_val;
 
     // add 'sign' items
-    if (l_key_tx_sign){
-        if(dap_chain_datum_tx_add_sign_item(&l_tx, l_key_tx_sign) != 1) {
+    if (a_key_tx_sign){
+        if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_tx_sign) != 1) {
             dap_chain_datum_tx_delete(l_tx);
             log_it( L_ERROR, "Can't add sign output");
             return NULL;
@@ -474,29 +474,30 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *
  *
  * return dap_chain_datum_t, NULL if Error
  */
-static dap_chain_datum_t* dap_chain_tx_create_cond(dap_chain_net_t * a_net,
-        dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-        const dap_chain_addr_t* a_addr_from,
+static dap_chain_datum_t* dap_chain_tx_create_cond(dap_chain_net_t *a_net,
+        dap_enc_key_t *a_key_from, dap_pkey_t *a_key_cond,
         const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
         uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit,
         dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size)
 {
     dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL;
     // check valid param
-    if(!a_net || ! l_ledger || !a_key_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
-            !dap_chain_addr_check_sum(a_addr_from) ||
-            IS_ZERO_256(a_value))
+    if (!a_net || !l_ledger || !a_key_from || !a_key_cond ||
+            !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || IS_ZERO_256(a_value))
         return NULL;
 
     // find the transactions from which to take away coins
     uint256_t l_value_transfer = {}; // how many coins to transfer
     uint256_t l_value_need = {};
     SUM_256_256(a_value, a_value_fee, &l_value_need);
+    // where to take coins for service
+    dap_chain_addr_t l_addr_from;
+    dap_chain_addr_fill_from_key(&l_addr_from, a_key_from, a_net->pub.id);
     // list of transaction with 'out' items
     dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
-                                                                             a_addr_from, l_value_need, &l_value_transfer);
+                                                                             &l_addr_from, l_value_need, &l_value_transfer);
     if(!l_list_used_out) {
-        log_it( L_ERROR, "nothing to tranfer (not enough funds)");
+        log_it( L_ERROR, "Nothing to tranfer (not enough funds)");
         return NULL;
     }
 
@@ -523,7 +524,7 @@ static dap_chain_datum_t* dap_chain_tx_create_cond(dap_chain_net_t * a_net,
         uint256_t l_value_back = {};
         SUBTRACT_256_256(l_value_transfer, l_value_pack, &l_value_back);
         if (!IS_ZERO_256(l_value_back)) {
-            if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_from, l_value_back) != 1) {
+            if(dap_chain_datum_tx_add_out_item(&l_tx, &l_addr_from, l_value_back) != 1) {
                 dap_chain_datum_tx_delete(l_tx);
                 log_it( L_ERROR, "Cant add coin back output");
                 return NULL;
@@ -542,62 +543,6 @@ static dap_chain_datum_t* dap_chain_tx_create_cond(dap_chain_net_t * a_net,
     dap_chain_datum_t *l_datum = dap_chain_datum_create( DAP_CHAIN_DATUM_TX, l_tx, l_tx_size );
 
     return l_datum;
-    /*dap_chain_hash_fast_t *l_key_hash = DAP_NEW_Z( dap_chain_hash_fast_t );
-    dap_hash_fast( l_tx, l_tx_size, l_key_hash );
-    DAP_DELETE( l_tx );
-
-    char * l_key_str = dap_chain_hash_fast_to_str_new( l_key_hash );
-    char * l_gdb_group = dap_chain_net_get_gdb_group_mempool_by_chain_type( a_net ,CHAIN_TYPE_TX);
-    if( dap_chain_global_db_gr_set( dap_strdup(l_key_str), (uint8_t *) l_datum, dap_chain_datum_size(l_datum)
-                                   , l_gdb_group ) ) {
-        log_it(L_NOTICE, "Transaction %s placed in mempool", l_key_str);
-    }
-    DAP_DELETE(l_gdb_group);
-    DAP_DELETE(l_key_str);
-
-    return l_key_hash;*/
-}
-
-/**
- * Make transfer transaction & insert to database
- *
- * return 0 Ok, -2 not enough funds to transfer, -1 other Error
- */
-dap_chain_hash_fast_t* dap_chain_proc_tx_create_cond(dap_chain_net_t * a_net,
-        dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-        const dap_chain_addr_t* a_addr_from,
-        const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
-        uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit,
-        dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size)
-{
-
-    dap_chain_t *l_chain = NULL;
-    if(a_net->pub.default_chain)
-        l_chain = a_net->pub.default_chain;
-    else
-        l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_TX);
-
-    if(!l_chain)
-            return NULL;
-    // Make transfer transaction
-    dap_chain_datum_t *l_datum = dap_chain_tx_create_cond(a_net,a_key_from, a_key_cond, a_addr_from,
-                                                          a_token_ticker, a_value, a_value_per_unit_max, a_unit,
-                                                          a_srv_uid, a_value_fee, a_cond, a_cond_size);
-
-    if(!l_datum)
-        return NULL;
-    size_t l_datums_number = l_chain->callback_add_datums(l_chain, &l_datum, 1);
-    if(!l_datums_number)
-            return NULL;
-
-    dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)&(l_datum->data);
-    size_t l_tx_size = l_datum->header.data_size;
-
-    dap_chain_hash_fast_t *l_key_hash = DAP_NEW_Z( dap_chain_hash_fast_t );
-    dap_hash_fast( l_tx, l_tx_size, l_key_hash );
-    //DAP_DELETE( l_tx );
-
-    return l_key_hash;
 }
 
 /**
@@ -606,16 +551,15 @@ dap_chain_hash_fast_t* dap_chain_proc_tx_create_cond(dap_chain_net_t * a_net,
  * return 0 Ok, -2 not enough funds to transfer, -1 other Error
  */
 dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net,
-        dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-        const dap_chain_addr_t* a_addr_from,
+        dap_enc_key_t *a_key_from, dap_pkey_t *a_key_cond,
         const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
         uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit,
         dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size)
 {
     // Make transfer transaction
-    dap_chain_datum_t *l_datum = dap_chain_tx_create_cond(a_net, a_key_from, a_key_cond, a_addr_from,
-                                                          a_token_ticker,a_value,a_value_per_unit_max, a_unit,
-                                                          a_srv_uid, a_value_fee, a_cond, a_cond_size);
+    dap_chain_datum_t *l_datum = dap_chain_tx_create_cond(a_net, a_key_from, a_key_cond,
+                                                          a_token_ticker, a_value, a_value_per_unit_max,
+                                                          a_unit, a_srv_uid, a_value_fee, a_cond, a_cond_size);
 
     if(!l_datum)
         return NULL;
@@ -631,7 +575,7 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net,
     char * l_gdb_group = dap_chain_net_get_gdb_group_mempool_by_chain_type( a_net ,CHAIN_TYPE_TX);
 
     if( dap_chain_global_db_gr_set( l_key_str, l_datum, dap_chain_datum_size(l_datum), l_gdb_group ) ) {
-        log_it(L_NOTICE, "Transaction %s placed in mempool", l_key_str);
+                log_it(L_NOTICE, "Transaction %s placed in mempool group %s", l_key_str, l_gdb_group);
     }
 
     DAP_DELETE(l_gdb_group);
@@ -640,140 +584,6 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net,
     return l_key_hash;
 }
 
-/**
- * Make receipt transaction & insert to cache
- *
- * return 0 Ok, -2 not enough funds to transfer, -1 other Error
- */
-int dap_chain_mempool_tx_create_receipt(uint64_t a_value)
-//(dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-//        const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_cond,
-//        const dap_chain_addr_t* a_addr_fee, const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
-//        uint64_t a_value, uint64_t a_value_fee, const void *a_cond, size_t a_cond_size)
-{
-    // check valid param
-/*    if(!a_key_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
-            !dap_chain_addr_check_sum(a_addr_from) || !dap_chain_addr_check_sum(a_addr_cond) ||
-            (a_addr_fee && !dap_chain_addr_check_sum(a_addr_fee)) || !a_value)
-        return -1;*/
-/*
-    // find the transactions from which to take away coins
-    dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
-    uint64_t l_value_transfer = 0; // how many coins to transfer
-    {
-        dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
-        uint64_t l_value_need = a_value + a_value_fee;
-        while(l_value_transfer < l_value_need)
-        {
-            // Get the transaction in the cache by the addr in out item
-            const dap_chain_datum_tx_t *l_tx = dap_chain_ledger_tx_find_by_addr(a_addr_from,
-                    &l_tx_cur_hash);
-            if(!l_tx)
-                break;
-            // Get all item from transaction by type
-            int l_item_count = 0;
-            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) l_tx, TX_ITEM_TYPE_OUT,
-                    &l_item_count);
-            dap_list_t *l_list_tmp = l_list_out_items;
-            int l_out_idx_tmp = 0; // current index of 'out' item
-            while(l_list_tmp) {
-                dap_chain_tx_out_t *out_item = l_list_tmp->data;
-                // if 'out' item has addr = a_addr_from
-                if(out_item && &out_item->addr && !memcmp(a_addr_from, &out_item->addr, sizeof(dap_chain_addr_t))) {
-
-                    // Check whether used 'out' items
-                    if(!dap_chain_ledger_tx_hash_is_used_out_item(&l_tx_cur_hash, l_out_idx_tmp)) {
-
-                        list_used_item_t *item = DAP_NEW(list_used_item_t);
-                        memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t));
-                        item->num_idx_out = l_out_idx_tmp;
-                        item->value = out_item->header.value;
-                        l_list_used_out = dap_list_append(l_list_used_out, item);
-                        l_value_transfer += item->value;
-                        // already accumulated the required value, finish the search for 'out' items
-                        if(l_value_transfer >= l_value_need) {
-                            break;
-                        }
-                    }
-                }
-                // go to the next 'out' item in l_tx transaction
-                l_out_idx_tmp++;
-                l_list_tmp = dap_list_next(l_list_tmp);
-            }
-            dap_list_free(l_list_out_items);
-        }
-
-        // nothing to tranfer (not enough funds)
-        if(!l_list_used_out || l_value_transfer < l_value_need) {
-            dap_list_free_full(l_list_used_out, free);
-            return -2;
-        }
-    }
-
-    // create empty transaction
-    dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
-    // add 'in' items
-    {
-        dap_list_t *l_list_tmp = l_list_used_out;
-        uint64_t l_value_to_items = 0; // how many coins to transfer
-        while(l_list_tmp) {
-            list_used_item_t *item = l_list_tmp->data;
-            if(dap_chain_datum_tx_add_in_item(&l_tx, &item->tx_hash_fast, item->num_idx_out) == 1) {
-                l_value_to_items += item->value;
-            }
-            l_list_tmp = dap_list_next(l_list_tmp);
-        }
-        assert(l_value_to_items == l_value_transfer);
-        dap_list_free_full(l_list_used_out, free);
-    }
-    // add 'out_cond' and 'out' items
-    {
-        uint64_t l_value_pack = 0; // how much coin add to 'out' items
-        if(dap_chain_datum_tx_add_out_cond_item(&l_tx, a_key_cond, (dap_chain_addr_t*) a_addr_cond, a_value, a_cond,
-                a_cond_size) == 1) {
-            l_value_pack += a_value;
-            // transaction fee
-            if(a_addr_fee) {
-                if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_fee, a_value_fee) == 1)
-                    l_value_pack += a_value_fee;
-            }
-        }
-        // coin back
-        uint64_t l_value_back = l_value_transfer - l_value_pack;
-        if(l_value_back) {
-            if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_from, l_value_back) != 1) {
-                dap_chain_datum_tx_delete(l_tx);
-                return -1;
-            }
-        }
-    }
-
-    // add 'sign' items
-    if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_from) != 1) {
-        dap_chain_datum_tx_delete(l_tx);
-        return -1;
-    }
-
-    size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
-    dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size);
-
-    dap_chain_hash_fast_t l_key_hash;
-    dap_hash_fast(l_tx, l_tx_size, &l_key_hash);
-    DAP_DELETE(l_tx);
-
-    char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
-    if(dap_chain_global_db_gr_set(dap_strdup(l_key_str), (uint8_t *) l_datum, dap_chain_datum_size(l_datum)
-            , c_dap_datum_mempool_gdb_group)) {
-        log_it(L_NOTICE, "Transaction %s placed in mempool", l_key_str);
-        // add transaction to ledger
-        if(dap_chain_ledger_tx_add((dap_chain_datum_tx_t*) l_datum->data) < 0)
-            log_it(L_ERROR, "Transaction %s not placed in LEDGER", l_key_str);
-    }
-    DAP_DELETE(l_key_str);*/
-
-    return 0;
-}
-
 uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size)
 {
     size_t a_request_size = 2 * sizeof(uint16_t), shift_size = 0;
diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h
index 4ecf470e0bddcf7f2f05fea13d0d7a23e57298f8..9cc95a0723979991432d3cb43129b6d925e68786 100644
--- a/modules/mempool/include/dap_chain_mempool.h
+++ b/modules/mempool/include/dap_chain_mempool.h
@@ -44,28 +44,21 @@ void dap_datum_mempool_free(dap_datum_mempool_t *datum);
 void dap_chain_mempool_add_proc(dap_http_t * a_http_server, const char * a_url);
 
 char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t *a_chain);
-dap_hash_fast_t*  dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_from,
-        const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_to,
-        const dap_chain_addr_t* a_addr_fee,
+dap_hash_fast_t*  dap_chain_mempool_tx_create(dap_chain_t *a_chain, dap_enc_key_t *a_key_from,
+        const dap_chain_addr_t *a_addr_from, const dap_chain_addr_t *a_addr_to,
+        const dap_chain_addr_t *a_addr_fee,
         const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
         uint256_t a_value, uint256_t a_value_fee);
 
 // Make transfer transaction & insert to cache
-dap_chain_hash_fast_t* dap_chain_proc_tx_create_cond(dap_chain_net_t * a_net,
-        dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-        const dap_chain_addr_t* a_addr_from,
-        const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
-        uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit,
-        dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size);
 dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net,
-        dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
-        const dap_chain_addr_t* a_addr_from,
+        dap_enc_key_t *a_key_from, dap_pkey_t *a_key_cond,
         const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
         uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit,
         dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size);
 
-dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net,dap_chain_hash_fast_t *a_tx_prev_hash,
-        const dap_chain_addr_t* a_addr_to, dap_enc_key_t * l_key_tx_sign, dap_chain_datum_tx_receipt_t * l_receipt, size_t l_receipt_size);
+dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash,
+        const dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_key_tx_sign, dap_chain_datum_tx_receipt_t *a_receipt);
 
 int dap_chain_mempool_tx_create_massive(dap_chain_t * a_chain, dap_enc_key_t *a_key_from,
         const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_to,
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index a465def44f361b21b7bfd244232c7466c979a30e..5f48f98dced0479ba4a731933ec9f913beb7f546 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -155,6 +155,7 @@ typedef struct dap_chain_net_pvt{
 
     dap_list_t *net_links;              // Links list
     size_t links_connected_count;
+    bool only_static_links;
 
     atomic_uint links_dns_requests;
 
@@ -409,7 +410,7 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c
     UNUSED(a_value);
     UNUSED(a_value_len);
     dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
-    if (PVT(l_net)->state == NET_STATE_ONLINE) {
+    if (PVT(l_net)->state >= NET_STATE_LINKS_ESTABLISHED) {
         char *l_group;
         if (a_op_code == DAP_DB$K_OPTYPE_DEL ) {
             l_group = dap_strdup_printf("%s.del", a_group);
@@ -487,7 +488,7 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
     if (!a_arg)
         return;
     dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg;
-    if (PVT(l_net)->state == NET_STATE_ONLINE) {
+    if (PVT(l_net)->state >= NET_STATE_LINKS_ESTABLISHED) {
         pthread_rwlock_rdlock(&PVT(l_net)->rwlock);
         for (dap_list_t *l_tmp = PVT(l_net)->net_links; l_tmp; l_tmp = dap_list_next(l_tmp)) {
             dap_chain_node_client_t *l_node_client = ((struct net_link *)l_tmp->data)->link;
@@ -742,6 +743,10 @@ static void s_node_link_callback_disconnected(dap_chain_node_client_t *a_node_cl
                 return;
             }
         }
+        if (l_net_pvt->only_static_links) {
+            pthread_rwlock_unlock(&l_net_pvt->rwlock);
+            return;
+        }
         dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net);
         if (l_link_node_info) {
             struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request);
@@ -1091,67 +1096,57 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
             } else {
                 log_it(L_WARNING,"No nodeinfo in global_db to prepare links for connecting, try to add links from root servers");
             }
-            switch (l_net_pvt->node_role.enums) {
-                case NODE_ROLE_ROOT:
-                case NODE_ROLE_ROOT_MASTER:
-                case NODE_ROLE_ARCHIVE:
-                case NODE_ROLE_CELL_MASTER: {
-                    if (l_net_pvt->seed_aliases_count) {
-                        // Add other root nodes as synchronization links
-                        pthread_rwlock_unlock(&l_net_pvt->rwlock);
-                        s_fill_links_from_root_aliases(l_net);
-                        pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-                        l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
-                        l_repeat_after_exit = true;
-                        break;
-                    }
+            if (l_net_pvt->only_static_links) {
+                if (l_net_pvt->seed_aliases_count) {
+                    // Add other root nodes as synchronization links
+                    pthread_rwlock_unlock(&l_net_pvt->rwlock);
+                    s_fill_links_from_root_aliases(l_net);
+                    pthread_rwlock_wrlock(&l_net_pvt->rwlock);
+                    l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
+                    l_repeat_after_exit = true;
+                    break;
                 }
-                case NODE_ROLE_FULL:
-                case NODE_ROLE_MASTER:
-                case NODE_ROLE_LIGHT:
-                default: {
-                    if (!l_net_pvt->seed_aliases_count && ! l_net_pvt->bootstrap_nodes_count) {
-                       log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests");
-                       if (l_net_pvt->net_links) { // We have other links
-                           l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
-                           l_repeat_after_exit = true;
-                       }
-                       break;
-                    }
-                    // Get DNS request result from root nodes as synchronization links
-                    bool l_sync_fill_root_nodes = false;
-                    uint32_t l_link_id = 0;
-                    if (!l_sync_fill_root_nodes) {
-                        for (size_t n = 0; l_net_pvt->links_dns_requests < s_max_links_count; n++) {
-                            dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net);
-                            if (!l_link_node_info)
-                                continue;
-                            l_net_pvt->links_dns_requests++;
-                            struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request);
-                            l_dns_request->net = l_net;
-                            l_dns_request->link_id = l_link_id++;
-                            if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4,
-                                                                l_link_node_info->hdr.ext_port,
-                                                                l_net->pub.name,
-                                                                l_link_node_info,  // use it twice
-                                                                s_net_state_link_prepare_success,
-                                                                s_net_state_link_prepare_error,
-                                                                l_dns_request)) {
-                                log_it(L_ERROR, "Can't process node info dns request");
-                                DAP_DEL_Z(l_dns_request);
-                                DAP_DEL_Z(l_link_node_info);
-                            }
-                            if (n > 1000)   // It's a problem with link prepare
-                                break;
+            } else {
+                if (!l_net_pvt->seed_aliases_count && ! l_net_pvt->bootstrap_nodes_count){
+                   log_it(L_ERROR, "No root servers present in configuration file. Can't establish DNS requests");
+                   if (l_net_pvt->net_links) { // We have other links
+                       l_net_pvt->state = NET_STATE_LINKS_CONNECTING;
+                       l_repeat_after_exit = true;
+                   }
+                   break;
+                }
+                // Get DNS request result from root nodes as synchronization links
+                bool l_sync_fill_root_nodes = false;
+                uint32_t l_link_id = 0;
+                if (!l_sync_fill_root_nodes) {
+                    for (size_t n = 0; l_net_pvt->links_dns_requests < s_max_links_count; n++) {
+                        dap_chain_node_info_t *l_link_node_info = s_get_dns_link_from_cfg(l_net);
+                        if (!l_link_node_info)
+                            continue;
+                        l_net_pvt->links_dns_requests++;
+                        struct link_dns_request *l_dns_request = DAP_NEW_Z(struct link_dns_request);
+                        l_dns_request->net = l_net;
+                        l_dns_request->link_id = l_link_id++;
+                        if (dap_chain_node_info_dns_request(l_link_node_info->hdr.ext_addr_v4,
+                                                            l_link_node_info->hdr.ext_port,
+                                                            l_net->pub.name,
+                                                            l_link_node_info,  // use it twice
+                                                            s_net_state_link_prepare_success,
+                                                            s_net_state_link_prepare_error,
+                                                            l_dns_request)) {
+                            log_it(L_ERROR, "Can't process node info dns request");
+                            DAP_DEL_Z(l_dns_request);
+                            DAP_DEL_Z(l_link_node_info);
                         }
+                        if (n > 1000)   // It's a problem with link prepare
+                            break;
                     }
-                    if (l_sync_fill_root_nodes) {
-                        log_it(L_ATT, "Not use bootstrap addresses, fill seed nodelist from root aliases");
-                        pthread_rwlock_unlock(&l_net_pvt->rwlock);
-                        s_fill_links_from_root_aliases(l_net);
-                        pthread_rwlock_wrlock(&l_net_pvt->rwlock);
-                    }
-                } break;
+                } else {
+                    log_it(L_ATT, "Not use bootstrap addresses, fill seed nodelist from root aliases");
+                    pthread_rwlock_unlock(&l_net_pvt->rwlock);
+                    s_fill_links_from_root_aliases(l_net);
+                    pthread_rwlock_wrlock(&l_net_pvt->rwlock);
+                }
             }
         } break;
 
@@ -1217,11 +1212,11 @@ bool dap_chain_net_sync_trylock(dap_chain_net_t *a_net, dap_chain_node_client_t
     if (!l_found) {
         l_net_pvt->active_link = a_client;
     }
-    pthread_rwlock_unlock(&l_net_pvt->rwlock);
     if (l_found && !dap_list_find_custom(l_net_pvt->links_queue, &a_client->uuid, s_net_list_compare_uuids)) {
         dap_events_socket_uuid_t *l_uuid = DAP_DUP(&a_client->uuid);
         l_net_pvt->links_queue = dap_list_append(l_net_pvt->links_queue, l_uuid);
     }
+    pthread_rwlock_unlock(&l_net_pvt->rwlock);
     return !l_found;
 }
 
@@ -1233,10 +1228,11 @@ bool dap_chain_net_sync_unlock(dap_chain_net_t *a_net, dap_chain_node_client_t *
     pthread_rwlock_rdlock(&l_net_pvt->rwlock);
     if (!a_client || l_net_pvt->active_link == a_client)
         l_net_pvt->active_link = NULL;
-    pthread_rwlock_unlock(&l_net_pvt->rwlock);
     while (l_net_pvt->active_link == NULL && l_net_pvt->links_queue) {
         dap_events_socket_uuid_t *l_uuid = l_net_pvt->links_queue->data;
+        pthread_rwlock_unlock(&l_net_pvt->rwlock);
         dap_chain_node_sync_status_t l_status = dap_chain_node_client_start_sync(l_uuid);
+        pthread_rwlock_rdlock(&l_net_pvt->rwlock);
         if (l_status != NODE_SYNC_STATUS_WAITING) {
             DAP_DELETE(l_uuid);
             dap_list_t *l_to_remove = l_net_pvt->links_queue;
@@ -1246,6 +1242,7 @@ bool dap_chain_net_sync_unlock(dap_chain_net_t *a_net, dap_chain_node_client_t *
             break;
         }
     }
+    pthread_rwlock_unlock(&l_net_pvt->rwlock);
     return l_net_pvt->active_link;
 }
 /**
@@ -1451,7 +1448,7 @@ void s_set_reply_text_node_status(char **a_str_reply, dap_chain_net_t * a_net){
  * @return true 
  * @return false 
  */
-bool s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
+void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
 {
     dap_chain_ledger_purge(l_net->pub.ledger, false);
     dap_chain_t *l_chain = NULL;
@@ -2413,6 +2410,7 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
         // Do specific role actions post-chain created
         l_net_pvt->state_target = NET_STATE_OFFLINE;
         dap_chain_net_state_t l_target_state = NET_STATE_OFFLINE;
+        l_net_pvt->only_static_links = false;
         switch ( l_net_pvt->node_role.enums ) {
             case NODE_ROLE_ROOT_MASTER:{
                 // Set to process everything in datum pool
@@ -2426,8 +2424,8 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
                 dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id,l_chain_id);
                 if (l_chain )
                    l_chain->is_datum_pool_proc = true;
-
-                l_target_state = NET_STATE_ONLINE;
+                l_net_pvt->only_static_links = true;
+                l_target_state = NET_STATE_ONLINE;     
                 log_it(L_INFO,"Root node role established");
             } break;
             case NODE_ROLE_CELL_MASTER:
@@ -2445,13 +2443,8 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
                             log_it( L_WARNING, "Can't find chain id " );
                         }
                     }
-                    DAP_DELETE( l_proc_chains[i]);
-                    l_proc_chains[i] = NULL;
                 }
-                //if ( l_proc_chains )
-                //    DAP_DELETE (l_proc_chains);
-                //l_proc_chains = NULL;
-
+                l_net_pvt->only_static_links = true;
                 l_target_state = NET_STATE_ONLINE;
                 log_it(L_INFO,"Master node role established");
             } break;
@@ -2464,7 +2457,8 @@ int s_net_load(const char * a_net_name, uint16_t a_acl_idx)
                 log_it(L_INFO,"Light node role established");
 
         }
-
+        if (!l_net_pvt->only_static_links)
+            l_net_pvt->only_static_links = dap_config_get_item_bool_default(l_cfg, "general", "static_links_only", false);
         if (s_seed_mode || !dap_config_get_item_bool_default(g_config ,"general", "auto_online",false ) ) { // If we seed we do everything manual. First think - prefil list of node_addrs and its aliases
             l_target_state = NET_STATE_OFFLINE;
         }
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index 55d0e3050078abf260f5c6e5eeac24611ea7866d..368da960cdc9ce7c3e9c073d4a483395b52775ad 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -1086,8 +1086,9 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
     dap_chain_node_cli_cmd_item_create ("tx_create", com_tx_create, "Make transaction",
             "tx_create -net <net name> -chain <chain name> -from_wallet <name> -to_addr <addr> -token <token ticker> -value <value> [-fee <addr> -value_fee <val>]\n" );
     dap_chain_node_cli_cmd_item_create ("tx_cond_create", com_tx_cond_create, "Make cond transaction",
-            "tx_cond_create -net <net name> -token <token_ticker> -wallet_f <wallet_from> -wallet_t <wallet_to>"
-                                        "-value <value_datoshi> -unit <mb|kb|b|sec|day> -service <vpn>\n" );
+                                        "tx_cond_create -net <net name> -token <token ticker> -wallet <from wallet> -cert <public cert>"
+                                        "-value <value datoshi> -unit <mb | kb | b | sec | day> -srv_uid <numeric uid>\n" );
+
     dap_chain_node_cli_cmd_item_create ("tx_verify", com_tx_verify, "Verifing transaction in mempool",
             "tx_verify -net <net name> -chain <chain name> -tx <tx_hash>\n" );
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 70b527e695270d62c48d9fcdeda63d1508c5b3f5..9724464f4039a18f7d033c545a1fe8e6b18c1c50 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -1827,12 +1827,12 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
 
         dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name((const char *) l_net_name);
         if(!l_net_name && !l_addr ) {
-            dap_chain_node_cli_set_reply_text(str_reply, "wallet info requires parameter 'net'");
+            dap_chain_node_cli_set_reply_text(str_reply, "Subcommand info requires parameter '-net'");
             return -1;
         }
         else if (! l_addr){
             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);
+                dap_chain_node_cli_set_reply_text(str_reply, "Not found net by name '%s'", l_net_name);
                 return -1;
             }
         }else{
@@ -1887,7 +1887,7 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply)
             if(l_wallet)
                 dap_chain_wallet_close(l_wallet);
             dap_string_free(l_string_ret, true);
-            dap_chain_node_cli_set_reply_text(str_reply, "wallet not found");
+            dap_chain_node_cli_set_reply_text(str_reply, "Wallet not found");
             return -1;
         }
     }
@@ -3485,29 +3485,29 @@ int com_tx_cond_create(int a_argc, char ** a_argv, char **a_str_reply)
     (void) a_argc;
     int arg_index = 1;
     const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
-    const char * l_token_ticker = NULL;
-    const char * l_wallet_from_str = NULL;
-    const char * l_wallet_to_str = NULL; //l_addr_to_str
+    const char * l_token_ticker = NULL;    
+    const char * l_wallet_str = NULL;
+    const char * l_cert_str = NULL;
     const char * l_value_datoshi_str = NULL;
     const char * l_net_name = NULL;
     const char * l_unit_str = NULL;
-    const char * l_service_str = NULL;
+    const char * l_srv_uid_str = NULL;
     uint256_t l_value_datoshi = {};
     const char * l_hash_out_type = NULL;
     dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
     if(!l_hash_out_type)
         l_hash_out_type = "hex";
     if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>");
         return -1;
     }
 
     // Token ticker
     dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-token", &l_token_ticker);
     // Wallet name - from
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-wallet_f", &l_wallet_from_str);
-    // Wallet address - to
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-wallet_t", &l_wallet_to_str);
+    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-wallet", &l_wallet_str);
+    // Public certifiacte of condition owner
+    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-cert", &l_cert_str);
     // value datoshi
     dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_datoshi_str);
     // net
@@ -3515,18 +3515,18 @@ int com_tx_cond_create(int a_argc, char ** a_argv, char **a_str_reply)
     // unit
     dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-unit", &l_unit_str);
     // service
-    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-service", &l_service_str);
+    dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str);
 
     if(!l_token_ticker) {
         dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-token'");
         return -1;
     }
-    if(!l_wallet_from_str) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-wallet_f'");
+    if (!l_wallet_str) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-wallet'");
         return -2;
     }
-    if(!l_wallet_to_str) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-wallet_t'");
+    if (!l_cert_str) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-cert'");
         return -3;
     }
     if(!l_value_datoshi_str) {
@@ -3539,20 +3539,18 @@ int com_tx_cond_create(int a_argc, char ** a_argv, char **a_str_reply)
         return -5;
     }
     if(!l_unit_str) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-unit={mb|kb|b|sec|day}'");
+        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-unit'");
         return -6;
     }
-    if(!l_service_str) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-service={vpn}'");
+
+    if(!l_srv_uid_str) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-srv_uid'");
         return -7;
     }
     dap_chain_net_srv_uid_t l_srv_uid = {};
-    if(!dap_strcmp(l_service_str, "vpn"))
-        l_srv_uid.uint64 = 0x0000000000000001;
-    //dap_chain_addr_t *addr_to = dap_chain_addr_from_str(l_addr_to_str);
-    if(!l_srv_uid.uint64) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't recognize service='%s' unit must look like {vpn}",
-                l_service_str);
+    l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10);
+    if (!l_srv_uid.uint64) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find service UID %s ", l_srv_uid_str);
         return -8;
     }
 
@@ -3569,59 +3567,49 @@ int com_tx_cond_create(int a_argc, char ** a_argv, char **a_str_reply)
         l_price_unit.enm = SERV_UNIT_B;
 
     if(l_price_unit.enm == SERV_UNIT_UNDEFINED) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't recognize unit='%s' unit must look like {mb|kb|b|sec|day}",
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't recognize unit '%s'. Unit must look like {mb | kb | b | sec | day}",
                 l_unit_str);
         return -9;
     }
 
     l_value_datoshi = dap_chain_balance_scan(l_value_datoshi_str);
     if(IS_ZERO_256(l_value_datoshi)) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't recognize value='%s' as a number", l_value_datoshi_str);
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't recognize value '%s' as a number", l_value_datoshi_str);
         return -10;
     }
 
     dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL;
     if(!l_net) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't find net '%s'", l_net_name);
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find net '%s'", l_net_name);
         return -11;
     }
-    dap_chain_wallet_t *l_wallet_from = dap_chain_wallet_open(l_wallet_from_str, c_wallets_path);
-    if(!l_wallet_from) {
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't open wallet '%s'", l_wallet_from);
+    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path);
+    if(!l_wallet) {
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't open wallet '%s'", l_wallet);
         return -12;
     }
-    dap_chain_wallet_t *l_wallet_cond = dap_chain_wallet_open(l_wallet_to_str, c_wallets_path);
-    if(!l_wallet_to_str) {
-        dap_chain_wallet_close(l_wallet_from);
-        dap_chain_node_cli_set_reply_text(a_str_reply, "can't open wallet '%s'", l_wallet_to_str);
+
+    dap_cert_t *l_cert_cond = dap_cert_find_by_name(l_cert_str);
+    if(!l_cert_cond) {
+        dap_chain_wallet_close(l_wallet);
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find cert '%s'", l_cert_str);
         return -13;
     }
-    dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet_from, 0);
-    dap_enc_key_t *l_key_cond = dap_chain_wallet_get_key(l_wallet_cond, 0);
-
 
-    // where to take coins for service
-    const dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, l_net->pub.id);
-    // who will be use service, usually the same address (addr_from)
-    //const dap_chain_addr_t *l_addr_cond = dap_chain_wallet_get_addr(l_wallet_cond, l_net->pub.id);
-
-
-/*    //dap_chain_net_srv_abstract_t l_cond;
-//    dap_chain_net_srv_abstract_set(&l_cond, SERV_CLASS_PERMANENT, SERV_ID_VPN, l_value, SERV_UNIT_MB,
-//            "test vpn service");
-//    dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name((const char *) c_net_name);
+    dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0);
+    dap_pkey_t *l_key_cond = dap_pkey_from_enc_key(l_cert_cond->enc_key);
+    if (!l_key_cond) {
+        dap_chain_wallet_close(l_wallet);
+        dap_chain_node_cli_set_reply_text(a_str_reply, "Cert '%s' doesn't contain a valid public key", l_cert_str);
+        return -14;
+    }
 
-    int res = dap_chain_mempool_tx_create_cond(NULL, l_key, l_key_cond, addr_from,
-            addr_cond,
-            NULL, l_token_ticker, l_value, 0, (const void*) &l_cond, sizeof(dap_chain_net_srv_abstract_t));
-*/
     uint256_t l_value_per_unit_max = {};
     uint256_t l_value_fee = {};
-    dap_chain_hash_fast_t *l_tx_cond_hash = dap_chain_mempool_tx_create_cond(l_net, l_key_from, l_key_cond, l_addr_from, l_token_ticker,
-            l_value_datoshi, l_value_per_unit_max, l_price_unit, l_srv_uid, l_value_fee, NULL, 0);
-
-    dap_chain_wallet_close(l_wallet_from);
-    dap_chain_wallet_close(l_wallet_cond);
+    dap_chain_hash_fast_t *l_tx_cond_hash = dap_chain_mempool_tx_create_cond(l_net, l_key_from, l_key_cond, l_token_ticker,
+                                        l_value_datoshi, l_value_per_unit_max, l_price_unit, l_srv_uid, l_value_fee, NULL, 0);
+    dap_chain_wallet_close(l_wallet);
+    DAP_DELETE(l_key_cond);
 
     char *l_hash_str;
     if(!dap_strcmp(l_hash_out_type, "hex")) {
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 26c6a1f916f6aad728f06b73728871b225d93ec2..172cbb61fde88278327be52ed0eb823027389652 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -206,8 +206,8 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
             break;
         case TX_ITEM_TYPE_RECEIPT:
             dap_string_append_printf(a_str_out, "\t Receipt:\n"
-                                                "\t\t size: %u\n"
-                                                "\t\t ext size:%u\n"
+                                                "\t\t size: %"DAP_UINT64_FORMAT_U"\n"
+                                                "\t\t ext size: %"DAP_UINT64_FORMAT_U"\n"
                                                 "\t\t Info:"
                                                 "\t\t\t   units: 0x%016"DAP_UINT64_FORMAT_x"\n"
                                                 "\t\t\t   uid: 0x%016"DAP_UINT64_FORMAT_x"\n"
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index b15bf29deb0ae6b92239eb2c4edf12a135b3223d..9b95cbbdac48fb5535feb0ca78558826d96b2286 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -57,11 +57,9 @@
 #include "dap_client_pvt.h"
 #include "dap_chain_global_db_remote.h"
 #include "dap_chain_global_db_hist.h"
-
 #include "dap_chain.h"
 #include "dap_chain_cell.h"
-
-#include "dap_chain_net_srv_common.h"
+#include "dap_chain_net_srv.h"
 #include "dap_stream_worker.h"
 #include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_chain.h"
@@ -71,8 +69,6 @@
 #include "dap_stream_ch_chain_net_srv.h"
 #include "dap_stream_ch_chain_voting.h"
 #include "dap_stream_pkt.h"
-
-//#include "dap_chain_common.h"
 #include "dap_chain_node_client.h"
 
 #define LOG_TAG "dap_chain_node_client"
@@ -99,7 +95,7 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
 static bool dap_chain_node_client_connect_internal(dap_chain_node_client_t *a_node_client, const char *a_active_channels);
 
 bool s_stream_ch_chain_debug_more = false;
-uint32_t s_timer_update_states=60;
+uint32_t s_timer_update_states = 600;
 
 /**
  * @brief dap_chain_node_client_init
@@ -107,8 +103,8 @@ uint32_t s_timer_update_states=60;
  */
 int dap_chain_node_client_init(void)
 {
-    s_stream_ch_chain_debug_more = dap_config_get_item_bool_default(g_config,"stream_ch_chain","debug_more",false);
-    s_timer_update_states = dap_config_get_item_uint32_default(g_config,"node_client","timer_update_states",60);
+    s_stream_ch_chain_debug_more = dap_config_get_item_bool_default(g_config, "stream_ch_chain", "debug_more", false);
+    s_timer_update_states = dap_config_get_item_uint32_default(g_config, "node_client", "timer_update_states", s_timer_update_states);
     return 0;
 }
 
@@ -483,19 +479,19 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha
             if (l_node_client->cur_cell)
                 l_cell_id = l_node_client->cur_cell->id;
             // Check if we have some more chains and cells in it to sync
+            dap_chain_node_addr_t l_node_addr;
+            l_node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
             if( l_node_client->cur_chain ){
                 l_chain_id=l_node_client->cur_chain->id;
                 if (s_stream_ch_chain_debug_more) {
-                    dap_chain_node_addr_t * l_node_addr = dap_chain_net_get_cur_addr(l_net);
                     log_it(L_INFO,"In: Link %s."NODE_ADDR_FP_STR" started to sync %s chain",l_net->pub.name,
-                           NODE_ADDR_FP_ARGS(l_node_addr), l_node_client->cur_chain->name );
+                           NODE_ADDR_FP_ARGS_S(l_node_addr), l_node_client->cur_chain->name );
                 }
                 dap_stream_ch_chain_pkt_write_unsafe(l_node_client->ch_chain, DAP_STREAM_CH_CHAIN_PKT_TYPE_UPDATE_CHAINS_REQ,
                                                      l_net->pub.id.uint64 ,
                                                      l_chain_id.uint64,l_cell_id.uint64,NULL,0);
             }else{ // If no - over with sync process
-                dap_chain_node_addr_t * l_node_addr = dap_chain_net_get_cur_addr(l_net);
-                log_it(L_INFO, "In: State node %s."NODE_ADDR_FP_STR" is SYNCED",l_net->pub.name, NODE_ADDR_FP_ARGS(l_node_addr) );
+                log_it(L_INFO, "In: State node %s."NODE_ADDR_FP_STR" is SYNCED",l_net->pub.name, NODE_ADDR_FP_ARGS_S(l_node_addr) );
                 bool l_have_waiting = dap_chain_net_sync_unlock(l_net, l_node_client);
                 l_node_client->state = NODE_CLIENT_STATE_SYNCED;
                 if (dap_chain_net_get_target_state(l_net) == NET_STATE_ONLINE) {
diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h
index 829ec01c4b8381e3887f7b017410bab1eb4d6e5a..b0bdbc79c352f34422b791d78e58e743270d01ce 100644
--- a/modules/net/include/dap_chain_node_client.h
+++ b/modules/net/include/dap_chain_node_client.h
@@ -81,9 +81,10 @@ typedef struct dap_chain_node_client_callbacks{
 
 // state for a client connection
 typedef struct dap_chain_node_client {
-    dap_chain_node_client_state_t state;
-
+    // Sould be first with current architecture
     dap_events_socket_uuid_t uuid;
+
+    dap_chain_node_client_state_t state;
     bool resync_gdb;
     bool resync_chains;
 
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 1ecd2cfb9536b223aaf853a6328577000cc8642d..9edc2562503dbee5ee625e91eb54b922f028b33e 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -595,6 +595,23 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply)
     return ret;
 }
 
+bool dap_chain_net_srv_pay_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner)
+{
+    if (!a_owner)
+        return false;
+    dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t *)
+                                               dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_RECEIPT, NULL);
+    if (!l_receipt)
+        return false;
+    dap_sign_t *l_sign = dap_chain_datum_tx_receipt_sign_get(l_receipt, l_receipt->size, 1);
+    if (!l_sign)
+        return false;
+    dap_hash_fast_t l_pkey_hash;
+    if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash))
+        return false;
+    return dap_hash_fast_compare(&l_pkey_hash, &a_cond->subtype.srv_pay.pkey_hash);
+}
+
 /**
  * @brief dap_chain_net_srv_add
  * @param a_uid
@@ -603,10 +620,14 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply)
  * @param a_callback_response_error
  * @return
  */
-dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_request,
+dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,
+                                           const char *a_config_section,
+                                           dap_chain_net_srv_callback_data_t a_callback_request,
                                            dap_chain_net_srv_callback_data_t a_callback_response_success,
                                            dap_chain_net_srv_callback_data_t a_callback_response_error,
-                                           dap_chain_net_srv_callback_data_t a_callback_receipt_next_success)
+                                           dap_chain_net_srv_callback_data_t a_callback_receipt_next_success,
+                                           dap_chain_net_srv_callback_custom_data_t a_callback_custom_data)
+
 {
     service_list_t *l_sdata = NULL;
     dap_chain_net_srv_t * l_srv = NULL;
@@ -620,14 +641,89 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_cha
         l_srv->callback_response_success = a_callback_response_success;
         l_srv->callback_response_error = a_callback_response_error;
         l_srv->callback_receipt_next_success = a_callback_receipt_next_success;
+        l_srv->callback_custom_data = a_callback_custom_data;
         pthread_mutex_init(&l_srv->banlist_mutex, NULL);
         l_sdata = DAP_NEW_Z(service_list_t);
         memcpy(&l_sdata->uid, &l_uid, sizeof(l_uid));
         l_sdata->srv = l_srv;
+        if (a_config_section) {
+            l_srv->grace_period = dap_config_get_item_uint32_default(g_config, a_config_section, "grace_period", 60);
+            //! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data
+            uint16_t l_pricelist_count = 0;
+            char **l_pricelist = dap_config_get_array_str(g_config, a_config_section, "pricelist", &l_pricelist_count);
+            for (uint16_t i = 0; i < l_pricelist_count; i++) {
+                dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
+                short l_iter = 0;
+                char *l_ctx;
+                for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) {
+                    //log_it(L_DEBUG, "Tokenizer: %s", l_price_token);
+                    switch (l_iter) {
+                    case 0:
+                        l_price->net_name = l_price_token;
+                        if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) {
+                            log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token);
+                            DAP_DELETE(l_price);
+                            break;
+                        }
+                        continue;
+                    case 1:
+                        l_price->value_datoshi = dap_chain_uint256_to(dap_chain_coins_to_balance(l_price_token));
+                        if (!l_price->value_datoshi) {
+                            log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token);
+                            l_iter = 0;
+                            DAP_DELETE(l_price);
+                            break;
+                        }
+                        continue;
+                    case 2:
+                        dap_stpcpy(l_price->token, l_price_token);
+                        continue;
+                    case 3:
+                        l_price->units = strtoul(l_price_token, NULL, 10);
+                        if (!l_price->units) {
+                            log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token);
+                            l_iter = 0;
+                            DAP_DELETE(l_price);
+                            break;
+                        }
+                        continue;
+                    case 4:
+                        if (!strcmp(l_price_token,      "SEC"))
+                            l_price->units_uid.enm = SERV_UNIT_SEC;
+                        else if (!strcmp(l_price_token, "DAY"))
+                            l_price->units_uid.enm = SERV_UNIT_DAY;
+                        else if (!strcmp(l_price_token, "MB"))
+                            l_price->units_uid.enm = SERV_UNIT_MB;
+                        else {
+                            log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token);
+                            l_iter = 0;
+                            DAP_DELETE(l_price);
+                            break;
+                        }
+                        continue;
+                    case 5:
+                        if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) {
+                            log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token);
+                            l_iter = 0;
+                            DAP_DELETE(l_price);
+                            break;
+                        }
+                        continue;
+                    case 6:
+                        log_it(L_INFO, "Price item correct, added to service");
+                        DL_APPEND(l_srv->pricelist, l_price);
+                        break;
+                    default:
+                        break;
+                    }
+                    log_it(L_DEBUG, "Done with price item %d", i);
+                    break; // double break exits tokenizer loop and steps to next price item
+                }
+            }
+        }
         HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata);
     }else{
         log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64);
-        //l_srv = l_sdata->srv;
     }
     pthread_mutex_unlock(&s_srv_list_mutex);
     return l_srv;
@@ -644,9 +740,8 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_cha
  */
 int dap_chain_net_srv_set_ch_callbacks(dap_chain_net_srv_uid_t a_uid,
                                        dap_chain_net_srv_callback_ch_t a_callback_stream_ch_opened,
-                                       dap_chain_net_srv_callback_data_t a_callback_stream_ch_read,
-                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_write,
-                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_closed
+                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_closed,
+                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_write
                                        )
 {
     service_list_t *l_sdata = NULL;
@@ -659,9 +754,8 @@ int dap_chain_net_srv_set_ch_callbacks(dap_chain_net_srv_uid_t a_uid,
     if( l_sdata ) {
         l_srv = l_sdata->srv;
         l_srv->callback_stream_ch_opened = a_callback_stream_ch_opened;
-        l_srv->callback_stream_ch_read = a_callback_stream_ch_read;
-        l_srv->callback_stream_ch_write = a_callback_stream_ch_write;
         l_srv->callback_stream_ch_closed = a_callback_stream_ch_closed;
+        l_srv->callback_stream_ch_write = a_callback_stream_ch_write;
     }else{
         log_it(L_ERROR, "Can't find service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64);
         l_ret= -1;
@@ -829,24 +923,14 @@ const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(void)
  * @param a_price
  * @return
  */
-dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv_t *a_srv,
-                dap_chain_net_srv_usage_t * a_usage,
-                dap_chain_net_srv_price_t * a_price,
-                const void * a_ext, size_t a_ext_size
-                )
+dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv_t *a_srv,                                                         
+                                                               dap_chain_net_srv_price_t * a_price,
+                                                               const void * a_ext, size_t a_ext_size)
 {
     dap_chain_datum_tx_receipt_t * l_receipt = dap_chain_datum_tx_receipt_create(
                     a_srv->uid, a_price->units_uid, a_price->units, dap_chain_uint256_from(a_price->value_datoshi), a_ext, a_ext_size);
-    size_t l_receipt_size = l_receipt->size; // nested receipt plus 8 bits for type
-
     // Sign with our wallet
-    l_receipt_size = dap_chain_datum_tx_receipt_sign_add(&l_receipt,l_receipt_size , dap_chain_wallet_get_key( a_price->wallet,0) );
-
-    a_usage->receipt = l_receipt;
-    a_usage->receipt_size = l_receipt_size;
-    a_usage->wallet = a_price->wallet;
-
-    return  l_receipt;
+    return dap_chain_datum_tx_receipt_sign_add(l_receipt, dap_chain_wallet_get_key(a_price->wallet, 0));
 }
 
 
diff --git a/modules/net/srv/dap_chain_net_srv_client.c b/modules/net/srv/dap_chain_net_srv_client.c
index 7b257961931740e37eef76590b53ed499fc9744f..84b92fe75fa4209d419229c9883825feca0966a8 100644
--- a/modules/net/srv/dap_chain_net_srv_client.c
+++ b/modules/net/srv/dap_chain_net_srv_client.c
@@ -35,12 +35,6 @@ static void s_srv_client_callback_connected(dap_chain_node_client_t *a_node_clie
 static void s_srv_client_callback_disconnected(dap_chain_node_client_t *a_node_client, void *a_arg);
 static void s_srv_client_callback_deleted(dap_chain_node_client_t *a_node_client, void *a_arg);
 
-static dap_chain_node_client_callbacks_t s_callbacks = {
-    .connected = s_srv_client_callback_connected,
-    .disconnected = s_srv_client_callback_disconnected,
-    .delete = s_srv_client_callback_deleted
-};
-
 dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_net_t *a_net, char *a_addr, uint16_t a_port,
                                                                       dap_chain_net_srv_client_callbacks_t *a_callbacks,
                                                                       void *a_callbacks_arg)
@@ -49,14 +43,19 @@ dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_
     if (a_callbacks)
         memcpy(&l_ret->callbacks, a_callbacks, sizeof(*a_callbacks));
     l_ret->callbacks_arg = a_callbacks_arg;
-    if (a_callbacks && a_callbacks->pkt_in)
-        s_callbacks.srv_pkt_in = a_callbacks->pkt_in;
-    else
-        s_callbacks.srv_pkt_in = (dap_stream_ch_callback_packet_t)s_srv_client_pkt_in;
+    dap_chain_node_client_callbacks_t l_callbacks = {
+        .connected = s_srv_client_callback_connected,
+        .disconnected = s_srv_client_callback_disconnected,
+        .delete = s_srv_client_callback_deleted
+    };
+    l_callbacks.srv_pkt_in = (dap_stream_ch_callback_packet_t)s_srv_client_pkt_in;
     dap_chain_node_info_t *l_info = DAP_NEW_Z(dap_chain_node_info_t);
     inet_pton(AF_INET, a_addr, &l_info->hdr.ext_addr_v4);
     l_info->hdr.ext_port = a_port;
-    l_ret->node_client = dap_chain_node_client_create_n_connect(a_net, l_info, "R", &s_callbacks, l_ret);
+    const char l_channels[] = {dap_stream_ch_chain_net_srv_get_id(), '\0'};
+    l_ret->node_client = dap_chain_node_client_create_n_connect(a_net, l_info,
+                                                                l_channels,
+                                                                &l_callbacks, l_ret);
     DAP_DELETE(l_info);
     return l_ret;
 }
@@ -65,6 +64,13 @@ ssize_t dap_chain_net_srv_client_write(dap_chain_net_srv_client_t *a_client, uin
 {
     if (!a_client || !a_client->net_client || dap_client_get_stage(a_client->net_client) != STAGE_STREAM_STREAMING)
         return -1;
+    if (a_type == DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST) {
+        dap_stream_ch_t *l_ch = dap_client_get_stream_ch_unsafe(a_client->net_client,
+                                                                dap_stream_ch_chain_net_srv_get_id());
+        dap_stream_ch_chain_net_srv_t *a_ch_chain = DAP_STREAM_CH_CHAIN_NET_SRV(l_ch);
+        dap_stream_ch_chain_net_srv_pkt_request_t *l_request = (dap_stream_ch_chain_net_srv_pkt_request_t *)a_pkt_data;
+        a_ch_chain->srv_uid.uint64 = l_request->hdr.srv_uid.uint64;
+    }
     dap_stream_worker_t *l_stream_worker = dap_client_get_stream_worker(a_client->net_client);
     return dap_stream_ch_pkt_write_mt(l_stream_worker, a_client->ch_uuid, a_type, a_pkt_data, a_pkt_data_size);
 }
@@ -77,15 +83,6 @@ static void s_srv_client_callback_connected(dap_chain_node_client_t *a_node_clie
     l_srv_client->net_client = a_node_client->client;
     if (l_srv_client->callbacks.connected)
         l_srv_client->callbacks.connected(l_srv_client, l_srv_client->callbacks_arg);
-    /* Test code for get reply from server
-    const int l_test_size = 64;
-    size_t l_request_size = l_test_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
-    dap_stream_ch_chain_net_srv_pkt_test_t *l_request = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_test_t, l_request_size);
-    l_request->data_size = l_test_size;
-    randombytes(l_request->data, l_test_size);
-    dap_hash_fast(l_request->data, l_request->data_size, &l_request->data_hash);
-    dap_chain_net_srv_client_write(l_srv_client, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST, l_request, l_request_size);
-    DAP_DELETE(l_request); */
 }
 
 static void s_srv_client_callback_disconnected(dap_chain_node_client_t *a_node_client, void *a_arg)
@@ -109,22 +106,84 @@ static void s_srv_client_callback_deleted(dap_chain_node_client_t *a_node_client
 
 static void s_srv_client_pkt_in(dap_stream_ch_chain_net_srv_t *a_ch_chain, uint8_t a_pkt_type, dap_stream_ch_pkt_t *a_pkt, void *a_arg)
 {
-    UNUSED(a_ch_chain);
-    //dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)a_arg;
+    dap_chain_net_srv_client_t *l_srv_client = (dap_chain_net_srv_client_t *)a_arg;
     switch (a_pkt_type) {
     case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE: {
-            dap_stream_ch_chain_net_srv_pkt_test_t *l_request = (dap_stream_ch_chain_net_srv_pkt_test_t *) a_pkt->data;
-            size_t l_request_size = l_request->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
-            if(a_pkt->hdr.size != l_request_size) {
-                log_it(L_WARNING, "Wrong request size, less or more than required");
-                break;
+        dap_stream_ch_chain_net_srv_pkt_test_t *l_response = (dap_stream_ch_chain_net_srv_pkt_test_t *)a_pkt->data;
+        size_t l_response_size = l_response->data_size + sizeof(dap_stream_ch_chain_net_srv_pkt_test_t);
+        if (a_pkt->hdr.size != l_response_size) {
+            log_it(L_WARNING, "Wrong response size %u, required %zu", a_pkt->hdr.size, l_response_size);
+            if (l_srv_client->callbacks.error)
+                l_srv_client->callbacks.error(l_srv_client,
+                                              DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_SIZE,
+                                              l_srv_client->callbacks_arg);
+            break;
+        }
+        struct timeval l_recv_time;
+        gettimeofday(&l_recv_time, NULL);
+        l_response->recv_time1 = l_recv_time;
+        dap_chain_hash_fast_t l_data_hash;
+        dap_hash_fast(l_response->data, l_response->data_size, &l_data_hash);
+        if (!dap_hash_fast_compare(&l_data_hash, &l_response->data_hash)) {
+            if (l_srv_client->callbacks.error)
+                l_srv_client->callbacks.error(l_srv_client,
+                                              DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_HASH,
+                                              l_srv_client->callbacks_arg);
+            break;
+        }
+        if (l_srv_client->callbacks.check)
+            l_srv_client->callbacks.check(l_srv_client, l_response, l_srv_client->callbacks_arg);
+    } break;
+    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST: {
+        log_it(L_NOTICE, "Requested receipt to sign");
+        dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t *)a_pkt->data;
+        if (a_pkt->hdr.size != l_receipt->size) {
+            log_it(L_WARNING, "Wrong response size %u, required %"DAP_UINT64_FORMAT_U, a_pkt->hdr.size, l_receipt->size);
+            if (l_srv_client->callbacks.error)
+                l_srv_client->callbacks.error(l_srv_client,
+                                              DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_SIZE,
+                                              l_srv_client->callbacks_arg);
+            break;
+        }
+        if (l_srv_client->callbacks.sign) {
+            // Duplicate receipt for realloc can be applied
+            dap_chain_datum_tx_receipt_t *l_rec_cpy = DAP_DUP_SIZE(l_receipt, l_receipt->size);
+            // Sign receipt
+            l_rec_cpy = l_srv_client->callbacks.sign(l_srv_client, l_rec_cpy, l_srv_client->callbacks_arg);
+            if (l_rec_cpy) {
+                dap_stream_ch_pkt_write_unsafe(a_ch_chain->ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE,
+                                               l_rec_cpy, l_rec_cpy->size);
+                DAP_DELETE(l_rec_cpy);
+            } else {
+                log_it(L_ERROR, "Problem with receipt signing, callback.sign returned NULL");
             }
-            log_it(L_INFO, "Service client check request success!");
-        } break;
-    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE:
-    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS:
-    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR:
-        break;
+        }
+    } break;
+    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS: {
+        log_it( L_NOTICE, "Responsed with success");
+        dap_stream_ch_chain_net_srv_pkt_success_t *l_success = (dap_stream_ch_chain_net_srv_pkt_success_t *)a_pkt->data;
+        size_t l_success_size = a_pkt->hdr.size;
+        if (l_srv_client->callbacks.success) {
+            l_srv_client->callbacks.success(l_srv_client, l_success, l_success_size, l_srv_client->callbacks_arg);
+        }
+    } break;
+    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR: {
+       if (a_pkt->hdr.size == sizeof (dap_stream_ch_chain_net_srv_pkt_error_t)) {
+            dap_stream_ch_chain_net_srv_pkt_error_t *l_err = (dap_stream_ch_chain_net_srv_pkt_error_t *)a_pkt->data;
+            log_it(L_WARNING, "Remote responsed with error code 0x%08X", l_err->code);
+            if (l_srv_client->callbacks.error)
+                l_srv_client->callbacks.error(l_srv_client, l_err->code, l_srv_client->callbacks_arg);
+        } else {
+            log_it(L_ERROR, "Wrong error response size, %u when expected %zu", a_pkt->hdr.size,
+                   sizeof ( dap_stream_ch_chain_net_srv_pkt_error_t) );
+        }
+    } break;
+    case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_DATA: {
+        dap_stream_ch_chain_net_srv_pkt_data_t *l_response = (dap_stream_ch_chain_net_srv_pkt_data_t *)a_pkt->data;
+        log_it(L_DEBUG, "Service client got custom data response");
+        if (l_srv_client->callbacks.data)
+            l_srv_client->callbacks.data(l_srv_client, l_response->data, l_response->hdr.data_size, l_srv_client->callbacks_arg);
+    }
     default:
         break;
     }
diff --git a/modules/net/srv/dap_chain_net_srv_common.c b/modules/net/srv/dap_chain_net_srv_common.c
deleted file mode 100644
index 36a84b59e898aa4eb4804641066bca01935d55f8..0000000000000000000000000000000000000000
--- a/modules/net/srv/dap_chain_net_srv_common.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * Aleksandr Lysikov <alexander.lysikov@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 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/>.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef WIN32
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#endif
-
-#include <pthread.h>
-
-#include "dap_strfuncs.h"
-#include "rand/dap_rand.h"
-#include "dap_chain_datum_tx_items.h"
-#include "dap_stream.h"
-#include "dap_chain_net_srv_common.h"
-#include "dap_chain_net_srv.h"
-/*
- * Init service client
- * l_uid service id
- * a_callback_client_success callback to start client service
- */
-//
-int dap_chain_net_srv_remote_init(dap_chain_net_srv_uid_t a_uid,
-        dap_chain_net_srv_callback_data_t a_callback_request,
-        dap_chain_net_srv_callback_data_t a_callback_response_success,
-        dap_chain_net_srv_callback_data_t a_callback_response_error,
-        dap_chain_net_srv_callback_data_t a_callback_receipt_next_success,
-        dap_chain_net_srv_callback_data_t a_callback_client_success,
-        dap_chain_net_srv_callback_sign_request_t a_callback_client_sign_request,
-        void *a_inhertor) {
-
-    dap_chain_net_srv_t *l_srv_custom = dap_chain_net_srv_get(a_uid);
-    if(!l_srv_custom) {
-        l_srv_custom = dap_chain_net_srv_add(a_uid, a_callback_request,
-                a_callback_response_success, a_callback_response_error,
-                a_callback_receipt_next_success);
-    }
-    l_srv_custom->callback_client_success = a_callback_client_success;
-    l_srv_custom->callback_client_sign_request = a_callback_client_sign_request;
-    if(a_inhertor)
-        l_srv_custom->_inhertor = a_inhertor;
-    return 0;
-}
diff --git a/modules/net/srv/dap_chain_net_srv_stream_session.c b/modules/net/srv/dap_chain_net_srv_stream_session.c
index 3a2763bd69fc82326c569d0a8318533659f007c0..e72e03bad1e86179aaa410e13d226e9e0ab36430 100644
--- a/modules/net/srv/dap_chain_net_srv_stream_session.c
+++ b/modules/net/srv/dap_chain_net_srv_stream_session.c
@@ -59,7 +59,6 @@ dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream
 {
     if ( a_srv_session && a_net && a_srv ){
         dap_chain_net_srv_usage_t * l_ret = DAP_NEW_Z(dap_chain_net_srv_usage_t);
-        //l_ret->id = 666;
         randombytes(&l_ret->id, sizeof(l_ret->id));
         l_ret->net = a_net;
         l_ret->service = a_srv;
diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h
index decccd52e1260d1b7f69895167254010630fbf9a..6767463c4c0a41873ae2f5420a6d1965f03f982a 100755
--- a/modules/net/srv/include/dap_chain_net_srv.h
+++ b/modules/net/srv/include/dap_chain_net_srv.h
@@ -24,16 +24,188 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 */
 #pragma once
 
+#include "dap_chain_net.h"
+#include "dap_chain_net_remote.h"
+#include "dap_chain_wallet.h"
+#include "dap_common.h"
 #include "dap_config.h"
-#include "dap_chain_net_srv_common.h"
-#include "dap_chain_net_srv_client.h"
-#include "dap_chain_net_srv_stream_session.h"
+#include "dap_stream_ch.h"
+
+//Service direction
+enum dap_chain_net_srv_order_direction{
+    SERV_DIR_BUY = 1,
+    SERV_DIR_SELL = 2,
+    SERV_DIR_UNDEFINED = 0
+};
+typedef byte_t dap_chain_net_srv_order_direction_t;
+
+
+typedef struct dap_chain_net_srv_abstract
+{
+    uint8_t class; //Class of service (once or permanent)
+    dap_chain_net_srv_uid_t type_id; //Type of service
+    union {
+        struct {
+            int bandwith;
+            int abuse_resistant;
+            size_t limit_bytes;
+        } vpn;
+        /*struct {
+         int value;
+         } another_srv;*/
+    } proposal_params;
+
+    //size_t pub_key_data_size;
+    //void * pub_key_data;
+
+    uint64_t price; //  service price, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT  for one unit.
+    uint8_t price_units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT
+    char decription[128];
+}DAP_ALIGN_PACKED dap_chain_net_srv_abstract_t;
+
+typedef void (*dap_chain_callback_trafic_t)(dap_events_socket_t *, dap_stream_ch_t *);
+
+typedef struct dap_chain_net_srv_price
+{
+    dap_chain_wallet_t *wallet;
+    char *net_name;
+    dap_chain_net_t *net;
+    uint64_t value_datoshi;
+    char token[DAP_CHAIN_TICKER_SIZE_MAX];
+    uint64_t units;
+    dap_chain_net_srv_price_unit_uid_t units_uid;
+    struct dap_chain_net_srv_price *next;
+    struct dap_chain_net_srv_price *prev;
+} dap_chain_net_srv_price_t;
+
+// Ch pkt types
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST                       0x01
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST                  0x10
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE                 0x11
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED                0x20
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_DATA                          0x30
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_DATA                 0x31
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS              0xf0
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR                0xff
+// for connection testing
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST                 0x40
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE                0x41
+
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNDEFINED                  0x00000000
+
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND          0x00000100
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_CH_NOT_FOUND       0x00000101
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_IN_CLIENT_MODE     0x00000102
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND          0x00000200
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER          0x00000201
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_CANT_ADD_USAGE             0x00000300
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND          0x00000400
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT        0x00000401
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH         0x00000402
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN   0x00000403
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID      0x00000404
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_SIZE                 0x00000405
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND          0x00000500
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_NO_SIGN            0x00000501
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_WRONG_PKEY_HASH    0x00000502
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH   0x00000503
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND            0x00000600
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_WRONG_HASH                 0x00000BAD
+
+#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNKNOWN                    0xffffffff
+// TYPE_REQUEST
+typedef struct dap_stream_ch_chain_net_srv_pkt_request_hdr{
+    dap_chain_net_id_t net_id;// Network id wheither to request
+    dap_chain_hash_fast_t tx_cond; // Conditioned transaction with paymemt for
+    dap_chain_net_srv_uid_t srv_uid;
+    char token[DAP_CHAIN_TICKER_SIZE_MAX];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_hdr_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_request{
+    dap_stream_ch_chain_net_srv_pkt_request_hdr_t hdr;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_t;
+
+// Custom service data packet
+typedef struct dap_stream_ch_chain_net_srv_pkt_data_hdr{
+    uint8_t version;
+    uint16_t data_size;
+    uint8_t padding;
+    uint32_t usage_id;
+    dap_chain_net_srv_uid_t srv_uid;
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_data_hdr_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_data{
+    dap_stream_ch_chain_net_srv_pkt_data_hdr_t hdr;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_data_t;
+
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_success_hdr{
+    uint32_t usage_id;
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_hdr_t;
+
+typedef struct dap_stream_ch_chain_net_srv_pkt_success{
+    dap_stream_ch_chain_net_srv_pkt_success_hdr_t hdr;
+    uint8_t custom_data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_t;
+
+// TYPE_RESPONSE_ERROR
+typedef struct dap_stream_ch_chain_net_srv_pkt_error{
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+    uint32_t usage_id;
+    uint32_t code; // error code
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_error_t;
+
+// data packet for connectiont test
+typedef struct dap_stream_ch_chain_net_srv_pkt_test{
+    uint32_t usage_id;
+    dap_chain_net_id_t net_id;
+    dap_chain_net_srv_uid_t srv_uid;
+    int32_t  time_connect_ms;
+    struct timeval recv_time1;
+    struct timeval recv_time2;
+    struct timeval send_time1;
+    struct timeval send_time2;
+    char ip_send[16];
+    char ip_recv[16];
+    int32_t err_code;
+    size_t data_size_send;
+    size_t data_size_recv;
+    size_t data_size;
+    dap_chain_hash_fast_t data_hash;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_test_t;
 
 typedef struct dap_chain_net_srv dap_chain_net_srv_t;
+typedef struct dap_chain_net_srv_usage dap_chain_net_srv_usage_t;
 
-typedef void (*dap_chain_net_srv_callback_t)(dap_chain_net_srv_t *, dap_chain_net_srv_client_remote_t *);
-typedef int (*dap_chain_net_srv_callback_data_t)(dap_chain_net_srv_t *, uint32_t, dap_chain_net_srv_client_remote_t *, const void *, size_t );
-typedef int (*dap_chain_net_srv_callback_sign_request_t)(dap_chain_net_srv_t *, uint32_t, dap_chain_net_srv_client_remote_t *, dap_chain_datum_tx_receipt_t **, size_t );
+typedef struct dap_chain_net_srv_grace {
+    dap_stream_worker_t *stream_worker;
+    dap_stream_ch_uuid_t ch_uuid;
+    dap_chain_net_srv_usage_t *usage;
+    dap_stream_ch_chain_net_srv_pkt_request_t *request;
+    size_t request_size;
+} dap_chain_net_srv_grace_t;
+
+typedef struct dap_chain_net_srv_client_remote
+{
+    dap_stream_ch_t * ch; // Use ONLY in own context, not thread-safe
+    time_t ts_created;
+    dap_stream_worker_t * stream_worker;
+    int session_id;
+    dap_chain_net_remote_t *net_remote; // For remotes
+    uint64_t bytes_received;
+    uint64_t bytes_sent;
+    struct dap_chain_net_srv_client_remote *prev;
+    struct dap_chain_net_srv_client_remote *next;
+} dap_chain_net_srv_client_remote_t;
+
+typedef int  (*dap_chain_net_srv_callback_data_t)(dap_chain_net_srv_t *, uint32_t, dap_chain_net_srv_client_remote_t *, const void *, size_t);
+typedef void* (*dap_chain_net_srv_callback_custom_data_t)(dap_chain_net_srv_t *, dap_chain_net_srv_usage_t *, const void *, size_t, size_t *);
 typedef void (*dap_chain_net_srv_callback_ch_t)(dap_chain_net_srv_t *, dap_stream_ch_t *);
 
 typedef struct dap_chain_net_srv_banlist_item {
@@ -67,50 +239,35 @@ typedef struct dap_chain_net_srv
     // Receipt next sign succesfull
     dap_chain_net_srv_callback_data_t callback_receipt_next_success;
 
-    // Stream CH callbacks - channed opened,ready for read, ready for write and closed
-    dap_chain_net_srv_callback_ch_t      callback_stream_ch_opened;
-    dap_chain_net_srv_callback_data_t callback_stream_ch_read;
-    dap_chain_net_srv_callback_ch_t callback_stream_ch_write;
-    dap_chain_net_srv_callback_ch_t      callback_stream_ch_closed;
-
-    // Client have to start service
-    dap_chain_net_srv_callback_data_t callback_client_success;
-    // Client have to sign receipt
-    dap_chain_net_srv_callback_sign_request_t callback_client_sign_request;
+    // Custom data processing
+    dap_chain_net_srv_callback_custom_data_t callback_custom_data;
 
+    // Stream CH callbacks - channel opened, closed and write
+    dap_chain_net_srv_callback_ch_t callback_stream_ch_opened;
+    dap_chain_net_srv_callback_ch_t callback_stream_ch_closed;
+    dap_chain_net_srv_callback_ch_t callback_stream_ch_write;
     // Pointer to inheritor object
-    void * _inhertor;
+    void *_inheritor;
+    // Pointer to internal server structure
+    void *_internal;
 } dap_chain_net_srv_t;
 
-typedef void (*dap_chain_net_srv_callback_new_t)(dap_chain_net_srv_t *, dap_config_t *);
-
-typedef struct dap_chain_net_srv_client_remote
-{
-    dap_stream_ch_t * ch; // Use ONLY in own context, not thread-safe
-    time_t ts_created;
-    dap_stream_worker_t * stream_worker;
-    int session_id;
-    dap_chain_net_remote_t *net_remote; // For remotes
-    uint64_t bytes_received;
-    uint64_t bytes_sent;
-    struct dap_chain_net_srv_client_remote *prev;
-    struct dap_chain_net_srv_client_remote *next;
-} dap_chain_net_srv_client_remote_t;
-
-
 int dap_chain_net_srv_init();
 void dap_chain_net_srv_deinit(void);
-dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_requested,
+bool dap_chain_net_srv_pay_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner);
+dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,
+                                           const char *a_config_section,
+                                           dap_chain_net_srv_callback_data_t a_callback_requested,
                                            dap_chain_net_srv_callback_data_t a_callback_response_success,
                                            dap_chain_net_srv_callback_data_t a_callback_response_error,
-                                           dap_chain_net_srv_callback_data_t a_callback_receipt_next_success
+                                           dap_chain_net_srv_callback_data_t a_callback_receipt_next_success,
+                                           dap_chain_net_srv_callback_custom_data_t a_callback_custom_data
                                            );
 
 int dap_chain_net_srv_set_ch_callbacks(dap_chain_net_srv_uid_t a_uid,
                                        dap_chain_net_srv_callback_ch_t a_callback_stream_ch_opened,
-                                       dap_chain_net_srv_callback_data_t a_callback_stream_ch_read,
-                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_write,
-                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_closed
+                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_closed,
+                                       dap_chain_net_srv_callback_ch_t a_callback_stream_ch_write
                                        );
 
 void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv);
@@ -124,16 +281,18 @@ dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t a_uid);
 size_t dap_chain_net_srv_count(void);
 const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(void);
 dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv_t *a_srv,
-                dap_chain_net_srv_usage_t * a_usage,
-                dap_chain_net_srv_price_t * a_price, const void * a_ext, size_t a_ext_size
-                );
-
-
-int dap_chain_net_srv_remote_init(dap_chain_net_srv_uid_t a_uid,
-        dap_chain_net_srv_callback_data_t a_callback_request,
-        dap_chain_net_srv_callback_data_t a_callback_response_success,
-        dap_chain_net_srv_callback_data_t a_callback_response_error,
-        dap_chain_net_srv_callback_data_t a_callback_receipt_next_success,
-        dap_chain_net_srv_callback_data_t a_callback_client_success,
-        dap_chain_net_srv_callback_sign_request_t a_callback_client_sign_request,
-        void *a_inhertor);
+                                                               dap_chain_net_srv_price_t * a_price,
+                                                               const void * a_ext, size_t a_ext_size);
+uint8_t dap_stream_ch_chain_net_srv_get_id();
+
+DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid )
+{
+    switch ( a_uid.enm) {
+        case SERV_UNIT_B: return "BYTE";
+        case SERV_UNIT_KB: return "KILOBYTE";
+        case SERV_UNIT_MB: return "MEGABYTE";
+        case SERV_UNIT_SEC: return "SECOND";
+        case SERV_UNIT_DAY: return  "DAY";
+        default: return "UNKNOWN";
+    }
+}
diff --git a/modules/net/srv/include/dap_chain_net_srv_client.h b/modules/net/srv/include/dap_chain_net_srv_client.h
index f1ea76d4e8e669e4e0e17f0ea6204543d2e48996..93c2c95f338b2ec78016efdad8cc04f7212578df 100644
--- a/modules/net/srv/include/dap_chain_net_srv_client.h
+++ b/modules/net/srv/include/dap_chain_net_srv_client.h
@@ -28,21 +28,29 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 
 
 #include "dap_enc_key.h"
-#include "dap_stream_session.h"
 #include "dap_stream_worker.h"
-#include "dap_chain_net_srv_common.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_net_remote.h"
 #include "dap_chain_node_client.h"
 
 typedef struct dap_chain_net_srv_client dap_chain_net_srv_client_t;
 
-typedef void (*dap_chain_net_srv_client_callback_t)(dap_chain_net_srv_client_t *, void *);
+typedef void   (*dap_chain_net_srv_client_callback_t)(dap_chain_net_srv_client_t *, void *);
+typedef void   (*dap_chain_net_srv_client_callback_check_t)(dap_chain_net_srv_client_t *, dap_stream_ch_chain_net_srv_pkt_test_t *, void *);
+typedef dap_chain_datum_tx_receipt_t * (*dap_chain_net_srv_client_callback_sign_t)(dap_chain_net_srv_client_t *, dap_chain_datum_tx_receipt_t *, void *);
+typedef void   (*dap_chain_net_srv_client_callback_success_t)(dap_chain_net_srv_client_t *, dap_stream_ch_chain_net_srv_pkt_success_t *, size_t, void *);
+typedef void   (*dap_chain_net_srv_client_callback_error_t)(dap_chain_net_srv_client_t *, int, void *);
+typedef void   (*dap_chain_net_srv_client_data_t)(dap_chain_net_srv_client_t *, uint8_t *, size_t, void *);
 
 typedef struct dap_chain_net_srv_client_callbacks {
     dap_chain_net_srv_client_callback_t connected;
     dap_chain_net_srv_client_callback_t disconnected;
     dap_chain_net_srv_client_callback_t deleted;
-    dap_stream_ch_callback_packet_t pkt_in;
+    dap_chain_net_srv_client_callback_check_t check;        // Client has got response for test
+    dap_chain_net_srv_client_callback_success_t success;    // Client has started service
+    dap_chain_net_srv_client_callback_error_t error;        // Client recieved an error
+    dap_chain_net_srv_client_callback_sign_t sign;          // Cleint has got receipt for sign
+    dap_chain_net_srv_client_data_t data;                   // Client has got custom data response
 } dap_chain_net_srv_client_callbacks_t;
 
 typedef struct dap_chain_net_srv_client {
@@ -51,6 +59,7 @@ typedef struct dap_chain_net_srv_client {
     dap_stream_ch_uuid_t ch_uuid;
     dap_chain_node_client_t *node_client;
     dap_client_t *net_client;
+    void *_inheritor;
 } dap_chain_net_srv_client_t;
 
 dap_chain_net_srv_client_t *dap_chain_net_srv_client_create_n_connect(dap_chain_net_t *a_net, char *a_addr, uint16_t a_port,
diff --git a/modules/net/srv/include/dap_chain_net_srv_common.h b/modules/net/srv/include/dap_chain_net_srv_common.h
deleted file mode 100755
index 9f316ee5d63f075042bdca596c45eead1a58b00c..0000000000000000000000000000000000000000
--- a/modules/net/srv/include/dap_chain_net_srv_common.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Authors:
- * Aleksandr Lysikov <alexander.lysikov@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 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/>.
- */
-
-#pragma once
-#include <stdint.h>
-#include <stdbool.h>
-#include "dap_server.h"
-#include "dap_common.h"
-#include "dap_math_ops.h"
-#include "dap_stream_ch.h"
-#include "dap_chain_common.h"
-#include "dap_chain_ledger.h"
-#include "dap_chain_net.h"
-#include "dap_chain_wallet.h"
-//#include "dap_chain_net_srv_stream_session.h"
-
-
-//Service direction
-enum dap_chain_net_srv_order_direction{
-    SERV_DIR_BUY = 1,
-    SERV_DIR_SELL = 2,
-    SERV_DIR_UNDEFINED = 0
-};
-typedef byte_t dap_chain_net_srv_order_direction_t;
-
-
-typedef struct dap_chain_net_srv_abstract
-{
-    uint8_t class; //Class of service (once or permanent)
-    dap_chain_net_srv_uid_t type_id; //Type of service
-    union {
-        struct {
-            int bandwith;
-            int abuse_resistant;
-            size_t limit_bytes;
-        } vpn;
-        /*struct {
-         int value;
-         } another_srv;*/
-    } proposal_params;
-
-    //size_t pub_key_data_size;
-    //void * pub_key_data;
-
-    uint64_t price; //  service price, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT  for one unit.
-    uint8_t price_units; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT
-    char decription[128];
-}DAP_ALIGN_PACKED dap_chain_net_srv_abstract_t;
-
-typedef void (*dap_chain_callback_trafic_t)(dap_events_socket_t *, dap_stream_ch_t *);
-
-typedef struct dap_chain_net_srv_price
-{
-    dap_chain_wallet_t * wallet;
-    char * net_name;
-    dap_chain_net_t * net;
-    uint64_t value_datoshi;
-    char token[DAP_CHAIN_TICKER_SIZE_MAX];
-    uint64_t units;
-    dap_chain_net_srv_price_unit_uid_t units_uid;
-    struct dap_chain_net_srv_price * next;
-    struct dap_chain_net_srv_price * prev;
-} dap_chain_net_srv_price_t;
-
-// Ch pkt types
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST                       0x01
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST                  0x10
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE                 0x11
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED                0x20
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_DATA                          0x30
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS              0xf0
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR                0xff
-// for connection testing
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_REQUEST                 0x40
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_CHECK_RESPONSE                0x41
-
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNDEFINED                  0x00000000
-
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND          0x00000100
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_CH_NOT_FOUND       0x00000101
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_IN_CLIENT_MODE     0x00000102
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND          0x00000200
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER          0x00000201
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_USAGE_CANT_ADD             0x00000300
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND          0x00000400
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT        0x00000401
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH         0x00000402
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN   0x00000403
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID      0x00000404
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SIZE         0x00000405
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND          0x00000500
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_NO_SIGN            0x00000501
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_WRONG_PKEY_HASH    0x00000502
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH   0x00000503
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND            0x00000600
-
-#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNKNOWN                    0xffffffff
-// TYPE_REQUEST
-typedef struct dap_stream_ch_chain_net_srv_pkt_request_hdr{
-    dap_chain_net_id_t net_id;// Network id wheither to request
-    dap_chain_hash_fast_t tx_cond; // Conditioned transaction with paymemt for
-    dap_chain_net_srv_uid_t srv_uid;
-    char token[DAP_CHAIN_TICKER_SIZE_MAX];
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_hdr_t;
-
-typedef struct dap_stream_ch_chain_net_srv_pkt_request{
-    dap_stream_ch_chain_net_srv_pkt_request_hdr_t hdr;
-    uint8_t data[];
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_t;
-
-// Custom service data packet
-typedef struct dap_stream_ch_chain_net_srv_pkt_data_hdr{
-    uint8_t version;
-    uint8_t offset[3];
-    uint32_t usage_id;
-    dap_chain_net_srv_uid_t srv_uid;
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_data_hdr_t;
-
-typedef struct dap_stream_ch_chain_net_srv_pkt_data{
-    dap_stream_ch_chain_net_srv_pkt_data_hdr_t hdr;
-    uint8_t data[];
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_data_t;
-
-
-typedef struct dap_stream_ch_chain_net_srv_pkt_success_hdr{
-    uint32_t usage_id;
-    dap_chain_net_id_t net_id;
-    dap_chain_net_srv_uid_t srv_uid;
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_hdr_t;
-
-typedef struct dap_stream_ch_chain_net_srv_pkt_success{
-    dap_stream_ch_chain_net_srv_pkt_success_hdr_t hdr;
-    uint8_t custom_data[];
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_t;
-
-// TYPE_RESPONSE_ERROR
-typedef struct dap_stream_ch_chain_net_srv_pkt_error{
-    dap_chain_net_id_t net_id;
-    dap_chain_net_srv_uid_t srv_uid;
-    uint32_t usage_id;
-    uint32_t code; // error code
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_error_t;
-
-// data packet for connectiont test
-typedef struct dap_stream_ch_chain_net_srv_pkt_test{
-    uint32_t usage_id;
-    dap_chain_net_id_t net_id;
-    dap_chain_net_srv_uid_t srv_uid;
-    int32_t  time_connect_ms;
-    struct timeval recv_time1;
-    struct timeval recv_time2;
-    struct timeval send_time1;
-    struct timeval send_time2;
-    char ip_send[16];
-    char ip_recv[16];
-    int32_t err_code;
-    size_t data_size_send;
-    size_t data_size_recv;
-    size_t data_size;
-    dap_chain_hash_fast_t data_hash;
-    uint8_t data[];
-} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_test_t;
-
-typedef struct dap_chain_net_srv_usage dap_chain_net_srv_usage_t;
-
-typedef struct dap_chain_net_srv_grace {
-    dap_stream_worker_t *stream_worker;
-    dap_stream_ch_uuid_t ch_uuid;
-    dap_chain_net_srv_usage_t *usage;
-    dap_stream_ch_chain_net_srv_pkt_request_t *request;
-    size_t request_size;
-} dap_chain_net_srv_grace_t;
-
-DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid )
-{
-    switch ( a_uid.enm) {
-        case SERV_UNIT_B: return "BYTE";
-        case SERV_UNIT_KB: return "KILOBYTE";
-        case SERV_UNIT_MB: return "MEGABYTE";
-        case SERV_UNIT_SEC: return "SECOND";
-        case SERV_UNIT_DAY: return  "DAY";
-        default: return "UNKNOWN";
-    }
-}
-
-uint8_t dap_stream_ch_chain_net_srv_get_id();
diff --git a/modules/net/srv/include/dap_chain_net_srv_order.h b/modules/net/srv/include/dap_chain_net_srv_order.h
index 93a92d529263c41a5db437433a80c1bf35b81ae7..64ba42eff1c20e4e61382fb988e20df6417fc0c4 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -27,7 +27,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_common.h"
 #include "dap_string.h"
 #include "dap_chain_common.h"
-#include "dap_chain_net_srv_common.h"
+#include "dap_chain_net_srv.h"
 
 typedef struct dap_chain_net_srv_order_old
 {
diff --git a/modules/net/srv/include/dap_chain_net_srv_stream_session.h b/modules/net/srv/include/dap_chain_net_srv_stream_session.h
index 66c192c2afc14c6d885ee43235fd21d43bb296a3..527927cc16e91a65156153917c54e4fdb9ecd1db 100644
--- a/modules/net/srv/include/dap_chain_net_srv_stream_session.h
+++ b/modules/net/srv/include/dap_chain_net_srv_stream_session.h
@@ -31,7 +31,7 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_sign.h"
 #include "dap_chain_datum_tx.h"
 #include "dap_chain_datum_tx_receipt.h"
-#include "dap_chain_net_srv_order.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_wallet.h"
 
 typedef struct dap_chain_net_srv dap_chain_net_srv_t;
@@ -42,14 +42,11 @@ typedef struct dap_chain_net_srv_usage{
     pthread_rwlock_t rwlock;
     time_t ts_created; // Created timpestamp
     dap_chain_net_t * net; // Chain network where everything happens
-    dap_chain_wallet_t * wallet;
     dap_chain_net_srv_t * service; // Service that used
 
     dap_chain_datum_tx_receipt_t* receipt;
     dap_chain_datum_tx_receipt_t* receipt_next; // Receipt on the next units amount
     dap_chain_net_srv_price_t * price; // Price for issue next receipt
-    size_t receipt_size;
-    size_t receipt_next_size;
     dap_chain_net_srv_client_remote_t *client;
     dap_chain_datum_tx_t * tx_cond;
     dap_chain_hash_fast_t tx_cond_hash;
diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c
index 1fa3580a981374522b1848c1adb50e17838ee9fb..ed53f8877b8debba6f42fdc8c56e137337ba0569 100644
--- a/modules/service/datum/dap_chain_net_srv_datum.c
+++ b/modules/service/datum/dap_chain_net_srv_datum.c
@@ -134,7 +134,7 @@ static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply) {
                     }
                     fclose(l_file);
                     DAP_DELETE(l_datum);
-                    return 0;
+                    return -5;
                 }else{
                     log_it(L_ERROR,"Can't serialize certificate in memory");
                     fclose(l_file);
@@ -154,15 +154,18 @@ static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply) {
             size_t l_datum_data_size = 0;
             uint8_t *l_datum_data = dap_chain_net_srv_file_datum_data_read(l_path, &l_datum_data_size);
 
-            int ret;
-            if ( (ret=dap_chain_net_srv_datum_custom_add(l_chain, l_datum_data, l_datum_data_size)) != 0 ) {
+            char *l_ret;
+            if ((l_ret = dap_chain_net_srv_datum_custom_add(l_chain, l_datum_data, l_datum_data_size)) == NULL) {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
-                        "Can't place datum custom \"%s\" to mempool, code=%d", l_datum_hash_str, ret);
+                        "Can't place datum custom \"%s\" to mempool", l_datum_hash_str);
             }
             else {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
                         "Datum custom %s was successfully placed to mempool", l_datum_hash_str); 
+                DAP_DELETE(l_ret);
+                return 0;
             }
         }
     }
+    return -1;
 }
diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c
index 886d4f3a897a8fe9254a33adb9aadc8110da0099..da8695e0176b3d90682f3b72c8c3a9225b747c19 100644
--- a/modules/service/stake/dap_chain_net_srv_stake.c
+++ b/modules/service/stake/dap_chain_net_srv_stake.c
@@ -28,7 +28,7 @@
 #include "dap_enc_base58.h"
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
-#include "dap_chain_net_srv_common.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_cs_block_poa.h"
 #include "dap_chain_cs_dag_poa.h"
 #include "dap_chain_net_srv_stake.h"
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index e1e2a3cda7c248d392db295788d03f17cbbbb077..0c4ede5eace204c3977697845cd9b0ca450a43f4 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -533,138 +533,6 @@ static dap_events_socket_t * s_tun_event_stream_create(dap_worker_t * a_worker,
     return l_es;
 }
 
-/**
- * @brief s_callback_client_success
- * @param a_srv
- * @param a_usage_id
- * @param a_srv_client
- * @param a_success
- * @param a_success_size
- * @return
- */
-static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t * a_srv_client,
-                    const void * a_success, size_t a_success_size)
-{
-    if(!a_srv || !a_srv_client || !a_srv_client->stream_worker || !a_success || a_success_size < sizeof(dap_stream_ch_chain_net_srv_pkt_success_t))
-        return -1;
-    dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*) a_success;
-
-    dap_stream_session_lock();
-    dap_stream_session_t *l_stream_session = dap_stream_session_id_unsafe(a_srv_client->session_id);
-    dap_chain_net_srv_stream_session_t * l_srv_session =
-            (dap_chain_net_srv_stream_session_t *) l_stream_session->_inheritor;
-
-    dap_chain_net_srv_vpn_t* l_srv_vpn = (dap_chain_net_srv_vpn_t*) a_srv->_inhertor;
-    //a_srv_client->ch->
-    dap_chain_net_t * l_net = dap_chain_net_by_id(l_success->hdr.net_id);
-    dap_chain_net_srv_usage_t *l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, a_srv);
-    if(!l_usage){
-        dap_stream_session_unlock();
-        return -2;
-    }
-
-    dap_chain_net_srv_ch_vpn_t * l_srv_ch_vpn =
-            (dap_chain_net_srv_ch_vpn_t*) a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID] ?
-                    a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID]->internal : NULL;
-    if ( ! l_srv_ch_vpn ){
-        log_it(L_ERROR, "No VPN service stream channel, its closed?");
-        return -3;
-    }
-    l_srv_ch_vpn->usage_id = l_usage->id;
-    l_usage->is_active = true;
-    l_usage->is_free = true;
-
-    dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch();
-
-
-    if(l_ch) { // Is present in hash table such destination address
-        size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str);
-        ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
-
-        pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST;
-        //pkt_out->header.sock_id = l_stream->stream->events_socket->socket;
-        //pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
-        //pkt_out->header.op_connect.port = a_port;
-        //memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
-
-        dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
-                pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-        dap_stream_ch_set_ready_to_write_unsafe(l_ch, true);
-        //DAP_DELETE(pkt_out);
-    }
-
-    // usage is present, we've accepted packets
-    dap_stream_ch_set_ready_to_read_unsafe( l_srv_ch_vpn->ch , true );
-    return 0;
-}
-
-/**
- * @brief callback_client_sign_request
- * @param a_srv
- * @param a_usage_id
- * @param a_srv_client
- * @param a_receipt
- * @param a_receipt_size
- * @return
- */
-static int s_callback_client_sign_request(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t * a_srv_client,
-                    dap_chain_datum_tx_receipt_t **a_receipt, size_t a_receipt_size)
-{
-    dap_chain_datum_tx_receipt_t *l_receipt = *a_receipt;
-    char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
-    char *l_wallet_name = (char*) dap_chain_global_db_gr_get(dap_strdup("wallet_name"), NULL, l_gdb_group);
-
-    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, dap_chain_wallet_get_path(g_config));
-    if(l_wallet) {
-        dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
-        dap_chain_datum_tx_receipt_sign_add(&l_receipt, dap_chain_datum_tx_receipt_get_size(l_receipt), l_enc_key);
-        dap_chain_wallet_close(l_wallet);
-        *a_receipt = l_receipt;
-    }
-    DAP_DELETE(l_gdb_group);
-    DAP_DELETE(l_wallet_name);
-    return 0;
-}
-
-
-/**
- * @brief dap_chain_net_srv_client_vpn_init
- * @details  Client VPN init (call after dap_chain_net_srv_vpn_init!)
- * @param l_config
- * @return
- */
-int dap_chain_net_srv_client_vpn_init(dap_config_t * l_config) {
-    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
-    dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get(l_uid);
-    dap_chain_net_srv_vpn_t* l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*) l_srv->_inhertor : NULL;
-    // if vpn server disabled
-    if(!l_srv_vpn) {
-        l_srv_vpn = DAP_NEW_Z(dap_chain_net_srv_vpn_t);
-        if(l_srv)
-            l_srv->_inhertor = l_srv_vpn;
-        dap_stream_ch_proc_add(DAP_STREAM_CH_ID_NET_SRV_VPN, s_ch_vpn_new, s_ch_vpn_delete, s_ch_packet_in, s_ch_packet_out);
-        pthread_mutex_init(&s_sf_socks_mutex, NULL);
-        pthread_cond_init(&s_sf_socks_cond, NULL);
-    }
-
-
-    if(!dap_chain_net_srv_remote_init(l_uid, s_callback_requested,
-            s_callback_response_success, s_callback_response_error,
-            s_callback_receipt_next_success,
-            s_callback_client_success,
-            s_callback_client_sign_request,
-            l_srv_vpn)) {
-        l_srv = dap_chain_net_srv_get(l_uid);
-        //l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*)l_srv->_inhertor : NULL;
-        //l_srv_vpn->parent = l_srv;
-        l_srv->_inhertor = l_srv_vpn;
-    }
-    l_srv_vpn->parent = (dap_chain_net_srv_t*) l_srv;
-
-    return 0;
-}
-
-
 /**
  * @brief s_vpn_tun_create
  * @param g_config
@@ -777,91 +645,16 @@ static int s_vpn_tun_init()
 static int s_vpn_service_create(dap_config_t * g_config)
 {
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
-    dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add( l_uid, s_callback_requested,
-                                                        s_callback_response_success, s_callback_response_error,
-                                                        s_callback_receipt_next_success);
+    dap_chain_net_srv_t *l_srv = dap_chain_net_srv_add(l_uid, "srv_vpn", s_callback_requested,
+                                                       s_callback_response_success, s_callback_response_error,
+                                                       s_callback_receipt_next_success, NULL);
 
     dap_chain_net_srv_vpn_t* l_srv_vpn  = DAP_NEW_Z( dap_chain_net_srv_vpn_t);
-    l_srv->_inhertor = l_srv_vpn;
+    l_srv->_internal = l_srv_vpn;
     l_srv_vpn->parent = l_srv;
 
     // Read if we need to dump all pkt operations
     s_debug_more= dap_config_get_item_bool_default(g_config,"srv_vpn", "debug_more",false);
-
-    l_srv->grace_period = dap_config_get_item_uint32_default(g_config, "srv_vpn", "grace_period", 60);
-    //! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data
-    //! it also must NOT be freed within this module !
-    uint16_t l_pricelist_count = 0;
-    char **l_pricelist = dap_config_get_array_str(g_config, "srv_vpn", "pricelist", &l_pricelist_count); // must not be freed!
-    for (uint16_t i = 0; i < l_pricelist_count; i++) {
-        dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
-        short l_iter = 0;
-        char *l_ctx;
-        for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) {
-            //log_it(L_DEBUG, "Tokenizer: %s", l_price_token);
-            switch (l_iter) {
-            case 0:
-                l_price->net_name = l_price_token;
-                if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) {
-                    log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token);
-                    DAP_DELETE(l_price);
-                    break;
-                }
-                continue;
-            case 1:
-                l_price->value_datoshi = dap_chain_coins_to_datoshi(strtold(l_price_token, NULL));
-                if (!l_price->value_datoshi) {
-                    log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token);
-                    l_iter = 0;
-                    DAP_DELETE(l_price);
-                    break;
-                }
-                continue;
-            case 2:
-                dap_stpcpy(l_price->token, l_price_token);
-                continue;
-            case 3:
-                l_price->units = strtoul(l_price_token, NULL, 10);
-                if (!l_price->units) {
-                    log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token);
-                    l_iter = 0;
-                    DAP_DELETE(l_price);
-                    break;
-                }
-                continue;
-            case 4:
-                if (!strcmp(l_price_token,      "SEC"))
-                    l_price->units_uid.enm = SERV_UNIT_SEC;
-                else if (!strcmp(l_price_token, "DAY"))
-                    l_price->units_uid.enm = SERV_UNIT_DAY;
-                else if (!strcmp(l_price_token, "MB"))
-                    l_price->units_uid.enm = SERV_UNIT_MB;
-                else {
-                    log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token);
-                    l_iter = 0;
-                    DAP_DELETE(l_price);
-                    break;
-                }
-                continue;
-            case 5:
-                if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) {
-                    log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token);
-                    l_iter = 0;
-                    DAP_DELETE(l_price);
-                    break;
-                }
-                continue;
-            case 6:
-                log_it(L_INFO, "Price item correct, added to service");
-                DL_APPEND(l_srv->pricelist, l_price);
-                break;
-            default:
-                break;
-            }
-            log_it(L_DEBUG, "Done with price item %d", i);
-            break; // double break exits tokenizer loop and steps to next price item
-        }
-    }
     return 0;
 
 }
@@ -1059,7 +852,7 @@ static void s_ch_vpn_delete(dap_stream_ch_t* a_ch, void* arg)
 {
     (void) arg;
     dap_chain_net_srv_ch_vpn_t * l_ch_vpn = CH_VPN(a_ch);
-    dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_ch_vpn->net_srv->_inhertor;
+    dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_ch_vpn->net_srv->_internal;
 
 
     // So complicated to update usage client to be sure that nothing breaks it
@@ -1200,10 +993,9 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
     // If issue new receipt
     if ( l_issue_new_receipt ) {
         if ( a_usage->receipt){
-            dap_chain_datum_tx_receipt_t * l_receipt =dap_chain_net_srv_issue_receipt(a_usage->service, a_usage,a_usage->price,NULL,0 );
-            a_usage->receipt_next = l_receipt;
-            dap_stream_ch_pkt_write_unsafe( a_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST ,
-                                     l_receipt, l_receipt->size);
+            a_usage->receipt_next = dap_chain_net_srv_issue_receipt(a_usage->service, a_usage->price, NULL, 0);
+            dap_stream_ch_pkt_write_unsafe(a_usage->client->ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
+                                           a_usage->receipt_next, a_usage->receipt_next->size);
         }
     }
 
@@ -1229,7 +1021,7 @@ static void send_pong_pkt(dap_stream_ch_t* a_ch)
  */
 static void s_ch_packet_in_vpn_address_request(dap_stream_ch_t* a_ch, dap_chain_net_srv_usage_t * a_usage){
     dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch);
-    dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) a_usage->service->_inhertor;
+    dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) a_usage->service->_internal;
     dap_chain_net_srv_stream_session_t * l_srv_session= DAP_CHAIN_NET_SRV_STREAM_SESSION(l_ch_vpn->ch->stream->session);
 
     if (! s_raw_server)
@@ -1412,7 +1204,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 
 
     // TODO move address leasing to this structure
-    //dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_usage->service->_inhertor;
+    //dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_usage->service->_internal;
 
     ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) l_pkt->data;
     size_t l_vpn_pkt_size = l_pkt->hdr.size - sizeof (l_vpn_pkt->header);
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
index d8e943f77d94b9742c3182f5fcea002538a86492..3e1d171e03a9d99f07930b898586ad5c958adaaa 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c
@@ -2,6 +2,7 @@
 #include "dap_chain_node_cli.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_net_srv_vpn_cmd.h"
+#include "dap_chain_net_srv_stream_session.h"
 #include "dap_chain_net_vpn_client.h"
 
 
diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c
index d51ca88b1de111ef73990cf31e7c03f2bd100530..4f1b396672dc6ccbecf6563d361c2b1cc8d69829 100644
--- a/modules/service/vpn/dap_chain_net_vpn_client.c
+++ b/modules/service/vpn/dap_chain_net_vpn_client.c
@@ -49,19 +49,19 @@
 
 #include "dap_client.h"
 #include "dap_enc_base58.h"
-#include "dap_chain_node_client.h"
 
+#include "dap_stream_ch_pkt.h"
 #include "dap_stream_ch_proc.h"
-//#include "dap_stream_ch_chain_net_srv.h"
+#include "dap_stream_ch_chain_net_srv.h"
 
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
 #include "dap_chain_node_cli.h"
+#include "dap_chain_node_client.h"
+#include "dap_chain_net_srv_order.h"
 #include "dap_chain_net_srv_vpn.h"
 #include "dap_chain_net_vpn_client.h"
-
-#include "dap_stream_ch_pkt.h"
-#include "dap_stream_ch_chain_net_srv.h"
+#include "dap_chain_net_srv_stream_session.h"
 #include "dap_chain_net_vpn_client_tun.h"
 #include "dap_chain_net_srv_vpn_cmd.h"
 #include "dap_modules_dynamic_cdb.h"
@@ -134,6 +134,98 @@ dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void)
 
  }*/
 
+/**
+ * @brief s_callback_client_success
+ * @param a_srv
+ * @param a_usage_id
+ * @param a_srv_client
+ * @param a_success
+ * @param a_success_size
+ * @return
+ */
+static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t * a_srv_client,
+                    const void * a_success, size_t a_success_size)
+{
+    if(!a_srv || !a_srv_client || !a_srv_client->stream_worker || !a_success || a_success_size < sizeof(dap_stream_ch_chain_net_srv_pkt_success_t))
+        return -1;
+    dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*) a_success;
+
+    dap_stream_session_lock();
+    dap_stream_session_t *l_stream_session = dap_stream_session_id_unsafe(a_srv_client->session_id);
+    dap_chain_net_srv_stream_session_t * l_srv_session =
+            (dap_chain_net_srv_stream_session_t *) l_stream_session->_inheritor;
+
+    //dap_chain_net_srv_vpn_t* l_srv_vpn = (dap_chain_net_srv_vpn_t*) a_srv->_internal;
+    //a_srv_client->ch->
+    dap_chain_net_t * l_net = dap_chain_net_by_id(l_success->hdr.net_id);
+    dap_chain_net_srv_usage_t *l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, a_srv);
+    if(!l_usage){
+        dap_stream_session_unlock();
+        return -2;
+    }
+
+    dap_chain_net_srv_ch_vpn_t * l_srv_ch_vpn =
+            (dap_chain_net_srv_ch_vpn_t*) a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID] ?
+                    a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID]->internal : NULL;
+    if ( ! l_srv_ch_vpn ){
+        log_it(L_ERROR, "No VPN service stream channel, its closed?");
+        return -3;
+    }
+    l_srv_ch_vpn->usage_id = l_usage->id;
+    l_usage->is_active = true;
+    l_usage->is_free = true;
+
+    dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch();
+
+
+    if(l_ch) { // Is present in hash table such destination address
+        size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str);
+        ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
+
+        pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST;
+        //pkt_out->header.sock_id = l_stream->stream->events_socket->socket;
+        //pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
+        //pkt_out->header.op_connect.port = a_port;
+        //memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
+
+        dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
+                pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
+        dap_stream_ch_set_ready_to_write_unsafe(l_ch, true);
+        //DAP_DELETE(pkt_out);
+    }
+
+    // usage is present, we've accepted packets
+    dap_stream_ch_set_ready_to_read_unsafe( l_srv_ch_vpn->ch , true );
+    return 0;
+}
+
+/**
+ * @brief callback_client_sign_request
+ * @param a_srv
+ * @param a_usage_id
+ * @param a_srv_client
+ * @param a_receipt
+ * @param a_receipt_size
+ * @return
+ */
+static dap_chain_datum_tx_receipt_t * s_callback_client_sign_request(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t * a_srv_client,
+                    dap_chain_datum_tx_receipt_t *a_receipt, size_t a_receipt_size)
+{
+    char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
+    char *l_wallet_name = (char*) dap_chain_global_db_gr_get(dap_strdup("wallet_name"), NULL, l_gdb_group);
+
+    dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, dap_chain_wallet_get_path(g_config));
+    dap_chain_datum_tx_receipt_t *l_ret = NULL;
+    if(l_wallet) {
+        dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+        l_ret = dap_chain_datum_tx_receipt_sign_add(a_receipt, l_enc_key);
+        dap_chain_wallet_close(l_wallet);
+    }
+    DAP_DELETE(l_gdb_group);
+    DAP_DELETE(l_wallet_name);
+    return l_ret;
+}
+
 /**
  * Get tx_cond_hash
  *
@@ -229,21 +321,15 @@ static dap_chain_hash_fast_t* dap_chain_net_vpn_client_tx_cond_hash(dap_chain_ne
     if(!l_tx_cond_hash) {
         dap_chain_wallet_t *l_wallet_from = a_wallet;
         log_it(L_DEBUG, "Create tx from wallet %s", l_wallet_from->name);
-        dap_enc_key_t *l_key_from = l_enc_key; //dap_chain_wallet_get_key(l_wallet_from, 0);
-        dap_enc_key_t *l_client_key = l_enc_key;
-        //dap_chain_cell_id_t *xccell = dap_chain_net_get_cur_cell(l_tpl->net);
-        //uint64_t uint64 =dap_chain_net_get_cur_cell(l_tpl->net)->uint64;
-
-        size_t l_pub_key_data_size = 0;
-        uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_enc_key, &l_pub_key_data_size);
+        dap_pkey_t *l_client_key = dap_pkey_from_enc_key(l_enc_key);
         // where to take coins for service
         dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, a_net->pub.id);
         dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = SERV_UNIT_SEC };
         dap_chain_net_srv_uid_t l_srv_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
         uint256_t l_value = dap_chain_uint256_from(a_value_datoshi);
-        l_tx_cond_hash = dap_chain_proc_tx_create_cond(a_net, l_key_from, l_client_key, l_addr_from,
-                a_token_ticker, l_value, uint256_0, l_price_unit, l_srv_uid, uint256_0, l_pub_key_data, l_pub_key_data_size);
-        //char *l_addr_from_str = dap_chain_addr_to_str(l_addr_from);
+        uint256_t l_zero = {};
+        l_tx_cond_hash = dap_chain_mempool_tx_create_cond(a_net, l_enc_key, l_client_key, a_token_ticker,
+                                                          l_value, l_zero, l_price_unit, l_srv_uid, l_zero, NULL, 0);
         DAP_DELETE(l_addr_from);
         if(!l_tx_cond_hash) {
             log_it(L_ERROR, "Can't create condition for user");
@@ -252,8 +338,7 @@ static dap_chain_hash_fast_t* dap_chain_net_vpn_client_tx_cond_hash(dap_chain_ne
             dap_chain_global_db_gr_set( "client_tx_cond_hash", l_tx_cond_hash, sizeof(dap_chain_hash_fast_t),
                     l_gdb_group);
         }
-        //DAP_DELETE(l_addr_from_str);
-        DAP_DELETE(l_pub_key_data);
+        DAP_DELETE(l_client_key);
     }
     dap_enc_key_delete(l_enc_key);
     DAP_DELETE(l_gdb_group);
@@ -561,7 +646,7 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
                 DAP_DELETE(l_tx_cond);
             }
             // set srv id
-            dap_stream_ch_chain_net_srv_set_srv_uid(l_ch, l_request.hdr.srv_uid);
+            //dap_stream_ch_chain_net_srv_set_srv_uid(l_ch, l_request.hdr.srv_uid);
             //dap_chain_hash_fast_t l_request
             //.hdr.tx_cond = a_txCond.value();
 //    	    strncpy(l_request->hdr.token, a_token.toLatin1().constData(),sizeof (l_request->hdr.token)-1);
@@ -688,8 +773,19 @@ int dap_chain_net_vpn_client_init(dap_config_t * g_config)
             "vpn_client check result -net <net name> [-H hex|base58(default)]\n"
             );
 
-
-    return dap_chain_net_srv_client_vpn_init(g_config);
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
+    /*if(!dap_chain_net_srv_remote_init(l_uid, s_callback_requested,
+            s_callback_response_success, s_callback_response_error,
+            s_callback_receipt_next_success,
+            s_callback_client_success,
+            s_callback_client_sign_request,
+            l_srv_vpn)) {
+        l_srv = dap_chain_net_srv_get(l_uid);
+        //l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*)l_srv->_internal : NULL;
+        //l_srv_vpn->parent = l_srv;
+        l_srv->_internal = l_srv_vpn;
+    }*/
+    return 0;
 }
 
 void dap_chain_net_vpn_client_deinit()
diff --git a/modules/service/vpn/include/dap_chain_net_vpn_client.h b/modules/service/vpn/include/dap_chain_net_vpn_client.h
index 5faf509bb8146bdcd271230957b67a9182755cf3..ac5ed4d4fcd27adb6a6c32e2e39aa7c271cb22a4 100644
--- a/modules/service/vpn/include/dap_chain_net_vpn_client.h
+++ b/modules/service/vpn/include/dap_chain_net_vpn_client.h
@@ -26,7 +26,9 @@
 
 #include "dap_stream_ch.h"
 #include "dap_stream_ch_pkt.h"
+#include "dap_stream_session.h"
 #include "dap_chain_net.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_vpn.h"
 
 typedef enum dap_chain_net_vpn_client_status_enum{
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 989977fd74a9f7018ece25b5a2842ee843714e73..cc9dc6e6b7af000adb2def96290f88ee0d64080a 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -27,7 +27,7 @@
 #include "dap_string.h"
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
-#include "dap_chain_net_srv_common.h"
+#include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_xchange.h"
 
 #define LOG_TAG "dap_chain_net_srv_xchange"
@@ -70,10 +70,11 @@ int dap_chain_net_srv_xchange_init()
          "\tDisable eXchange service\n"
     );
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_XCHANGE_ID };
-    dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, s_callback_requested, s_callback_response_success,
-                                                       s_callback_response_error, s_callback_receipt_next_success);
+    dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, "srv_xchange", s_callback_requested,
+                                                       s_callback_response_success, s_callback_response_error,
+                                                       s_callback_receipt_next_success, NULL);
     s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t);
-    l_srv->_inhertor = s_srv_xchange;
+    l_srv->_internal = s_srv_xchange;
     s_srv_xchange->parent = l_srv;
     s_srv_xchange->enabled = false;
     size_t l_prices_count = 0;
diff --git a/modules/type/blocks/dap_chain_cs_blocks_session.c b/modules/type/blocks/dap_chain_cs_blocks_session.c
index 51d64f7deb77e47209fa90e75a24689d71e38909..67284346abd04f3f98599a1a5d75875b732c1c09 100644
--- a/modules/type/blocks/dap_chain_cs_blocks_session.c
+++ b/modules/type/blocks/dap_chain_cs_blocks_session.c
@@ -164,9 +164,9 @@ static bool s_session_block_submit(dap_chain_cs_blocks_session_items_t *a_sessio
 	// dap_chain_net_t * l_net = dap_chain_net_by_id(l_chain->net_id);
     dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain);
 
-    if (!l_blocks->block_new)
+    if (!l_blocks->block_new) {
     	return false; // for timer
-
+    }
 	size_t l_submit_size = sizeof(dap_chain_cs_blocks_session_message_submit_t)+l_blocks->block_new_size;
 	dap_chain_cs_blocks_session_message_submit_t * l_submit =
 							DAP_NEW_SIZE(dap_chain_cs_blocks_session_message_submit_t, l_submit_size);
@@ -312,8 +312,9 @@ static void s_session_packet_in(void * a_arg, dap_chain_node_addr_t * a_sender_n
     dap_chain_hash_fast_t l_data_hash;
     dap_hash_fast(a_data, a_data_size, &l_data_hash);
 
-    if (l_message->hdr.chain_id.uint64 != l_session->chain->id.uint64 )
+    if (l_message->hdr.chain_id.uint64 != l_session->chain->id.uint64 ) {
     	goto handler_finish;
+    }
 
 	if (memcmp(a_data_hash, &l_data_hash, sizeof(dap_chain_hash_fast_t)) != 0)
 		goto handler_finish;
diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c
index 37c0ee8ae87367bef043accfcda5cf049994d6c6..a839cad8010d8da0c46703f123a3913bfe51e3af 100644
--- a/modules/type/dag/dap_chain_cs_dag.c
+++ b/modules/type/dag/dap_chain_cs_dag.c
@@ -344,7 +344,6 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger
         break;
         case DAP_CHAIN_DATUM_TOKEN_EMISSION: {
             return dap_chain_ledger_token_emission_load(a_ledger, l_datum->data, l_datum->header.data_size);
-            //return dap_chain_ledger_token_emission_load(a_ledger, l_datum, l_datum->header.data_size+sizeof(l_datum->header));
         }
         break;
         case DAP_CHAIN_DATUM_TX: {
@@ -369,19 +368,15 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger
             }
             if (l_err != EDEADLK)
                 pthread_rwlock_unlock(l_events_rwlock);
+            return l_ret == 1 ? 0 : l_ret;
         }
         break;
-        case DAP_CHAIN_DATUM_CA: {
+        case DAP_CHAIN_DATUM_CA:
             dap_cert_chain_file_save(l_datum, a_dag->chain->net_name);
             return DAP_CHAIN_DATUM_CA;
-        }
-        break;
-        case DAP_CHAIN_DATUM_SIGNER: {
-            return 0;
-    	}
-        case DAP_CHAIN_DATUM_CUSTOM: {
+        case DAP_CHAIN_DATUM_SIGNER:
+        case DAP_CHAIN_DATUM_CUSTOM:
             return 0;
-        }
         default:
             return -1;
     }
@@ -1790,9 +1785,6 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply)
                 }else if (l_from_events_str && (strcmp(l_from_events_str,"events") == 0) ){
                     dap_string_t * l_str_tmp = dap_string_new(NULL);
                     pthread_rwlock_rdlock(&PVT(l_dag)->events_rwlock);
-                    size_t l_events_count = HASH_COUNT(PVT(l_dag)->events);
-                    dap_string_append_printf(l_str_tmp,"%s.%s: Have %zu events :\n",
-                                             l_net->pub.name,l_chain->name,l_events_count);
                     dap_chain_cs_dag_event_item_t * l_event_item = NULL,*l_event_item_tmp = NULL;
                     HASH_ITER(hh,PVT(l_dag)->events,l_event_item, l_event_item_tmp ) {
                         char buf[50];
@@ -1802,7 +1794,10 @@ static int s_cli_dag(int argc, char ** argv, char **a_str_reply)
                                                  l_event_item_hash_str, dap_ctime_r( &l_ts_create,buf ) );
                         DAP_DELETE(l_event_item_hash_str);
                     }
+                    size_t l_events_count = HASH_COUNT(PVT(l_dag)->events);
                     pthread_rwlock_unlock(&PVT(l_dag)->events_rwlock);
+                    dap_string_append_printf(l_str_tmp,"%s.%s have total %zu events :\n",
+                                             l_net->pub.name, l_chain->name, l_events_count);
                     dap_chain_node_cli_set_reply_text(a_str_reply, l_str_tmp->str);
                     dap_string_free(l_str_tmp,false);