diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c
index 236806288defa1f0c6aa353b3b6ef391f220c384..0c6111846fcfd374326fb084cd1c113e25f941a7 100644
--- a/modules/chain/dap_chain_ch.c
+++ b/modules/chain/dap_chain_ch.c
@@ -276,6 +276,8 @@ struct legacy_sync_context *s_legacy_sync_context_create(dap_stream_ch_t *a_ch)
             .state          = DAP_CHAIN_CH_STATE_IDLE,
             .last_activity  = dap_time_now()
         };
+
+    
     dap_stream_ch_uuid_t *l_uuid = DAP_DUP(&a_ch->uuid);
     if (!l_uuid) {
         log_it(L_CRITICAL, "%s", c_error_memory_alloc);
@@ -1065,8 +1067,6 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
         }
         l_context->is_type_of_gdb = true;
         l_context->db_list = l_db_list;
-        l_context->remote_addr = *(dap_stream_node_addr_t *)l_chain_pkt->data;
-        l_context->request_hdr = l_chain_pkt->hdr;
         l_ch_chain->legacy_sync_context = l_context;
         l_context->state = DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB;
         debug_if(s_debug_legacy, L_DEBUG, "Sync out gdb proc, requested %" DAP_UINT64_FORMAT_U " records from address " NODE_ADDR_FP_STR " (unverified)",
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 aad8bcf09d66040efccf7d5f17d80831dbe4cc40..200158c7a4f00a9c61ba07bc61e5537c465b8589 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
@@ -75,8 +75,15 @@ typedef struct client_statistic_value{
     } grace;
 } client_statistic_value_t;
 
+typedef struct receipt_sign_waiting_args {
+    dap_stream_worker_t *worker;
+    dap_stream_ch_uuid_t uuid;
+    dap_chain_net_srv_usage_t *usage;
+} receipt_sign_waiting_args_t;
+
 static void s_stream_ch_new(dap_stream_ch_t* ch , void* arg);
 static void s_stream_ch_delete(dap_stream_ch_t* ch , void* arg);
+static void s_start_receipt_timeout_timer(dap_chain_net_srv_usage_t *a_usage);
 static bool s_stream_ch_packet_in(dap_stream_ch_t* ch , void* arg);
 static bool s_stream_ch_packet_out(dap_stream_ch_t* ch , void* arg);
 
@@ -236,6 +243,35 @@ static bool s_unban_client(dap_chain_net_srv_banlist_item_t *a_item)
     return false;
 }
 
