diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index aa089177b0d1d6a5e66d58150b79b62907555ee4..6e1b6d174df015b3953090a9b6eae766a8e2c1bb 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -81,6 +81,7 @@ typedef struct dap_chain_ledger_token_item {
     char ticker[DAP_CHAIN_TICKER_SIZE_MAX];
     uint16_t type;
     dap_chain_datum_token_t * datum_token;
+    uint64_t datum_token_size;
 
     uint256_t total_supply;
     uint256_t current_supply;
@@ -436,6 +437,22 @@ int dap_chain_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *
         case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL: // 256
             if(s_debug_more)
                 log_it( L_NOTICE, "Private token %s type=DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL ", a_token->ticker);
+            l_token_item->total_supply = a_token->header_private.total_supply_256;
+            l_token_item->current_supply = a_token->header_private.current_supply_256;
+            
+            l_token_item->auth_signs= dap_chain_datum_token_simple_signs_parse(a_token,a_token_size,
+                                                                                    &l_token_item->auth_signs_total,
+                                                                                    &l_token_item->auth_signs_valid );
+            if(l_token_item->auth_signs_total){
+                l_token_item->auth_signs_pkey_hash = DAP_NEW_Z_SIZE(dap_chain_hash_fast_t,sizeof (dap_chain_hash_fast_t)* l_token_item->auth_signs_total);
+                for(uint16_t k=0; k<l_token_item->auth_signs_total;k++){
+                    dap_sign_get_pkey_hash(l_token_item->auth_signs[k],&l_token_item->auth_signs_pkey_hash[k]);
+                }
+                if(s_debug_more)
+                    log_it(L_NOTICE, "Simple token %s added (total_supply = %.1Lf total_signs_valid=%hu signs_total=%hu type=DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE)",
+                    a_token->ticker, dap_chain_datoshi_to_coins(a_token->header_private.total_supply),
+                    a_token->header_private.signs_valid, a_token->header_private.signs_total);
+            }
             s_token_tsd_parse(a_ledger,l_token_item, a_token, a_token_size);
             break;
         case DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL: {
@@ -480,7 +497,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
     size_t l_tsd_size=0;
     size_t l_tsd_total_size =a_token_size-  (((byte_t*)l_tsd)- (byte_t*) a_token );
 
-    for( size_t l_offset=0; l_tsd && l_offset < l_tsd_total_size;  l_offset += l_tsd_size ){
+    for( size_t l_offset=0; l_offset < l_tsd_total_size;  l_offset += l_tsd_size ){
         l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd ) +l_offset);
         l_tsd_size =  l_tsd? dap_tsd_size(l_tsd): 0;
         if( l_tsd_size==0 ){
@@ -567,7 +584,7 @@ static int s_token_tsd_parse(dap_ledger_t * a_ledger, dap_chain_ledger_token_ite
                     // Check if its correct
                     dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
                     int l_add_addr_check;
-                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=0){
+                    if (  (l_add_addr_check=dap_chain_addr_check_sum(l_add_addr))!=1){
                         if(s_debug_more)
                             log_it(L_ERROR,"Wrong address checksum in TSD param DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD (code %d)",
                                l_add_addr_check);
@@ -925,6 +942,7 @@ int dap_chain_ledger_token_load(dap_ledger_t *a_ledger, dap_chain_datum_token_t
         pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
         if (l_token_item)
             return 0;
+        //l_token_item->current_supply = l_token_item->total_supply;
     }
     return dap_chain_ledger_token_add(a_ledger, a_token, a_token_size);
 }
@@ -952,14 +970,29 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger)
             default:
                 l_type_str = "UNKNOWN"; break;
         }
-        char *l_item_str = dap_strdup_printf("Token name '%s', type %s, flags %hu\n"
-                                             "\tSupply (current/total) %s/%s \n"
-                                             "\tAuth signs (valid/total) %zu/%zu\n"
-                                             "\tTotal emissions %u\n",
-                                             &l_token_item->ticker, l_type_str, l_token_item->flags,
-                                             dap_chain_balance_print(l_token_item->current_supply), dap_chain_balance_print(l_token_item->total_supply),
-                                             l_token_item->auth_signs_valid, l_token_item->auth_signs_total,
-                                             HASH_COUNT(l_token_item->token_emissions));
+       char *l_item_str = NULL;
+
+            if ((l_token_item->type == DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL) | (l_token_item->type == DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_UPDATE)){
+                l_item_str = dap_strdup_printf("Token name '%s', type %s, flags: %s\n"
+                                                "\tSupply (current/total) %s/%s\n"
+                                                "\tAuth signs (valid/total) %zu/%zu\n"
+                                                "\tTotal emissions %u\n",
+                                                &l_token_item->ticker, l_type_str, s_flag_str_from_code(l_token_item->datum_token->header_private_decl.flags),
+                                                dap_chain_balance_print(l_token_item->current_supply), dap_chain_balance_print(l_token_item->total_supply),
+                                                l_token_item->auth_signs_valid, l_token_item->auth_signs_total,
+                                                HASH_COUNT(l_token_item->token_emissions));
+            } 
+            else{
+                l_item_str = dap_strdup_printf("Token name '%s', type %s, flags: %hu\n"
+                                                "\tSupply (current/total) %s/%s\n"
+                                                "\tAuth signs (valid/total) %zu/%zu\n"
+                                                "\tTotal emissions %u\n",
+                                                &l_token_item->ticker, l_type_str, l_token_item->datum_token->header_private_decl.flags,
+                                                dap_chain_balance_print(l_token_item->current_supply), dap_chain_balance_print(l_token_item->total_supply),
+                                                l_token_item->auth_signs_valid, l_token_item->auth_signs_total,
+                                                HASH_COUNT(l_token_item->token_emissions));
+            }
+
         l_ret_list = dap_list_append(l_ret_list, l_item_str);
     }
     pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock);
