diff --git a/dap-sdk b/dap-sdk
index d6ff75b22f70b79af1b54ee8d5da03252c8d599a..d3ce46e3c991bc58d97c951c2c731bd3eed9ca6f 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit d6ff75b22f70b79af1b54ee8d5da03252c8d599a
+Subproject commit d3ce46e3c991bc58d97c951c2c731bd3eed9ca6f
diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c
index 782c239dfa0a3679c9791978520e026f134c0673..e27960b2e989a47d177ec1b9f248e60a32513d3e 100644
--- a/modules/common/dap_chain_datum_tx_items.c
+++ b/modules/common/dap_chain_datum_tx_items.c
@@ -47,7 +47,7 @@ static size_t dap_chain_tx_in_cond_get_size(const dap_chain_tx_in_cond_t *a_item
     return size;
 }
 
-static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_old_t *a_item)
+static size_t dap_chain_tx_out_old_get_size(const dap_chain_tx_out_old_t *a_item)
 {
     (void) a_item;
     size_t size = sizeof(dap_chain_tx_out_old_t);
@@ -55,7 +55,7 @@ static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_old_t *a_item)
 }
 
 // 256
-static size_t dap_chain_256_tx_out_get_size(const dap_chain_tx_out_t *a_item)
+static size_t dap_chain_tx_out_get_size(const dap_chain_tx_out_t *a_item)
 {
     (void) a_item;
     size_t size = sizeof(dap_chain_tx_out_t);
@@ -193,10 +193,10 @@ size_t dap_chain_datum_item_tx_get_size(const void *a_item)
         size = dap_chain_tx_in_get_size((const dap_chain_tx_in_t*) a_item);
         break;
     case TX_ITEM_TYPE_OUT_OLD: //64
-        size = dap_chain_tx_out_get_size((const dap_chain_tx_out_old_t*) a_item);
+        size = dap_chain_tx_out_old_get_size((const dap_chain_tx_out_old_t*) a_item);
         break;
     case TX_ITEM_TYPE_OUT: // Transaction outputs
-        size = dap_chain_256_tx_out_get_size((const dap_chain_tx_out_t*) a_item);
+        size = dap_chain_tx_out_get_size((const dap_chain_tx_out_t*) a_item);
         break;
     case TX_ITEM_TYPE_OUT_EXT: // Exchange transaction outputs
         size = dap_chain_tx_out_ext_get_size((const dap_chain_tx_out_ext_t*) a_item);
@@ -574,11 +574,14 @@ json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_o
 }
 
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value,
-                                                                           dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr)
+                                                                           dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr,
+                                                                           dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax)
 {
     if (IS_ZERO_256(a_value))
         return NULL;
-    dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z(dap_chain_tx_out_cond_t);
+    size_t l_tsd_total_size = a_sovereign_addr && !dap_chain_addr_is_blank(a_sovereign_addr) ?
+                sizeof(dap_tsd_t) * 2 + sizeof(*a_sovereign_addr) + sizeof(a_sovereign_tax) : 0;
+    dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + l_tsd_total_size);
     if (!l_item) {
         return NULL;
     }
@@ -588,6 +591,11 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c
     l_item->header.srv_uid = a_srv_uid;
     l_item->subtype.srv_stake_pos_delegate.signing_addr = *a_signing_addr;
     l_item->subtype.srv_stake_pos_delegate.signer_node_addr = *a_signer_node_addr;
+    if (a_sovereign_addr) {
+        l_item->tsd_size = l_tsd_total_size;
+        byte_t *l_next_tsd_ptr = dap_tsd_write(l_item->tsd, DAP_CHAIN_TX_OUT_COND_TSD_ADDR, a_sovereign_addr, sizeof(*a_sovereign_addr));
+        dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_VALUE, &a_sovereign_tax, sizeof(a_sovereign_tax));
+    }
     return l_item;
 }
 
diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h
index 9d31a756c3cd548f28d3453e16b32d03662e83df..c646a3b4990b2aba060336faf78f1b870c0f7707 100644
--- a/modules/common/include/dap_chain_datum_tx_items.h
+++ b/modules/common/include/dap_chain_datum_tx_items.h
@@ -189,7 +189,8 @@ json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_o
  * return item, NULL Error
  */
 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value,
-                                                                               dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr);
+                                                                           dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr,
+                                                                           dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax);
 
 json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake);
 
diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h
index 94fdd48b6cf4a3502789e7cd3c1e0b1523ec6077..77ae1149364f749fcf2f5dca60df2247bd695e27 100644
--- a/modules/common/include/dap_chain_datum_tx_out_cond.h
+++ b/modules/common/include/dap_chain_datum_tx_out_cond.h
@@ -61,6 +61,12 @@ DAP_STATIC_INLINE const char *dap_chain_tx_out_cond_subtype_to_str(dap_chain_tx_
 // Emit with single lock TX
 #define DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_EMIT              0x00000020
 
+/// Conditional ouptput TSD types
+// 256-bit value
+#define DAP_CHAIN_TX_OUT_COND_TSD_VALUE                     0xf000
+// Cahin wallet address
+#define DAP_CHAIN_TX_OUT_COND_TSD_ADDR                      0xf001
+
 /**
  * @struct dap_chain_tx_out
  * @brief Transaction item out_cond
diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
index 9cb9695fea063368c5eee50cbfb3d5c6432f7dfd..5ad77a015b7156141c62dc06576740649e0c64dc 100644
--- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c
+++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c
@@ -519,9 +519,37 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf
     return 0;
 }
 
-bool dap_chain_esbocs_started()
+bool dap_chain_esbocs_started(dap_chain_net_id_t a_net_id)
 {
-    return s_session_items;
+    dap_chain_esbocs_session_t *l_session;
+    DL_FOREACH(s_session_items, l_session) {
+        if (l_session->chain->net_id.uint64 == a_net_id.uint64 &&
+                l_session->esbocs && l_session->esbocs->_pvt)
+            return true;
+    }
+    return false;
+}
+
+dap_pkey_t *dap_chain_esbocs_get_sign_pkey(dap_chain_net_id_t a_net_id)
+{
+    dap_chain_esbocs_session_t *l_session;
+    DL_FOREACH(s_session_items, l_session) {
+        if (l_session->chain->net_id.uint64 == a_net_id.uint64 &&
+                l_session->esbocs && l_session->esbocs->_pvt)
+            return PVT(l_session->esbocs)->block_sign_pkey;
+    }
+    return NULL;
+}
+
+uint256_t dap_chain_esbocs_get_fee(dap_chain_net_id_t a_net_id)
+{
+    dap_chain_esbocs_session_t *l_session;
+    DL_FOREACH(s_session_items, l_session) {
+        if (l_session->chain->net_id.uint64 == a_net_id.uint64 &&
+                l_session->esbocs && l_session->esbocs->_pvt)
+            return PVT(l_session->esbocs)->minimum_fee;
+    }
+    return uint256_0;
 }
 
 void dap_chain_esbocs_stop_timer(dap_chain_net_id_t a_net_id)
diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
index fb23fe97a9617a75ef0185b5041f14f6a035fa8b..0f9d9a554427bde03e0d537a2f06e3d7febe0bd8 100644
--- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
+++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h
@@ -212,3 +212,5 @@ bool dap_chain_esbocs_started();
 
 void dap_chain_esbocs_stop_timer(dap_chain_net_id_t a_net_id);
 void dap_chain_esbocs_start_timer(dap_chain_net_id_t a_net_id);
+dap_pkey_t *dap_chain_esbocs_get_sign_pkey(dap_chain_net_id_t a_net_id);
+uint256_t dap_chain_esbocs_get_fee(dap_chain_net_id_t a_net_id);
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index b27a585e03ed8da7f3cd392695c43bbaada41529..4d0e37e3182baf620964c234a7cf177c36c842ae 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -65,6 +65,7 @@
 #include "dap_chain_datum_tx_items.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_cs_blocks.h"
+#include "dap_chain_net_srv_stake_pos_delegate.h"
 
 #include "dap_chain_mempool_rpc.h"
 
@@ -344,6 +345,10 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_
         }
         SUM_256_256(l_value_out, l_value_out_block, &l_value_out);
     }
+    dap_hash_fast_t l_sign_pkey_hash;
+    dap_hash_fast(l_sign_pkey->pkey, l_sign_pkey->header.size, &l_sign_pkey_hash);
+    DAP_DELETE(l_sign_pkey);
+
     //add 'fee' items
     {
         uint256_t l_value_pack = {};
@@ -367,21 +372,39 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_
                 return NULL;
             }
         }
-        if(compare256(l_value_out,l_value_pack)!=-1)
-            SUBTRACT_256_256(l_value_out,l_value_pack,&l_value_out);
-        else
-        {
+        if (compare256(l_value_out, l_value_pack) == 1)
+            SUBTRACT_256_256(l_value_out, l_value_pack, &l_value_out);
+        else {
             log_it(L_WARNING, "The transaction fee is greater than the sum of the block fees");
             dap_chain_datum_tx_delete(l_tx);
             return NULL;
         }
     }
 
+    // Check and apply sovereign tax for this key
+    uint256_t l_value_tax = {};
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
+    if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
+                dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
+        MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
+        if (compare256(l_value_tax, l_value_out) < 1)
+            SUBTRACT_256_256(l_value_out, l_value_tax, &l_value_out);
+    }
+
     //add 'out' items
-    if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) {
-        dap_chain_datum_tx_delete(l_tx);
-        log_it(L_WARNING, "Can't create out item in transaction fee");
-        return NULL;
+    if (!IS_ZERO_256(l_value_out)) {
+        if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) {
+            dap_chain_datum_tx_delete(l_tx);
+            log_it(L_WARNING, "Can't create out item in transaction fee");
+            return NULL;
+        }
+    }
+    if (!IS_ZERO_256(l_value_tax)) {
+        if (dap_chain_datum_tx_add_out_item(&l_tx, &l_key_item->sovereign_addr, l_value_tax) != 1) {
+            dap_chain_datum_tx_delete(l_tx);
+            log_it(L_WARNING, "Can't create out item in transaction fee");
+            return NULL;
+        }
     }
 
     // add 'sign' items
@@ -487,11 +510,29 @@ char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_en
         dap_chain_datum_tx_delete(l_tx);
         return NULL;
     }
-    //add 'out' item
-    if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) {
-        dap_chain_datum_tx_delete(l_tx);
-        log_it(L_WARNING, "Can't create out item in transaction fee");
-        return NULL;
+    // Check and apply sovereign tax for this key
+    uint256_t l_value_tax = {};
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
+    if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
+                dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
+        MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
+        if (compare256(l_value_tax, l_value_out) < 1)
+            SUBTRACT_256_256(l_value_out, l_value_tax, &l_value_out);
+    }
+    //add 'out' items
+    if (!IS_ZERO_256(l_value_out)) {
+        if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, l_value_out) != 1) {
+            dap_chain_datum_tx_delete(l_tx);
+            log_it(L_WARNING, "Can't create out item in transaction fee");
+            return NULL;
+        }
+    }
+    if (!IS_ZERO_256(l_value_tax)) {
+        if (dap_chain_datum_tx_add_out_item(&l_tx, &l_key_item->sovereign_addr, l_value_tax) != 1) {
+            dap_chain_datum_tx_delete(l_tx);
+            log_it(L_WARNING, "Can't create out item in transaction fee");
+            return NULL;
+        }
     }
     // add 'sign' item
     if(dap_chain_datum_tx_add_sign_item(&l_tx, a_sign_key) != 1) {
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index 366908e66e011234333d2d79bda79f802b560692..7a36a6408add968ef4acabbe6a341837c3a6fe59 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -56,7 +56,7 @@
 #include "json.h"
 #include "json_object.h"
 #include "dap_notify_srv.h"
-
+#include "dap_chain_net_srv_stake_pos_delegate.h"
 
 #define LOG_TAG "dap_ledger"
 
@@ -3465,6 +3465,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
     dap_chain_hash_fast_t l_tx_first_sign_pkey_hash = {};
     dap_pkey_t *l_tx_first_sign_pkey = NULL;
     bool l_girdled_ems_used = false;
+    uint256_t l_taxed_value = {};
 
     // find all previous transactions
     for (dap_list_t *it = l_list_in; it; it = it->next) {
@@ -3736,6 +3737,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
             }
             l_bound_item->token_item = l_token_item;
             l_bound_item->reward_key = l_search_key;
+            // Overflow checked later with overall values sum
+            SUM_256_256(l_taxed_value, l_value, &l_taxed_value);
         } break;
 
         case TX_ITEM_TYPE_IN:
@@ -3819,7 +3822,17 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                 l_err_num = DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND;
                 break;
             }
-
+            if (dap_hash_fast_is_blank(&l_tx_first_sign_pkey_hash)) {
+                // Get sign item
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
+                        TX_ITEM_TYPE_SIG, NULL);
+                assert(l_tx_sig);
+                // Get sign from sign item
+                dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
+                assert(l_tx_first_sign);
+                // calculate hash from sign public key
+                dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash);
+            }
             if (l_cond_type == TX_ITEM_TYPE_IN) {
                 dap_chain_addr_t *l_addr_from = NULL;
                 dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_prev_out;
@@ -3846,17 +3859,6 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                 l_bound_item->in.addr_from = *l_addr_from;
                 strncpy(l_bound_item->in.token_ticker, l_token, DAP_CHAIN_TICKER_SIZE_MAX - 1);
                 // 4. compare public key hashes in the signature of the current transaction and in the 'out' item of the previous transaction
-                if (dap_hash_fast_is_blank(&l_tx_first_sign_pkey_hash)) {
-                    // Get sign item
-                    dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(a_tx, NULL,
-                            TX_ITEM_TYPE_SIG, NULL);
-                    assert(l_tx_sig);
-                    // Get sign from sign item
-                    dap_sign_t *l_tx_first_sign = dap_chain_datum_tx_item_sign_get_sig(l_tx_sig);
-                    assert(l_tx_first_sign);
-                    // calculate hash from sign public key
-                    dap_sign_get_pkey_hash(l_tx_first_sign, &l_tx_first_sign_pkey_hash);
-                }
                 if (!dap_hash_fast_compare(&l_tx_first_sign_pkey_hash, &l_addr_from->data.hash_fast)) {
                     l_err_num = DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH;
                     break;
@@ -3912,9 +3914,6 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
 
                 dap_chain_tx_out_cond_t *l_tx_prev_out_cond = NULL;
                 l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out;
-                if (l_tx_prev_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
-                    l_token = a_ledger->net->pub.native_ticker;
-                l_main_ticker = l_token;
                 bool l_owner = false;
                 l_owner = dap_sign_match_pkey_signs(l_prev_sign, l_sign);
 
@@ -3938,6 +3937,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
                 }
                 l_bound_item->cond = l_tx_prev_out_cond;
                 l_value = l_tx_prev_out_cond->header.value;
+                if (l_tx_prev_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) {
+                    l_token = a_ledger->net->pub.native_ticker;
+                    // Overflow checked later with overall values sum
+                    SUM_256_256(l_taxed_value, l_value, &l_taxed_value);
+                }
+                l_main_ticker = l_token;
             }
         } break;
 
@@ -3969,7 +3974,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
             HASH_ADD_STR(l_values_from_prev_tx, token_ticker, l_value_cur);
         }
         // calculate  from previous transactions per each token
-        SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum);
+        if (SUM_256_256(l_value_cur->sum, l_value, &l_value_cur->sum)) {
+            debug_if(s_debug_more, L_WARNING, "Sum result overflow for tx_add_check with ticker %s",
+                                    l_value_cur->token_ticker);
+            l_err_num = -88;
+            break;
+        }
     }
 
     if (l_list_in)
@@ -4016,9 +4026,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
         HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur);
     }
 
+    dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_tx_first_sign_pkey_hash);
+    bool l_tax_check = !dap_chain_addr_is_blank(&l_key_item->sovereign_addr) && !IS_ZERO_256(l_key_item->sovereign_tax);
+
     // find 'out' items
     dap_list_t *l_list_out = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) a_tx, TX_ITEM_TYPE_OUT_ALL, NULL);
-    uint256_t l_value = {}, l_fee_sum = {};
+    uint256_t l_value = {}, l_fee_sum = {}, l_tax_sum = {};
     bool l_fee_check = !IS_ZERO_256(a_ledger->net->pub.fee_value) && !dap_chain_addr_is_blank(&a_ledger->net->pub.fee_addr);
     int l_item_idx = 0;
     for (dap_list_t *it = l_list_out; it; it = it->next, l_item_idx++) {
@@ -4075,6 +4088,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
             }
             l_value = l_tx_out->header.value;
             l_list_tx_out = dap_list_append(l_list_tx_out, l_tx_out);
+            if (l_tx_out->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE &&
+                    SUBTRACT_256_256(l_taxed_value, l_value, &l_taxed_value)) {
+                log_it(L_WARNING, "Fee is greater than sum of inputs");
+                l_err_num = -89;
+                break;
+            }
         } break;
         default: {}
         }
@@ -4136,9 +4155,12 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
         }
 
         if (l_fee_check && dap_chain_addr_compare(&l_tx_out_to, &a_ledger->net->pub.fee_addr) &&
-                !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker)) {
+                !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker))
             SUM_256_256(l_fee_sum, l_value, &l_fee_sum);
-        }
+
+        if (l_tax_check && dap_chain_addr_compare(&l_tx_out_to, &l_key_item->sovereign_addr) &&
+                !dap_strcmp(l_value_cur->token_ticker, a_ledger->net->pub.native_ticker))
+            SUM_256_256(l_tax_sum, l_value, &l_tax_sum);
     }
 
     if ( l_list_out )
@@ -4176,6 +4198,24 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
         }
     }
 
+    // 8. Check sovereign tax
+    if (l_fee_check && SUBTRACT_256_256(l_taxed_value, l_fee_sum, &l_taxed_value)) {
+        log_it(L_WARNING, "Fee is greater than sum of inputs");
+        l_err_num = -89;
+    }
+    if (l_tax_check && !l_err_num) {
+        uint256_t l_expected_tax = {};
+        MULT_256_COIN(l_taxed_value, l_key_item->sovereign_tax, &l_expected_tax);
+        if (compare256(l_tax_sum, l_expected_tax) == -1) {
+            char *l_current_tax_str = dap_chain_balance_to_coins(l_tax_sum);
+            char *l_expected_tax_str = dap_chain_balance_to_coins(l_expected_tax);
+            log_it(L_ERROR, "Tax value is invalid, expected %s pointed %s", l_expected_tax_str, l_current_tax_str);
+            l_err_num = -55;
+            DAP_DEL_Z(l_current_tax_str);
+            DAP_DEL_Z(l_expected_tax_str);
+        }
+    }
+
     if (a_main_ticker && !l_err_num)
         *a_main_ticker = dap_strdup(l_main_ticker);
 
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index a167020174c150463752b7b9b57e4679a5c22c0f..8686bb5d7c51b9c1cecdb9735b4afc90301f9f34 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -2060,7 +2060,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
 
             char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
             if(l_wallet)
-                dap_string_append_printf(l_string_ret, "%s\nwallet: %s\n", dap_chain_wallet_check_sign(l_wallet), l_wallet->name);
+                dap_string_append_printf(l_string_ret, "%swallet: %s\n", dap_chain_wallet_check_sign(l_wallet), l_wallet->name);
             dap_string_append_printf(l_string_ret, "addr: %s\n", (l_l_addr_str) ? l_l_addr_str : "-");
             dap_string_append_printf(l_string_ret, "network: %s\n", (l_net_name ) ? l_net_name : "-");
 
@@ -2165,7 +2165,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
                     }
 
                     log_it(L_INFO, "Wallet %s has been converted", l_wallet_name);
-                    dap_string_append_printf(l_string_ret, "%s\nWallet: %s successfully converted\n", dap_chain_wallet_check_sign(l_wallet), l_wallet_name);
+                    dap_string_append_printf(l_string_ret, "%sWallet: %s successfully converted\n", dap_chain_wallet_check_sign(l_wallet), l_wallet_name);
                     dap_chain_wallet_close(l_wallet);
                     break;
                 }
@@ -4339,11 +4339,11 @@ int com_tx_cond_create(int a_argc, char ** a_argv, char **a_str_reply)
     DAP_DELETE(l_key_cond);
 
     if (l_hash_str) {
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "Conditional 256bit TX created succefully, hash=%s\n%s\n", l_hash_str, l_sign_str);
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "%sConditional 256bit TX created succefully, hash=%s\n", l_hash_str, l_sign_str);
         DAP_DELETE(l_hash_str);
         return 0;
     }
-    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create conditional 256bit TX\n%s\n", l_sign_str);
+    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create conditional 256bit TX\n");
     return -1;
 }
 
@@ -5118,7 +5118,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, char **a_str_reply)
                     log_it(L_ERROR, "Json TX: bad node_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE");
                     break;
                 }
-                dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_srv_uid, l_value, l_signing_addr, &l_signer_node_addr);
+                dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_srv_uid, l_value, l_signing_addr,
+                                                                                                             &l_signer_node_addr, NULL, uint256_0);
                 l_item = (const uint8_t*) l_out_cond_item;
                 // Save value for using in In item
                 if(l_item) {
@@ -5661,7 +5662,7 @@ int com_tx_create(int a_argc, char **a_argv, char **a_str_reply)
         dap_cli_server_cmd_set_reply_text(a_str_reply, "wallet %s does not exist", l_from_wallet_name);
         return -9;
     } else {
-        dap_string_append_printf(l_string_ret, "%s\n", dap_chain_wallet_check_sign(l_wallet));
+        dap_string_append(l_string_ret, dap_chain_wallet_check_sign(l_wallet));
     }
     const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
 
@@ -5965,8 +5966,7 @@ int com_tx_history(int a_argc, char ** a_argv, char **a_str_reply)
     dap_string_t *l_str_ret = dap_string_new("");
     if (l_addr) {
         char *l_addr_str = dap_chain_addr_to_str(l_addr);
-        dap_string_append_printf(l_str_ret, "%s\n%s\n", dap_strdup_printf("History for addr %s:\n%s", l_addr_str,
-                l_str_out ? l_str_out : " empty"), l_sign_str);
+        dap_string_append_printf(l_str_ret, "%sHistory for addr %s:\n%s", l_sign_str, l_addr_str, l_str_out ? l_str_out : " empty");
         DAP_DELETE(l_addr_str);
         DAP_DELETE(l_str_out);
     } else
diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c
index 2e473780f6c75727ebbedd94c7ee11ec521395d2..5036e2a08b13ae5d8a7281c8466f1f8c9a2fc7b4 100644
--- a/modules/net/dap_chain_node_cli_cmd_tx.c
+++ b/modules/net/dap_chain_node_cli_cmd_tx.c
@@ -303,7 +303,7 @@ char* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, const
                 dap_chain_tx_in_ems_t *l_tx_in_ems = (dap_chain_tx_in_ems_t *)it->data;
                 l_base_tx = true;
                 l_noaddr_token = l_tx_in_ems->header.ticker;
-            }
+            } break;
             case TX_ITEM_TYPE_IN_REWARD: {
                 l_base_tx = l_reward_collect = true;
                 l_noaddr_token = l_native_ticker;
@@ -820,7 +820,7 @@ int com_ledger(int a_argc, char ** a_argv, char **a_str_reply)
         DAP_DELETE(l_str_out);
         DAP_DELETE(l_addr);
         s_dap_chain_tx_hash_processed_ht_free(&l_list_tx_hash_processd);
-        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\n%s", l_str_ret->str, l_sign_str);
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "%s%s", l_sign_str, l_str_ret->str);
         dap_string_free(l_str_ret, true);
         return 0;       
     }
diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c
index 6fb414757554acd550311d2be3a54245c9bc4ef5..ebf145c201fddf4193b96a1903346ff706776cca 100644
--- a/modules/net/srv/dap_chain_net_srv.c
+++ b/modules/net/srv/dap_chain_net_srv.c
@@ -313,7 +313,7 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply)
                     }
                     if(l_continent_num>=0)
                         l_order->continent = l_continent_num;*/
-                    char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order);
+                    char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order, false);
                     if (l_new_order_hash_str) {
                         // delete prev order
                         if(dap_strcmp(l_new_order_hash_str, l_order_hash_hex_str))
diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c
index c53d35d127e1adacce2d2ac51ed8ac39bad74bd2..72d73bd09f0cbdcc57a49985e5cc0db3f85504d9 100644
--- a/modules/net/srv/dap_chain_net_srv_order.c
+++ b/modules/net/srv/dap_chain_net_srv_order.c
@@ -259,7 +259,7 @@ char * dap_chain_net_srv_order_create(
                                                                          a_region, a_continent_num, a_key);
     if (!l_order)
         return NULL;
-    char *l_ret = dap_chain_net_srv_order_save(a_net, l_order);
+    char *l_ret = dap_chain_net_srv_order_save(a_net, l_order, false);
     DAP_DELETE(l_order);
     return l_ret;
 }
