diff --git a/dap_chain_mempool.c b/dap_chain_mempool.c
index 2f397ba917b79e6c7e96faf31a4bceaca0ec96bd..f51bac321c2fc72d17220e0c9b0420edb8a6105e 100755
--- a/dap_chain_mempool.c
+++ b/dap_chain_mempool.c
@@ -9,19 +9,19 @@
 
  This file is part of DAP (Deus Applications Prototypes) the open source project
 
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
+ DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ DAP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+ */
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
@@ -62,19 +62,17 @@ typedef struct list_used_item {
     int num_idx_out;
     uint64_t value;
 
-    //dap_chain_tx_out_t *tx_out;
+//dap_chain_tx_out_t *tx_out;
 } list_used_item_t;
 
 const char* c_dap_datum_mempool_gdb_group = NULL;
 
-
 int dap_datum_mempool_init()
 {
-    c_dap_datum_mempool_gdb_group = dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool");
+    c_dap_datum_mempool_gdb_group = dap_config_get_item_str_default(g_config, "mempool", "gdb_group", "datum-pool");
     return 0;
 }
 
-
 /**
  * @brief dap_chain_mempool_datum_add
  * @param a_datum
@@ -82,19 +80,18 @@ int dap_datum_mempool_init()
  */
 int dap_chain_mempool_datum_add(dap_chain_datum_t * a_datum)
 {
-   return 0;
+    return 0;
 }
 
