diff --git a/dap-sdk b/dap-sdk
index c68d541df022ed50c0daef6367ba6b10e1408c90..1df644274f2d0aecea9cc46d2c691035ec01a9c3 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit c68d541df022ed50c0daef6367ba6b10e1408c90
+Subproject commit 1df644274f2d0aecea9cc46d2c691035ec01a9c3
diff --git a/modules/chain/dap_chain_policy.c b/modules/chain/dap_chain_policy.c
new file mode 100644
index 0000000000000000000000000000000000000000..2b6e06c41c0b9d65cef64779d6c62e798e16941a
--- /dev/null
+++ b/modules/chain/dap_chain_policy.c
@@ -0,0 +1,375 @@
+/*
+* Authors:
+* Pavel Uhanov <pavel.uhanov@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2025
+* All rights reserved.
+
+This file is part of CellFrame SDK the open source project
+
+CellFrame SDK is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+CellFrame SDK is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dap_chain_policy.h"
+#include "dap_chain_datum_decree.h"
+#include "dap_list.h"
+#include "uthash.h"
+
+#define LOG_TAG "dap_chain_policy"
+
+typedef struct dap_chain_net dap_chain_net_t;
+
+struct net_policy_item {
+    uint64_t net_id;
+    uint32_t last_num_policy;
+    dap_list_t *exception_list;
+    dap_list_t *policies;
+    UT_hash_handle hh;
+};
+
+static struct net_policy_item *s_net_policy_items = NULL;
+
+/**
+ * @brief search net element in list by id
+ * @param a_net_id
+ * @return pointer if find, NULL if not
+ */
+DAP_STATIC_INLINE struct net_policy_item *s_net_item_find(uint64_t a_net_id)
+{
+    struct net_policy_item *l_item = NULL;
+    HASH_FIND_BYHASHVALUE(hh, s_net_policy_items, &a_net_id, sizeof(a_net_id), a_net_id, l_item);
+    return l_item;
+}
+
+DAP_STATIC_INLINE int s_policy_num_compare(dap_list_t  *a_list1, dap_list_t  *a_list2)
+{
+    dap_chain_policy_t
+        *l_policy1 = a_list1->data,
+        *l_policy2 = a_list2->data;
+    if (l_policy1->type != DAP_CHAIN_POLICY_ACTIVATE || l_policy2->type != DAP_CHAIN_POLICY_ACTIVATE) {
+        log_it(L_WARNING, "Compare wrong policy type");
+        return 0;
+    }
+    return ((dap_chain_policy_activate_t *)(l_policy1->data))->num == ((dap_chain_policy_activate_t *)(l_policy2->data))->num ? 0 :
+        ((dap_chain_policy_activate_t *)(l_policy1->data))->num > ((dap_chain_policy_activate_t *)(l_policy2->data))->num ? 1 : -1;
+}
+
+DAP_STATIC_INLINE bool s_policy_is_cond(dap_chain_policy_t *a_policy)
+{
+    return a_policy->type == DAP_CHAIN_POLICY_ACTIVATE &&
+        (DAP_FLAG_CHECK(a_policy->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS) ||
+        DAP_FLAG_CHECK(a_policy->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM));
+}
+
+static bool s_policy_cond_activated(dap_chain_policy_activate_t *a_policy_activate, uint64_t a_flags)
+{
+    bool l_ret = false;
+    if (DAP_FLAG_CHECK(a_flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS)) {
+        time_t l_current_time = dap_time_now();
+        l_ret |= l_current_time >= a_policy_activate->ts_start;
+    }
+    if (DAP_FLAG_CHECK(a_flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM)) {
+        if (!a_policy_activate->chain_union.chain) {
+            log_it(L_ERROR, "Chain is null in policy item with upped DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM flag");
+            return l_ret;
+        }
+        l_ret |= a_policy_activate->chain_union.chain->atom_num_last >= a_policy_activate->block_start;
+    }
+    return l_ret;
+}
+
+/**
+ * @brief init policy commands
+ * @return 0 if pass, other if error
+ */
+int dap_chain_policy_init()
+{
+    return 0;
+}
+
+/**
+ * @brief deinit policy commands
+ */
+void dap_chain_policy_deinit()
+{
+    struct net_policy_item
+        *l_temp = NULL,
+        *l_current = NULL;
+    HASH_ITER(hh, s_net_policy_items, l_current, l_temp) {
+        HASH_DEL(s_net_policy_items, l_current);
+        dap_list_free_full(l_current->policies, NULL);
+        dap_list_free(l_current->exception_list);
+        DAP_DELETE(l_current);
+    }
+}
+
+/**
+ * @brief add new net to policies list
+ * @param a_net_id
+ * @return 0 if pass, other if error
+ */
+int dap_chain_policy_net_add(uint64_t a_net_id)
+{
+    dap_return_val_if_pass(!a_net_id, -1);
+    if(s_net_item_find(a_net_id)) {
+        log_it(L_ERROR, "Net with id %"DAP_UINT64_FORMAT_X" already added", a_net_id);
+        return -2;
+    }
+    struct net_policy_item *l_new_item = DAP_NEW_Z_RET_VAL_IF_FAIL(struct net_policy_item, -3);
+    l_new_item->net_id = a_net_id;
+    HASH_ADD_BYHASHVALUE(hh, s_net_policy_items, net_id, sizeof(l_new_item->net_id), l_new_item->net_id, l_new_item);
+    return 0;
+}
+
+/**
+ * @brief remove net from policies list
+ * @param a_net_id
+ * @return 0 if pass, other if error
+ */
+int dap_chain_policy_net_remove(uint64_t a_net_id)
+{
+    dap_return_val_if_pass(!a_net_id, -1);
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    if (!l_net_item) {
+        log_it(L_ERROR, "Can't find net %"DAP_UINT64_FORMAT_X" in policy list", a_net_id);
+        return -2;
+    }
+    HASH_DEL(s_net_policy_items, l_net_item);
+    dap_list_free_full(l_net_item->policies, NULL);
+    dap_list_free(l_net_item->exception_list);
+    DAP_DELETE(l_net_item);
+    return 0;
+}
+
+/**
+ * @brief add new policy
+ * @param a_policy_num
+ * @param a_net_id net id
+ * @return 0 if pass, other if error
+ */
+int dap_chain_policy_add(dap_chain_policy_t *a_policy, uint64_t a_net_id)
+{
+    dap_return_val_if_pass(!a_policy, -1);
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    if (!l_net_item) {
+        log_it(L_ERROR, "Can't find net %"DAP_UINT64_FORMAT_X" in policy list", a_net_id);
+        return -2;
+    }
+    switch (a_policy->type) {
+        case DAP_CHAIN_POLICY_ACTIVATE:
+            if (dap_list_find(l_net_item->policies, a_policy, s_policy_num_compare)) {
+                log_it(L_ERROR, "CN-%u already added to net %"DAP_UINT64_FORMAT_X, ((dap_chain_policy_activate_t *)(a_policy->data))->num, a_net_id);
+                return -3;
+            }
+            l_net_item->policies = dap_list_insert_sorted(l_net_item->policies, a_policy, s_policy_num_compare);
+            if (!s_policy_is_cond(a_policy))
+                l_net_item->last_num_policy = dap_max(((dap_chain_policy_activate_t *)(a_policy->data))->num, l_net_item->last_num_policy);
+            break;
+        case DAP_CHAIN_POLICY_DEACTIVATE:
+            for (size_t i = 0; i < ((dap_chain_policy_deactivate_t *)(a_policy->data))->count; ++i) {
+                uint32_t l_policy_num = ((dap_chain_policy_deactivate_t *)(a_policy->data))->nums[i];
+                if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_policy_num, NULL)) {
+                    log_it(L_ERROR, "CN-%u already added to exception list net %"DAP_UINT64_FORMAT_X, l_policy_num, a_net_id);
+                    continue;
+                }
+                l_net_item->exception_list = dap_list_append(l_net_item->exception_list, (void *)(uintptr_t)l_policy_num);
+            }
+            break;
+        default:
+            log_it(L_ERROR, "Unknow policy type %u", a_policy->type);
+            break;
+    }
+    return 0;
+}
+
+/**
+ * @brief add policy num to exception list
+ * @param a_policy_num
+ * @param a_net_id net id
+ * @return 0 if pass, other if error
+ */
+int dap_chain_policy_add_to_exception_list(uint32_t a_policy_num, uint64_t a_net_id)
+{
+    dap_return_val_if_pass(!a_policy_num, -1);
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    if (!l_net_item) {
+        log_it(L_ERROR, "Can't find net %"DAP_UINT64_FORMAT_X" in policy list", a_net_id);
+        return -2;
+    }
+    if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)a_policy_num, NULL)) {
+        log_it(L_ERROR, "CN-%u already added to exception list net %"DAP_UINT64_FORMAT_X, a_policy_num, a_net_id);
+        return -3;
+    }
+    l_net_item->exception_list = dap_list_append(l_net_item->exception_list, (void *)(uintptr_t)a_policy_num);
+    return 0;
+}
+
+/**
+ * @brief check policy activation
+ * @param a_policy_num
+ * @param a_net_id net id
+ * @return true if yes, false if no
+ */
+bool dap_chain_policy_activated(uint32_t a_policy_num, uint64_t a_net_id)
+{
+    const bool l_ret_false = false;
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    dap_return_val_if_pass(!l_net_item, l_ret_false);
+    // exception list check
+    if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)a_policy_num, NULL))
+        return l_ret_false;
+    // seach politics to condition check
+    dap_chain_policy_t *l_to_search = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_activate_t), false);
+    l_to_search->type = DAP_CHAIN_POLICY_ACTIVATE;
+    ((dap_chain_policy_activate_t *)(l_to_search->data))->num = a_policy_num;
+    dap_list_t *l_list_item = dap_list_find(l_net_item->policies, l_to_search, s_policy_num_compare);
+    DAP_DELETE(l_to_search);
+    if (l_list_item && s_policy_is_cond((dap_chain_policy_t *)l_list_item->data)) {
+        dap_chain_policy_activate_t *l_activate = (dap_chain_policy_activate_t *)((dap_chain_policy_t *)(l_list_item->data))->data;
+        bool l_ret = s_policy_cond_activated(l_activate, ((dap_chain_policy_t *)l_list_item->data)->flags);
+        if (l_ret)
+            l_net_item->last_num_policy = dap_max(l_activate->num, l_net_item->last_num_policy);
+        return l_ret;
+    }
+    // cumulative return
+    return a_policy_num <= l_net_item->last_num_policy;
+}
+
+/**
+ * @brief find policy
+ * @param a_policy_num
+ * @param a_net_id net id
+ * @return true if yes, false if no
+ */
+dap_chain_policy_t *dap_chain_policy_find(uint32_t a_policy_num, uint64_t a_net_id)
+{
+    dap_return_val_if_pass(!a_policy_num, NULL);
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    dap_return_val_if_pass(!l_net_item, NULL);
+
+    dap_chain_policy_t *l_to_search = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_activate_t), false);
+    l_to_search->type = DAP_CHAIN_POLICY_ACTIVATE;
+    ((dap_chain_policy_activate_t *)(l_to_search->data))->num = a_policy_num;
+    dap_list_t *l_find = dap_list_find(l_net_item->policies, l_to_search, s_policy_num_compare);
+    DAP_DELETE(l_to_search);
+    if (!l_find) {
+        log_it(L_DEBUG, "Can't find CN-%u in net %"DAP_UINT64_FORMAT_X, a_policy_num, a_net_id);
+        return NULL;
+    }
+    return (dap_chain_policy_t *)l_find->data;
+}
+
+/**
+ * @brief return last policy num in enet
+ * @param a_net_id net id to search
+ * @return last num
+ */
+DAP_INLINE uint32_t dap_chain_policy_get_last_num(uint64_t a_net_id)
+{
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    dap_return_val_if_pass(!l_net_item, 0);
+    return l_net_item->last_num_policy;
+}
+
+
+json_object *dap_chain_policy_list(uint64_t a_net_id)
+{
+    struct net_policy_item *l_net_item = s_net_item_find(a_net_id);
+    dap_return_val_if_pass(!l_net_item, NULL);
+    json_object *l_ret = json_object_new_object();
+
+    dap_string_t *l_active_str = dap_string_new("");
+    dap_string_t *l_inactive_str = dap_string_new("");
+    if (l_net_item->last_num_policy)
+        dap_string_append_printf(l_active_str, "%s CN-%u ", dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_net_item->last_num_policy, NULL) ? "<" : "<=", l_net_item->last_num_policy);
+    json_object_object_add(l_ret, "cumulative active", json_object_new_string(l_active_str->str));
+    dap_string_erase(l_active_str, 0, -1);
+    for (dap_list_t *l_iter = dap_list_first(l_net_item->policies); l_iter; l_iter = l_iter->next) {
+        dap_chain_policy_activate_t *l_policy_activate =  (dap_chain_policy_activate_t *)((dap_chain_policy_t *)(l_iter->data))->data;
+        if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_policy_activate->num, NULL))
+            continue;
+        if (s_policy_is_cond((dap_chain_policy_t *)(l_iter->data))) {
+            if (s_policy_cond_activated(l_policy_activate, ((dap_chain_policy_t *)(l_iter->data))->flags))
+                dap_string_append_printf(l_active_str, "CN-%u ", l_policy_activate->num);
+            else
+                dap_string_append_printf(l_inactive_str, "CN-%u ", l_policy_activate->num);
+        }
+    }
+    json_object_object_add(l_ret, "conditional active", json_object_new_string(l_active_str->str));
+    json_object_object_add(l_ret, "conditional inactive", json_object_new_string(l_inactive_str->str));
+    
+    dap_string_free(l_active_str, true);
+    dap_string_erase(l_inactive_str, 0, -1);
+    for (dap_list_t *l_iter = dap_list_first(l_net_item->exception_list); l_iter; l_iter = l_iter->next) {
+        dap_string_append_printf(l_inactive_str, "CN-%u ", (uint32_t)(uintptr_t)l_iter->data);
+    }
+    json_object_object_add(l_ret, "exception list", json_object_new_string(l_inactive_str->str));
+    dap_string_free(l_inactive_str, true);
+    return l_ret;
+}
+
+json_object *dap_chain_policy_json_collect(dap_chain_policy_t *a_policy)
+{
+    dap_return_val_if_pass(!a_policy, NULL);
+    json_object *l_ret = json_object_new_object();
+
+    json_object_object_add(l_ret, "version", json_object_new_uint64(a_policy->version));
+    json_object_object_add(l_ret, "type", json_object_new_string(dap_chain_policy_to_str(a_policy)));
+    switch (a_policy->type) {
+        case DAP_CHAIN_POLICY_ACTIVATE: {
+            dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)a_policy->data;
+            json_object_object_add(l_ret, "num", json_object_new_uint64(l_policy_activate->num));
+            if (l_policy_activate->ts_start) {
+                char l_time[DAP_TIME_STR_SIZE] = {};
+                dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, l_policy_activate->ts_start);
+                json_object_object_add(l_ret, "ts_start", json_object_new_string(l_time));
+            } else {
+                json_object_object_add(l_ret, "ts_start", json_object_new_int(0));
+            }
+            json_object_object_add(l_ret, "block_start", json_object_new_uint64(l_policy_activate->block_start));
+            if (l_policy_activate->block_start) {
+                if (!l_policy_activate->chain_union.chain) {
+                    json_object_object_add(l_ret, "chain", json_object_new_string("ERROR pointer chain is NULL"));
+                } else {
+                    char l_chain_id[32] = { };
+                    snprintf(l_chain_id, sizeof(l_chain_id) - 1, "0x%016"DAP_UINT64_FORMAT_x, l_policy_activate->chain_union.chain->id.uint64);
+                    json_object_object_add(l_ret, "chain", json_object_new_string(l_chain_id));
+                }
+            } else {
+                json_object_object_add(l_ret, "chain", json_object_new_string(""));
+            }
+            json_object_object_add(l_ret, "description", json_object_new_string("WIKI"));
+        }
+            break;
+        
+        case DAP_CHAIN_POLICY_DEACTIVATE: {
+            dap_chain_policy_deactivate_t *l_policy_deactivate = (dap_chain_policy_deactivate_t *)a_policy->data;
+            if (l_policy_deactivate->count) {
+                dap_string_t *l_nums_list = dap_string_sized_new(l_policy_deactivate->count * (sizeof(uint32_t) + 4));
+                for (size_t i = 0; i < l_policy_deactivate->count; ++i) {
+                    dap_string_append_printf(l_nums_list, "CN-%u ", l_policy_deactivate->nums[i]);
+                }
+                json_object_object_add(l_ret, "deactivate", json_object_new_string(l_nums_list->str));
+                dap_string_free(l_nums_list, true);
+            } else {
+                json_object_object_add(l_ret, "deactivate", json_object_new_string(""));
+            }
+        }
+            break;
+        default:
+            break;
+    }
+    return l_ret;
+}
\ No newline at end of file
diff --git a/modules/chain/include/dap_chain_policy.h b/modules/chain/include/dap_chain_policy.h
new file mode 100644
index 0000000000000000000000000000000000000000..883e8469c5a942e044b34c65710af201c12e097c
--- /dev/null
+++ b/modules/chain/include/dap_chain_policy.h
@@ -0,0 +1,109 @@
+/*
+* Authors:
+* Pavel Uhanov <pavel.uhanov@demlabs.net>
+* Cellframe       https://cellframe.net
+* DeM Labs Inc.   https://demlabs.net
+* Copyright  (c) 2017-2025
+* All rights reserved.
+
+This file is part of CellFrame SDK the open source project
+
+CellFrame SDK is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+CellFrame SDK is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "dap_common.h"
+#include "dap_chain.h"
+
+#define DAP_CHAIN_POLICY_VERSION                1
+
+#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS            BIT(0)
+#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM     BIT(1)
+#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG        BIT(2)
+
+
+typedef enum {
+    DAP_CHAIN_POLICY_DEACTIVATE = 0,
+    DAP_CHAIN_POLICY_ACTIVATE
+} dap_chain_policy_type_t;
+
+typedef struct dap_chain_policy_deactivate {
+    uint32_t count;
+    uint32_t nums[];
+} DAP_ALIGN_PACKED dap_chain_policy_deactivate_t;
+
+
+typedef struct dap_chain_policy_activate {
+    uint32_t num;
+    int64_t ts_start;
+    uint64_t block_start;
+    union {
+        dap_chain_id_t chain_id;
+        dap_chain_t *chain;
+    } chain_union;
+    uint16_t generation;
+} DAP_ALIGN_PACKED dap_chain_policy_activate_t;
+
+typedef struct dap_chain_policy {
+    uint16_t version;
+    uint16_t type;
+    uint64_t flags;
+    uint64_t data_size;
+    uint8_t data[];
+} DAP_ALIGN_PACKED dap_chain_policy_t;
+
+int dap_chain_policy_init();
+void dap_chain_policy_deinit();
+int dap_chain_policy_net_add(uint64_t a_net_id);
+int dap_chain_policy_net_remove(uint64_t a_net_id);
+int dap_chain_policy_add(dap_chain_policy_t *a_policy, uint64_t a_net_id);
+int dap_chain_policy_add_to_exception_list(uint32_t a_policy_num, uint64_t a_net_id);
+uint32_t dap_chain_policy_get_last_num(uint64_t a_net_id);
+dap_chain_policy_t *dap_chain_policy_find(uint32_t a_policy_num, uint64_t a_net_id);
+json_object *dap_chain_policy_json_collect(dap_chain_policy_t *a_policy);
+json_object *dap_chain_policy_list(uint64_t a_net_id);
+bool dap_chain_policy_activated(uint32_t a_policy_num, uint64_t a_net_id);
+
+DAP_STATIC_INLINE size_t dap_chain_policy_deactivate_calc_size(size_t a_deactivate_count)
+{
+    return sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_deactivate_t) + sizeof(uint32_t) * a_deactivate_count;
+}
+
+DAP_STATIC_INLINE size_t dap_chain_policy_get_size(dap_chain_policy_t *a_policy)
+{
+    return a_policy ? sizeof(dap_chain_policy_t)  + a_policy->data_size : 0;
+}
+
+DAP_STATIC_INLINE const char *dap_chain_policy_to_str(dap_chain_policy_t *a_policy)
+{
+    if(!a_policy)
+        return "NULL";
+    switch (a_policy->type) {
+        case DAP_CHAIN_POLICY_ACTIVATE: return ("DAP_CHAIN_POLICY_ACTIVATE");
+        case DAP_CHAIN_POLICY_DEACTIVATE: return ("DAP_CHAIN_POLICY_DEACTIVATE");
+        default: return ("UNKNOWN");
+    }
+}
+
+/**
+ * @brief check policy num
+ * @param a_num
+ * @return true if valid, fail if not
+ */
+DAP_STATIC_INLINE bool dap_chain_policy_num_is_valid(uint64_t a_num)
+{
+    uint32_t l_num = dap_maxval(l_num);
+    return (a_num && a_num <= l_num);
+}
\ No newline at end of file
diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c
index 2f61eab67173449aec7130caafa0e0fa8789f4c7..be040aaeb615f2c41983bb88dd58a70b317b3dbd 100644
--- a/modules/common/dap_chain_datum_decree.c
+++ b/modules/common/dap_chain_datum_decree.c
@@ -28,6 +28,7 @@
 #include "dap_chain_datum_decree.h"
 #include "dap_enc_base58.h"
 #include "dap_chain_common.h"