+static bool s_receipt_timeout_handler(dap_chain_net_srv_usage_t *a_usage)
+{
+    log_it(L_WARNING, "Waiting receipt signing from client timeout!");
+    if (a_usage->receipt_sign_req_cnt < RECEIPT_SIGN_MAX_ATTEMPT - 1){
+        // New attempt
+        a_usage->receipt_sign_req_cnt++;
+        log_it(L_WARNING, "Try to send receipt again. Attempt %d", a_usage->receipt_sign_req_cnt+1);
+        if (a_usage->is_waiting_first_receipt_sign ){
+            dap_stream_ch_pkt_write_unsafe(a_usage->client->ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
+                                       a_usage->receipt, a_usage->receipt->size);
+            return true;
+        } else if (a_usage->is_waiting_next_receipt_sign ){
+            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);
+            return true;
+        }
+    }
+    log_it(L_WARNING, "Receipt signing by client max attempt is reached!");
+    a_usage->receipt_sign_req_cnt = 0;
+    a_usage->is_waiting_first_receipt_sign = false;
+    a_usage->is_waiting_next_receipt_sign = false;
+    return false;
+}
+
+static void s_start_receipt_timeout_timer(dap_chain_net_srv_usage_t *a_usage)
+{
+    a_usage->receipts_timeout_timer = dap_timerfd_start_on_worker(dap_worker_get_current(), 10000,
+                                                             (dap_timerfd_callback_t)s_receipt_timeout_handler, a_usage);
+}
 /**
  * @brief create string with usage service statistic
  * @return string with staticstic
@@ -324,6 +360,10 @@ static bool s_service_start(dap_stream_ch_t *a_ch , dap_stream_ch_chain_net_srv_
     l_err.net_id.uint64 = a_request->hdr.net_id.uint64;
     l_err.srv_uid.uint64 = a_request->hdr.srv_uid.uint64;
 
+    char *l_user_key = dap_chain_hash_fast_to_str_new(&a_request->hdr.client_pkey_hash);
+    log_it(L_DEBUG, "Got service request from user %s", l_user_key);
+    DAP_DELETE(l_user_key);
+
     if (dap_hash_fast_is_blank(&a_request->hdr.order_hash)){
         log_it( L_ERROR, "No order hash in request.");
         l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND;
@@ -334,6 +374,16 @@ static bool s_service_start(dap_stream_ch_t *a_ch , dap_stream_ch_chain_net_srv_
         return false;
     }
 
+    if (dap_hash_fast_is_blank(&a_request->hdr.tx_cond)){
+        log_it( L_ERROR, "No transaction hash in request.");
+        l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND;
+        if(a_ch)
+            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 && l_srv->callbacks.response_error)
+            l_srv->callbacks.response_error(l_srv, 0, NULL, &l_err, sizeof(l_err));
+        return false;
+    }
+
     char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = {};
     dap_chain_hash_fast_to_str(&a_request->hdr.order_hash, l_order_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
     log_it(L_MSG, "Got order with hash %s.", l_order_hash_str);
@@ -400,6 +450,7 @@ static bool s_service_start(dap_stream_ch_t *a_ch , dap_stream_ch_chain_net_srv_
     l_usage->net = l_net;
     l_usage->service = l_srv;
     l_usage->client_pkey_hash = a_request->hdr.client_pkey_hash;
+    l_usage->receipt_timeout_timer_start_callback = s_start_receipt_timeout_timer;
 
     dap_chain_net_srv_price_t * l_price = NULL;
     bool l_specific_order_free = false;
@@ -541,9 +592,11 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
             HASH_FIND(hh, a_grace->usage->service->ban_list, &a_grace->usage->client_pkey_hash, sizeof(dap_chain_hash_fast_t), l_item);
             pthread_mutex_unlock(&a_grace->usage->service->banlist_mutex);
             if (l_item) {   // client banned
-                log_it(L_INFO, "Client pkey is banned!");
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&a_grace->usage->client_pkey_hash);
+                log_it(L_DEBUG, "Client %s is banned!", l_user_key);
+                DAP_DELETE(l_user_key);
                 l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH ;
-                s_grace_error(a_grace, l_err);;
+                s_grace_error(a_grace, l_err);
                 return false;
             }
         }
@@ -552,7 +605,8 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
 
         if (a_grace->usage->receipt){ // If it is repeated grace
             char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&a_grace->usage->static_order_hash);
-            log_it(L_MSG, "Using price from order %s.", l_order_hash_str);
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&a_grace->usage->client_pkey_hash);
+            log_it(L_MSG, "Using price from order %s for user %s.", l_order_hash_str, l_user_key);
             DAP_DELETE(l_order_hash_str);
             l_price = a_grace->usage->price;
 
@@ -566,6 +620,7 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
             if (!l_item) {
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
                 s_grace_error(a_grace, l_err);
+                DAP_DELETE(l_user_key);
                 return false;
             }
             l_item->grace = a_grace;
@@ -576,7 +631,8 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
             pthread_mutex_unlock(&a_grace->usage->service->grace_mutex);
             a_grace->timer = dap_timerfd_start_on_worker(a_grace->stream_worker->worker, a_grace->usage->service->grace_period * 1000,
                                                                  (dap_timerfd_callback_t)s_grace_period_finish, l_item);
-            log_it(L_INFO, "Start grace timer %s.", a_grace->timer ? "successfuly." : "failed." );
+            log_it(L_INFO, "Start grace timer %s for user %s.", a_grace->timer ? "successfuly." : "failed.", l_user_key);
+            DAP_DELETE(l_user_key);
         } else { // Else if first grace at service start
             dap_chain_net_srv_grace_usage_t *l_item = DAP_NEW_Z(dap_chain_net_srv_grace_usage_t);
             if (!l_item) {
@@ -607,8 +663,9 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
 
                 char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
                 dap_hash_fast_to_str(&a_grace->usage->tx_cond_hash, l_hash_str, sizeof(l_hash_str));
-                    log_it(L_NOTICE, "Transaction %s can't be found. Start the grace period for %d seconds", l_hash_str,
-                            a_grace->usage->service->grace_period);
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&a_grace->usage->client_pkey_hash);
+                log_it(L_NOTICE, "Transaction %s can't be found. Start the grace period for %d seconds for user %s", l_hash_str,
+                            a_grace->usage->service->grace_period, l_user_key);
 
                 if (a_grace->usage->service->callbacks.response_success)
                     a_grace->usage->service->callbacks.response_success(a_grace->usage->service, a_grace->usage->id,
@@ -619,7 +676,8 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
                 pthread_mutex_unlock(&a_grace->usage->service->grace_mutex);
                 a_grace->timer = dap_timerfd_start_on_worker(a_grace->stream_worker->worker, a_grace->usage->service->grace_period * 1000,
                                                                      (dap_timerfd_callback_t)s_grace_period_finish, l_item);
-                log_it(L_INFO, "Start grace timer %s.", a_grace->timer ? "successfuly." : "failed." );
+                log_it(L_INFO, "Start grace timer %s for user %s.", a_grace->timer ? "successfuly." : "failed.", l_user_key );
+                DAP_DELETE(l_user_key);
             }
         }
 
@@ -741,9 +799,11 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
                         l_srv_session->limits_bytes = l_remain_service->limits_bytes;
                         break;
                 }
-
-                log_it(L_INFO, "User has %ld %s remain service. Start service without paying.", l_remain_service->limits_ts ? l_remain_service->limits_ts : l_remain_service->limits_bytes, dap_chain_srv_unit_enum_to_str(l_tx_out_cond->subtype.srv_pay.unit.enm));
-
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&a_grace->usage->client_pkey_hash);
+                log_it(L_INFO, "User %s has %ld %s remain service. Start service without paying.", l_user_key, 
+                                l_remain_service->limits_ts ? l_remain_service->limits_ts : l_remain_service->limits_bytes, 
+                                dap_chain_srv_unit_enum_to_str(l_tx_out_cond->subtype.srv_pay.unit.enm));
+                DAP_DELETE(l_user_key);
                 size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t );
                 dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
                                                                                       l_success_size);
@@ -763,7 +823,6 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
                     // create and fill first receipt
                     a_grace->usage->receipt = dap_chain_datum_tx_receipt_create(
                                 a_grace->usage->service->uid, l_price->units_uid, l_price->units, l_price->value_datoshi, NULL, 0);
-
                     if (a_grace->usage->service->callbacks.response_success)
                         a_grace->usage->service->callbacks.response_success(a_grace->usage->service, a_grace->usage->id,
                                                                             a_grace->usage->client, a_grace->usage->receipt,
@@ -777,13 +836,19 @@ static bool s_grace_period_start(dap_chain_net_srv_grace_t *a_grace)
             }
         }
 
-        if (a_grace->usage->receipt_next){
+        if (a_grace->usage->receipt_next && !a_grace->usage->is_waiting_first_receipt_sign){
             DAP_DEL_Z(a_grace->usage->receipt_next);
             a_grace->usage->receipt_next = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0);
+            a_grace->usage->is_waiting_next_receipt_sign = true;
+            //start timeout timer
+            a_grace->usage->receipt_timeout_timer_start_callback(a_grace->usage);
         }else{
             a_grace->usage->receipt = dap_chain_net_srv_issue_receipt(a_grace->usage->service, a_grace->usage->price, NULL, 0);
             dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
                                        a_grace->usage->receipt, a_grace->usage->receipt->size);
+            a_grace->usage->is_waiting_first_receipt_sign = true;
+            //start timeout timer
+            a_grace->usage->receipt_timeout_timer_start_callback(a_grace->usage);
         }
         DAP_DELETE(a_grace->request);
         DAP_DELETE(a_grace);
@@ -880,8 +945,8 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
         if (error) { \
             l_err.code = error ; \
             s_grace_error(l_grace, l_err); \
-        } \
-        DAP_DELETE(l_grace); \
+        } else\
+            DAP_DELETE(l_grace); \
         DAP_DELETE(a_grace_item); \
         return false; \
     } \
@@ -1022,8 +1087,11 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
                         l_srv_session->limits_bytes = l_remain_service->limits_bytes;
                         break;
                 }
-                log_it(L_INFO, "User has %ld %s remain service. Start service without paying.", l_remain_service->limits_ts ? l_remain_service->limits_ts : l_remain_service->limits_bytes, dap_chain_srv_unit_enum_to_str(l_tx_out_cond->subtype.srv_pay.unit.enm));
-
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&l_grace->usage->client_pkey_hash);
+                log_it(L_INFO, "User %s has %ld %s remain service. Start service without paying.", l_user_key,
+                            l_remain_service->limits_ts ? l_remain_service->limits_ts : l_remain_service->limits_bytes, 
+                            dap_chain_srv_unit_enum_to_str(l_tx_out_cond->subtype.srv_pay.unit.enm));
+                DAP_DELETE(l_user_key);
                 size_t l_success_size = sizeof (dap_stream_ch_chain_net_srv_pkt_success_hdr_t );
                 dap_stream_ch_chain_net_srv_pkt_success_t *l_success = DAP_NEW_Z_SIZE(dap_stream_ch_chain_net_srv_pkt_success_t,
                                                                                       l_success_size);
@@ -1043,7 +1111,7 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
                     // create and fill limits and first receipt
                     l_grace->usage->receipt = dap_chain_datum_tx_receipt_create(
                                 l_grace->usage->service->uid, l_price->units_uid, l_price->units, l_price->value_datoshi, NULL, 0);
-
+                    // l_grace->usage->is_waiting_first_receipt_sign = true;
                     if (l_grace->usage->service->callbacks.response_success)
                         l_grace->usage->service->callbacks.response_success(l_grace->usage->service, l_grace->usage->id,
                                                                             l_grace->usage->client, l_grace->usage->receipt,
@@ -1065,6 +1133,9 @@ static bool s_grace_period_finish(dap_chain_net_srv_grace_usage_t *a_grace_item)
         } else {
             log_it(L_INFO, "Send first receipt to sign");
             l_grace->usage->receipt = dap_chain_net_srv_issue_receipt(l_grace->usage->service, l_grace->usage->price, NULL, 0);
+            l_grace->usage->is_waiting_first_receipt_sign = true;
+            // start timeout timer
+            l_grace->usage->receipt_timeout_timer_start_callback(l_grace->usage);
             if (l_grace->usage->receipt )
                 dap_stream_ch_pkt_write_unsafe(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
                                        l_grace->usage->receipt, l_grace->usage->receipt->size);
@@ -1255,6 +1326,16 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
     case DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE: { // Check receipt sign and make tx if success
         dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active;
 
+        if (!l_usage->is_waiting_first_receipt_sign && !l_usage->is_waiting_next_receipt_sign){
+            break;
+        }
+
+        if (l_usage->receipts_timeout_timer){
+            log_it(L_INFO, "Delete receipt timeout timer.");
+            dap_timerfd_delete_unsafe(l_usage->receipts_timeout_timer);
+            l_usage->receipts_timeout_timer = NULL;
+        } 
+
         if (dap_chain_net_get_state(l_usage->net) == NET_STATE_OFFLINE) {
             log_it(L_ERROR, "Can't pay service because net %s is offline.", l_usage->net->pub.name);
             l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_IS_OFFLINE;
@@ -1264,7 +1345,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         if (l_ch_pkt->hdr.data_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.data_size,
                    sizeof(dap_chain_receipt_info_t));
-            if ( l_usage->receipt_next ){ // If we have receipt next
+            if ( l_usage->receipt_next && !l_usage->is_waiting_first_receipt_sign && l_usage->is_waiting_next_receipt_sign){ // If we have receipt next
                 DAP_DEL_Z(l_usage->receipt_next);
             }else if (l_usage->receipt ){ // If we sign first receipt
                 DAP_DEL_Z(l_usage->receipt);
@@ -1274,20 +1355,16 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         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.data_size;
 
-        if (l_usage->is_grace && l_usage->receipt && !l_usage->receipt_next)
-            l_usage->is_grace = false;
-
         bool l_is_found = false;
-        if ( l_usage->receipt_next ){ // If we have receipt next
+        if ( l_usage->receipt_next && !l_usage->is_waiting_first_receipt_sign && l_usage->is_waiting_next_receipt_sign){ // If we have receipt next
             if ( memcmp(&l_usage->receipt_next->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){
                 l_is_found = true;
             }
-        }else if (l_usage->receipt ){ // If we sign first receipt
+        }else if (l_usage->receipt){ // If we sign first receipt
             if ( memcmp(&l_usage->receipt->receipt_info, &l_receipt->receipt_info,sizeof (l_receipt->receipt_info) )==0 ){
                 l_is_found = true;
             }
         }
-
         if ( !l_is_found || ! l_usage ){
             log_it(L_WARNING, "Can't find receipt in usages thats equal to response receipt");
             l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND;
@@ -1301,25 +1378,22 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         l_err.srv_uid.uint64 = l_usage->service->uid.uint64;
 
         dap_chain_tx_out_cond_t *l_tx_out_cond = NULL;
-        if (!l_usage->is_grace) {
-            if (! l_usage->tx_cond ){
-                log_it(L_WARNING, "No tx out in usage");
-                l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ;
-                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_usage->service->callbacks.response_error)
-                        l_usage->service->callbacks.response_error( l_usage->service, l_usage->id, l_usage->client,
-                                                                  &l_err, sizeof (l_err) );
-                break;
-            }
-            l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_usage->tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL );
-            if ( ! l_tx_out_cond ){ // No conditioned output
-                l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
-                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_usage->service->callbacks.response_error)
-                        l_usage->service->callbacks.response_error( l_usage->service, l_usage->id, l_usage->client,&l_err,sizeof (l_err) );
-                break;
-            }
-
+        if (! l_usage->tx_cond ){
+            log_it(L_WARNING, "No tx out in usage");
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND ;
+            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_usage->service->callbacks.response_error)
+                    l_usage->service->callbacks.response_error( l_usage->service, l_usage->id, l_usage->client,
+                                                                &l_err, sizeof (l_err) );
+            break;
+        }
+        l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_usage->tx_cond, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, NULL );
+        if ( ! l_tx_out_cond ){ // No condition output
+            l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT ;
+            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_usage->service->callbacks.response_error)
+                    l_usage->service->callbacks.response_error( l_usage->service, l_usage->id, l_usage->client,&l_err,sizeof (l_err) );
+            break;
         }
         // get a second signature - from the client (first sign in server, second sign in client)
         dap_sign_t * l_receipt_sign = dap_chain_datum_tx_receipt_sign_get( l_receipt, l_receipt_size, 1);
@@ -1343,7 +1417,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
 
         // Update actual receipt
         bool l_is_first_sign = false;
-        if (!l_usage->receipt_next && l_usage->receipt) {
+        if (l_usage->receipt && (!l_usage->receipt_next || l_usage->is_waiting_first_receipt_sign)) {
             DAP_DELETE(l_usage->receipt);
             l_usage->receipt = DAP_DUP_SIZE(l_receipt, l_receipt_size);
             if (!l_usage->receipt) {
@@ -1351,7 +1425,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
                 break;
             }
             l_is_first_sign     = true;
-            l_usage->is_active  = true;
+            // l_usage->is_active  = true;
         } else if (l_usage->receipt_next) {
             DAP_DELETE(l_usage->receipt_next);
             l_usage->receipt_next = DAP_DUP_SIZE(l_receipt, l_receipt_size);
@@ -1359,7 +1433,16 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
                 log_it(L_CRITICAL, "%s", c_error_memory_alloc);
                 break;
             }
-            l_usage->is_active = true;
+            // l_usage->is_active = true;
+        }
+
+        if (!l_usage->is_waiting_first_receipt_sign && l_usage->is_waiting_next_receipt_sign){
+            l_usage->is_waiting_next_receipt_sign = false;
+        }
+
+        if (l_usage->is_grace && l_usage->is_waiting_first_receipt_sign){
+            l_usage->is_waiting_first_receipt_sign = false;
+            l_usage->is_grace = false;
         }
 
         // Store receipt if any problems with transactions
@@ -1370,8 +1453,10 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         if (!l_usage->is_grace) {
             // Form input transaction
             char *l_hash_str = dap_hash_fast_to_str_new(&l_usage->tx_cond_hash);
-            log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt", l_hash_str);
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage->client_pkey_hash);
+            log_it(L_NOTICE, "Trying create input tx cond from tx %s with active receipt for user %s", l_hash_str, l_user_key);
             DAP_DEL_Z(l_hash_str);
+            DAP_DEL_Z(l_user_key);
             int ret_status = 0;
             char *l_tx_in_hash_str = dap_chain_mempool_tx_create_cond_input(l_usage->net, &l_usage->tx_cond_hash, l_usage->price->wallet_addr,
                                                                             l_usage->price->receipt_sign_cert->enc_key,
@@ -1481,12 +1566,16 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
         if (l_usage->is_grace) {
             char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' };
             dap_hash_fast_to_str(&l_usage->tx_cond_hash, l_hash_str, sizeof(l_hash_str));
-                log_it(L_NOTICE, "Receipt is OK, but tx transaction %s %s. Start the grace period for %d seconds", l_hash_str,
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage->client_pkey_hash);
+            log_it(L_NOTICE, "Receipt is OK, but tx transaction %s %s. Start the grace period for %d seconds for user %s", l_hash_str,
                        l_usage->is_waiting_new_tx_cond ? "have no enough funds. New tx cond requested": "can't be found",
-                       l_srv->grace_period);
+                       l_srv->grace_period, l_user_key);
+            DAP_DELETE(l_user_key);
         } else {
             dap_hash_fast_to_str(&l_usage->tx_cond_hash, (char*)l_success->custom_data, DAP_CHAIN_HASH_FAST_STR_SIZE);
-            log_it(L_NOTICE, "Receipt with client sign is accepted, start service providing");
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage->client_pkey_hash);
+            log_it(L_NOTICE, "Receipt with client %s sign is accepted, start service providing", l_user_key);
+            DAP_DELETE(l_user_key);
         }
 
         dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS,
@@ -1606,6 +1695,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg)
             }
         }else{
             if (l_curr_grace_item){
+                log_it(L_INFO, "Can't find tx in ledger. Waiting...");
                 l_curr_grace_item->grace->usage->tx_cond_hash = l_responce->hdr.tx_cond;
                 l_curr_grace_item->grace->request->hdr.tx_cond = l_responce->hdr.tx_cond;
                 pthread_mutex_lock(&l_srv->grace_mutex);
@@ -1630,7 +1720,6 @@ static bool 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_SUCCESS, l_success, l_success_size);
         DAP_DELETE(l_success);
     } break;
-
     default:
         log_it( L_WARNING, "Unknown packet type 0x%02X", l_ch_pkt->hdr.type);
         return false;
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 3bca41c7ed362b4ebda3893e9fa3c31f0748cfff..057a08d520c45974dae3d365d4fde2cd45ba3a92 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
@@ -142,7 +142,6 @@ typedef struct dap_stream_ch_chain_net_srv_pkt_test {
     uint8_t                 data[];
 } DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_test_t;
 
-
 size_t dap_stream_ch_chain_net_srv_pkt_data_write(dap_stream_ch_t *a_ch,
                                                   dap_chain_net_srv_uid_t a_srv_uid, uint32_t a_usage_id  ,
                                                   const void * a_data, size_t a_data_size);
diff --git a/modules/common/dap_chain_datum_tx_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c
index c21099f921225284537647f54974dc7b602e3f35..b4e4c836c4632987d4243461d94b071ebd510673 100644
--- a/modules/common/dap_chain_datum_tx_receipt.c
+++ b/modules/common/dap_chain_datum_tx_receipt.c
@@ -59,6 +59,7 @@ dap_chain_datum_tx_receipt_t * dap_chain_datum_tx_receipt_create( dap_chain_net_
         l_ret->exts_size = a_ext_size;
         memcpy(l_ret->exts_n_signs, a_ext, a_ext_size);
     }
+
     return  l_ret;
 }
 
@@ -68,6 +69,7 @@ dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datu
         log_it(L_ERROR, "NULL receipt, can't add sign");
         return NULL;
     }
+
     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) {
@@ -84,6 +86,7 @@ dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datu
     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;
 }
 
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index d559a8eceb40df4dd6dd41fec09c8d2e581b2192..b2980610c5cd2286628bfebcd70f9232bc3a8b33 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -938,6 +938,9 @@ char *dap_chain_mempool_tx_create_cond(dap_chain_net_t *a_net,
     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);
+    if (l_net_fee_used) {
+        SUM_256_256(l_value_need, l_net_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);
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 1aa8a000bb6e363fb007b9ee9ce98dd911178592..48250421cce50d999ac3f2b5a71bfee49be77d44 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -3220,7 +3220,7 @@ dap_hash_fast_t *dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_
             break;      // Not found in ledger
         }
         int l_out_num = 0;
-        if (dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num]) || !dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num))
+        if (!dap_chain_datum_tx_out_cond_get(l_item->tx, a_cond_type, &l_out_num) || dap_hash_fast_is_blank(&l_item->cache_data.tx_hash_spent_fast[l_out_num]))
             break;      // Unused conditional output found, that's what we need
         else {
             l_tx_hash = &l_item->cache_data.tx_hash_spent_fast[l_out_num];
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index af936ef8a2993c9238854fc1b64779ac7a82c321..de8618dbd6f60b4058fd820b101b887d4dcb7c83 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -97,9 +97,9 @@ int dap_chain_net_srv_init()
         "net_srv -net <net_name> order find [-direction {sell|buy}] [-srv_uid <service_UID>] [-price_unit <price_unit>]"
         " [-price_token <token_ticker>] [-price_min <price_minimum>] [-price_max <price_maximum>]\n"
         "\tOrders list, all or by UID and/or class\n"
-        "net_srv -net <net_name> order delete -hash <ip_addr>\n"
+        "net_srv -net <net_name> order delete -hash <order_hash>\n"
         "\tOrder delete\n"
-        "net_srv -net <net_name> order dump -hash <ip_addr>\n"
+        "net_srv -net <net_name> order dump -hash <order_hash>\n"
         "\tOrder dump info\n"
         "net_srv -net <net_name> order create -direction {sell|buy} -srv_uid <service_UID> -price <price>\n"
         " -price_unit <price_unit> -price_token <token_ticker> -units <units> [-node_addr <node_address>] [-tx_cond <TX_cond_hash>]\n"
@@ -314,6 +314,17 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                             l_order->continent = l_continent_num;*/
                         char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order, false);
                         if (l_new_order_hash_str) {
+                            const char *l_cert_str = NULL;
+                            dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-cert", &l_cert_str);
+                            if (!l_cert_str) {
+                                dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee order creation requires parameter -cert");
+                                return -7;
+                            }
+                            dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str);
+                            if (!l_cert) {
+                                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str);
+                                return -8;
+                            }
                             // delete prev order
                             if(dap_strcmp(l_new_order_hash_str, l_order_hash_hex_str))
                                 dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str);