-
 /**
  * Make transfer transaction & insert to cache
  *
- * return 1 Ok, 0 not enough funds to transfer, -1 other Error
+ * return 0 Ok, -2 not enough funds to transfer, -1 other Error
  */
 int dap_chain_mempool_tx_create(dap_enc_key_t *a_key_from,
         const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_to,
-                                const dap_chain_addr_t* a_addr_fee,
-                                const char a_token_ticker[10],
+        const dap_chain_addr_t* a_addr_fee,
+        const char a_token_ticker[10],
         uint64_t a_value, uint64_t a_value_fee)
 {
     // check valid param
@@ -137,7 +134,7 @@ int dap_chain_mempool_tx_create(dap_enc_key_t *a_key_from,
                         l_list_used_out = dap_list_append(l_list_used_out, item);
                         l_value_transfer += item->value;
                         // already accumulated the required value, finish the search for 'out' items
-                        if(l_value_transfer >= l_value_need){
+                        if(l_value_transfer >= l_value_need) {
                             break;
                         }
                     }
@@ -152,7 +149,7 @@ int dap_chain_mempool_tx_create(dap_enc_key_t *a_key_from,
         // nothing to tranfer (not enough funds)
         if(!l_list_used_out || l_value_transfer < l_value_need) {
             dap_list_free_full(l_list_used_out, free);
-            return 0;
+            return -2;
         }
     }
 
@@ -199,26 +196,157 @@ int dap_chain_mempool_tx_create(dap_enc_key_t *a_key_from,
         return -1;
     }
 
+    size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
+    dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, l_tx_size);
+
+    dap_chain_hash_fast_t l_key_hash;
+    dap_hash_fast(l_tx, l_tx_size, &l_key_hash);
+    DAP_DELETE(l_tx);
+
+    char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
+    if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, dap_chain_datum_data_size(l_datum)
+            , c_dap_datum_mempool_gdb_group)) {
+        log_it(L_NOTICE, "Transaction %s placed in mempool", l_key_str);
+        // add transaction to utxo
+        if(dap_chain_utxo_tx_add((dap_chain_datum_tx_t*) l_datum->data)<0)
+            log_it(L_ERROR, "Transaction %s not placed in UTXO", l_key_str);
+    }
+    DAP_DELETE(l_key_str);
+
+    return 0;
+}
+
+/**
+ * Make transfer transaction & insert to cache
+ *
+ * return 1 Ok, 0 not enough funds to transfer, -1 other Error
+ */
+int dap_chain_mempool_tx_create_cond(dap_enc_key_t *a_key_from, dap_enc_key_t *a_key_cond,
+        const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_cond,
+        const dap_chain_addr_t* a_addr_fee, const char a_token_ticker[10],
+        uint64_t a_value, uint64_t a_value_fee, const void *a_cond, size_t a_cond_size)
+{
+    // check valid param
+    if(!a_key_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
+            !dap_chain_addr_check_sum(a_addr_from) || !dap_chain_addr_check_sum(a_addr_cond) ||
+            (a_addr_fee && !dap_chain_addr_check_sum(a_addr_fee)) || !a_value)
+        return -1;
+
+    // find the transactions from which to take away coins
+    dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
+    uint64_t l_value_transfer = 0; // how many coins to transfer
+    {
+        dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
+        uint64_t l_value_need = a_value + a_value_fee;
+        while(l_value_transfer < l_value_need)
+        {
+            // Get the transaction in the cache by the addr in out item
+            const dap_chain_datum_tx_t *l_tx = dap_chain_utxo_tx_find_by_addr(a_addr_from,
+                    &l_tx_cur_hash);
+            if(!l_tx)
+                break;
+            // Get all item from transaction by type
+            int l_item_count = 0;
+            dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) l_tx, TX_ITEM_TYPE_OUT,
+                    &l_item_count);
+            dap_list_t *l_list_tmp = l_list_out_items;
+            int l_out_idx_tmp = 0; // current index of 'out' item
+            while(l_list_tmp) {
+                dap_chain_tx_out_t *out_item = l_list_tmp->data;
+                // if 'out' item has addr = a_addr_from
+                if(out_item && &out_item->addr && !memcmp(a_addr_from, &out_item->addr, sizeof(dap_chain_addr_t))) {
+
+                    // Check whether used 'out' items
+                    if(!dap_chain_utxo_tx_hash_is_used_out_item(&l_tx_cur_hash, l_out_idx_tmp)) {
+
+                        list_used_item_t *item = DAP_NEW(list_used_item_t);
+                        memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t));
+                        item->num_idx_out = l_out_idx_tmp;
+                        item->value = out_item->header.value;
+                        l_list_used_out = dap_list_append(l_list_used_out, item);
+                        l_value_transfer += item->value;
+                        // already accumulated the required value, finish the search for 'out' items
+                        if(l_value_transfer >= l_value_need) {
+                            break;
+                        }
+                    }
+                }
+                // go to the next 'out' item in l_tx transaction
+                l_out_idx_tmp++;
+                l_list_tmp = dap_list_next(l_list_tmp);
+            }
+            dap_list_free(l_list_out_items);
+        }
+
+        // nothing to tranfer (not enough funds)
+        if(!l_list_used_out || l_value_transfer < l_value_need) {
+            dap_list_free_full(l_list_used_out, free);
+            return 0;
+        }
+    }
+
+    // create empty transaction
+    dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create();
+    // add 'in' items
+    {
+        dap_list_t *l_list_tmp = l_list_used_out;
+        uint64_t l_value_to_items = 0; // how many coins to transfer
+        while(l_list_tmp) {
+            list_used_item_t *item = l_list_tmp->data;
+            if(dap_chain_datum_tx_add_in_item(&l_tx, &item->tx_hash_fast, item->num_idx_out) == 1) {
+                l_value_to_items += item->value;
+            }
+            l_list_tmp = dap_list_next(l_list_tmp);
+        }
+        assert(l_value_to_items == l_value_transfer);
+        dap_list_free_full(l_list_used_out, free);
+    }
+    // add 'out_cond' and 'out' items
+    {
+        uint64_t l_value_pack = 0; // how much coin add to 'out' items
+        if(dap_chain_datum_tx_add_out_cond_item(&l_tx, a_key_cond, a_addr_cond, a_value, a_cond, a_cond_size) == 1) {
+            l_value_pack += a_value;
+            // transaction fee
+            if(a_addr_fee) {
+                if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_fee, a_value_fee) == 1)
+                    l_value_pack += a_value_fee;
+            }
+        }
+        // coin back
+        uint64_t l_value_back = l_value_transfer - l_value_pack;
+        if(l_value_back) {
+            if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_from, l_value_back) != 1) {
+                dap_chain_datum_tx_delete(l_tx);
+                return -1;
+            }
+        }
+    }
+
+    // add 'sign' items
+    if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_from) != 1) {
+        dap_chain_datum_tx_delete(l_tx);
+        return -1;
+    }
+
     size_t l_datum_data_size = dap_chain_datum_tx_get_size(l_tx);