+#include "dap_chain_policy.h"
 #ifdef DAP_OS_UNIX
 #include <arpa/inet.h>
 #endif
@@ -177,9 +178,14 @@ dap_pkey_t *dap_chain_datum_decree_get_pkey(dap_chain_datum_decree_t *a_decree)
 {
     dap_return_val_if_fail(a_decree, NULL);
     dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY);
-    if (!l_tsd)
-        return NULL;
-    return dap_pkey_get_size((dap_pkey_t *)l_tsd->data) == l_tsd->size ? (dap_pkey_t *)l_tsd->data : NULL;
+    return (l_tsd && dap_pkey_get_size((dap_pkey_t *)l_tsd->data) == l_tsd->size) ? (dap_pkey_t *)l_tsd->data : NULL;
+}
+
+dap_chain_policy_t *dap_chain_datum_decree_get_policy(dap_chain_datum_decree_t *a_decree)
+{
+    dap_return_val_if_fail(a_decree, NULL);
+    dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE);
+    return (l_tsd  && dap_chain_policy_get_size((dap_chain_policy_t *)l_tsd->data) == l_tsd->size) ? (dap_chain_policy_t *)l_tsd->data : NULL;
 }
 
 void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type)
@@ -348,7 +354,14 @@ void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_d
                 break;
             }
             json_object_object_add(a_json_out, "pkey type", json_object_new_string( dap_pkey_type_to_str(((dap_pkey_t *)(l_tsd->data))->header.type) ));