@@ -988,6 +1021,7 @@ bool s_update_token_cache(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t
                                         dap_chain_balance_print(l_emission_value));
        return false;
     }   
+    // load ledger cache from GDB
     // Get dap_chain_datum_token_t token object from GDB, key is token name
     char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_TOKENS_STR);
     size_t l_obj_length = 0;
@@ -995,11 +1029,14 @@ bool s_update_token_cache(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t
             dap_chain_global_db_gr_get(l_token_item->ticker, &l_obj_length, l_gdb_group);
     l_token_cache->header_private.current_supply_256 = l_token_item->current_supply;
     if (!dap_chain_global_db_gr_set(l_token_item->ticker, l_token_cache, l_obj_length, l_gdb_group)) {
-       if(s_debug_more)
-          log_it(L_WARNING, "Ledger cache mismatch");
+        if(s_debug_more)
+            log_it(L_WARNING, "Ledger cache mismatch");
+        DAP_DELETE(l_gdb_group);
+        return false;
     }
     DAP_DELETE(l_token_cache);
     DAP_DELETE(l_gdb_group);
+
     return true;
 }
 
@@ -1073,6 +1110,7 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger)
         l_token_item->ticker[sizeof(l_token_item->ticker) - 1] = '\0';
         size_t l_token_size = l_objs[i].value_len;
         l_token_item->datum_token = dap_chain_datum_token_read(l_objs[i].value, &l_token_size);
+        l_token_item->datum_token_size = l_objs[i].value_len;
         pthread_rwlock_init(&l_token_item->token_emissions_rwlock, NULL);
         l_token_item->type = l_token_item->datum_token->type;
         // test tsd
@@ -1297,6 +1335,49 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_
     return l_ret;
 }
 