@@ -342,7 +342,7 @@ dap_chain_net_srv_order_t *dap_chain_net_srv_order_compose(dap_chain_net_t *a_ne
  * @param a_order
  * @return
  */
-char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order)
+char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order, bool a_common)
 {
     if (!a_net || !a_order)
         return NULL;
@@ -350,12 +350,16 @@ char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_ord
     size_t l_order_size = dap_chain_net_srv_order_get_size(a_order);
     dap_hash_fast(a_order, l_order_size, &l_order_hash);
     char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_order_hash);
-    char *l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(a_net);
-    if ( dap_global_db_set_sync( l_gdb_group_str,l_order_hash_str, a_order,  l_order_size, true ) != 0) {
-        DAP_DELETE(l_gdb_group_str);
+    if (!l_order_hash_str)
         return NULL;
-    }
+    char *l_gdb_group_str = a_common ? dap_chain_net_srv_order_get_common_group(a_net)
+                                     : dap_chain_net_srv_order_get_gdb_group(a_net);
+    if (!l_gdb_group_str)
+        return NULL;
+    int l_rc = dap_global_db_set_sync(l_gdb_group_str, l_order_hash_str, a_order, l_order_size, true);
     DAP_DELETE(l_gdb_group_str);
+    if (l_rc != DAP_GLOBAL_DB_RC_SUCCESS)
+        DAP_DEL_Z(l_order_hash_str);
     return l_order_hash_str;
 }
 
