diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index 541df35a7c1c81592d84e82686a168744a664f4c..bf81b508e04906f091429f44ea332ef9b5b50ee4 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -159,7 +159,9 @@ void dap_chain_delete(dap_chain_t * a_chain)
        log_it(L_WARNING,"Trying to remove non-existent 0x%16llX:0x%16llX chain",a_chain->id.uint64,
               a_chain->net_id.uint64);
     a_chain->datum_types_count = 0;
-    DAP_DELETE (a_chain->datum_types);
+    DAP_DELETE(a_chain->datum_types);
+    a_chain->autoproc_datum_types_count = 0;
+    DAP_DELETE(a_chain->autoproc_datum_types);
     pthread_rwlock_unlock(&s_chain_items_rwlock);
 }
 
@@ -187,6 +189,48 @@ dap_chain_t * dap_chain_find_by_id(dap_chain_net_id_t a_chain_net_id,dap_chain_i
         return NULL;
 }
 
+static dap_chain_type_t s_chain_type_from_str(const char *a_type_str)
+{
+    if(!dap_strcmp(a_type_str, "token")) {
+        return CHAIN_TYPE_TOKEN;
+    }
+    if(!dap_strcmp(a_type_str, "emission")) {
+        return CHAIN_TYPE_EMISSION;
+    }
+    if(!dap_strcmp(a_type_str, "transaction")) {
+        return CHAIN_TYPE_TX;
+    }
+    return CHAIN_TYPE_LAST;
+}
+
+static uint16_t s_datum_type_from_str(const char *a_type_str)
+{
+    if(!dap_strcmp(a_type_str, "token")) {
+        return DAP_CHAIN_DATUM_TOKEN_DECL;
+    }
+    if(!dap_strcmp(a_type_str, "emission")) {
+        return DAP_CHAIN_DATUM_TOKEN_EMISSION;
+    }
+    if(!dap_strcmp(a_type_str, "transaction")) {
+        return DAP_CHAIN_DATUM_TX;
+    }
+    return DAP_CHAIN_DATUM_CUSTOM;
+}
+
+static uint16_t s_chain_type_convert(dap_chain_type_t a_type)
+{
+    switch (a_type) {
+    case CHAIN_TYPE_TOKEN:
+        return DAP_CHAIN_DATUM_TOKEN_DECL;
+    case CHAIN_TYPE_EMISSION:
+        return DAP_CHAIN_DATUM_TOKEN_EMISSION;
+    case CHAIN_TYPE_TX:
+        return DAP_CHAIN_DATUM_TX;
+    default:
+        return DAP_CHAIN_DATUM_CUSTOM;
+    }
+}
+
 /**
  * @brief dap_chain_load_from_cfg
  * @param a_chain_net_name
@@ -236,15 +280,6 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha
                 return NULL;
             }
 
-            // Read chain datum types
-            char** l_datum_types = NULL;
-            uint16_t l_datum_types_count = 0;
-            if((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "datum_types", &l_datum_types_count)) == NULL) {
-                log_it(L_WARNING, "Can't read chain datum types ", l_chain_id_str);
-                //dap_config_close(l_cfg);
-                //return NULL;
-            }
-
             l_chain =  dap_chain_create(a_ledger,a_chain_net_name,l_chain_name, a_chain_net_id,l_chain_id);
             if ( dap_chain_cs_create(l_chain, l_cfg) == 0 ) {
                 log_it (L_NOTICE,"Consensus initialized for chain id 0x%016llX",
@@ -271,27 +306,51 @@ dap_chain_t * dap_chain_load_from_cfg(dap_ledger_t* a_ledger, const char * a_cha
                 dap_chain_delete(l_chain);
                 l_chain = NULL;
             }
+            // Read chain datum types
+            char** l_datum_types = NULL;
+            uint16_t l_datum_types_count = 0;
+            if((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "datum_types", &l_datum_types_count)) == NULL) {
+                log_it(L_WARNING, "Can't read chain datum types ", l_chain_id_str);
+                //dap_config_close(l_cfg);
+                //return NULL;
+            }
             // add datum types
             if(l_chain && l_datum_types_count > 0) {
                 l_chain->datum_types = DAP_NEW_SIZE(dap_chain_type_t, l_datum_types_count * sizeof(dap_chain_type_t));
                 uint16_t l_count_recognized = 0;
                 for(uint16_t i = 0; i < l_datum_types_count; i++) {
-                    if(!dap_strcmp(l_datum_types[i], "token")) {
-                        l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_TOKEN;
+                    dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]);
+                    if (l_chain_type != CHAIN_TYPE_LAST) {
+                        l_chain->datum_types[l_count_recognized] = l_chain_type;
                         l_count_recognized++;
                     }
-                    else if(!dap_strcmp(l_datum_types[i], "emission")) {
-                        l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_EMISSION;
-                        l_count_recognized++;
+                }
+                l_chain->datum_types_count = l_count_recognized;
+            }
+            if((l_datum_types = dap_config_get_array_str(l_cfg, "chain", "mempool_auto_types", &l_datum_types_count)) == NULL) {
+                log_it(L_WARNING, "Can't read chain mempool auto types ", l_chain_id_str);
+            }
+            // add datum types
+            if(l_chain && l_datum_types_count) {
+                l_chain->autoproc_datum_types = DAP_NEW_SIZE(uint16_t, l_datum_types_count * sizeof(uint16_t));
+                uint16_t l_count_recognized = 0;
+                for(uint16_t i = 0; i < l_datum_types_count; i++) {
+                    if (!strcmp(l_datum_types[i], "all")) {
+                        l_chain->autoproc_datum_types = DAP_REALLOC(l_chain->autoproc_datum_types, l_chain->datum_types_count * sizeof(uint16_t));
+                        for (int j = 0; j < l_chain->datum_types_count; j++) {
+                            l_chain->autoproc_datum_types[j] = s_chain_type_convert(l_chain->datum_types[j]);
+                        }
+                        l_count_recognized = l_chain->datum_types_count;
+                        break;
                     }
-                    else if(!dap_strcmp(l_datum_types[i], "transaction")) {
-                        l_chain->datum_types[l_count_recognized] = CHAIN_TYPE_TX;
+                    uint16_t l_chain_type = s_datum_type_from_str(l_datum_types[i]);
+                    if (l_chain_type != DAP_CHAIN_DATUM_CUSTOM) {
+                        l_chain->autoproc_datum_types[l_count_recognized] = l_chain_type;
                         l_count_recognized++;
                     }
                 }
-                l_chain->datum_types_count = l_count_recognized;
+                l_chain->autoproc_datum_types_count = l_count_recognized;
             }
-
             dap_config_close(l_cfg);
             return l_chain;
         }else
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 8634ef4e112769e2b6b1e2cfe9657c2c2b1bc907..2556d2e9b41b5aa857ad75b36f858a80a5f5e84a 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -100,6 +100,8 @@ typedef struct dap_chain{
 
     uint16_t datum_types_count;
     dap_chain_type_t *datum_types;
+    uint16_t autoproc_datum_types_count;
+    uint16_t *autoproc_datum_types;
 
     // To hold it in double-linked lists
     struct dap_chain * next;
diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c
index bcdfbdd0f1c67d1190358a8197d28d25ee588678..983c394edf84f5fff53722dbcda1a55de234ba68 100644
--- a/modules/net/dap_chain_node.c
+++ b/modules/net/dap_chain_node.c
@@ -239,7 +239,7 @@ dap_chain_node_info_t* dap_chain_node_info_read( dap_chain_net_t * a_net,dap_cha
     return node_info;
 }*/
 