@@ -558,16 +569,14 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
                         return -20;
                     }
                 // create order
-                    char *l_order_new_hash_str = dap_chain_net_srv_order_create(
-                                l_net,l_direction, l_srv_uid, l_node_addr,l_tx_cond_hash, &l_price, l_price_unit,
-                                l_price_token, l_expires, (uint8_t *)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key);
-                    if (l_order_new_hash_str) {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Created order %s\n", l_order_new_hash_str);
-                        DAP_DELETE(l_order_new_hash_str);
-                        return 0;
-                    } else {
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Error! Can't created order\n");
-                        return -4;
+                    char * l_order_new_hash_str = dap_chain_net_srv_order_create(
+                        l_net,l_direction, l_srv_uid, l_node_addr,l_tx_cond_hash, &l_price, l_price_unit,
+                        l_price_token, l_expires, (uint8_t *)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key);
+                    if (l_order_new_hash_str)
+                        dap_string_append_printf( l_string_ret, "Created order %s\n", l_order_new_hash_str);
+                    else {
+                        dap_string_append_printf( l_string_ret, "Error! Can't created order\n");
+                        l_ret = -4;
                     }
                 } else {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Missed some required params\n");
@@ -611,7 +620,7 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply)
 
             dap_stream_ch_chain_net_srv_remain_service_store_t *l_remain_service = NULL;
             size_t l_remain_service_size = 0;