-    dap_chain_datum_t * l_datum = DAP_NEW_Z_SIZE(dap_chain_datum_t, sizeof(l_datum->header) + l_datum_data_size );
-    memcpy (l_datum->data, l_tx, l_datum_data_size);
+    dap_chain_datum_t * l_datum = DAP_NEW_Z_SIZE(dap_chain_datum_t, sizeof(l_datum->header) + l_datum_data_size);
+    memcpy(l_datum->data, l_tx, l_datum_data_size);
     l_datum->header.data_size = l_datum_data_size;
     l_datum->header.version_id = DAP_CHAIN_DATUM_VERSION;
     DAP_DELETE(l_tx);
 
     dap_chain_hash_fast_t l_key_hash;
-    dap_hash_fast(l_datum,l_datum_data_size+sizeof(l_datum->header),&l_key_hash);
+    dap_hash_fast(l_datum, l_datum_data_size + sizeof(l_datum->header), &l_key_hash);
     char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash);
-    if(dap_chain_global_db_gr_set(l_key_str,(uint8_t *) l_datum, l_datum_data_size
-                                  , c_dap_datum_mempool_gdb_group)) {
-        log_it (L_NOTICE, "Transaction %s placed in mempool",l_key_str);
+    if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, l_datum_data_size
+            , c_dap_datum_mempool_gdb_group)) {
+        log_it(L_NOTICE, "Transaction %s placed in mempool", l_key_str);
     }
-    DAP_DELETE( l_key_str );
+    DAP_DELETE(l_key_str);
 
     return 0;
 }
 
-
 uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size)
 {
     size_t a_request_size = 2 * sizeof(uint16_t), shift_size = 0;
@@ -389,7 +517,7 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg)
                     //a_value = DAP_NEW_Z_SIZE(char, request_size * 2);
                     //bin2hex((char*) a_value, (const unsigned char*) request_str, request_size);
                     if(dap_chain_global_db_gr_set(a_key, request_str, request_size,
-                                                  dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" )  )) {
+                            dap_config_get_item_str_default(g_config, "mempool", "gdb_group", "datum-pool"))) {
                         *return_code = Http_Status_OK;
                     }
                     log_it(L_INFO, "Insert hash: key=%s result:%s", a_key,
@@ -400,7 +528,8 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg)
                 case DAP_DATUM_MEMPOOL_CHECK: // check datum in base
 
                     strcpy(cl_st->reply_mime, "text/text");
-                    char *str = dap_chain_global_db_gr_get((const char*) a_key, NULL,dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" ));
+                    char *str = dap_chain_global_db_gr_get((const char*) a_key, NULL,
+                            dap_config_get_item_str_default(g_config, "mempool", "gdb_group", "datum-pool"));
                     if(str) {
                         dg->response = strdup("1");
                         DAP_DELETE(str);
@@ -418,7 +547,8 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg)
 
                 case DAP_DATUM_MEMPOOL_DEL: // delete datum in base
                     strcpy(cl_st->reply_mime, "text/text");
-                    if(dap_chain_global_db_gr_del( ((const char*) a_key),dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" )) ) {
+                    if(dap_chain_global_db_gr_del(((const char*) a_key),
+                            dap_config_get_item_str_default(g_config, "mempool", "gdb_group", "datum-pool"))) {
                         dg->response = strdup("1");
                         DAP_DELETE(str);
                         log_it(L_INFO, "Delete hash: key=%s result: Ok", a_key);