@@ -409,21 +413,26 @@ dap_chain_net_srv_order_t *dap_chain_net_srv_order_read(byte_t *a_order, size_t
  * @param a_hash_str
  * @return
  */
-dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash_str(dap_chain_net_t * a_net, const char * a_hash_str)
+dap_chain_net_srv_order_t *dap_chain_net_srv_order_find_by_hash_str(dap_chain_net_t *a_net, const char *a_hash_str)
 {
-    dap_chain_net_srv_order_t * l_order = NULL;
-    if ( a_net && a_hash_str ){
-        char * l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group( a_net);
-        size_t l_order_size =0;
-        l_order = (dap_chain_net_srv_order_t *) dap_global_db_get_sync(l_gdb_group_str, a_hash_str, &l_order_size, NULL, NULL );
+    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);
+        size_t l_order_size = 0;
+        byte_t *l_gdb_order = dap_global_db_get_sync(l_gdb_group_str, a_hash_str, &l_order_size, NULL, NULL);
+        DAP_DELETE(l_gdb_group_str);
+        if (!l_gdb_order)
+            continue;
         // check order size
-        if(l_order_size != dap_chain_net_srv_order_get_size(l_order)) {
-            log_it( L_ERROR, "Found wrong size order");
-            DAP_DELETE( l_order );
-            DAP_DELETE( l_gdb_group_str );
+        size_t l_expected_size = dap_chain_net_srv_order_get_size(l_order);
+        if (l_order_size != l_expected_size) {
+            log_it(L_ERROR, "Found wrong size order %zu, expected %zu", l_order_size, l_expected_size);
+            DAP_DELETE(l_gdb_order);
             return NULL;
         }
-        DAP_DELETE( l_gdb_group_str );
+        l_order = dap_chain_net_srv_order_read(l_gdb_order, l_order_size);
+        DAP_DELETE(l_gdb_order);
     }
     return l_order;
 }
@@ -448,56 +457,59 @@ int dap_chain_net_srv_order_find_all_by(dap_chain_net_t * a_net,const dap_chain_
 {
     if (!a_net || !a_output_orders || !a_output_orders_count)
         return -1;
-    char *l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(a_net);
-    size_t l_orders_count = 0;
-    dap_global_db_obj_t *l_orders = dap_global_db_get_all_sync(l_gdb_group_str, &l_orders_count);
-    log_it( L_DEBUG, "Loaded %zu orders", l_orders_count);
-    dap_chain_net_srv_order_t *l_order = NULL;
-    *a_output_orders = NULL;
-    size_t l_output_orders_count = 0;
-    size_t l_orders_size = 0;
-    for (size_t i = 0; i < l_orders_count; i++) {
-        DAP_DEL_Z(l_order);
-        l_order = dap_chain_net_srv_order_read(l_orders[i].value, l_orders[i].value_len);
-        if (!l_order) {
-            dap_global_db_del_sync(l_gdb_group_str, l_orders[i].key);
-            continue; // order is corrupted
-        }
-        dap_chain_hash_fast_t l_hash, l_hash_gdb;
-        dap_hash_fast(l_orders[i].value, l_orders[i].value_len, &l_hash);
-        dap_chain_hash_fast_from_str(l_orders[i].key, &l_hash_gdb);
-        if (memcmp(&l_hash, &l_hash_gdb, sizeof(dap_chain_hash_fast_t))) {
-            dap_global_db_del_sync(l_gdb_group_str, l_orders[i].key);
-            continue; // order is corrupted
+    for (int i = 0; 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);
+        size_t l_orders_count = 0;
+        dap_global_db_obj_t *l_orders = dap_global_db_get_all_sync(l_gdb_group_str, &l_orders_count);
+        log_it( L_DEBUG, "Loaded %zu orders", l_orders_count);
+        dap_chain_net_srv_order_t *l_order = NULL;
+        *a_output_orders = NULL;
+        size_t l_output_orders_count = 0;
+        size_t l_orders_size = 0;
+        for (size_t i = 0; i < l_orders_count; i++) {
+            DAP_DEL_Z(l_order);
+            l_order = dap_chain_net_srv_order_read(l_orders[i].value, l_orders[i].value_len);
+            if (!l_order) {
+                dap_global_db_del_sync(l_gdb_group_str, l_orders[i].key);
+                continue; // order is corrupted
+            }
+            dap_chain_hash_fast_t l_hash, l_hash_gdb;
+            dap_hash_fast(l_orders[i].value, l_orders[i].value_len, &l_hash);
+            dap_chain_hash_fast_from_str(l_orders[i].key, &l_hash_gdb);
+            if (memcmp(&l_hash, &l_hash_gdb, sizeof(dap_chain_hash_fast_t))) {
+                dap_global_db_del_sync(l_gdb_group_str, l_orders[i].key);
+                continue; // order is corrupted
+            }
+            // Check direction
+            if (a_direction != SERV_DIR_UNDEFINED && l_order->direction != a_direction)
+                continue;
+            // Check srv uid
+            if (a_srv_uid.uint64 && l_order->srv_uid.uint64 != a_srv_uid.uint64)
+                continue;
+            // check price unit
+            if (a_price_unit.uint32 && a_price_unit.uint32 != l_order->price_unit.uint32)
+                continue;
+            // Check price minimum
+            if (!IS_ZERO_256(a_price_min) && compare256(l_order->price, a_price_min) == -1)
+                continue;
+            // Check price maximum
+            if (!IS_ZERO_256(a_price_max) && compare256(l_order->price, a_price_max) == 1)
+                continue;
+            // Check ticker
+            if (a_price_ticker && strcmp( l_order->price_ticker, a_price_ticker))
+                continue;
+            size_t l_order_mem_size = dap_chain_net_srv_order_get_size(l_order);
+            *a_output_orders = DAP_REALLOC(*a_output_orders, l_orders_size + l_order_mem_size);
+            memcpy((byte_t *)*a_output_orders + l_orders_size, l_order, l_order_mem_size);
+            l_orders_size += l_order_mem_size;
+            l_output_orders_count++;
         }
-        // Check direction
-        if (a_direction != SERV_DIR_UNDEFINED && l_order->direction != a_direction)
-            continue;
-        // Check srv uid
-        if (a_srv_uid.uint64 && l_order->srv_uid.uint64 != a_srv_uid.uint64)
-            continue;
-        // check price unit
-        if (a_price_unit.uint32 && a_price_unit.uint32 != l_order->price_unit.uint32)
-            continue;
-        // Check price minimum
-        if (!IS_ZERO_256(a_price_min) && compare256(l_order->price, a_price_min) == -1)
-            continue;
-        // Check price maximum
-        if (!IS_ZERO_256(a_price_max) && compare256(l_order->price, a_price_max) == 1)
-            continue;
-        // Check ticker
-        if (a_price_ticker && strcmp( l_order->price_ticker, a_price_ticker))
-            continue;
-        size_t l_order_mem_size = dap_chain_net_srv_order_get_size(l_order);
-        *a_output_orders = DAP_REALLOC(*a_output_orders, l_orders_size + l_order_mem_size);
-        memcpy((byte_t *)*a_output_orders + l_orders_size, l_order, l_order_mem_size);
-        l_orders_size += l_order_mem_size;
-        l_output_orders_count++;
+        *a_output_orders_count = l_output_orders_count;
+        DAP_DEL_Z(l_order);
+        dap_global_db_objs_delete(l_orders, l_orders_count);
+        DAP_DELETE(l_gdb_group_str);
     }
-    *a_output_orders_count = l_output_orders_count;
-    DAP_DEL_Z(l_order);
-    dap_global_db_objs_delete(l_orders, l_orders_count);
-    DAP_DELETE(l_gdb_group_str);
     return 0;
 }
 
@@ -507,14 +519,16 @@ int dap_chain_net_srv_order_find_all_by(dap_chain_net_t * a_net,const dap_chain_
  * @param a_hash_str
  * @return
  */
-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)
 {
     int l_ret = -2;
-    if ( a_net && a_hash_str  ){
-        char * l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group( a_net);
-
-        l_ret = dap_global_db_del_sync( l_gdb_group_str, a_hash_str) ;
-        DAP_DELETE( l_gdb_group_str );
+    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);
+        l_ret = dap_global_db_del_sync(l_gdb_group_str, a_hash_str);
+        DAP_DELETE(l_gdb_group_str);
+        if (!l_ret)
+            break;
     }
     return l_ret;
 }
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 24f26df936320eba9fb69029f1a48fbd16ed3b4f..8ebb4ed5d09f22a68d468d1645d844085c9f80a6 100644
--- a/modules/net/srv/include/dap_chain_net_srv_order.h
+++ b/modules/net/srv/include/dap_chain_net_srv_order.h
@@ -157,8 +157,11 @@ dap_chain_net_srv_order_t *dap_chain_net_srv_order_compose(
         dap_enc_key_t *a_key
         );
 
-char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order);
-void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,dap_string_t * a_str_out, const char *a_hash_out_type, const char *a_native_ticker);
+char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_order_t *a_order, bool a_common);
+
+void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order, dap_string_t *a_str_out,
+                                            const char *a_hash_out_type, const char *a_native_ticker);
+
 void dap_chain_net_srv_order_add_notify_callback(dap_chain_net_t *a_net, dap_store_obj_callback_notify_t a_callback, void *a_cb_arg);
 /**
 * @brief dap_chain_net_srv_order_get_gdb_group_mempool
@@ -169,3 +172,8 @@ DAP_STATIC_INLINE char * dap_chain_net_srv_order_get_gdb_group(dap_chain_net_t *
 {
     return a_net ? dap_strdup_printf("%s.service.orders",a_net->pub.gdb_groups_prefix) : NULL;
 }
+
+DAP_STATIC_INLINE char *dap_chain_net_srv_order_get_common_group(dap_chain_net_t * a_net)
+{
+    return a_net ? dap_strdup_printf("%s.orders", a_net->pub.gdb_groups_prefix) : NULL;
+}
diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c
index 6a3d0ff3e01028f81a95b28b7be80c9da5d82269..cfeb70da97b63608ee8473cc341d97f3415912a7 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_lock.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c
@@ -299,7 +299,7 @@ static enum error_code s_cli_hold(int a_argc, char **a_argv, int a_arg_index, da
         dap_string_append_printf(output_line, "'%s'", l_wallet_str);
         return WALLET_OPEN_ERROR;
     } else {
-        dap_string_append_printf(output_line, "%s\n", dap_chain_wallet_check_sign(l_wallet));
+        dap_string_append(output_line, dap_chain_wallet_check_sign(l_wallet));
     }
 
     if (compare256(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_ticker_str), l_value) == -1) {
@@ -454,7 +454,7 @@ static enum error_code s_cli_take(int a_argc, char **a_argv, int a_arg_index, da
     if (NULL == (l_wallet = dap_chain_wallet_open(l_wallet_str, l_wallets_path)))
         return WALLET_OPEN_ERROR;
     else
-        dap_string_append_printf(output_line, "%s\n", dap_chain_wallet_check_sign(l_wallet));
+        dap_string_append(output_line, dap_chain_wallet_check_sign(l_wallet));
 
 
     if (NULL == (l_owner_key = dap_chain_wallet_get_key(l_wallet, 0))) {
diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
index 055145bcba99ace7f1d98d40034ac02fb59ff7b9..130d6ed21da3eaa9d4626a485a5088df04515d58 100644
--- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
+++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c
@@ -66,18 +66,23 @@ int dap_chain_net_srv_stake_pos_delegate_init()
     dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, s_stake_verificator_callback, s_stake_updater_callback);
     dap_cli_server_cmd_add("srv_stake", s_cli_srv_stake, "Delegated stake service commands",
     "\t\t=== Commands for work with orders ===\n"
-    "srv_stake order create -net <net_name> -value <value> -cert <priv_cert_name> \n"
-        "\tCreates a new order signed with a delegated key, which declares the commission for which \n"
-        "\tthe node agrees to conduct the transaction.\n"
-    "srv_stake order remove -net <net_name> -order <order_hash> [-H {hex | base58(default)}]\n"
+    "srv_stake order create [fee] -net <net_name> -value <value> -cert <priv_cert_name> [-H {hex(default) | base58}]\n"
+        "\tCreates an order declaring the minimum fee that the validator agrees to for process a transaction.\n"
+    "srv_stake order create validator -net <net_name> -value_min <minimum_stake_value> -value_max <maximum_stake_value>"
+                        " -tax <percent> [-H {hex(default) | base58}]\n"
+        "\tCreates an order declaring wanted tax and minimum/maximum stake value that the validator agrees to work.\n"
+    "srv_stake order create staker -net <net_name> -w <wallet_wtih_m_tokens> -value <stake_value> -tax <percent> [-addr <for_tax_collecting>] [-H {hex(default) | base58}]\n"
+        "\tCreates an order allowing the validator to delegate it's key with specified params\n"
+    "srv_stake order update -net <net_name> -order <order_hash> [-params]\n"
+         "\tUpdates an order with specified hash\n"
+    "srv_stake order list [fee | validator | staker] -net <net_name>\n"
+         "\tGet orders list of specified type within specified net name\n"
+    "srv_stake order remove -net <net_name> -order <order_hash>\n"
          "\tRemove order with specified hash\n"
-    "srv_stake order update -net <net_name> -order <order_hash> [-H {hex | base58(default)}] -cert <priv_cert_name>  -value <value>\n"
-         "\tUpdate order with specified hash\n"
-    "srv_stake order list -net <net_name>\n"
-         "\tGet the fee orders list within specified net name\n"
      "\t\t === Commands for work with stake delegate ===\n"
-    "srv_stake delegate -cert <pub_cert_name> -net <net_name> -w <wallet_name> -value <datoshi> [-node_addr <node_addr>] -fee <value> \n"
-         "\tDelegate public key in specified certificate with specified net name. Pay with specified value of m-tokens of native net token.\n"
+    "srv_stake delegate {-cert <pub_cert_name> [-node_addr <node_addr>] | -order <order_hash> [-tax_addr <wallet_addr_for_tax_collecting>]}"
+                        " -net <net_name> -w <wallet_name> -value <datoshi> -fee <value> \n"
+         "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n"
     "srv_stake approve -net <net_name> -tx <transaction_hash> -poa_cert <priv_cert_name>\n"
          "\tApprove stake transaction by root node certificate within specified net name\n"
     "srv_stake list keys -net <net_name> [-cert <delegated_cert> | -pkey <pkey_hash_str>]\n"
@@ -151,11 +156,22 @@ void dap_chain_net_srv_stake_pos_delegate_deinit()
 }
 
 static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_chain_tx_out_cond_t UNUSED_ARG *a_cond,
-                                         dap_chain_datum_tx_t UNUSED_ARG *a_tx_in, bool a_owner)
+                                         dap_chain_datum_tx_t *a_tx_in, bool a_owner)
 {
     assert(s_srv_stake);
     if (!a_owner)
         return false;
+    if (a_tx_in->header.ts_created < 1702857600) // Dec 18 2023 00:00:00 GMT
+        return true;
+    dap_chain_tx_in_cond_t *l_tx_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx_in, 0, TX_ITEM_TYPE_IN_COND, 0);
+    if (!l_tx_in_cond)
+        return false;
+    if (dap_hash_fast_is_blank(&l_tx_in_cond->header.tx_prev_hash))
+        return false;
+    dap_chain_net_srv_stake_item_t *l_stake;
+    HASH_FIND(hh, s_srv_stake->tx_itemlist, &l_tx_in_cond->header.tx_prev_hash, sizeof(dap_hash_t), l_stake);
+    if (l_stake)
+        return false;
     return true;
 }
 
@@ -186,8 +202,8 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr
                                           uint256_t a_value, dap_chain_node_addr_t *a_node_addr)
 {
     assert(s_srv_stake);
-    if (!a_signing_addr || !a_node_addr || !a_stake_tx_hash)
-        return;
+    dap_return_if_fail(a_net && a_signing_addr && a_node_addr && a_stake_tx_hash);
+
     dap_chain_net_srv_stake_item_t *l_stake = NULL;
     bool l_found = false;
     HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
@@ -205,8 +221,21 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr
     l_stake->is_active = true;
     if (!l_found)
         HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake);
-    if (!dap_hash_fast_is_blank(a_stake_tx_hash))
+    if (!dap_hash_fast_is_blank(a_stake_tx_hash)) {
         HASH_ADD(ht, s_srv_stake->tx_itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake);
+        dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_stake_tx_hash);
+        if (l_tx) {
+            dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL);
+            if (l_cond && l_cond->tsd_size) {
+                dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR);
+                l_stake->sovereign_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t);
+                l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE);
+                l_stake->sovereign_tax = dap_tsd_get_scalar(l_tsd, uint256_t);
+                if (compare256(l_stake->sovereign_tax, dap_chain_coins_to_balance("1.0")) == 1)
+                    l_stake->sovereign_tax = dap_chain_coins_to_balance("1.0");
+            }
+        }
+    }
     char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
     dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast,
                                l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE);
@@ -277,19 +306,6 @@ dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id,
     return l_ret;
 }
 
-dap_chain_node_addr_t *dap_chain_net_srv_stake_key_get_node_addr(dap_chain_addr_t *a_signing_addr)
-{
-    assert(s_srv_stake);
-    if (!a_signing_addr)
-        NULL;
-
-    dap_chain_net_srv_stake_item_t *l_stake = NULL;
-    HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake);
-    if (l_stake) // public key delegated for this network
-        return &l_stake->node_addr;
-    return NULL;
-}
-
 int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off)
 {
     assert(s_srv_stake);
@@ -357,12 +373,9 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         return -1;
     }
     dap_ledger_t *l_ledger = a_net->pub.ledger;
-    if(!l_ledger) {
-        log_it(L_ERROR, "Invalid arguments l_ledger in dap_chain_net_srv_stake_load_cache");
-        return -1;
-    }
     if (!dap_ledger_cache_enabled(l_ledger))
         return 0;
+
     char *l_gdb_group = dap_ledger_get_gdb_group(l_ledger, DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_GDB_GROUP);
     size_t l_objs_count = 0;
     
@@ -370,7 +383,7 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
 
     if (!l_objs_count || !l_store_obj) {
         log_it(L_ATT, "Stake cache data not found");
-        return -1;
+        return -2;
     }
     for (size_t i = 0; i < l_objs_count; i++){
         dap_chain_net_srv_stake_cache_data_t *l_cache_data =
@@ -378,7 +391,7 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net)
         dap_chain_net_srv_stake_cache_item_t *l_cache = DAP_NEW_Z(dap_chain_net_srv_stake_cache_item_t);
         if (!l_cache) {
             log_it(L_CRITICAL, "Memory allocation error");
-            return -1;
+            return -3;
         }
         l_cache->signing_addr   = l_cache_data->signing_addr;
         l_cache->tx_hash        = l_cache_data->tx_hash;
@@ -402,7 +415,8 @@ void dap_chain_net_srv_stake_purge(dap_chain_net_t *a_net)
 // Freeze staker's funds when delegating a key
 static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chain_wallet_t *a_wallet,
                                                uint256_t a_value, uint256_t a_fee,
-                                               dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr)
+                                               dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr,
+                                               dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax)
 {
     if (!a_net || !a_wallet || IS_ZERO_256(a_value) || !a_signing_addr || !a_node_addr)
         return NULL;
@@ -456,7 +470,8 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_chai
 
     // add 'out_cond' & 'out_ext' items
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID };
-    dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_value, a_signing_addr, a_node_addr);
+    dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_value, a_signing_addr, a_node_addr,
+                                                                                          a_sovereign_addr, a_sovereign_tax);
     if (!l_tx_out) {
         log_it(L_ERROR, "Can't compose the transaction conditional output");
         goto tx_fail;
@@ -513,6 +528,13 @@ tx_fail:
     return NULL;
 }
 
+static dap_chain_datum_tx_t *s_order_tx_create(dap_chain_net_t * a_net, dap_enc_key_t *a_key,
+                                               uint256_t a_value, uint256_t a_fee,
+                                                uint256_t a_sovereign_tax, dap_chain_addr_t *a_sovereign_addr)
+{
+    return NULL;
+}
+
 // Put the transaction to mempool
 static char *s_stake_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net)
 {
@@ -984,7 +1006,7 @@ static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a
     return l_decree;
 }
 
-char *s_stake_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key_t *a_key)
+char *s_fee_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key_t *a_key, const char *a_hash_out_type)
 {
     dap_chain_hash_fast_t l_tx_hash = {};
     dap_chain_net_srv_order_direction_t l_dir = SERV_DIR_SELL;
@@ -994,181 +1016,301 @@ char *s_stake_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key
     char *l_order_hash_str = dap_chain_net_srv_order_create(a_net, l_dir, l_uid, g_node_addr,
                                                             l_tx_hash, a_fee, l_unit, l_native_ticker, 0,
                                                             NULL, 0, 1, NULL, 0, a_key);
+    if (l_order_hash_str && !dap_strcmp(a_hash_out_type, "base58")) {
+        char *l_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
+        DAP_DELETE(l_order_hash_str);
+        l_order_hash_str = l_base58_str;
+    }
+    return l_order_hash_str;
+}
+
+char *s_validator_order_create(dap_chain_net_t *a_net, uint256_t a_value_min, uint256_t a_value_max, uint256_t a_tax, const char *a_hash_out_type)
+{
+    dap_chain_hash_fast_t l_tx_hash = {};
+    dap_chain_net_srv_order_direction_t l_dir = SERV_DIR_BUY;
+    const char *l_native_ticker = a_net->pub.native_ticker;
+    dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 =  SERV_UNIT_PCS};
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS };
+    struct odrer_ext {
+        uint256_t value_min;
+        uint256_t value_max;
+    } DAP_ALIGN_PACKED l_order_ext = { a_value_min, a_value_max };
+    dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_compose(a_net, l_dir, l_uid, g_node_addr,
+                                                            l_tx_hash, &a_tax, l_unit, l_native_ticker, 0,
+                                                            (const uint8_t *)&l_order_ext, sizeof(l_order_ext),
+                                                            1, NULL, 0, NULL);
+    if (!l_order)
+        return NULL;
+    char *l_order_hash_str = dap_chain_net_srv_order_save(a_net, l_order, true);
+    DAP_DELETE(l_order);
+    if (l_order_hash_str && !dap_strcmp(a_hash_out_type, "base58")) {
+        char *l_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
+        DAP_DELETE(l_order_hash_str);
+        l_order_hash_str = l_base58_str;
+    }
+    return l_order_hash_str;
+}
+
+char *s_staker_order_create(dap_chain_net_t *a_net, uint256_t a_value, uint256_t a_tax, dap_hash_fast_t *a_tx_hash,
+                            dap_chain_addr_t *a_addr, const char *a_hash_out_type)
+{
+    dap_chain_net_srv_order_direction_t l_dir = SERV_DIR_SELL;
+    const char *l_native_ticker = a_net->pub.native_ticker;
+    dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 =  SERV_UNIT_PCS};
+    dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS };
+    struct odrer_ext {
+        uint256_t value;
+        dap_chain_addr_t addr;
+    } DAP_ALIGN_PACKED l_order_ext = { a_value, *a_addr };
+    dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_compose(a_net, l_dir, l_uid, g_node_addr,
+                                                            *a_tx_hash, &a_tax, l_unit, l_native_ticker, 0,
+                                                             (const uint8_t *)&l_order_ext, sizeof(l_order_ext),
+                                                             1, NULL, 0, NULL);
+    if (!l_order)
+        return NULL;
+    char *l_order_hash_str = dap_chain_net_srv_order_save(a_net, l_order, true);
+    DAP_DELETE(l_order);
+    if (l_order_hash_str && !dap_strcmp(a_hash_out_type, "base58")) {
+        char *l_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
+        DAP_DELETE(l_order_hash_str);
+        l_order_hash_str = l_base58_str;
+    }
     return l_order_hash_str;
 }
 
 static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, char **a_str_reply, const char *a_hash_out_type)
 {
     enum {
-        CMD_NONE, CMD_CREATE, CMD_DECLARE, CMD_REMOVE, CMD_LIST, CMD_UPDATE
+        CMD_NONE, CMD_CREATE_FEE, CMD_CREATE_VALIDATOR, CMD_CREATE_STAKER, CMD_UPDATE, CMD_LIST, CMD_REMOVE
     };
     int l_cmd_num = CMD_NONE;
-    if(dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "create", NULL)) {
-        l_cmd_num = CMD_CREATE;
-    }
-    else if(dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "remove", NULL)) {
-        l_cmd_num = CMD_REMOVE;
-    }
-    else if(dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "list", NULL)) {
-        l_cmd_num = CMD_LIST;
-    }
-    else if(dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "update", NULL)) {
+    const char *l_create_type = NULL;
+    if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "create", &l_create_type)) {
+        if (!dap_strcmp(l_create_type, "validator"))
+            l_cmd_num = CMD_CREATE_VALIDATOR;
+        else if (!dap_strcmp(l_create_type, "staker"))
+            l_cmd_num = CMD_CREATE_STAKER;
+        else
+            l_cmd_num = CMD_CREATE_FEE;
+    }
+    else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "update") >= 0)
         l_cmd_num = CMD_UPDATE;
-    }
-    int l_arg_index = a_arg_index + 1;
-    switch (l_cmd_num) {
-        case CMD_CREATE: {
-            const char *l_net_str = NULL,
-                       *l_value_str = NULL,
-                       *l_cert_str = NULL;
-            dap_chain_net_t *l_net = NULL;
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
-            if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -net");
-                return -3;
-            }
-            l_net = dap_chain_net_by_name(l_net_str);
-            if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
-            }
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str);
-            if (!l_value_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' requires parameter -value");
-                return -5;
-            }
-            uint256_t l_value = dap_chain_balance_scan(l_value_str);
-            if (IS_ZERO_256(l_value)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <256 bit integer>");
-                return -6;
-            }
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
-            if (!l_cert_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order create' 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;
-            }
-            // Create the order & put it in GDB
-            char *l_order_hash_str = s_stake_order_create(l_net, &l_value, l_cert->enc_key);
-            if (l_order_hash_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
-                DAP_DELETE(l_order_hash_str);
-            } else {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose the order");
-                return -9;
-            }
-        } break;
-        case CMD_REMOVE: {
-            const char *l_net_str = NULL, *l_order_hash_str = NULL;
-            dap_chain_net_t *l_net = NULL;
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
-            if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order remove' requires parameter -net");
-                return -3;
-            }
-            l_net = dap_chain_net_by_name(l_net_str);
-            if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
-            }
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
-
-            char *l_order_hash_hex_str;
-            char *l_order_hash_base58_str;
-            // datum hash may be in hex or base58 format
-            if(!dap_strncmp(l_order_hash_str, "0x", 2) || !dap_strncmp(l_order_hash_str, "0X", 2)) {
-                l_order_hash_hex_str = dap_strdup(l_order_hash_str);
-                l_order_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
-            }
-            else {
-                l_order_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
-                l_order_hash_base58_str = dap_strdup(l_order_hash_str);
-            }
+    else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "list") >= 0)
+        l_cmd_num = CMD_LIST;
+    else if (dap_cli_server_cmd_check_option(a_argv, a_arg_index, dap_min(a_argc, a_arg_index + 1), "remove") >= 0)
+        l_cmd_num = CMD_REMOVE;
 
-            dap_chain_net_srv_order_t *l_order =  dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
-            if (!l_order) {
-                if(!dap_strcmp(a_hash_out_type,"hex"))
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_hex_str);
-                else
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_base58_str);
-                return -5;
-            }
+    int l_arg_index = a_arg_index + 1;
+    const char *l_net_str = NULL;
+    dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
+    if (!l_net_str) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order' requires parameter -net");
+        return -3;
+    }
+    dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+    if (!l_net) {
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
+        return -4;
+    }
 
-            if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID) {
-                if(!dap_strcmp(a_hash_out_type,"hex"))
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Order %s is not a delegated stake order.\n",
-                                                      l_order_hash_hex_str);
-                else
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                                      "Order %s is not a delegated stake order.\n", l_order_hash_base58_str);
-                return -6;
+    switch (l_cmd_num) {
+    case CMD_CREATE_FEE: {
+        const char *l_value_str = NULL,
+                   *l_cert_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str);
+        if (!l_value_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Fee order creation requires parameter -value");
+            return -5;
+        }
+        uint256_t l_value = dap_chain_balance_scan(l_value_str);
+        if (IS_ZERO_256(l_value)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <256 bit integer>");
+            return -6;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_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;
+        }
+        // Create the order & put it in GDB
+        char *l_order_hash_str = s_fee_order_create(l_net, &l_value, l_cert->enc_key, a_hash_out_type);
+        if (l_order_hash_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
+            DAP_DELETE(l_order_hash_str);
+        } else {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose the order");
+            return -9;
+        }
+    } break;
+
+    case CMD_CREATE_VALIDATOR: {
+        const char *l_value_min_str = NULL,
+                   *l_value_max_str = NULL,
+                   *l_tax_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value_min", &l_value_min_str);
+        if (!l_value_min_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -value_min");
+            return -5;
+        }
+        uint256_t l_value_min = dap_chain_balance_scan(l_value_min_str);
+        if (IS_ZERO_256(l_value_min)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value_min <256 bit integer>");
+            return -6;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value_max", &l_value_max_str);
+        if (!l_value_max_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -value_max");
+            return -7;
+        }
+        uint256_t l_value_max = dap_chain_balance_scan(l_value_max_str);
+        if (IS_ZERO_256(l_value_max)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value_max <256 bit integer>");
+            return -8;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tax", &l_tax_str);
+        if (!l_tax_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -tax");
+            return -9;
+        }
+        uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str);
+        if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
+                compare256(l_tax, GET_256_FROM_64(100)) == -1) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+            return -10;
+        }
+        // Create the order & put it in GDB
+        char *l_order_hash_str = s_validator_order_create(l_net, l_value_min, l_value_max, l_tax, a_hash_out_type);
+        if (l_order_hash_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str);
+            DAP_DELETE(l_order_hash_str);
+        } else {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose the order");
+            return -9;
+        }
+    } break;
+
+    case CMD_CREATE_STAKER: {
+        const char *l_value_str = NULL,
+                   *l_wallet_str = NULL,
+                   *l_tax_str = NULL,
+                   *l_addr_str = NULL,
+                   *l_fee_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str);
+        if (!l_value_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -value");
+            return -5;
+        }
+        uint256_t l_value = dap_chain_balance_scan(l_value_str);
+        if (IS_ZERO_256(l_value)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -value <256 bit integer>");
+            return -6;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
+        if (!l_fee_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -fee");
+            return -7;
+        }
+        uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
+        if (IS_ZERO_256(l_fee)) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Format -fee <256 bit integer>");
+            return -8;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tax", &l_tax_str);
+        if (!l_tax_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -tax");
+            return -9;
+        }
+        uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str);
+        if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
+                compare256(l_tax, GET_256_FROM_64(100)) == -1) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+            return -10;
+        }
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str);
+        if (!l_wallet_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Validator order creation requires parameter -w");
+            return -17;
+        }
+        dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config));
+        if (!l_wallet) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified wallet not found");
+            return -18;
+        }
+        // Create conditional transaction for order
+        const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet);
+        dap_chain_addr_t l_addr = {};
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_str);
+        if (l_addr_str) {
+            dap_chain_addr_t *l_spec_addr = dap_chain_addr_from_str(l_addr_str);
+            if (!l_spec_addr) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified address is ivalid");
+                dap_chain_wallet_close(l_wallet);
+                return -24;
             }
-
+            l_addr = *l_spec_addr;
+            DAP_DELETE(l_spec_addr);
+        }
+        dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+        dap_chain_datum_tx_t *l_tx = s_order_tx_create(l_net, l_enc_key, l_value, l_fee, l_tax, &l_addr);
+        dap_chain_wallet_close(l_wallet);
+        DAP_DEL_Z(l_enc_key);
+        char *l_tx_hash_str = NULL;
+        /*if (!l_tx || !(l_tx_hash_str = s_stake_tx_put(l_tx, l_net))) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose transaction for order, examine log files for details");
+            DAP_DEL_Z(l_tx);
+            return -21;
+        }*/ // TODO - make conditional transaction with specified params
+        // Create the order & put it in GDB
+        dap_hash_fast_t l_tx_hash = {};
+        dap_chain_hash_fast_from_hex_str(l_tx_hash_str, &l_tx_hash);
+        char *l_order_hash_str = s_staker_order_create(l_net, l_value, l_tax, &l_tx_hash, &l_addr, a_hash_out_type);
+        if (l_order_hash_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "%sSuccessfully created order %s", l_sign_str, l_order_hash_str);
+            DAP_DELETE(l_order_hash_str);
+        } else {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't compose the order");
+            return -9;
+        }
+    } break;
+
+    case CMD_REMOVE:
+    case CMD_UPDATE: {
+        const char *l_order_hash_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
+
+        char *l_order_hash_hex_str;
+        // datum hash may be in hex or base58 format
+        if(!dap_strncmp(l_order_hash_str, "0x", 2) || !dap_strncmp(l_order_hash_str, "0X", 2))
+            l_order_hash_hex_str = dap_strdup(l_order_hash_str);
+        else
+            l_order_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
+        dap_chain_net_srv_order_t *l_order =  dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str);
+        if (!l_order) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_str);
+            DAP_DELETE(l_order_hash_hex_str);
+            return -5;
+        }
+        if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Order %s is not a delegated stake order\n", l_order_hash_str);
+            DAP_DELETE(l_order_hash_hex_str);
+            return -6;
+        }
+        if (l_cmd_num == CMD_REMOVE) {
             if (dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str)) {
-                if(!dap_strcmp(a_hash_out_type,"hex"))
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't remove order %s\n", l_order_hash_hex_str);
-                else
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't remove order %s\n", l_order_hash_base58_str);
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't remove order %s\n", l_order_hash_str);
                 return -14;
             }
             dap_cli_server_cmd_set_reply_text(a_str_reply, "Stake order successfully removed");