+bool s_chain_compare_token_addresses(dap_chain_addr_t * l_add_addr01, dap_chain_addr_t * l_add_addr02)
+{
+    char *l_addr_str01 = dap_chain_addr_to_str(l_add_addr01);
+    char *l_addr_str02 = dap_chain_addr_to_str(l_add_addr02);
+    if (strcmp(l_addr_str01, l_addr_str02) == 0)
+        return true;
+    else
+        return false;
+}
+
+// new__
+// s_chain_ledger_token_tsd_check
+//
+
+bool s_chain_ledger_token_tsd_check(dap_ledger_t *a_ledger, dap_chain_ledger_token_item_t * l_token_item, dap_chain_datum_token_emission_t *a_token_emission)
+{   
+    // for multiple tsd we need to parse every tsd in cycle
+    if (!l_token_item){
+        log_it(L_WARNING, "Token object is null. Probably, you set unknown token ticker in -token parameter");
+        return false;
+    }
+    dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(l_token_item->datum_token, l_token_item->datum_token_size);
+    if (!l_tsd)
+        return false;
+    switch(l_tsd->type){
+        case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD:
+
+            //s_token_tsd_parse(a_ledger, l_token_item , l_token_item->datum_token, l_token_item->datum_token_size);
+            dap_chain_addr_t * l_add_addr = (dap_chain_addr_t *) l_tsd->data;
+
+           if (!s_chain_compare_token_addresses(&a_token_emission->hdr.address, l_add_addr)){
+               log_it(L_WARNING, "address %s is not allowed for emission for token %s", dap_chain_addr_to_str(&a_token_emission->hdr.address), l_token_item->ticker);
+               return false;
+           }
+
+        break;
+        default:
+            break;
+    }
+    log_it(L_WARNING, "private tokens limitations were checked successful");
+    return true;
+}
+
 /**
  * @brief dap_chain_ledger_token_emission_add
  * @param a_token_emission
@@ -1314,6 +1395,13 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_
     HASH_FIND_STR(l_ledger_priv->tokens, c_token_ticker, l_token_item);
     pthread_rwlock_unlock(&l_ledger_priv->tokens_rwlock);
     dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL;
+    //additional check for private tokens
+    if ((l_token_item->type == DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL) | (l_token_item->type == DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_UPDATE))
+    {
+        if (!s_chain_ledger_token_tsd_check(a_ledger, l_token_item, (dap_chain_datum_token_emission_t *)a_token_emission))
+                return -1;
+    }
+   
     if (!l_token_item && a_from_threshold)
         return DAP_CHAIN_CS_VERIFY_CODE_TX_NO_TOKEN;
     // check if such emission is already present in table
@@ -1335,6 +1423,24 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_
             if (!PVT(a_ledger)->load_mode && l_token_item && !s_token_supply_limit_disable)
                 if (!s_update_token_cache(a_ledger, l_token_item, l_token_emission_item->datum_token_emission->hdr.value_256))
                    return -4;
+
+            // if cache is disabled, we need calc tokens manually
+            if (PVT(a_ledger)->load_mode)
+            {
+                if (!dap_config_get_item_bool_default(g_config, "ledger", "cached", true)) {
+
+                    if (compare256(l_token_item->current_supply, l_token_emission_item->datum_token_emission->hdr.value_256) >= 0) {
+                        SUBTRACT_256_256(l_token_item->current_supply, l_token_emission_item->datum_token_emission->hdr.value_256, &l_token_item->current_supply);
+                        log_it(L_DEBUG,"New current supply %s for token %s",
+                            dap_chain_balance_print(l_token_item->current_supply), l_token_item->ticker);
+                    } else {
+                    log_it(L_WARNING,"Token current supply %s lower, than emission value = %s",
+                            dap_chain_balance_print(l_token_item->current_supply),
+                                                        dap_chain_balance_print(l_token_emission_item->datum_token_emission->hdr.value_256));
+                        return -4;
+                    }  
+                }
+            }   
             if (s_token_supply_limit_disable)
                 log_it(L_WARNING,"s_token_supply_limit_disable is enabled in config, please fix it and disable");
 
diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c
index 16cf0202ad9146ff6b04a15feadf2777cf06891d..60c735deef5384e53583f6ae8042dca958f5a0c9 100644
--- a/modules/channel/chain/dap_stream_ch_chain.c
+++ b/modules/channel/chain/dap_stream_ch_chain.c
@@ -768,16 +768,19 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg)
                             (dap_chain_datum_t** restrict) &l_store_obj_value, 1,
                             l_store_obj[i].group);
                 }
+            } else 
+            {
+                // save data to global_db
+                if(!dap_chain_global_db_obj_save(l_obj, 1)) {
+                    struct sync_request *l_sync_req_err = DAP_DUP(l_sync_request);
+                    dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id,
+                                                    s_gdb_in_pkt_error_worker_callback, l_sync_req_err);
+                } else {
+                    if (s_debug_more)
+                        log_it(L_DEBUG, "Added new GLOBAL_DB synchronization record");
+                }
             }
-            // save data to global_db
-            if(!dap_chain_global_db_obj_save(l_obj, 1)) {
-                struct sync_request *l_sync_req_err = DAP_DUP(l_sync_request);
-                dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id,
-                                                  s_gdb_in_pkt_error_worker_callback, l_sync_req_err);
-            } else {
-                if (s_debug_more)
-                    log_it(L_DEBUG, "Added new GLOBAL_DB synchronization record");
-            }
+
         }
         if(l_store_obj) {
             dap_store_obj_free(l_store_obj, l_data_obj_count);
diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c
index 349f1c6cd66a70478be51170ca1913c9a3d8d75b..1b9313d6b8dff4a8b8677b86d592126686dd559b 100644
--- a/modules/common/dap_chain_datum_token.c
+++ b/modules/common/dap_chain_datum_token.c
@@ -65,7 +65,7 @@ dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t *a_token, size_
 {
     // Check if token type could have tsd section
     size_t l_tsd_size;
-    size_t l_hdr_size = sizeof(dap_chain_datum_token_old_t);
+    size_t l_hdr_size = sizeof(dap_chain_datum_token_t);
     if (l_hdr_size > a_token_size){
         log_it(L_WARNING, "Token size smaller then header, corrupted data");
         return NULL;
diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h
index 6ddb5f88422ffe4cb2d35dfe04af98f79c74a2db..b208c06f9ca8e2faa97ae18cc5179f6f03898f34 100644
--- a/modules/common/include/dap_chain_datum_token.h
+++ b/modules/common/include/dap_chain_datum_token.h
@@ -131,69 +131,70 @@ typedef struct dap_chain_datum_token{
 // Macros for token flags
 /// ------- Global section flags --------
 // No any flags
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_NONE                                    0x0000
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_NONE                                           0x0000
 // Blocked all permissions, usefull issue it by default and then allow what you want to allow
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED                             0x0001
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED                             1 << 1
 // Allowed all permissions if not blocked them. Be careful with this mode
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED                             0x0002
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED                             1 << 2
 // All permissions are temprorary frozen
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN                              0x0003
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN                              1 << 3
 // Unfrozen permissions
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN                            0x0004
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN                            1 << 4
 
 // Blocked all permissions, usefull issue it by default and then allow what you want to allow
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED                             0x0011
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED                             1 << 5
 // Allowed all permissions if not blocked them. Be careful with this mode
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED                             0x0012
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED                             1 << 6
 // All permissions are temprorary frozen
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN                              0x0013
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN                              1 << 7
 // Unfrozen permissions
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN                            0x0014
-
-//  Maximal flag
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_MAX                                     0x0014
-
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED                               0xffff
-
-extern const char *c_dap_chain_datum_token_flag_str[];
-
-#define dap_chain_datum_token_flag_to_str(a) (if (a<=DAP_CHAIN_DATUM_TOKEN_FLAG_MAX) c_dap_chain_datum_token_flag_str[a]; else "OUT_OF_RANGE")
-
-/**
- * @brief dap_chain_datum_token_flag_from_str
- * @param a_str
- * @return
- */
-static inline uint16_t dap_chain_datum_token_flag_from_str(const char* a_str)
-{
-    if (a_str == NULL)
-        return DAP_CHAIN_DATUM_TOKEN_FLAG_NONE;
-
-    for (uint16_t i = DAP_CHAIN_DATUM_TOKEN_FLAG_NONE; i <=DAP_CHAIN_DATUM_TOKEN_FLAG_MAX; i++ ){
-        if ( strcmp( a_str, c_dap_chain_datum_token_flag_str[i]) == 0 )
-            return i;
-    }
-    return DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED;
-}
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN                            1 << 8
 
 /// ------ Static configured flags
 // No token manipulations after declarations at all. Token declares staticly and can't variabed after
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_ALL                              0x0010
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_ALL                              1 << 9
 
 // No token manipulations after declarations with flags.
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_FLAGS                            0x0011
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_FLAGS                            1 << 10
 
 // No all permissions lists manipulations after declarations
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_ALL                  0x0012
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_ALL                  1 << 11
 
 // No datum type permissions lists manipulations after declarations
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_DATUM_TYPE           0x0013
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_DATUM_TYPE           1 << 12
 
 // No tx sender permissions lists manipulations after declarations
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_SENDER            0x0014
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_SENDER            1 << 13
 
 // No tx receiver permissions lists manipulations after declarations