-            char *l_remain_limits_gdb_group =  dap_strdup_printf( "%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s",
+            char *l_remain_limits_gdb_group =  dap_strdup_printf( "local.%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s",
                                                                 l_net->pub.gdb_groups_prefix, l_srv_uid.uint64,
                                                                 l_provider_pkey_hash_str);
 
@@ -851,7 +860,7 @@ dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net
 
     dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash(l_net, a_order_hash);
     if (!l_order){
-        log_it(L_ERROR, "Memory allocation error");
+        log_it(L_ERROR, "Can't find order!");
         return NULL;
     }
 
@@ -861,8 +870,6 @@ dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net
         DAP_DEL_Z(l_order);
         return NULL;
     }
-
-    uint64_t l_max_price_cfg = dap_config_get_item_uint64_default(g_config, a_config_section, "max_price", 0xFFFFFFFFFFFFFFF);
     if (l_order->node_addr.uint64 != g_node_addr.uint64 &&
         l_order->srv_uid.uint64 != a_srv->uid.uint64) {
         DAP_DELETE(l_price);
@@ -872,7 +879,6 @@ dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net
 
     l_price->net = l_net;
     l_price->net_name = dap_strdup(l_net->pub.name);
-    uint256_t l_max_price = GET_256_FROM_64(l_max_price_cfg); // Change this value when max price wil be calculated
     if ((IS_ZERO_256(l_order->price) || l_order->units == 0 ) && !a_srv->allow_free_srv){
         log_it(L_ERROR, "Invalid order: units count or price unspecified");
         DAP_DELETE(l_price);
@@ -883,19 +889,6 @@ dap_chain_net_srv_price_t * dap_chain_net_srv_get_price_from_order(dap_chain_net
     dap_stpcpy(l_price->token, l_order->price_ticker);
     l_price->units = l_order->units;
     l_price->units_uid = l_order->price_unit;
-    if (!IS_ZERO_256(l_max_price)){
-        uint256_t l_price_unit = uint256_0;
-        DIV_256(l_price->value_datoshi,  GET_256_FROM_64(l_order->units), &l_price_unit);
-        if (compare256(l_price_unit, l_max_price)>0){
-            char *l_price_unit_str = dap_chain_balance_print(l_price_unit), *l_max_price_str = dap_chain_balance_print(l_max_price);
-            log_it(L_ERROR, "Unit price exeeds max permitted value: %s > %s", l_price_unit_str, l_max_price_str);
-            DAP_DELETE(l_price_unit_str);
-            DAP_DELETE(l_max_price_str);
-            DAP_DELETE(l_price);
-            DAP_DEL_Z(l_order);
-            return NULL;
-        }
-    }
 
     l_price->wallet_addr = dap_chain_addr_from_str(l_wallet_addr);
     if(!l_price->wallet_addr){
@@ -1212,7 +1205,7 @@ dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv
 }
 
 /**
- * @brief dap_chain_net_srv_issue_receipt
+ * @brief s_str_to_price_unit
  * @param a_str_price_unit
  * @param a_price_unit
  * @return 0 if OK, other if error
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index d020aefde084f571a8d1dff271a961440e62196b..f8d627ae2faad2cd910eec6d3fd163caa875df86 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -485,8 +485,6 @@ int dap_chain_net_srv_order_find_all_by(dap_chain_net_t *a_net, const dap_chain_
 int dap_chain_net_srv_order_delete_by_hash_str_sync(dap_chain_net_t *a_net, const char *a_hash_str)
 {
     int l_ret = -2;
-
-    dap_chain_net_srv_order_t *l_order = NULL;
     for (int i = 0; a_net && a_hash_str && i < 2; i++) {
         char *l_gdb_group_str = i ? dap_chain_net_srv_order_get_gdb_group(a_net)
                                   : dap_chain_net_srv_order_get_common_group(a_net);
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 ccdce7024a7f1b7b06e8ded12b64bd64dc158403..0898053d89a2700892c6a825dc3596455a925851 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -88,8 +88,7 @@ int dap_chain_net_srv_order_find_all_by(
     dap_list_t** a_output_orders,
     size_t* a_output_orders_count);
 
-int dap_chain_net_srv_order_delete_by_hash_str_sync(dap_chain_net_t *a_net, const char *a_hash_str);
-
+int dap_chain_net_srv_order_delete_by_hash_str_sync( dap_chain_net_t *a_net, const char *a_hash_str);
 /**
  * @brief dap_chain_net_srv_order_delete_by_hash
  * @param a_net
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 4209f0a89991317ebd2ef08106c5194fea3800e2..7df15d24bed608b3ef6a48e588417a780a008410 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
@@ -33,6 +33,8 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 #include "dap_chain_datum_tx_receipt.h"
 #include "dap_chain_wallet.h"
 
+
+#define RECEIPT_SIGN_MAX_ATTEMPT 3
 typedef struct dap_chain_net_srv dap_chain_net_srv_t;
 typedef struct dap_chain_net_srv_client_remote dap_chain_net_srv_client_remote_t;
 typedef struct dap_chain_net_srv_price dap_chain_net_srv_price_t;
@@ -53,6 +55,9 @@ typedef struct dap_chain_net_srv_usage{
     dap_chain_hash_fast_t client_pkey_hash;
     dap_chain_hash_fast_t static_order_hash;
     dap_timerfd_t *save_limits_timer;
+    dap_timerfd_t *receipts_timeout_timer;
+    void (*receipt_timeout_timer_start_callback)(struct dap_chain_net_srv_usage *a_usage);
+    int receipt_sign_req_cnt;
     char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     bool is_active;
     bool is_free;
@@ -60,6 +65,7 @@ typedef struct dap_chain_net_srv_usage{
     bool is_waiting_new_tx_cond;
     bool is_waiting_new_tx_cond_in_ledger;
     bool is_waiting_first_receipt_sign;
+    bool is_waiting_next_receipt_sign;
     bool is_limits_changed;
 //    UT_hash_handle hh; //
 } dap_chain_net_srv_usage_t;
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index be273aff004cde2f5ccbbdde96354eaf390cdd1a..f62673467990f8263169456c9cd4384936fb3aaf 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -102,6 +102,10 @@ typedef struct iphdr dap_os_iphdr_t;
 #include "dap_chain_ledger.h"
 #include "dap_events.h"
 
+#include "dap_http_simple.h"
+#include "http_status_code.h"
+#include "json-c/json.h"
+
 #define LOG_TAG "dap_chain_net_srv_vpn"
 
 #define SF_MAX_EVENTS 256
@@ -206,6 +210,7 @@ static bool s_ch_packet_out(dap_stream_ch_t* ch, void* arg);
 static void s_ch_vpn_esocket_assigned(dap_events_socket_t* a_es, dap_worker_t * l_worker);
 static void s_ch_vpn_esocket_unassigned(dap_events_socket_t* a_es, dap_worker_t * l_worker);
 
+static void s_callback_remain_limits(dap_http_simple_t *a_http_simple , void *arg);
 
 //static int srv_ch_sf_raw_write(uint8_t op_code, const void * data, size_t data_size);
 //static void srv_stream_sf_disconnect(ch_vpn_socket_proxy_t * sf_sock);
@@ -891,20 +896,25 @@ static int s_vpn_service_create(dap_config_t * g_config)
  * @return 0 if everything is okay, lesser then zero if errors
  */
 int dap_chain_net_srv_vpn_init(dap_config_t * g_config) {
-    s_vpn_tun_init();
+    
+    if(s_vpn_tun_init()){
+        log_it(L_CRITICAL, "Error initializing TUN device driver!");
+        dap_chain_net_srv_vpn_deinit();
+        return -1;
+    }
 
     log_it(L_DEBUG,"Initializing TUN driver...");
     if(s_vpn_tun_create(g_config)){
-        log_it(L_CRITICAL, "Error initializing TUN device driver!");
+        log_it(L_CRITICAL, "Error creating TUN device driver!");
         dap_chain_net_srv_vpn_deinit();
-        return -1;
+        return -2;
     }
 
     log_it(L_INFO,"TUN driver configured successfuly");
     if (s_vpn_service_create(g_config)){
         log_it(L_CRITICAL, "VPN service creating failed");
         dap_chain_net_srv_vpn_deinit();
-        return -2;
+        return -3;
     }
     dap_stream_ch_proc_add(DAP_STREAM_CH_NET_SRV_ID_VPN, s_ch_vpn_new, s_ch_vpn_delete, s_ch_packet_in,
             s_ch_packet_out);
@@ -913,6 +923,24 @@ int dap_chain_net_srv_vpn_init(dap_config_t * g_config) {
     dap_cli_server_cmd_add ("vpn_stat", com_vpn_statistics, "VPN statistics",
             "vpn_stat -net <net_name> [-full]\n"
             );
+
+
+    dap_server_t *l_server_default = dap_server_get_default();
+    if (!l_server_default) {
+        log_it(L_ERROR,"Server should be enabled, change in config file");
+        return -100;
+    }
+
+    dap_http_server_t * l_http = l_server_default->_inheritor;
+    if(!l_http){
+        return -100;
+    }
+
+    dap_http_simple_proc_add(l_http, "/remain_limits_vpn",24000, s_callback_remain_limits);
+
+    // add groups with limits into clusters
+
+    
     return 0;
 }
 
@@ -990,16 +1018,20 @@ static int s_callback_response_success(dap_chain_net_srv_t * a_srv, uint32_t a_u
             case SERV_UNIT_SEC:{
                 l_srv_session->last_update_ts = time(NULL);
                 if (!l_usage_active->is_grace && l_srv_session->limits_ts <= 0){
-                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" seconds more for VPN usage", l_srv_session->limits_ts < 0 ? l_usage_active->receipt->receipt_info.units + l_srv_session->limits_ts :
-                                                                                                                        l_usage_active->receipt->receipt_info.units);
+                    char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage_active->client_pkey_hash);
+                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" seconds more for VPN usage for user %s", l_srv_session->limits_ts < 0 ? l_usage_active->receipt->receipt_info.units + l_srv_session->limits_ts :
+                                                                                                                        l_usage_active->receipt->receipt_info.units, l_user_key);
+                    DAP_DELETE(l_user_key);
                     l_srv_session->limits_ts += (time_t)l_usage_active->receipt->receipt_info.units;
                 }
             } break;
             case SERV_UNIT_B:{
                 if (!l_usage_active->is_grace && l_srv_session->limits_bytes <= 0){
-                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" bytes more for VPN usage", l_srv_session->limits_ts < 0 ? l_usage_active->receipt->receipt_info.units + l_srv_session->limits_ts :
-                                                                                                                        l_usage_active->receipt->receipt_info.units);
-                    l_srv_session->limits_bytes = (uintmax_t) l_usage_active->receipt->receipt_info.units;
+                    char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage_active->client_pkey_hash);
+                    log_it(L_INFO,"%ld bytes more for VPN usage for user %s", l_srv_session->limits_bytes < 0 ? (intmax_t)l_usage_active->receipt->receipt_info.units + l_srv_session->limits_bytes :
+                                                                                                                        (intmax_t)l_usage_active->receipt->receipt_info.units, l_user_key);
+                    DAP_DELETE(l_user_key);
+                    l_srv_session->limits_bytes += (intmax_t) l_usage_active->receipt->receipt_info.units;
                 }
             } break;
             default: {
@@ -1081,10 +1113,10 @@ static dap_stream_ch_chain_net_srv_remain_service_store_t* s_callback_get_remain
         log_it(L_DEBUG, "Can't get server pkey hash.");
         return NULL;
     }