-        } break;
-        case CMD_UPDATE: {
-            const char *l_net_str = NULL, *l_value_str = NULL;
-            const char *l_cert_str = NULL, *l_order_hash_str = NULL;
-            dap_chain_net_t *l_net = NULL;
-            dap_enc_key_t *l_key = NULL;
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
-            if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order update' requires parameter -net");
-                return -3;
-            }
-            l_net = dap_chain_net_by_name(l_net_str);
-            if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
-            }
-            if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order update' requires parameter -order");
-                return -5;
-            }
-            dap_chain_net_srv_order_t *l_order =  dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
-
-            char *l_order_hash_hex_str;
-            char *l_order_hash_base58_str;
-            // datum hash may be in hex or base58 format
-            if(!dap_strncmp(l_order_hash_str, "0x", 2) || !dap_strncmp(l_order_hash_str, "0X", 2)) {
-                l_order_hash_hex_str = dap_strdup(l_order_hash_str);
-                l_order_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_str);
-            } else {
-                l_order_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_order_hash_str);
-                l_order_hash_base58_str = dap_strdup(l_order_hash_str);
-            }
-
-            if (!l_order) {
-                if(!dap_strcmp(a_hash_out_type,"hex"))
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_hex_str);
-                else
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_base58_str);
-                return -6;
-            }
-
-            if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID) {
-                if(!dap_strcmp(a_hash_out_type,"hex"))
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Order %s is not a delegated stake order.\n",
-                                                      l_order_hash_hex_str);
-                else
-                    dap_cli_server_cmd_set_reply_text(a_str_reply,
-                                                      "Order %s is not a delegated stake order.\n", l_order_hash_base58_str);
-                return -7;
-            }
-
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str);
-            uint256_t l_value = {0};
+            DAP_DELETE(l_order_hash_hex_str);
+        } else { // l_cmd_num == CMD_UPDATE
+            const char *l_cert_str = NULL, *l_value_str = NULL;
+            // TODO make orders updatable
+            /*uint256_t l_value = {0};
             if (l_value_str) {
                 l_value = dap_chain_balance_scan(l_value_str);
                 if (IS_ZERO_256(l_value)) {
@@ -1191,67 +1333,61 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha
             dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str);
             DAP_DELETE(l_order_hash_hex_str);
             DAP_DELETE(l_order_hash_base58_str);
-            l_order_hash_hex_str = s_stake_order_create(l_net, &l_value, l_key);
+            l_order_hash_hex_str = s_fee_order_create(l_net, &l_value, l_key);
             if(!l_order_hash_hex_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create new order");
                 return -15;
-            }
-            if(!dap_strcmp(a_hash_out_type, "hex")) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_hex_str);
-            } else {
-                l_order_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_order_hash_hex_str);
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_base58_str);
-                DAP_DELETE(l_order_hash_base58_str);
-            }
-            DAP_DELETE(l_order_hash_hex_str);
-        } break;
-        case CMD_LIST: {
-            const char *l_net_str = NULL;
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
-            if (!l_net_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order list' requires parameter -net");
-                return -3;
-            }
-            dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
-            if (!l_net) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
-                return -4;
-            }
-            char * l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(l_net);
-            size_t l_orders_count = 0;
-            dap_global_db_obj_t * l_orders = dap_global_db_get_all_sync(l_gdb_group_str, &l_orders_count);
-            dap_string_t *l_reply_str = dap_string_new("");
-            for (size_t i = 0; i < l_orders_count; i++) {
-                dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)l_orders[i].value;
-                if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID)
-                    continue;
-                // TODO add filters to list (token, address, etc.)
-                char *l_price_coins = dap_chain_balance_to_coins(l_order->price);
-                char *l_price_datoshi = dap_chain_balance_print(l_order->price);
-                char *l_node_addr = dap_strdup_printf(NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_order->node_addr));
-                char l_created[80] = {'\0'};
-                dap_time_t l_ts_created = l_order->ts_created;
-                dap_ctime_r(&l_ts_created, l_created);
-                dap_string_append_printf(l_reply_str, "Order: %s\n"
-                                                      "\tCreated: %s"
-                                                      "\tPrice: %s (%s) %s\n"
-                                                      "\tNode addr: %s\n",
-                                                      l_orders[i].key, l_created, l_price_coins, l_price_datoshi, l_order->price_ticker, l_node_addr);
-                DAP_DELETE(l_price_coins);
-                DAP_DELETE(l_price_datoshi);
-                DAP_DELETE(l_node_addr);
-            }
-            dap_global_db_objs_delete(l_orders, l_orders_count);
-            DAP_DELETE( l_gdb_group_str);
-            if (!l_reply_str->len) {
-                dap_string_append(l_reply_str, "No orders found");
-            }
-            *a_str_reply = dap_string_free(l_reply_str, false);
-        } break;
-        default: {
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand %s not recognized", a_argv[a_arg_index]);
-            return -2;
+            }*/
+        }
+    } break;
+
+    case CMD_LIST: {
+        const char *l_net_str = NULL;
+        dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
+        if (!l_net_str) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'order list' requires parameter -net");
+            return -3;
+        }
+        dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+        if (!l_net) {
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str);
+            return -4;
         }