-#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_RECEIVER          0x0015
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_RECEIVER          1 << 14
+
+//  Maximal flag
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_MAX                                     1 << 15
+
+#define DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED                               0xffff
+
+extern const char *c_dap_chain_datum_token_flag_str[];
+
+#define dap_chain_datum_token_flag_to_str(a) ((a<=DAP_CHAIN_DATUM_TOKEN_FLAG_MAX) ? c_dap_chain_datum_token_flag_str[a] : "OUT_OF_RANGE")
+
+
+// /**
+//  * @brief dap_chain_datum_token_flag_from_str
+//  * @param a_str
+//  * @return
+//  */
+// static inline uint16_t dap_chain_datum_token_flag_from_str(const char* a_str)
+// {
+//     if (a_str == NULL)
+//         return DAP_CHAIN_DATUM_TOKEN_FLAG_NONE;
+
+//     for (uint16_t i = DAP_CHAIN_DATUM_TOKEN_FLAG_NONE; i <=DAP_CHAIN_DATUM_TOKEN_FLAG_MAX; i++ ){
+//         if ( strcmp( a_str, c_dap_chain_datum_token_flag_str[i]) == 0 )
+//             return i;
+//     }
+//     return DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED;
+// }
 
 /// -------- General tsd types ----
 // Flags set/unsed