-    char *l_remain_limits_gdb_group =  dap_strdup_printf( "%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s", l_net->pub.gdb_groups_prefix, a_srv->uid.uint64, l_server_pkey_hash);
+    char *l_remain_limits_gdb_group =  dap_strdup_printf( "local.%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s", l_net->pub.gdb_groups_prefix, a_srv->uid.uint64, l_server_pkey_hash);
     DAP_DEL_Z(l_server_pkey_hash);
     char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage->client_pkey_hash);
-    log_it(L_DEBUG, "Checkout user %s in group %s", l_user_key, l_remain_limits_gdb_group);
+    debug_if(s_debug_more, L_DEBUG, "Checkout user %s in group %s", l_user_key, l_remain_limits_gdb_group);
     dap_stream_ch_chain_net_srv_remain_service_store_t* l_remain_service = NULL;
     size_t l_remain_service_size = 0;
     l_remain_service = (dap_stream_ch_chain_net_srv_remain_service_store_t*) dap_global_db_get_sync(l_remain_limits_gdb_group, l_user_key, &l_remain_service_size, NULL, NULL);
@@ -1159,10 +1191,10 @@ static int s_callback_save_remain_service(dap_chain_net_srv_t * a_srv,  uint32_t
         log_it(L_DEBUG, "Can't get server pkey hash.");
         return -101;
     }