+        char * l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group(l_net);
+        size_t l_orders_count = 0;
+        dap_global_db_obj_t * l_orders = dap_global_db_get_all_sync(l_gdb_group_str, &l_orders_count);
+        dap_string_t *l_reply_str = dap_string_new("");
+        for (size_t i = 0; i < l_orders_count; i++) {
+            dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)l_orders[i].value;
+            if (l_order->srv_uid.uint64 != DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID)
+                continue;
+            // TODO add filters to list (token, address, etc.)
+            char *l_price_coins = dap_chain_balance_to_coins(l_order->price);
+            char *l_price_datoshi = dap_chain_balance_print(l_order->price);
+            char *l_node_addr = dap_strdup_printf(NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_order->node_addr));
+            char l_created[80] = {'\0'};
+            dap_time_t l_ts_created = l_order->ts_created;
+            dap_ctime_r(&l_ts_created, l_created);
+            dap_string_append_printf(l_reply_str, "Order: %s\n"
+                                                  "\tCreated: %s"
+                                                  "\tPrice: %s (%s) %s\n"
+                                                  "\tNode addr: %s\n",
+                                                  l_orders[i].key, l_created, l_price_coins, l_price_datoshi, l_order->price_ticker, l_node_addr);
+            DAP_DELETE(l_price_coins);
+            DAP_DELETE(l_price_datoshi);
+            DAP_DELETE(l_node_addr);
+        }
+        dap_global_db_objs_delete(l_orders, l_orders_count);
+        DAP_DELETE( l_gdb_group_str);
+        if (!l_reply_str->len) {
+            dap_string_append(l_reply_str, "No orders found");
+        }
+        *a_str_reply = dap_string_free(l_reply_str, false);
+    } break;
+
+    default:
+        dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand %s not recognized", a_argv[a_arg_index]);
+        return -2;
     }
     return 0;
 }