-int dap_chain_node_mempool_process(dap_chain_t *a_chain)
+int dap_chain_node_mempool_process(dap_chain_t *a_chain, dap_chain_node_role_t a_role)
 {
     char *l_gdb_group_mempool = NULL;
     if (!a_chain) {
@@ -251,8 +251,28 @@ int dap_chain_node_mempool_process(dap_chain_t *a_chain)
     if (l_objs_size) {
         for (size_t i = 0; i < l_objs_size; i++) {
             dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value;
-            if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX) {
+            bool l_need_process = false;
+            for (uint16_t j = 0; j < a_chain->autoproc_datum_types_count; j++) {
+                if (l_datum->header.type_id == a_chain->autoproc_datum_types[j]) {
+                    l_need_process = true;
+                    break;
+                }
+            }
+            if (!l_need_process)
                 continue;
+            if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX) {
+                dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
+                dap_chain_tx_in_t *l_tx_in = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(l_tx, NULL, TX_ITEM_TYPE_IN, NULL);
+                // Is it a base transaction?
+                if (dap_hash_fast_is_blank(&l_tx_in->header.tx_prev_hash)) {
+                    dap_chain_tx_token_t *l_tx_token = (dap_chain_tx_token_t *)dap_chain_datum_tx_item_get(l_tx, NULL, TX_ITEM_TYPE_TOKEN, NULL);
+                    if (l_tx_token && !dap_chain_ledger_token_emission_find(a_chain->ledger, l_tx_token->header.ticker,
+                                                                            &l_tx_token->header.token_emission_hash)) {
+                        continue;
+                    }
+                } else if (a_role.enums == NODE_ROLE_ROOT) {
+                        continue;
+                }
             }
             if (a_chain->callback_datums_pool_proc(a_chain, &l_datum, 1) != 1) {
                 continue;
@@ -268,11 +288,11 @@ int dap_chain_node_mempool_process(dap_chain_t *a_chain)
 void dap_chain_node_mempool_periodic(void *a_param)
 {
     UNUSED(a_param);
-    size_t l_net_count;
+    uint16_t l_net_count;
     bool l_mempool_auto;
     bool l_mempool_auto_default = false;
     dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count);
-    for (int i = 0; i < l_net_count; i++) {
+    for (uint16_t i = 0; i < l_net_count; i++) {
         dap_chain_node_role_t l_role = dap_chain_net_get_role(l_net_list[i]);
 
         switch (l_role.enums) {
@@ -290,11 +310,7 @@ void dap_chain_node_mempool_periodic(void *a_param)
         if (l_mempool_auto) {
             dap_chain_t *l_chain;
             DL_FOREACH(l_net_list[i]->pub.chains, l_chain) {
-                for (uint16_t i = 0; i < l_chain->datum_types_count; i++) {
-                    if (l_chain->datum_types[i] == CHAIN_TYPE_TX) {
-                        dap_chain_node_mempool_process(l_chain);
-                    }
-                }
+                dap_chain_node_mempool_process(l_chain, l_role);
             }
         }
     }
diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h
index 1e5f0b6d7f4fe06e8c98923151ca79c10a256ea5..78931e2864782a8b0b015598f505bda2635dc3b0 100644
--- a/modules/net/include/dap_chain_node.h
+++ b/modules/net/include/dap_chain_node.h
@@ -141,6 +141,6 @@ inline static char* dap_chain_node_addr_to_hash_str(dap_chain_node_addr_t *addre
     return a_key;
 }
 
-int dap_chain_node_mempool_process(dap_chain_t *a_chain);
+int dap_chain_node_mempool_process(dap_chain_t *a_chain, dap_chain_node_role_t a_role);
 int dap_chain_node_mempool_init();
 void dap_chain_node_mempool_deinit();