-    char *l_remain_limits_gdb_group =  dap_strdup_printf( "%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s", l_net->pub.gdb_groups_prefix, a_srv->uid.uint64, l_server_pkey_hash);
+    char *l_remain_limits_gdb_group =  dap_strdup_printf( "local.%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s", l_net->pub.gdb_groups_prefix, a_srv->uid.uint64, l_server_pkey_hash);
     DAP_DEL_Z(l_server_pkey_hash);
     char *l_user_key = dap_chain_hash_fast_to_str_new(&l_usage->client_pkey_hash);
-    log_it(L_DEBUG, "Save user %s remain service into group %s", l_user_key, l_remain_limits_gdb_group);
+    debug_if(s_debug_more, L_DEBUG, "Save user %s remain service into group %s", l_user_key, l_remain_limits_gdb_group);
 
     dap_stream_ch_chain_net_srv_remain_service_store_t l_remain_service = {};
     dap_sign_t * l_receipt_sign = NULL;
@@ -1171,21 +1203,20 @@ static int s_callback_save_remain_service(dap_chain_net_srv_t * a_srv,  uint32_t
     }
 
 //    l_remain_service.remain_units_type.enm = l_srv_session->limits_units_type.enm;
-    switch(l_srv_session->limits_units_type.enm){
-        case SERV_UNIT_SEC:
-            l_remain_service.limits_ts = l_srv_session->limits_ts >= 0 ? l_srv_session->limits_ts : 0;
-            if(l_receipt_sign)
-                l_remain_service.limits_ts += l_srv_session->usage_active->receipt_next->receipt_info.units;
-            break;
-        case SERV_UNIT_B:
-            l_remain_service.limits_bytes = l_srv_session->limits_bytes >= 0 ? l_srv_session->limits_bytes : 0;            
-            if (l_receipt_sign)
-                l_remain_service.limits_bytes += l_srv_session->usage_active->receipt_next->receipt_info.units;
-            break;
-    }
+    l_remain_service.limits_ts = l_srv_session->limits_ts >= 0 ? l_srv_session->limits_ts : 0;
+    if(l_receipt_sign && l_srv_session->limits_units_type.enm == SERV_UNIT_SEC)
+        l_remain_service.limits_ts += l_srv_session->usage_active->receipt_next->receipt_info.units;
 