@@ -252,6 +253,104 @@ static inline uint16_t dap_chain_datum_token_flag_from_str(const char* a_str)
 
 #define DAP_CHAIN_DATUM_NONCE_SIZE                                    64
 
+typedef struct { char *key; uint64_t val; } t_datum_token_flag_struct;
+
+// new__
+static t_datum_token_flag_struct s_flags_table[] = {
+    { "NO_FLAGS", DAP_CHAIN_DATUM_TOKEN_FLAG_NONE}, 
+    { "ALL_BLOCKED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED | DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED}, 
+    { "ALL_FROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN | DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN }, 
+    { "ALL_ALLOWED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED | DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED},
+    { "ALL_UNFROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN | DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN }, 
+    { "STATIC_ALL", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_ALL},
+    { "STATIC_FLAGS", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_FLAGS }, 
+    { "STATIC_PERMISSIONS_ALL", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_ALL }, 
+    { "STATIC_PERMISSIONS_DATUM_TYPE", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_DATUM_TYPE }, 
+    { "STATIC_PERMISSIONS_TX_SENDER", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_SENDER },
+    { "STATIC_PERMISSIONS_TX_RECEIVER", DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_RECEIVER },
+    { "ALL_SENDER_BLOCKED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED}, 
+    { "ALL_SENDER_FROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN}, 
+    { "ALL_SENDER_ALLOWED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED},
+    { "ALL_SENDER_UNFROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN}, 
+    { "ALL_RECEIVER_BLOCKED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED}, 
+    { "ALL_RECEIVER_FROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN }, 
+    { "ALL_RECEIVER_ALLOWED", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED},
+    { "ALL_RECEIVER_UNFROZEN", DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN }, 
+};
+
+
+#define NKEYS (sizeof(s_flags_table)/sizeof(t_datum_token_flag_struct))
+
+static inline int s_flag_code_from_str(const char *key)
+{
+    uint64_t i;
+    for (i=0; i < NKEYS; i++) {
+        t_datum_token_flag_struct sym = s_flags_table[i];
+        if (strcmp(s_flags_table[i].key, key) == 0)
+            return s_flags_table[i].val;
+    }
+
+    return DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED;
+}
+
+static inline char* s_flag_str_from_code(uint64_t code)
+{
+    uint64_t i;
+    uint64_t flags_count = 0;
+
+    for (i=0; i < NKEYS; i++) {
+        t_datum_token_flag_struct sym = s_flags_table[i];
+        if (s_flags_table[i].val == code)
+            return s_flags_table[i].key;
+    }
+
+    // split multiple flags in string
+
+    char* s_multiple_flag = "";
+
+    for (i=0; i < NKEYS; i++) {
+        t_datum_token_flag_struct sym = s_flags_table[i];
+        if ((s_flags_table[i].val & code) > 0)
+        {
+            flags_count += 1;
+            if (flags_count > 1)
+                s_multiple_flag = dap_strjoin(";", s_multiple_flag, s_flags_table[i].key, (char*)NULL);
+            else
+                s_multiple_flag = dap_strjoin(NULL, s_multiple_flag, s_flags_table[i].key, (char*)NULL);
+        }         
+    }
+
+    char* s_no_flags = "NO FLAGS";
+
+    if (flags_count > 0)
+        return s_multiple_flag;
+    else
+        return s_no_flags;
+}
+
+/**
+ * @brief dap_chain_datum_token_flag_from_str
+ * @param a_str
+ * @return
+ */
+static inline char* dap_chain_datum_str_token_flag_from_code(uint64_t code)
+{   
+    return s_flag_str_from_code(code);
+}
+
+/**
+ * @brief dap_chain_datum_token_flag_from_str
+ * @param a_str
+ * @return
+ */
+static inline uint16_t dap_chain_datum_token_flag_from_str(const char* a_str)
+{
+    if (a_str == NULL)
+        return DAP_CHAIN_DATUM_TOKEN_FLAG_NONE;
+    
+    return s_flag_code_from_str(a_str);
+}
+
 struct DAP_ALIGN_PACKED dap_chain_emission_header_v0 {
     uint8_t version;
     uint8_t type; // Emission Type
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index ea269085792dbe15fc115ef3e30175bd71d01c9f..7f8af05da34ecfac4668230f2b0253d9a57be3c5 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -435,8 +435,12 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c
         }
         dap_store_obj_pkt_t *l_data_out = dap_store_packet_single(l_obj);
         dap_store_obj_free(l_obj, 1);
+        dap_chain_id_t l_chain_id;
+        l_chain_id.uint64 = 0;
         dap_chain_t *l_chain = dap_chain_get_chain_from_group_name(l_net->pub.id, a_group);
-        dap_chain_id_t l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t) {};
+        if (l_chain)  
+            l_chain_id = l_chain ? l_chain->id : (dap_chain_id_t) {};
+
         dap_chain_cell_id_t l_cell_id = l_chain ? l_chain->cells->id : (dap_chain_cell_id_t){};
         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)) {
@@ -523,6 +527,9 @@ static void s_chain_callback_notify(void * a_arg, dap_chain_t *a_chain, dap_chai
             }
         }
         pthread_rwlock_unlock(&PVT(l_net)->rwlock);
+    }else{
+        if (s_debug_more)    
+             log_it(L_WARNING,"Node current state is %d. Real-time syncing is possible when you in NET_STATE_LINKS_ESTABLISHED (and above) state", PVT(l_net)->state);     
     }
 }
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 2fac9a02075bbf23122695ebc39754292544ebf8..dea4554097b2f8f23202d7eff097b8b40b988be0 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2904,10 +2904,40 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
 
     switch(l_type){
         case DAP_CHAIN_DATUM_TOKEN_TYPE_PRIVATE_DECL: { // 256
-            dap_list_t *l_tsd_list = dap_list_alloc();
+            dap_list_t *l_tsd_list = NULL;
             size_t l_tsd_total_size = 0;
             uint16_t l_flags = 0;
             char ** l_str_flags = NULL;
+            dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-signs_total", &l_signs_total_str);
+            // Certificates thats will be used to sign currend datum token
+            dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-certs", &l_certs_str);
+
+            // Check certs list
+            if(!l_certs_str) {
+                dap_chain_node_cli_set_reply_text(a_str_reply, "token_decl requires parameter 'certs'");
+                return -9;
+            }
+
+            // Load certs lists
+            dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count);
+            if(!l_certs_count) {
+                dap_chain_node_cli_set_reply_text(a_str_reply,
+                        "token_decl command requres at least one valid certificate to sign the basic transaction of emission");
+                return -10;
+            }
+
+                        // Signs total
+            if(!l_signs_total_str) {
+                dap_chain_node_cli_set_reply_text(a_str_reply, "token_decl requires parameter 'signs_total'");
+                return -7;
+            } else {
+                char * l_tmp = NULL;
+                if((l_signs_total = (uint16_t) strtol(l_signs_total_str, &l_tmp, 10)) == 0) {
+                    dap_chain_node_cli_set_reply_text(a_str_reply,
+                            "token_create requires parameter 'signs_total' to be unsigned integer value that fits in 2 bytes");
+                    return -8;
+                }
+            }
             l_arg_index++;
             while (l_arg_index<a_argc-1){
                 char * l_arg_param=  a_argv[l_arg_index+1];
@@ -2919,7 +2949,7 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
                              dap_chain_node_cli_set_reply_text(a_str_reply, "Flag can't be \"%s\"",*l_str_flags);
                              return -20;
                          }
-                         l_flags |= (1<<l_flag);
+                         l_flags |= l_flag; // if we have multiple flags
                          l_str_flags++;
                      }
                 } else if ( strcmp( a_argv[l_arg_index],"-total_supply" )==0){ // Total supply
@@ -2927,14 +2957,14 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
                     uint256_t l_param_value = dap_chain_balance_scan(l_arg_param);
                     l_tsd = dap_tsd_create_scalar(
                                     DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_256, l_param_value);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-total_signs_valid" )==0){ // Signs valid
                     uint16_t l_param_value = (uint16_t)atoi(l_arg_param);
                     l_signs_total = l_param_value;
                     dap_tsd_t * l_tsd = dap_tsd_create_scalar(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID, l_param_value);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-signs" )==0){
                     dap_cert_parse_str_list(l_arg_param, &l_certs, &l_certs_count);
@@ -2946,32 +2976,35 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
                 }else if ( strcmp( a_argv[l_arg_index],"-datum_type_allowed" )==0){
                     dap_tsd_t * l_tsd = dap_tsd_create_string(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-datum_type_blocked" )==0){
                     dap_tsd_t * l_tsd = dap_tsd_create_string(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-tx_receiver_allowed" )==0){
-                    dap_tsd_t * l_tsd = dap_tsd_create_string(
-                                                            DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    const char *a_tx_receiver_allowed_base58 = NULL;
+                    dap_chain_node_cli_find_option_val(a_argv, 0, a_argc, "-tx_receiver_allowed", &a_tx_receiver_allowed_base58);
+                    dap_chain_addr_t *addr_to = dap_chain_addr_from_str(a_tx_receiver_allowed_base58);
+                    dap_tsd_t * l_tsd = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, addr_to, sizeof(dap_chain_addr_t));
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
+                    //dap_tsd_t * l_tsd = dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD, a_tx_receiver_allowed_base58);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-tx_receiver_blocked" )==0){
                     dap_tsd_t * l_tsd = dap_tsd_create_string(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-tx_sender_allowed" )==0){
                     dap_tsd_t * l_tsd = dap_tsd_create_string(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else if ( strcmp( a_argv[l_arg_index],"-tx_sender_blocked" )==0){
                     dap_tsd_t * l_tsd = dap_tsd_create_string(
                                                             DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_arg_param);
-                    dap_list_append( l_tsd_list, l_tsd);
+                    l_tsd_list = dap_list_append( l_tsd_list, l_tsd);
                     l_tsd_total_size+= dap_tsd_size( l_tsd);
                 }else {
                     dap_chain_node_cli_set_reply_text(a_str_reply, "Unknown param \"%s\"",a_argv[l_arg_index]);
@@ -3024,8 +3057,7 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
                                dap_tsd_get_string_const(l_tsd) );
                     break;
                     case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD:
-                        log_it(L_DEBUG,"== TX_SENDER_ALLOWED_ADD: %s",
-                                dap_tsd_get_string_const(l_tsd) );
+                        log_it(L_DEBUG,"== TX_RECEIVER_ALLOWED_ADD: binary data");
                     break;
                     case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD:
                         log_it(L_DEBUG,"== TX_SENDER_BLOCKED_ADD: %s",
@@ -3042,6 +3074,8 @@ int com_token_decl(int a_argc, char ** a_argv, char ** a_str_reply)
                     default: log_it(L_DEBUG, "== 0x%04X: binary data %u size ",l_tsd->type, l_tsd->size );
                 }
                 size_t l_tsd_size = dap_tsd_size( l_tsd);
+                //add realloc
+                l_datum_token = DAP_REALLOC(l_datum_token, sizeof(dap_chain_datum_token_t) + l_datum_data_offset + l_tsd_size);
                 memcpy(l_datum_token->data_n_tsd + l_datum_data_offset, l_tsd, l_tsd_size);
                 l_datum_token->header_private_decl.tsd_total_size += l_tsd_size;
                 l_datum_data_offset += l_tsd_size;