-            break; 
+            break;
+        case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE:
+            if (l_tsd->size != dap_chain_policy_get_size((dap_chain_policy_t *)(l_tsd->data))) {
+                json_object_object_add(a_json_out, "policy_type", json_object_new_string("WRONG SIZE"));
+                break;
+            }
+            json_object_object_add(a_json_out, "policy_type", json_object_new_string( dap_chain_policy_to_str((dap_chain_policy_t *)(l_tsd->data))));
+            break;
         default:
             json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string(""));
             break;
diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h
index f8a49f0a39b5cb20247504ee040204c056a6d9ac..fceff87616ecf26f12f2576bda89a06fbdfa8d59 100644
--- a/modules/common/include/dap_chain_datum_decree.h
+++ b/modules/common/include/dap_chain_datum_decree.h
@@ -27,6 +27,7 @@
 #include "dap_time.h"
 #include "dap_list.h"
 #include "dap_cert.h"
+#include "dap_chain_policy.h"
 #include <stdint.h>
 
 #define DAP_CHAIN_DATUM_DECREE_VERSION  0
@@ -75,7 +76,8 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT                    0x000C
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS          0x000D
 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE         0x000E
-#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE             0x0010 
+#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE             0x0010
+#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_POLICY                        0x0012
 
 // DECREE TSD types
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE                               0x0100
@@ -94,7 +96,8 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING                              0x0115
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION                              0x010A
 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE                      0x010B