@@ -1280,17 +1416,24 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t
     char l_active_str[32] = {};
     if (s_chain_esbocs_started(a_stake->net))
         snprintf(l_active_str, 32, "\tActive: %s\n", a_stake->is_active ? "true" : "false");
+    char *l_sov_addr_str = dap_chain_addr_is_blank(&a_stake->sovereign_addr) ?
+                dap_strdup("N/A") : dap_chain_addr_to_str(&a_stake->sovereign_addr);
+    char *l_sov_tax_str = dap_chain_balance_to_coins(a_stake->sovereign_tax);
     dap_string_append_printf(a_string, "Pkey hash: %s\n"
                                         "\tStake value: %s\n"
                                         "\tRelated weight: %s%%\n"
                                         "\tTx hash: %s\n"
                                         "\tNode addr: "NODE_ADDR_FP_STR"\n"
+                                        "\tSovereign addr: %s\n"
+                                        "\tSovereign tax: %s\n"
                                         "%s\n",
                              l_pkey_hash_str, l_balance, l_rel_weight_str,
                              l_tx_hash_str, NODE_ADDR_FP_ARGS_S(a_stake->node_addr),
-                             l_active_str);
+                             l_sov_addr_str, l_sov_tax_str, l_active_str);
     DAP_DELETE(l_balance);
     DAP_DELETE(l_rel_weight_str);