-    if(dap_global_db_set_sync(l_remain_limits_gdb_group, l_user_key, &l_remain_service, sizeof(l_remain_service), false))
+    l_remain_service.limits_bytes = l_srv_session->limits_bytes >= 0 ? l_srv_session->limits_bytes : 0;            
+    if (l_receipt_sign && l_srv_session->limits_units_type.enm == SERV_UNIT_B)
+        l_remain_service.limits_bytes += l_srv_session->usage_active->receipt_next->receipt_info.units;
+
+
+
+    int l_ret = dap_global_db_set_sync(l_remain_limits_gdb_group, l_user_key, &l_remain_service, sizeof(l_remain_service), false);
+    if(l_ret)
     {
+        log_it(L_DEBUG, "Can't save remain limits into GDB. Error code: %d", l_ret);
         DAP_DELETE(l_remain_limits_gdb_group);
         DAP_DELETE(l_user_key);
         return -102;
@@ -1356,14 +1387,18 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
         a_srv_session->limits_ts -= time(NULL) - a_srv_session->last_update_ts;
         a_usage->is_limits_changed = true;
 
-        if(a_srv_session->limits_ts < l_current_limit_ts/2 && !a_usage->receipt_next && !a_usage->is_grace){
+        if(a_srv_session->limits_ts && a_srv_session->limits_ts < l_current_limit_ts/2 && 
+            !a_usage->receipt_next && !a_usage->is_waiting_first_receipt_sign){
             l_issue_new_receipt = true;
         }
         a_srv_session->last_update_ts = time(NULL);
 
 
-        if( a_srv_session->limits_ts <= 0 && !a_usage->is_grace){
-            log_it(L_INFO, "Limits by timestamp are over. Switch to the next receipt");
+        if( a_srv_session->limits_ts <= 0 && !a_usage->is_grace && 
+                    !a_usage->is_waiting_next_receipt_sign && !a_usage->is_waiting_first_receipt_sign){
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+            log_it(L_INFO, "Limits by timestamp are over for user %s. Switch to the next receipt", l_user_key);
+            DAP_DELETE(l_user_key);
             if (a_usage->receipt_next){
                 dap_sign_t * l_receipt_sign = dap_chain_datum_tx_receipt_sign_get( a_usage->receipt_next, a_usage->receipt_next->size, 1);
                 if ( ! l_receipt_sign ){
@@ -1379,7 +1414,9 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
                 switch( a_usage->receipt->receipt_info.units_type.enm){
                 case SERV_UNIT_SEC:{
                     a_srv_session->limits_ts += (time_t)a_usage->receipt->receipt_info.units;
-                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" seconds more for VPN usage", a_usage->receipt->receipt_info.units);
+                    char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" seconds more for VPN usage for user %s", a_usage->receipt->receipt_info.units, l_user_key);
+                    DAP_DELETE(l_user_key);
                 } break;
                 default: {
                     log_it(L_WARNING, "VPN doesnt accept serv unit type 0x%08X for limits_ts", a_usage->receipt->receipt_info.units_type.uint32 );
@@ -1389,7 +1426,9 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
                 }
                 }
             }else if (!a_usage->is_grace){
-                log_it( L_NOTICE, "No activate receipt in usage, switch off write callback for channel");
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+                log_it( L_NOTICE, "No activate receipt in usage for user %s, switch off write callback for channel", l_user_key);
+                DAP_DELETE(l_user_key);
                 dap_stream_ch_chain_net_srv_pkt_error_t l_err = { };
                 l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND ;
                 dap_stream_ch_pkt_write_unsafe(a_ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , &l_err, sizeof(l_err));
@@ -1401,20 +1440,30 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
         intmax_t current_limit_bytes = 0;
         if ( a_usage->receipt){// if we have active receipt and a_srv_session->last_update_ts == 0 then we counts units by traffic
             switch( a_usage->receipt->receipt_info.units_type.enm){
-            case SERV_UNIT_B:{
-                current_limit_bytes = (uintmax_t) a_usage->receipt->receipt_info.units;
-            } break;
+                case SERV_UNIT_B:{
+                    current_limit_bytes = (uintmax_t) a_usage->receipt->receipt_info.units;
+                } break;
+                default: {
+                    log_it(L_WARNING, "VPN doesnt accept serv unit type 0x%08X for limits_ts", a_usage->receipt->receipt_info.units_type.uint32 );
+                    dap_stream_ch_pkt_write_unsafe( a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
+                    dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
+                    dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
+                }
             }
         }
 
         a_srv_session->limits_bytes -= (intmax_t) a_bytes;
         a_usage->is_limits_changed = true;
-        if (a_srv_session->limits_bytes && a_srv_session->limits_bytes < current_limit_bytes/2 && ! a_usage->receipt_next){
+        if (a_srv_session->limits_bytes && a_srv_session->limits_bytes < current_limit_bytes/2 &&
+            !a_usage->receipt_next && !a_usage->is_waiting_first_receipt_sign){
             l_issue_new_receipt = true;
         }
 
-        if (a_srv_session->limits_bytes <= 0  && !a_usage->is_grace){
-            log_it(L_INFO, "Limits by traffic is over. Switch to the next receipt");
+        if (a_srv_session->limits_bytes <= 0  && !a_usage->is_grace && 
+            !a_usage->is_waiting_next_receipt_sign && !a_usage->is_waiting_first_receipt_sign){
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+            log_it(L_INFO, "Limits by traffic is over for user %s. Switch to the next receipt", l_user_key);
+            DAP_DELETE(l_user_key);
             if (a_usage->receipt_next){
                 dap_sign_t * l_receipt_sign = dap_chain_datum_tx_receipt_sign_get( a_usage->receipt_next, a_usage->receipt_next->size, 1);
                 if ( ! l_receipt_sign ){
@@ -1430,7 +1479,9 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
                 switch( a_usage->receipt->receipt_info.units_type.enm){
                 case SERV_UNIT_B:{
                     a_srv_session->limits_bytes +=  (uintmax_t) a_usage->receipt->receipt_info.units;
-                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" bytes more for VPN usage", a_usage->receipt->receipt_info.units);
+                    char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+                    log_it(L_INFO,"%"DAP_UINT64_FORMAT_U" bytes more for VPN usage for user", a_usage->receipt->receipt_info.units, l_user_key);
+                    DAP_DELETE(l_user_key);
                 } break;
                 default: {
                     log_it(L_WARNING, "VPN doesnt accept serv unit type 0x%08X for limits_bytes", a_usage->receipt->receipt_info.units_type.uint32 );
@@ -1440,7 +1491,9 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
                 }
                 }
             }else if (!a_usage->is_grace){
-                log_it( L_NOTICE, "No activate receipt in usage, switch off write callback for channel");
+                char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+                log_it( L_NOTICE, "No activate receipt in usage for user %s, switch off write callback for channel", l_user_key);
+                DAP_DELETE(l_user_key);
                 dap_stream_ch_chain_net_srv_pkt_error_t l_err = { };
                 l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND ;
                 dap_stream_ch_pkt_write_unsafe( a_ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , &l_err, sizeof(l_err));
@@ -1453,9 +1506,14 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
     // If issue new receipt
     if ( l_issue_new_receipt && !dap_hash_fast_is_blank(&a_usage->tx_cond_hash)) {
         if ( a_usage->receipt){
-            log_it( L_NOTICE, "Send next receipt to sign");
+            char *l_user_key = dap_chain_hash_fast_to_str_new(&a_usage->client_pkey_hash);
+            log_it( L_NOTICE, "Send next receipt to sign to user %s", l_user_key);
+            DAP_DELETE(l_user_key);
             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_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST,
+            a_usage->is_waiting_next_receipt_sign = true;
+            //start timeout timer
+            a_usage->receipt_timeout_timer_start_callback(a_usage);
+            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);
         }
     }
@@ -2081,3 +2139,127 @@ static int s_tun_deattach_queue(int fd)
 }
 
 #endif
+
+
+static void s_callback_remain_limits(dap_http_simple_t *a_http_simple , void *a_arg)
+{
+    http_status_code_t * l_return_code = (http_status_code_t*)a_arg;
+    *l_return_code = Http_Status_OK;
+    strcpy(a_http_simple->reply_mime, "text/text");
+
+    const char* l_query = a_http_simple->http_client->in_query_string;
+    uint32_t l_query_length = a_http_simple->http_client->in_query_string_len;
+
+    const char *l_net_id_str = NULL;
+    const char *l_user_pkey_hash_str = NULL;
+    dap_chain_net_id_t l_net_id = {};
+    // request parsing
+    // example: net_id=id&user_pkey_hash=pkeyhash
+    char *l_first_param = DAP_DUP_SIZE(l_query, l_query_length);
+    char *l_second_param = strchr(l_first_param, '&');
+    if (!l_second_param || strlen(l_second_param) == 1){
+        dap_http_simple_reply_f(a_http_simple, "Wrong parameters!");
+        *l_return_code = Http_Status_OK;
+        return;
+    }
+    *l_second_param++ = '\0';
+
+    if (strstr(l_first_param, "net_id")){
+        if (*(l_first_param + strlen("net_id")) == '='){
+            l_net_id_str = l_first_param + strlen("net_id") + 1;
+        }
+    } else if (strstr(l_first_param, "user_pkey_hash")) {
+        if (*(l_first_param + strlen("user_pkey_hash")) == '='){
+            l_user_pkey_hash_str = l_first_param + strlen("user_pkey_hash") + 1;
+        }
+    }
+
+    if (strstr(l_second_param, "net_id")){
+        if (*(l_second_param + strlen("net_id")) == '='){
+            l_net_id_str = l_second_param + strlen("net_id") + 1;
+        }
+    } else if (strstr(l_second_param, "user_pkey_hash")) {
+        if (*(l_second_param + strlen("user_pkey_hash")) == '='){
+            l_user_pkey_hash_str = l_second_param + strlen("user_pkey_hash") + 1;
+        }
+    }
+
+    if (!l_net_id_str || !l_user_pkey_hash_str){
+        dap_http_simple_reply_f(a_http_simple, "Wrong parameters!");
+        *l_return_code = Http_Status_OK;
+        return;
+    }
+
+    l_net_id.uint64 = strtoul(l_net_id_str, NULL, 10);
+
+    dap_stream_ch_chain_net_srv_remain_service_store_t *l_remain_service = NULL;
+    const char *l_cert_name = dap_config_get_item_str_default(g_config, "srv_vpn", "receipt_sign_cert", NULL);
+    if (l_cert_name){
+        dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name);
+        dap_hash_fast_t price_pkey_hash = {};
+        size_t l_key_size = 0;
+        uint8_t *l_pub_key = dap_enc_key_serialize_pub_key(l_cert->enc_key, &l_key_size);
+        if (!l_pub_key || !l_key_size)
+        {
+            log_it(L_ERROR, "Can't get pkey from cert %s.", l_cert_name);
+            dap_http_simple_reply_f(a_http_simple, "Internal error!");
+            *l_return_code = Http_Status_OK;
+            return;
+        }
+
+        dap_hash_fast(l_pub_key, l_key_size, &price_pkey_hash);
+        DAP_DELETE(l_pub_key);
+        char* l_server_pkey_hash = dap_chain_hash_fast_to_str_new(&price_pkey_hash);
+        if (!l_server_pkey_hash){
+            log_it(L_DEBUG, "Can't get server pkey hash.");
+            dap_http_simple_reply_f(a_http_simple, "Internal error!");
+            *l_return_code = Http_Status_OK;
+            return;
+        }
+
+        dap_chain_net_t *l_net = dap_chain_net_by_id(l_net_id);
+        if(!l_net){
+            log_it(L_DEBUG, "Can't find net with id %"DAP_UINT64_FORMAT_U, l_net_id.uint64);
+            dap_http_simple_reply_f(a_http_simple, "Can't find net with id %"DAP_UINT64_FORMAT_U"!", l_net_id.uint64);
+            DAP_DEL_Z(l_server_pkey_hash);
+            *l_return_code = Http_Status_OK;
+            return;
+        }
+        char *l_remain_limits_gdb_group =  dap_strdup_printf( "local.%s.0x%016"DAP_UINT64_FORMAT_x".remain_limits.%s", l_net->pub.gdb_groups_prefix, (uint64_t)DAP_CHAIN_NET_SRV_VPN_ID, l_server_pkey_hash);
+        log_it(L_DEBUG, "Checkout user %s in group %s", l_user_pkey_hash_str, l_remain_limits_gdb_group);
+        size_t l_remain_service_size = 0;
+        l_remain_service = (dap_stream_ch_chain_net_srv_remain_service_store_t*) dap_global_db_get_sync(l_remain_limits_gdb_group, l_user_pkey_hash_str, &l_remain_service_size, NULL, NULL);
+        DAP_DELETE(l_remain_limits_gdb_group);
+
+        // Create JSON responce
+        json_object *l_json_response = json_object_new_object();
+
+        json_object *l_new_data = json_object_new_uint64(l_net_id.uint64);
+        json_object_object_add(l_json_response, "netId", l_new_data);
+
+        l_new_data = json_object_new_uint64((uint64_t)DAP_CHAIN_NET_SRV_VPN_ID);
+        json_object_object_add(l_json_response, "srvUid", l_new_data);
+
+        l_new_data = json_object_new_string(l_user_pkey_hash_str ? l_user_pkey_hash_str : "");
+        json_object_object_add(l_json_response, "userPkeyHash", l_new_data);
+
+        l_new_data = json_object_new_string(l_server_pkey_hash ? l_server_pkey_hash : "");
+        json_object_object_add(l_json_response, "serverPkeyHash", l_new_data);
+
+        l_new_data = json_object_new_uint64(l_remain_service ? l_remain_service->limits_bytes : 0);
+        json_object_object_add(l_json_response, "limitsBytes", l_new_data);
+
+        l_new_data = json_object_new_uint64(l_remain_service ? l_remain_service->limits_ts : 0);
+        json_object_object_add(l_json_response, "limitsSec", l_new_data);
+
+        const char *output_string = json_object_to_json_string(l_json_response);
+        dap_http_simple_reply(a_http_simple, (void*)output_string, strlen(output_string));
+        strcpy(a_http_simple->reply_mime, "application/json");
+        json_object_put(l_json_response);
+        DAP_DEL_Z(l_server_pkey_hash);
+        DAP_DEL_Z(l_first_param);
+    } else {
+        dap_http_simple_reply_f(a_http_simple, "Internal error!");
+        *l_return_code = Http_Status_InternalServerError;
+    }
+}
\ No newline at end of file