-#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY                          0x010D 
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY                          0x010D
+#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE                      0x010E 
 
 
 #ifdef __cplusplus
@@ -132,6 +135,8 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d
         return "DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE";
     case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE:
         return "DECREE_COMMON_SUBTYPE_STAKE_UPDATE";
+    case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_POLICY:
+        return "DECREE_COMMON_SUBTYPE_POLICY";
     default:
         return "DECREE_SUBTYPE_UNKNOWN";
     }
@@ -166,6 +171,8 @@ DAP_STATIC_INLINE uint16_t dap_chain_datum_decree_type_from_str(const char *a_de
         return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE;
     } else if (!dap_strcmp(a_decree_type, "stake_update")) {
         return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE;
+    } else if (!dap_strcmp(a_decree_type, "policy")) {
+        return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_POLICY;
     } else {
         return 0;
     }
@@ -207,6 +214,8 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_
          return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE";
     case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY:
          return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY";
+    case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE:
+         return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE";
     default:
         return "DECREE_TSD_TYPE_UNKNOWN";
     }
@@ -315,6 +324,12 @@ int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_
 int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type);
 int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr);
 dap_pkey_t *dap_chain_datum_decree_get_pkey(dap_chain_datum_decree_t *a_decree);
+/**
+ * @brief get policy from decree tsd
+ * @param a_decree
+ * @return pointer to dap_chain_policy_t if find, if not or error - NULL
+ */
+dap_chain_policy_t *dap_chain_datum_decree_get_policy(dap_chain_datum_decree_t *a_decree);
 
 /**
  * @breif dap_chain_datum_decree_dump Dump information about decree
@@ -358,7 +373,6 @@ void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a
 dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree,
                                                   size_t a_certs_count, size_t *a_total_sign_count);
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index f7cb0fea80639e403d166760c87405e9855f80c3..a1950dc3422c605aa006732f37d2464b8f395829 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -108,6 +108,8 @@
 #include "dap_http_ban_list_client.h"
 #include "dap_net.h"
 #include "dap_context.h"
+#include "dap_chain_cs_esbocs.h"
+#include "dap_chain_policy.h"
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -775,6 +777,39 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg)
                                 l_net_name_str),
                 NULL;
     log_it (L_NOTICE, "Node role \"%s\" selected for network '%s'", a_node_role, l_net_name_str);
+    
+    if (dap_chain_policy_net_add(l_ret->pub.id.uint64)) {
+        log_it(L_ERROR, "Can't add net %s to policy module", l_ret->pub.name);
+        DAP_DEL_MULTY(l_ret->pub.name, l_ret);
+        return NULL;
+    }
+    // activate policy
+    uint64_t l_policy_num = dap_config_get_item_uint64(a_cfg, "policy", "activate");
+    dap_chain_policy_t *l_new_policy = NULL;
+    if (l_policy_num) {
+        if (!dap_chain_policy_num_is_valid(l_policy_num)) {
+            log_it(L_ERROR, "Can't add policy CN-%"DAP_UINT64_FORMAT_U, l_policy_num);
+        } else {
+            dap_chain_policy_t *l_new_policy = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, sizeof(dap_chain_policy_activate_t), NULL, l_ret->pub.name, l_ret); 
+            l_new_policy->type = DAP_CHAIN_POLICY_ACTIVATE;
+            l_new_policy->version = DAP_CHAIN_POLICY_VERSION;
+            ((dap_chain_policy_activate_t *)(l_new_policy->data))->num = l_policy_num;
+            l_new_policy->flags = DAP_FLAG_ADD(l_new_policy->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG);
+            dap_chain_policy_add(l_new_policy, l_ret->pub.id.uint64);
+        }
+    }
+    // deactivate policy
+    uint16_t l_policy_count = 0;
+    const char **l_policy_str = dap_config_get_array_str(a_cfg, "policy", "deactivate", &l_policy_count);
+    for (uint16_t i = 0; i < l_policy_count; ++i) {
+        l_policy_num = strtoull(l_policy_str[i], NULL, 10);
+        if (!dap_chain_policy_num_is_valid(l_policy_num)) {
+            log_it(L_ERROR, "Can't add policy CN-%"DAP_UINT64_FORMAT_U" to exception list", l_policy_num);
+        } else {
+            dap_chain_policy_add_to_exception_list(l_policy_num, l_ret->pub.id.uint64);
+        }
+    }
+    
     l_ret->pub.config = a_cfg;
     l_ret->pub.gdb_groups_prefix
         = dap_config_get_item_str_default( a_cfg, "general", "gdb_groups_prefix", dap_config_get_item_str(a_cfg, "general", "name") );
@@ -1783,6 +1818,7 @@ void dap_chain_net_deinit()
         dap_chain_net_delete(l_net);
     }
     dap_http_ban_list_client_deinit();
+    dap_chain_policy_deinit();
 }
 
 /**
@@ -1820,6 +1856,7 @@ void dap_chain_net_delete(dap_chain_net_t *a_net)
             dap_chain_delete(l_cur);
         }
     }
+    dap_chain_policy_net_remove(a_net->pub.id.uint64);
     HASH_DEL(s_nets_by_name, a_net);
     HASH_DELETE(hh2, s_nets_by_id, a_net);
     DAP_DELETE(a_net);
@@ -2511,7 +2548,7 @@ DAP_INLINE dap_chain_net_state_t dap_chain_net_get_state (dap_chain_net_t *a_net
     return PVT(a_net)->state;
 }
 
-dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t *a_net)
+dap_chain_cell_id_t *dap_chain_net_get_cur_cell( dap_chain_net_t *a_net)
 {
     return  PVT(a_net)->node_info ? &PVT(a_net)->node_info->cell_id: 0;
 }
@@ -2865,7 +2902,7 @@ int dap_chain_datum_remove(dap_chain_t *a_chain, dap_chain_datum_t *a_datum, siz
     return 0;
 }
 
-bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net)
+DAP_INLINE bool dap_chain_net_get_load_mode(dap_chain_net_t * a_net)
 {
     return PVT(a_net)->state == NET_STATE_LOADING;
 }
diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c
index 509e4e6af5089c1392e43ce6c0fdbbb03924540c..cc93696978515291da98da74b80986254bec10f0 100644
--- a/modules/net/dap_chain_net_decree.c
+++ b/modules/net/dap_chain_net_decree.c
@@ -33,6 +33,7 @@
 #include "dap_chain_net_tx.h"
 #include "dap_chain_net_srv_stake_pos_delegate.h"
 #include "dap_http_ban_list_client.h"
+#include "dap_chain_policy.h"
 
 
 
@@ -632,6 +633,22 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
                 break;
             dap_chain_esbocs_set_emergency_validator(l_chain, l_action, l_sign_type, &l_hash);
         } break;
+        case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_POLICY: {
+            if (!a_apply)
+                break;
+            dap_chain_policy_t *l_policy = NULL;
+            if ( !(l_policy = dap_chain_datum_decree_get_policy(a_decree)) ){
+                log_it(L_WARNING,"Can't get policy from decree.");
+                return -105;
+            }
+            l_policy = DAP_DUP_SIZE_RET_VAL_IF_FAIL(l_policy, dap_chain_policy_get_size(l_policy), -106);
+            if (l_policy->type == DAP_CHAIN_POLICY_ACTIVATE) {
+                dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)l_policy->data;
+                if(DAP_FLAG_CHECK(l_policy->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM))
+                    l_policy_activate->chain_union.chain = dap_chain_find_by_id(a_net->pub.id, l_policy_activate->chain_union.chain_id);
+            }
+            return dap_chain_policy_add(l_policy, a_net->pub.id.uint64);
+        }
         default:
             return -1;
     }
diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c
index 2ef482d1e92fb948fdb369bd5b9485be9a986f91..2f6fe124db9572ca9ae88cbd581e2603493bb0af 100644
--- a/modules/net/dap_chain_node_cli.c
+++ b/modules/net/dap_chain_node_cli.c
@@ -354,6 +354,26 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
                            "\tTypes decree: fee, owners, owners_min, stake_approve, stake_invalidate, min_value, "
                            "min_validators_count, ban, unban, reward, validator_max_weight, emergency_validators, check_signs_structure\n");
 
+
+    dap_cli_server_cmd_add ("policy", com_policy, "Policy commands",
+                "policy activate - prepare policy activate decree\n"
+                "\t[execute] - used to create policy decree, otherwise show policy decree draft\n"
+                "\t-net <net_name>\n"
+                "\t-num <policy_num>\n"
+                "\t[-ts_start <dd/mm/yy-H:M:S>] - date to start policy\n"
+                "\t[{\n\t\t-block_start <block_num> - block num to start policy\n"
+                "\t\t-chain <chain_name> - chain name to check blocks num\n\t}]\n"
+                "\t-certs <cert1[,cert2,...,certN]> - list signing certs\n"
+                "policy deactivate - prepare policy deactivate decree\n"
+                "\t[execute] - used to create policy decree, otherwise show policy decree draft\n"
+                "\t-net <net_name>\n"
+                "\t-num <num1[,num2,...,numN]> - deactivated policy list\n"
+                "\t-certs <cert1[,cert2,...,certN]> - list signing certs\n"
+                "policy find - find info about policy in net\n"
+                "\t-net <net_name>\n"
+                "\t-num <policy_num>\n"
+                "policy list - show all policies from table in net\n"
+                "\t-net <net_name>\n");
     // Exit - always last!
     dap_cli_server_cmd_add ("exit", com_exit, "Stop application and exit",
                 "exit\n" );
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 0ed75d90af413864d881810dd6ddcc16d7b8062e..e68f46be1218fe7b8953f8e4e352e2e7ceedc22f 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -105,6 +105,11 @@
 #include "dap_client_pvt.h"
 #include "dap_enc.h"
 #include "dap_notify_srv.h"
+#include "dap_chain_wallet_cache.h"
+#include "dap_chain_net_srv_stake_pos_delegate.h"
+#include "dap_chain_policy.h"
+#include "dap_time.h"
+
 
 #include "dap_chain_net_tx.h"
 
@@ -8211,3 +8216,274 @@ int com_exec_cmd(int argc, char **argv, void **reply) {
     dap_json_rpc_request_free(l_request);
     return 0;
 }
+
+static dap_chain_datum_decree_t *s_decree_policy_execute(dap_chain_net_t *a_net, dap_chain_policy_t *a_policy)
+{
+    dap_return_val_if_pass(!a_net || !a_policy, NULL);
+    // create updating decree
+    size_t l_total_tsd_size = sizeof(dap_tsd_t) + dap_chain_policy_get_size(a_policy);
+
+    dap_chain_t *l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE);
+    if (!l_chain) {
+        log_it(L_ERROR, "No chain supported decree datum type");
+        return NULL;
+    }
+
+    dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, l_chain->id, *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size);
+    if (!l_decree) {
+        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
+        return NULL;
+    }
+    l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_POLICY;
+    dap_tsd_write((byte_t*)l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE, a_policy, dap_chain_policy_get_size(a_policy));
+
+    return l_decree;
+}
+
+// Put the decree to mempool
+static char *s_decree_policy_put(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net)
+{
+    size_t l_decree_size = dap_chain_datum_decree_get_size(a_decree);
+    dap_chain_datum_t *l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_DECREE, a_decree, l_decree_size);
+    dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE);
+    if (!l_chain)
+        l_chain =  dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_DECREE);
+    if (!l_chain) {
+        log_it(L_ERROR, "No chain supported decree datum type");
+        return NULL;
+    }
+    // Processing will be made according to autoprocess policy
+    char *l_ret = dap_chain_mempool_datum_add(l_datum, l_chain, "hex");
+    DAP_DELETE(l_datum);
+    return l_ret;
+}
+
+int com_policy(int argc, char **argv, void **reply) {
+    json_object ** a_json_arr_reply = (json_object **) reply;
+    char **l_deactivate_array = NULL;
+    const char
+        *l_num_str = NULL,
+        *l_net_str = NULL,
+        *l_deactivate_str = NULL,
+        *l_chain_str = NULL,
+        *l_ts_start_str = NULL,
+        *l_block_start_str = NULL,
+        *l_certs_str = NULL;
+    size_t
+        l_deactivate_count = 0,
+        l_certs_count = 0;
+    dap_cert_t **l_certs = NULL;
+    uint64_t l_flags = 0;
+    bool l_execute = false;
+
+    enum { CMD_NONE = 0, CMD_ACTIVATE, CMD_DEACTIVATE, CMD_FIND, CMD_LIST };  
+    int l_arg_index = 1;
+
+    int l_cmd = CMD_NONE;
+    if (dap_cli_server_cmd_find_option_val(argv, 1, 2, "activate", NULL))
+        l_cmd = CMD_ACTIVATE;
+    else if (dap_cli_server_cmd_find_option_val(argv, 1, 2, "deactivate", NULL))
+            l_cmd = CMD_DEACTIVATE;
+    else if (dap_cli_server_cmd_find_option_val(argv, 1, 2, "find", NULL))
+        l_cmd = CMD_FIND;
+    else if (dap_cli_server_cmd_find_option_val(argv, 1, 2, "list", NULL))
+        l_cmd = CMD_LIST;
+
+    if (l_cmd == CMD_NONE) {
+        dap_json_rpc_error_add(*a_json_arr_reply, -4, "Unknown subcommand");
+        return -4;
+    }
+
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-net", &l_net_str);
+
+    if (!l_net_str) {
+        dap_json_rpc_error_add(*a_json_arr_reply, -3, "Command policy require args -net");
+        return -4;
+    }
+    dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
+    if (!l_net){
+        dap_json_rpc_error_add(*a_json_arr_reply, -3, "Can't find net %s", l_net_str);
+        return -4;
+    }
+
+    if (l_cmd == CMD_LIST) {
+        json_object *l_answer = dap_chain_policy_list(l_net->pub.id.uint64);
+        json_object_array_add(*a_json_arr_reply, l_answer);
+        return 0;
+    }
+
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-num", &l_num_str);
+    if (!l_num_str) {
+        dap_json_rpc_error_add(*a_json_arr_reply, -7, "Command policy require args -num");
+        return -7;
+    }
+
+    void *l_policy_data = NULL;
+    size_t l_data_size = 0;
+    uint64_t l_policy_num = 0;
+    int l_policy_type = -1;
+    if (l_cmd == CMD_DEACTIVATE) {
+        l_policy_type = DAP_CHAIN_POLICY_DEACTIVATE;
+        l_deactivate_count = dap_str_symbol_count(l_num_str, ',') + 1;
+        l_deactivate_array = dap_strsplit(l_num_str, ",", l_deactivate_count);
+        l_data_size = sizeof(dap_chain_policy_deactivate_t) + l_deactivate_count * sizeof(uint32_t);
+        l_policy_data = DAP_NEW_Z_SIZE(void, l_data_size);
+        if (!l_policy_data) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -16, "%s", c_error_memory_alloc);
+            dap_strfreev(l_deactivate_array);
+            return -16;
+        }
+        ((dap_chain_policy_deactivate_t *)l_policy_data)->count = l_deactivate_count;
+        for (size_t i = 0; i < l_deactivate_count; ++i) {
+            l_policy_num = strtoull(l_deactivate_array[i], NULL, 10);
+            if (!dap_chain_policy_num_is_valid(l_policy_num)) {
+                dap_json_rpc_error_add(*a_json_arr_reply, -16, "Policy nums sould be less or equal than %u and not equal 0", dap_maxval((uint32_t)l_policy_num));
+                dap_strfreev(l_deactivate_array);
+                DAP_DELETE(l_policy_data);
+                return -16;
+            }
+            ((dap_chain_policy_deactivate_t *)l_policy_data)->nums[i] = l_policy_num;
+        }
+        dap_strfreev(l_deactivate_array);
+    } else {
+        l_policy_num = strtoull(l_num_str, NULL, 10);
+        if (!dap_chain_policy_num_is_valid(l_policy_num)) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -16, "Policy num sould be less or equal than %u and not equal 0", dap_maxval((uint32_t)l_policy_num));
+            return -16;
+        }
+    }
+
+    uint32_t l_last_num = dap_chain_policy_get_last_num(l_net->pub.id.uint64);
+
+    if (l_cmd == CMD_FIND) {
+        dap_chain_policy_t *l_policy = dap_chain_policy_find(l_policy_num, l_net->pub.id.uint64);
+        json_object *l_answer = dap_chain_policy_json_collect(l_policy);
+        if (l_answer) {
+            json_object_object_add(l_answer, "active", json_object_new_string(dap_chain_policy_activated(((dap_chain_policy_activate_t *)(l_policy->data))->num, l_net->pub.id.uint64) ? "true" : "false"));
+            json_object_array_add(*a_json_arr_reply, l_answer);
+        } else {
+            json_object_array_add(*a_json_arr_reply, json_object_new_string("Detailed information not exist"));
+        }
+        return 0;
+    }
+
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-chain", &l_chain_str);
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-ts_start", &l_ts_start_str);
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-block_start", &l_block_start_str);
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-deactivate", &l_deactivate_str);
+    dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "-certs", &l_certs_str);
+    l_execute = dap_cli_server_cmd_find_option_val(argv, l_arg_index, argc, "execute", NULL);
+
+    if (l_execute) {
+        if (!l_certs_str) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -4, "Command 'execute' requires parameter -certs");
+            DAP_DELETE(l_policy_data);
+            return -4;
+        }
+        dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count);
+        if (!l_certs || !l_certs_count) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -5, "Specified certificates not found");
+            DAP_DELETE(l_policy_data);
+            return -5;
+        }
+    }
+
+    if (l_cmd == CMD_ACTIVATE) {
+        if (l_policy_num == l_last_num) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -15, "Specified policy num already existed");
+            return -15;
+        }
+        l_policy_type = DAP_CHAIN_POLICY_ACTIVATE;
+        l_data_size = sizeof(dap_chain_policy_activate_t);
+        l_policy_data = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(void, l_data_size, -5);
+        dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)l_policy_data;
+        
+        l_policy_activate->num = l_policy_num;
+        if (l_ts_start_str) {
+            l_policy_activate->ts_start = dap_time_from_str_custom(l_ts_start_str, "%d/%m/%y-%H:%M:%S");
+            if (!l_policy_activate->ts_start) {
+                dap_json_rpc_error_add(*a_json_arr_reply, -13, "Can't read ts_start \"%s\"", l_ts_start_str);
+                DAP_DELETE(l_policy_activate);
+                return -13;
+            }
+            l_flags = DAP_FLAG_ADD(l_flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS);
+        }
+
+        if (l_block_start_str)
+            l_policy_activate->block_start = strtoull(l_block_start_str, NULL, 10);
+        
+        if (l_policy_activate->block_start) {
+            if (!l_chain_str) {
+                dap_json_rpc_error_add(*a_json_arr_reply, -8, "Command policy create with -block_start require args -chain");
+                DAP_DELETE(l_policy_activate);
+                return -8;
+            }
+            dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str);
+            if (!l_chain) {
+                dap_json_rpc_error_add(*a_json_arr_reply, -9, "%s Chain not found", l_chain_str);
+                DAP_DELETE(l_policy_activate);
+                return -9;
+            }
+            l_policy_activate->chain_union.chain = l_chain;
+            l_flags = DAP_FLAG_ADD(l_flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM);
+        }
+        if (!l_flags && l_policy_activate->num < l_last_num) {
+            dap_json_rpc_error_add(*a_json_arr_reply, -16, "Specified policy already activated by CN-%u", l_last_num);
+            DAP_DELETE(l_policy_activate);
+            return -16;
+        }
+    }
+
+    dap_chain_policy_t *l_policy = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, l_data_size + sizeof(dap_chain_policy_t), -5, l_policy_data);
+    l_policy->data_size = l_data_size;
+    l_policy->version = DAP_CHAIN_POLICY_VERSION;
+    l_policy->type = l_policy_type;
+    l_policy->flags = l_flags;
+    memcpy(l_policy->data, l_policy_data, l_policy->data_size);
+    DAP_DELETE(l_policy_data);
+    // if cmd none - only print preaparing result
+    if (!l_execute) {
+        json_object *l_answer = dap_chain_policy_json_collect(l_policy);
+        char l_time[DAP_TIME_STR_SIZE] = {};
+        dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, dap_time_now());
+        json_object_object_add(l_answer, "Current time", json_object_new_string(l_time));
+        json_object_object_add(l_answer, "Notification", json_object_new_string("It's policy draft, check and use 'execute' command to apply"));
+        if (l_answer) {
+            json_object_array_add(*a_json_arr_reply, l_answer);
+        } else {
+            dap_json_rpc_error_add(*a_json_arr_reply, -11, "Policy draft creation failed");
+            DAP_DELETE(l_policy);
+            return -11;
+        }
+        DAP_DELETE(l_policy);
+        return 0;
+    }
+    // change pointer to id to decree
+    if (l_policy->type == DAP_CHAIN_POLICY_ACTIVATE && ((dap_chain_policy_activate_t *)(l_policy->data))->chain_union.chain) {
+        ((dap_chain_policy_activate_t *)(l_policy->data))->chain_union.chain_id = ((dap_chain_policy_activate_t *)(l_policy->data))->chain_union.chain->id;
+    }
+
+    dap_chain_datum_decree_t *l_decree = s_decree_policy_execute(l_net, l_policy);
+    DAP_DELETE(l_policy);
+    size_t l_total_signs_success = 0;
+    l_decree = dap_chain_datum_decree_sign_in_cycle(l_certs, l_decree, l_certs_count, &l_total_signs_success);
+
+    if (!l_decree || l_total_signs_success == 0){
+        dap_json_rpc_error_add(*a_json_arr_reply, -11, "Decree creation failed. Successful count of certificate signing is 0");
+            return -11;
+    }
+
+    char *l_decree_hash_str = NULL;;
+    if (!(l_decree_hash_str = s_decree_policy_put(l_decree, l_net))) {
+        dap_json_rpc_error_add(*a_json_arr_reply, -12, "Policy decree error");
+        return -12;
+    }
+    DAP_DELETE(l_decree);
+
+    char l_approve_str[128];
+    snprintf(l_approve_str, sizeof(l_approve_str), "Policy decree %s successfully created", l_decree_hash_str);
+    json_object_array_add(*a_json_arr_reply, json_object_new_string(l_approve_str));
+    DAP_DELETE(l_decree_hash_str);
+
+    return 0;
+}
diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h
index 7f8a39ea7d0adca1c4474306422d2688aa833d2c..fba416a4c88fb6da4595c5c4e74d2befc43e43f6 100644
--- a/modules/net/include/dap_chain_node_cli_cmd.h
+++ b/modules/net/include/dap_chain_node_cli_cmd.h
@@ -474,6 +474,11 @@ void dap_notify_new_client_send_info(dap_events_socket_t *a_es, void *a_arg);
 
 int com_exec_cmd(int argc, char **argv, void **reply);
 
+/**
+ * Policy management
+ */
+int com_policy(int a_argc, char **a_argv, void **a_str_reply);
+
 #ifdef __cplusplus
 }
 #endif
\ No newline at end of file