+    DAP_DELETE(l_sov_addr_str);
+    DAP_DELETE(l_sov_tax_str);
 }
 
 /**
@@ -1581,7 +1724,9 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                        *l_cert_str = NULL,
                        *l_value_str = NULL,
                        *l_fee_str = NULL,
-                       *l_node_addr_str = NULL;
+                       *l_node_addr_str = NULL,
+                       *l_order_hash_str = NULL,
+                       *l_sovereign_addr_str = NULL;
             l_arg_index++;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str);
             if (!l_net_str) {
@@ -1606,33 +1751,97 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
             } else {
                 l_sign_str = dap_chain_wallet_check_sign(l_wallet);
             }
+            dap_chain_addr_t l_signing_addr, l_sovereign_addr = {};
+            uint256_t l_sovereign_tax = uint256_0;
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
-            if (!l_cert_str) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -cert");
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-order", &l_order_hash_str);
+            if (!l_cert_str && !l_order_hash_str) {
+                dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -cert or -order");
+                dap_chain_wallet_close(l_wallet);
                 return -13;
             }
-            dap_cert_t *l_signing_cert = dap_cert_find_by_name(l_cert_str);
-            if (!l_signing_cert) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
-                return -19;
-            }
-            dap_chain_addr_t l_signing_addr;
-            if (dap_chain_addr_fill_from_key(&l_signing_addr, l_signing_cert->enc_key, l_net->pub.id)) {
-                dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
-                return -20;
+            dap_chain_node_addr_t l_node_addr;
+            if (l_cert_str) {
+                dap_cert_t *l_signing_cert = dap_cert_find_by_name(l_cert_str);
+                if (!l_signing_cert) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found");
+                    dap_chain_wallet_close(l_wallet);
+                    return -19;
+                }
+                if (dap_chain_addr_fill_from_key(&l_signing_addr, l_signing_cert->enc_key, l_net->pub.id)) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong");
+                    dap_chain_wallet_close(l_wallet);
+                    return -20;
+                }
+                dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-node_addr", &l_node_addr_str);
+                if (l_node_addr_str) {
+                    if (dap_chain_node_addr_from_str(&l_node_addr, l_node_addr_str)) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized node addr %s", l_node_addr_str);
+                        dap_chain_wallet_close(l_wallet);
+                        return -14;
+                    }
+                } else
+                    l_node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
+            } else {
+                dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tax_addr", &l_sovereign_addr_str);
+                if (l_sovereign_addr_str) {
+                    dap_chain_addr_t *l_spec_addr = dap_chain_addr_from_str(l_sovereign_addr_str);
+                    if (!l_spec_addr) {
+                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified address is ivalid");
+                        return -24;
+                    }
+                    l_sovereign_addr = *l_spec_addr;
+                    DAP_DELETE(l_spec_addr);
+                } else
+                    dap_chain_addr_fill_from_key(&l_sovereign_addr, dap_chain_wallet_get_key(l_wallet, 0), l_net->pub.id);
+                dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_str);
+                if (!l_order) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order not found");
+                    dap_chain_wallet_close(l_wallet);
+                    return -25;
+                }
+                dap_pkey_t *l_pkey = (dap_pkey_t *)l_order->ext_n_sign;
+                if (l_order->ext_size < sizeof(dap_pkey_t) || l_order->ext_size != dap_pkey_get_size(l_pkey)) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order has invalid size");
+                    dap_chain_wallet_close(l_wallet);
+                    DAP_DELETE(l_order);
+                    return -26;
+                }
+                if (dap_strcmp(l_order->price_ticker, l_net->pub.native_ticker)) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified order is invalid");
+                    dap_chain_wallet_close(l_wallet);
+                    DAP_DELETE(l_order);
+                    return -27;
+                }
+                dap_hash_t l_pkey_hash;
+                dap_pkey_get_hash(l_pkey, &l_pkey_hash);
+                dap_chain_addr_fill(&l_signing_addr, dap_pkey_type_to_sign_type(l_pkey->header.type), &l_pkey_hash, l_net->pub.id);
+                l_node_addr = l_order->node_addr;
+                l_sovereign_tax = l_order->price;
+                DAP_DELETE(l_order);
+                if (compare256(l_sovereign_tax, dap_chain_coins_to_balance("100.0")) == 1 ||
+                        compare256(l_sovereign_tax, GET_256_FROM_64(100)) == -1) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%");
+                    dap_chain_wallet_close(l_wallet);
+                    return -28;
+                }
+                DIV_256(l_sovereign_tax, GET_256_FROM_64(100), &l_sovereign_tax);
             }
             if (dap_chain_net_srv_stake_key_delegated(&l_signing_addr)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is already delegated");
+                dap_chain_wallet_close(l_wallet);
                 return -21;
             }
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-value", &l_value_str);
             if (!l_value_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -value");
+                dap_chain_wallet_close(l_wallet);
                 return -9;
             }
             uint256_t l_value = dap_chain_balance_scan(l_value_str);
             if (IS_ZERO_256(l_value)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-value' param");
+                dap_chain_wallet_close(l_wallet);
                 return -10;
             }
             if (compare256(l_value, s_srv_stake->delegate_allowed_min) == -1) {
@@ -1644,44 +1853,43 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                 DAP_DELETE(l_coin_str);
                 DAP_DELETE(l_value_min_str);
                 DAP_DELETE(l_coin_min_str);
+                dap_chain_wallet_close(l_wallet);
                 return -11;
             }
-            dap_chain_node_addr_t l_node_addr;
-            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-node_addr", &l_node_addr_str);
-            if (l_node_addr_str) {
-                if (dap_chain_node_addr_from_str(&l_node_addr, l_node_addr_str)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized node addr %s", l_node_addr_str);
-                    return -14;
-                }
-            } else
-                l_node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
+
             dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-fee", &l_fee_str);
             if (!l_fee_str) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'delegate' requires parameter -fee");
+                dap_chain_wallet_close(l_wallet);
                 return -15;
             }
             uint256_t l_fee = dap_chain_balance_scan(l_fee_str);
             if (IS_ZERO_256(l_fee)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-fee' param");
+                dap_chain_wallet_close(l_wallet);
                 return -16;
             }
             int ret_val = 0;
             if((ret_val = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr)) != 0){
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Key and node verification error");
+                dap_chain_wallet_close(l_wallet);
                 return ret_val;
             }
+
             // Create conditional transaction
-            dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_net, l_wallet, l_value, l_fee, &l_signing_addr, &l_node_addr);
+            dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_net, l_wallet, l_value, l_fee, &l_signing_addr, &l_node_addr,
+                                                           &l_sovereign_addr, l_sovereign_tax);
             dap_chain_wallet_close(l_wallet);
             if (!l_tx || !s_stake_tx_put(l_tx, l_net)) {
                 dap_cli_server_cmd_set_reply_text(a_str_reply, "Stake transaction error");
+                DAP_DEL_Z(l_tx);
                 return -12;
             }
             dap_hash_fast_t l_tx_hash;
             dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
             DAP_DELETE(l_tx);
             char *l_tx_hash_str = dap_hash_fast_to_str_new(&l_tx_hash);
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nSAVE TO TAKE ===>>> Stake transaction %s has done", l_sign_str, l_tx_hash_str);
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "%sSAVE TO TAKE ===>>> Stake transaction %s has done", l_sign_str, l_tx_hash_str);
             DAP_DELETE(l_tx_hash_str);
         } break;
         case CMD_APPROVE: {
@@ -1950,14 +2158,22 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                 }
             }
 
-            dap_hash_fast_t *l_final_tx_hash = NULL;
+            dap_hash_fast_t l_tx_hash = {};
             if (l_tx_hash_str) {
-                l_final_tx_hash = DAP_NEW(dap_hash_fast_t);
-                dap_chain_hash_fast_from_str(l_tx_hash_str, l_final_tx_hash);
-                if(!dap_ledger_tx_find_by_hash(l_net->pub.ledger, l_final_tx_hash)) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is not found.", l_tx_hash_str);
+                dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash);
+                if (!dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash)) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s is not found", l_tx_hash_str);
                     return -20;
                 }
+                dap_chain_net_srv_stake_item_t *l_stake;
+                HASH_FIND(hh, s_srv_stake->tx_itemlist, &l_tx_hash, sizeof(dap_hash_t), l_stake);
+                if (l_stake) {
+                    char l_pkey_hash_str[DAP_HASH_FAST_STR_SIZE];
+                    dap_hash_fast_to_str(&l_stake->signing_addr.data.hash_fast, l_pkey_hash_str, DAP_HASH_FAST_STR_SIZE);
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s has active delegated key %s, need to revoke it first",
+                                                      l_tx_hash_str, l_pkey_hash_str);
+                    return -30;
+                }
             } else {
                 dap_chain_addr_t l_signing_addr;
                 if (l_cert_str) {
@@ -1985,7 +2201,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                                                                    " Try to invalidate with tx hash instead");
                     return -24;
                 }
-                l_final_tx_hash = &l_stake->tx_hash;
+                l_tx_hash = l_stake->tx_hash;
             }
             if (l_wallet_str) {
                 const char* l_sign_str = "";
@@ -1997,23 +2213,20 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                     l_sign_str = dap_chain_wallet_check_sign(l_wallet);
                 }
                 dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
-                dap_chain_datum_tx_t *l_tx = s_stake_tx_invalidate(l_net, l_final_tx_hash, l_fee, l_enc_key);
-                if (l_tx_hash_str) {
-                    DAP_DELETE(l_final_tx_hash);
-                }
+                dap_chain_datum_tx_t *l_tx = s_stake_tx_invalidate(l_net, &l_tx_hash, l_fee, l_enc_key);
                 dap_chain_wallet_close(l_wallet);
                 dap_enc_key_delete(l_enc_key);
-                char *l_decree_hash_str = NULL;
-                if (l_tx && (l_decree_hash_str = s_stake_tx_put(l_tx, l_net))) {
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nAll m-tokens successfully returned to "
-                                                                   "owner. Returning tx hash %s.", l_sign_str, l_decree_hash_str);
-                    DAP_DEL_Z(l_decree_hash_str);
+                char *l_tx_hash_str = NULL;
+                if (l_tx && (l_tx_hash_str = s_stake_tx_put(l_tx, l_net))) {
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%sAll m-tokens successfully returned to "
+                                                                   "owner. Returning tx hash %s.", l_sign_str, l_tx_hash_str);
+                    DAP_DEL_Z(l_tx_hash_str);
                     DAP_DELETE(l_tx);
                 } else {
-                    char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_new(l_final_tx_hash);
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "%s\nCan't invalidate transaction %s, examine log files for details", l_sign_str, l_final_tx_hash_str);
-                    DAP_DELETE(l_final_tx_hash_str);
-                    DAP_DELETE(l_tx);
+                    l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_tx_hash);
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't invalidate transaction %s, examine log files for details", l_tx_hash_str);
+                    DAP_DELETE(l_tx_hash_str);
+                    DAP_DEL_Z(l_tx);
                     return -21;
                 }
             } else {
@@ -2026,7 +2239,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one");
                     return -26;
                 }
-                dap_chain_datum_decree_t *l_decree = s_stake_decree_invalidate(l_net, l_final_tx_hash, l_poa_cert);
+                dap_chain_datum_decree_t *l_decree = s_stake_decree_invalidate(l_net, &l_tx_hash, l_poa_cert);
                 char *l_decree_hash_str = NULL;
                 if (l_decree && (l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) {
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified delageted key invalidated. "
@@ -2035,10 +2248,10 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply)
                     DAP_DELETE(l_decree);
                     DAP_DELETE(l_decree_hash_str);
                 } else {
-                    char l_final_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
-                    dap_chain_hash_fast_to_str(l_final_tx_hash, l_final_tx_hash_str, sizeof(l_final_tx_hash_str));
-                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't invalidate transaction %s, examine log files for details", l_final_tx_hash_str);
-                    DAP_DELETE(l_decree);
+                    char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+                    dap_chain_hash_fast_to_str(&l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't invalidate transaction %s, examine log files for details", l_tx_hash_str);
+                    DAP_DEL_Z(l_decree);
                     return -21;
                 }
             }
diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
index d0089145573457fa8e00216e583add209ca77d23..ff69a780555530f66e2115885afc85fe3d3bf932 100644
--- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
+++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h
@@ -31,6 +31,7 @@
 #include "dap_stream_ch_chain_net.h"
 
 #define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID 0x13
+#define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS 0x14
 
 typedef struct dap_chain_net_srv_stake_item {
     bool is_active;
@@ -39,6 +40,8 @@ typedef struct dap_chain_net_srv_stake_item {
     dap_chain_addr_t signing_addr;
     dap_chain_hash_fast_t tx_hash;
     dap_chain_node_addr_t node_addr;
+    dap_chain_addr_t sovereign_addr;
+    uint256_t sovereign_tax;
     UT_hash_handle hh, ht;
 } dap_chain_net_srv_stake_item_t;
 
@@ -73,7 +76,6 @@ uint256_t dap_chain_net_srv_stake_get_allowed_min_value();
 int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr);
 int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t* a_signing_addr, dap_chain_node_addr_t* a_node_addr);
 dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active);
-dap_chain_node_addr_t *dap_chain_net_srv_stake_key_get_node_addr(dap_chain_addr_t *a_signing_addr);
 
 bool dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net,
                                                 uint256_t *a_max_fee, uint256_t *a_average_fee, uint256_t *a_min_fee, uint256_t *a_median_fee);
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 5ae67b39dae1e6d901d53134be6fdca184396c34..2a5a7f498de62d641584826731a9597d7193461d 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -34,6 +34,8 @@
 #include "dap_cli_server.h"
 #include "dap_chain_node_cli_cmd.h"
 #include "dap_chain_mempool.h"
+#include "dap_chain_net_srv_stake_pos_delegate.h"
+#include "dap_chain_cs_esbocs.h"
 
 #define LOG_TAG "dap_chain_cs_blocks"
 
@@ -182,7 +184,7 @@ int dap_chain_cs_blocks_init()
         "Commission collect:\n"
             "block -net <net_name> -chain <chain_name> fee collect"
             " -cert <priv_cert_name> -addr <addr> -hashes <hashes_list> -fee <value>\n"
-                "\t\t Take the whole commission\n\n"
+                "\t\t Take delegated part of commission\n\n"
 
         "Reward for block signs:\n"
             "block -net <net_name> -chain <chain_name> reward set"
@@ -195,7 +197,7 @@ int dap_chain_cs_blocks_init()
 
             "block -net <net_name> -chain <chain_name> reward collect"
             " -cert <priv_cert_name> -addr <addr> -hashes <hashes_list> -fee <value>\n"
-                "\t\t Take reward\n\n"
+                "\t\t Take delegated part of reward\n\n"
 
         "Rewards and comission autocollect status:\n"
             "block -net <net_name> -chain <chain_name> autocollect status\n\n"
@@ -462,9 +464,31 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re
     }
     if (l_objs_count) {
         dap_global_db_objs_delete(l_objs, l_objs_count);
+        uint256_t l_collect_fee = dap_chain_esbocs_get_fee(a_net->pub.id);
+        SUM_256_256(l_collect_fee, a_net->pub.fee_value, &l_collect_fee);
+        uint256_t l_collect_tax = {}, l_collect_value = {};
+        if (compare256(l_total_value, l_collect_fee) == 1) {
+            SUBTRACT_256_256(l_total_value, l_collect_fee, &l_collect_value);
+            dap_pkey_t *l_my_sign_pkey = dap_chain_esbocs_get_sign_pkey(a_net->pub.id);
+            dap_hash_t l_my_sign_pkey_hash;
+            dap_hash_fast(l_my_sign_pkey->pkey, l_my_sign_pkey->header.size, &l_my_sign_pkey_hash);
+            dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_my_sign_pkey_hash);
+            if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
+                    !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
+                MULT_256_COIN(l_collect_value, l_key_item->sovereign_tax, &l_collect_tax);
+                SUBTRACT_256_256(l_collect_value, l_collect_tax, &l_collect_value);
+            }
+        }
         char *l_total_str = dap_chain_balance_to_coins(l_total_value);
-        dap_string_append_printf(a_reply_str, "Total prepared value: %s %s\n", l_total_str, a_net->pub.native_ticker);
+        char *l_profit_str = dap_chain_balance_to_coins(l_collect_value);
+        char *l_tax_str = dap_chain_balance_to_coins(l_collect_tax);
+        char *l_fee_str = dap_chain_balance_to_coins(l_collect_fee);
+        dap_string_append_printf(a_reply_str, "Total prepared value: %s %s, where\n\tprofit is %s, tax is %s, fee is %s\n",
+                                 l_total_str, a_net->pub.native_ticker, l_profit_str, l_tax_str, l_fee_str);
         DAP_DEL_Z(l_total_str);
+        DAP_DEL_Z(l_profit_str);
+        DAP_DEL_Z(l_tax_str);
+        DAP_DEL_Z(l_fee_str);
     } else
         dap_string_append(a_reply_str, "Empty\n");
 }
diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c
index 900fb942a484ecffbb317c16015dac6f9035bbeb..01ec3cf9662c11c81d06f1e4e93da627c34adaa3 100644
--- a/modules/wallet/dap_chain_wallet.c
+++ b/modules/wallet/dap_chain_wallet.c
@@ -997,7 +997,7 @@ const char* dap_chain_wallet_check_sign(dap_chain_wallet_t *a_wallet) {
     for (size_t i = 0; i < l_wallet_internal->certs_count; ++i) {
         dap_sign_type_t l_sign_type = dap_sign_type_from_key_type(l_wallet_internal->certs[i]->enc_key->type);
         if (SIG_TYPE_BLISS == l_sign_type.type || SIG_TYPE_PICNIC == l_sign_type.type || SIG_TYPE_TESLA == l_sign_type.type) {
-            return "The Bliss, Picnic and Tesla signatures is deprecated. We recommend you to create a new wallet with another available signature and transfer funds there.";
+            return "The Bliss, Picnic and Tesla signatures is deprecated. We recommend you to create a new wallet with another available signature and transfer funds there.\n";
         }
     }
     return "";