diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c
index 33032a2b09806a5f44b2ca43cb195fc768a4d20e..b153d5b86af6b78bf5e82bb1807e3ee41255d58d 100644
--- a/modules/net/dap_chain_net_tx.c
+++ b/modules/net/dap_chain_net_tx.c
@@ -31,6 +31,14 @@
 #include "dap_chain_tx.h"
 #include "dap_list.h"
 
+#include "dap_chain_datum_tx_receipt.h"
+#include "dap_chain_wallet.h"
+#include "dap_chain_datum_tx_voting.h"
+#include "json.h"
+#include "dap_chain_srv.h"
+#include "dap_chain_net_srv.h"
+#include "dap_enc_base64.h"
+
 #define LOG_TAG "dap_chain_net_tx"
 
 typedef struct cond_all_with_spends_by_srv_uid_arg{
@@ -537,3 +545,1191 @@ bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, da
 
     return true;
 }
+
+static const char* s_json_get_text(struct json_object *a_json, const char *a_key)
+{
+    if(!a_json || !a_key)
+        return NULL;
+    struct json_object *l_json = json_object_object_get(a_json, a_key);
+    if(l_json && json_object_is_type(l_json, json_type_string)) {
+        // Read text
+        return json_object_get_string(l_json);
+    }
+    return NULL;
+}
+
+static bool s_json_get_int64(struct json_object *a_json, const char *a_key, int64_t *a_out)
+{
+    if(!a_json || !a_key || !a_out)
+        return false;
+    struct json_object *l_json = json_object_object_get(a_json, a_key);
+    if(l_json) {
+        if(json_object_is_type(l_json, json_type_int)) {
+            // Read number
+            *a_out = json_object_get_int64(l_json);
+            return true;
+        } else if (json_object_is_type(l_json, json_type_string)){
+            // Read number
+            const char* l_value_text = json_object_get_string(l_json);
+            *a_out = atol(l_value_text);
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool s_json_get_unit(struct json_object *a_json, const char *a_key, dap_chain_net_srv_price_unit_uid_t *a_out)
+{
+    const char *l_unit_str = s_json_get_text(a_json, a_key);
+    if(!l_unit_str || !a_out)
+        return false;
+    dap_chain_net_srv_price_unit_uid_t l_unit = dap_chain_net_srv_price_unit_uid_from_str(l_unit_str);
+    if(l_unit.enm == SERV_UNIT_UNDEFINED)
+        return false;
+    a_out->enm = l_unit.enm;
+    return true;
+}
+
+static bool s_json_get_uint256(struct json_object *a_json, const char *a_key, uint256_t *a_out)
+{
+    const char *l_uint256_str = s_json_get_text(a_json, a_key);
+    if(!a_out || !l_uint256_str)
+        return false;
+    uint256_t l_value = dap_chain_balance_scan(l_uint256_str);
+    if(!IS_ZERO_256(l_value)) {
+        memcpy(a_out, &l_value, sizeof(uint256_t));
+        return true;
+    }
+    return false;
+}
+
+// service names: srv_stake, srv_vpn, srv_xchange
+static bool s_json_get_srv_uid(struct json_object *a_json, const char *a_key_service_id, const char *a_key_service, uint64_t *a_out)
+{
+    uint64_t l_srv_id;
+    if(!a_out)
+        return false;
+    // Read service id
+    if(s_json_get_int64(a_json, a_key_service_id, (int64_t*) &l_srv_id)) {
+        *a_out = l_srv_id;
+        return true;
+    }
+    else {
+        // Read service as name
+        const char *l_service = s_json_get_text(a_json, a_key_service);
+        if (l_service)
+            *a_out = dap_chain_srv_get_uid_by_name(l_service).uint64;
+    }
+    return false;
+}
+
+static dap_chain_wallet_t* s_json_get_wallet(struct json_object *a_json, const char *a_key)
+{
+    return dap_chain_wallet_open(s_json_get_text(a_json, a_key), dap_chain_wallet_get_path(g_config), NULL);
+}
+
+static const dap_cert_t* s_json_get_cert(struct json_object *a_json, const char *a_key)
+{
+    return dap_cert_find_by_name(s_json_get_text(a_json, a_key));
+}
+
+// Read pkey from wallet or cert
+static dap_pkey_t* s_json_get_pkey(struct json_object *a_json)
+{
+    dap_pkey_t *l_pub_key = NULL;
+    // From wallet
+    dap_chain_wallet_t *l_wallet = s_json_get_wallet(a_json, "wallet");
+    if(l_wallet) {
+        l_pub_key = dap_chain_wallet_get_pkey(l_wallet, 0);
+        dap_chain_wallet_close(l_wallet);
+        if(l_pub_key) {
+            return l_pub_key;
+        }
+    }
+    // From cert
+    const dap_cert_t *l_cert = s_json_get_cert(a_json, "cert");
+    if(l_cert) {
+        l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key);
+    }
+    return l_pub_key;
+}
+
+int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, 
+                                        dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready)
+{
+
+    json_object *l_json = a_tx_json;
+    json_object *l_jobj_errors = a_json_obj_error ? a_json_obj_error : NULL;
+    
+    if (!a_tx_json)
+        return log_it(L_ERROR, "Empty json"), DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE;
+
+    if(!a_out_tx){
+        log_it(L_ERROR, "a_out_tx is NULL");
+        return DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS;
+    }
+
+    const char *l_native_token = a_net ? a_net->pub.native_ticker : NULL;
+    const char *l_main_token = NULL;
+    bool l_multichanel = false;
+
+
+    // Read items from json file
+    struct json_object *l_json_items = json_object_object_get(l_json, "items");
+    size_t l_items_count;
+    if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) {
+        json_object_put(l_json);
+        return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS;
+    }
+
+    log_it(L_ERROR, "Json TX: found %lu items", l_items_count);
+    // Create transaction
+    dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t));
+    if(!l_tx) {
+        json_object_put(l_json);
+        return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED;
+    }
+
+    struct json_object *l_json_timestamp = json_object_object_get(l_json, "ts_created");
+    if (l_json_timestamp)
+        l_tx->header.ts_created = json_object_get_int64(l_json_timestamp);
+    else
+        l_tx->header.ts_created = time(NULL);
+
+    size_t l_items_ready = 0;
+    dap_list_t *l_in_list = NULL;// list 'in' items
+    dap_list_t *l_sign_list = NULL;// list 'sign' items
+    uint256_t l_value_need = { };// how many tokens are needed in the 'out' item
+    uint256_t l_value_need_fee = {};
+
+    if(a_net){ // if composition is not offline
+        // First iteration in input file. Check the tx will be multichannel or not
+        for(size_t i = 0; i < l_items_count; ++i) {
+            struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i);
+            if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) {
+                continue;
+            }
+            struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type");
+            if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) {
+                log_it(L_WARNING, "Item %zu without type", i);
+                continue;
+            }
+            const char *l_item_type_str = json_object_get_string(l_json_item_type);
+            dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str);
+            if(l_item_type == TX_ITEM_TYPE_UNKNOWN) {
+                log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str);
+                continue;
+            }
+
+            switch (l_item_type) {
+                case TX_ITEM_TYPE_IN: {
+                    const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token");
+                    if (l_json_item_token && dap_strcmp(l_json_item_token, l_native_token)){
+                        l_multichanel = true;
+                        l_main_token = l_json_item_token;
+                        break;
+                    }
+                    const char *l_prev_hash_str = s_json_get_text(l_json_item_obj, "prev_hash");
+                    int64_t l_out_prev_idx;
+                    bool l_is_out_prev_idx = s_json_get_int64(l_json_item_obj, "out_prev_idx", &l_out_prev_idx);
+                    // If prev_hash and out_prev_idx were read
+                    if(l_prev_hash_str && l_is_out_prev_idx){
+                        dap_chain_hash_fast_t l_tx_prev_hash = {};
+                        if(!dap_chain_hash_fast_from_str(l_prev_hash_str, &l_tx_prev_hash)) {
+                            //check out token
+                            dap_chain_datum_tx_t *l_prev_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_tx_prev_hash);
+                            byte_t *l_prev_item = l_prev_tx ? dap_chain_datum_tx_item_get_nth(l_prev_tx, TX_ITEM_TYPE_OUT_ALL, l_out_prev_idx) : NULL;
+                            if (l_prev_item){
+                                const char* l_token = NULL;
+                                if (*l_prev_item == TX_ITEM_TYPE_OUT){
+                                    l_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_prev_hash);
+                                } else if(*l_prev_item == TX_ITEM_TYPE_OUT_EXT){
+                                    l_token = ((dap_chain_tx_out_ext_t*)l_prev_item)->token;
+                                } else {
+                                    log_it(L_WARNING, "Invalid 'in' item, wrong type of item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str);
+                                    char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, "
+                                                                        "wrong type of item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str);
+                                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                                    break;
+                                }
+                                if (dap_strcmp(l_token, l_native_token)){
+                                    l_multichanel = true;
+                                    l_main_token = l_json_item_token;
+                                    break;
+                                }
+
+                            } else {
+                                log_it(L_WARNING, "Invalid 'in' item, can't find item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str);
+                                char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, "
+                                                                    "can't find item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str);
+                                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                            }                            
+                        } else {
+                            log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str);
+                            char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, "
+                                                                "bad prev_hash %s", l_prev_hash_str);
+                            json_object *l_jobj_err = json_object_new_string(l_str_err);
+                            if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                        }
+                    }
+                }break;
+                case TX_ITEM_TYPE_IN_COND:
+                case TX_ITEM_TYPE_IN_EMS:
+                case TX_ITEM_TYPE_IN_REWARD:
+                default: continue;
+            }
+            if(l_multichanel)
+                break;
+        }
+    }
+
+    // Creating and adding items to the transaction
+    for(size_t i = 0; i < l_items_count; ++i) {
+        struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i);
+        if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) {
+            continue;
+        }
+        struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type");
+        if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) {
+            log_it(L_WARNING, "Item %zu without type", i);
+            continue;
+        }
+        const char *l_item_type_str = json_object_get_string(l_json_item_type);
+        dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str);
+        if(l_item_type == TX_ITEM_TYPE_UNKNOWN) {
+            log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str);
+            continue;
+        }
+
+        log_it(L_DEBUG, "Json TX: process item %s", json_object_get_string(l_json_item_type));
+        // Create an item depending on its type
+        const uint8_t *l_item = NULL;
+        switch (l_item_type) {
+        case TX_ITEM_TYPE_IN: {
+            // Save item obj for in
+            // Read prev_hash and out_prev_idx
+            const char *l_prev_hash_str = s_json_get_text(l_json_item_obj, "prev_hash");
+            int64_t l_out_prev_idx;
+            bool l_is_out_prev_idx = s_json_get_int64(l_json_item_obj, "out_prev_idx", &l_out_prev_idx);
+            // If prev_hash and out_prev_idx were read
+            if(l_prev_hash_str && l_is_out_prev_idx) {
+                dap_chain_hash_fast_t l_tx_prev_hash;
+                if(!dap_chain_hash_fast_from_str(l_prev_hash_str, &l_tx_prev_hash)) {
+                    // Create IN item
+                    dap_chain_tx_in_t *l_in_item = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, (uint32_t) l_out_prev_idx);
+                    if (!l_in_item) {
+                        json_object *l_jobj_err = json_object_new_string("Unable to create in for transaction.");
+                        if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                    }
+                    l_item = (const uint8_t*) l_in_item;
+                } else {
+                    log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str);
+                    char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, "
+                                                        "bad prev_hash %s", l_prev_hash_str);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                }
+            }
+            // Read addr_from
+            else {
+               l_in_list = dap_list_append(l_in_list, l_json_item_obj);
+            }
+        }
+            break;
+
+        case TX_ITEM_TYPE_OUT:
+        case TX_ITEM_TYPE_OUT_EXT: {
+            // Read address and value
+            uint256_t l_value = { };
+            const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr");
+            bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value);
+            const char *l_token = s_json_get_text(l_json_item_obj, "token");
+            if(l_is_value && l_json_item_addr_str) {
+                dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_json_item_addr_str);
+                if(l_addr && !IS_ZERO_256(l_value)) {
+                    if(l_item_type == TX_ITEM_TYPE_OUT) {
+                        // Create OUT item
+                        const uint8_t *l_out_item = NULL;
+                        if (a_net) {// if composition is not offline
+                            if(l_multichanel)
+                                l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token ? l_token : (l_main_token ? l_main_token : l_native_token));
+                            else
+                                l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value);
+                            if (!l_out_item) {
+                                json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. "
+                                                                                "There may not be enough funds in the wallet.");
+                                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                            }
+                            if (l_out_item){
+                                if (l_multichanel && !dap_strcmp(((dap_chain_tx_out_ext_t*)l_out_item)->token, l_native_token))
+                                    SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee);
+                                else
+                                    SUM_256_256(l_value_need, l_value, &l_value_need);
+                            }
+                        } else {
+                            l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value);
+                            if (!l_out_item) {
+                                json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. "
+                                                                                "There may not be enough funds in the wallet.");
+                                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                            }
+                        }
+                        l_item = (const uint8_t*) l_out_item;
+                    } else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) {
+                        // Read address and value
+                        if(l_token) {
+                            // Create OUT_EXT item
+                            const uint8_t *l_out_item = NULL;
+                            if (a_net){ // if composition is not offline
+                                if(l_multichanel)
+                                    l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token);
+                                else
+                                    l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value);
+                                if (!l_out_item) {
+                                    json_object *l_jobj_err = json_object_new_string("Failed to create a out ext"
+                                                                        "for a transaction. There may not be enough funds "
+                                                                        "on the wallet or the wrong ticker token "
+                                                                        "is indicated.");
+                                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                                }
+                                if (l_out_item){
+                                    if (l_multichanel && !dap_strcmp(l_token, l_native_token))
+                                        SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee);
+                                    else 
+                                        SUM_256_256(l_value_need, l_value, &l_value_need);
+                                }
+                            } else {
+                                l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token);
+                                if (!l_out_item) {
+                                    json_object *l_jobj_err = json_object_new_string("Failed to create a out ext"
+                                                                        "for a transaction. There may not be enough funds "
+                                                                        "on the wallet or the wrong ticker token "
+                                                                        "is indicated.");
+                                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                                }
+                            }
+                            l_item = (const uint8_t*) l_out_item;
+                        }
+                        else {
+                            log_it(L_WARNING, "Invalid 'out_ext' item %zu", i);
+                            continue;
+                        }
+                    }
+                } else {
+                    if(l_item_type == TX_ITEM_TYPE_OUT) {
+                        log_it(L_WARNING, "Invalid 'out' item %zu", i);
+                    }
+                    else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) {
+                        log_it(L_WARNING, "Invalid 'out_ext' item %zu", i);
+                    }
+                    char *l_str_err = dap_strdup_printf("For item %zu of type 'out' or 'out_ext' the "
+                                                        "string representation of the address could not be converted, "
+                                                        "or the size of the output sum is 0.", i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                    continue;
+                }
+            }
+        }
+            break;
+        case TX_ITEM_TYPE_OUT_COND: {
+            // Read subtype of item
+            const char *l_subtype_str = s_json_get_text(l_json_item_obj, "subtype");
+            dap_chain_tx_out_cond_subtype_t l_subtype = dap_chain_tx_out_cond_subtype_from_str(l_subtype_str);
+            switch (l_subtype) {
+
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:{
+                uint256_t l_value = { };
+                bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value);
+                if(!l_is_value || IS_ZERO_256(l_value)) {
+                    log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_PAY");
+                    break;
+                }
+                uint256_t l_value_max_per_unit = { };
+                l_is_value = s_json_get_uint256(l_json_item_obj, "value_max_per_unit", &l_value_max_per_unit);
+                if(!l_is_value || IS_ZERO_256(l_value_max_per_unit)) {
+                    log_it(L_ERROR, "Json TX: bad value_max_per_unit in OUT_COND_SUBTYPE_SRV_PAY");
+                    break;
+                }
+                dap_chain_net_srv_price_unit_uid_t l_price_unit;
+                if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) {
+                    log_it(L_ERROR, "Json TX: bad price_unit in OUT_COND_SUBTYPE_SRV_PAY");
+                    break;
+                }
+                dap_chain_srv_uid_t l_srv_uid;
+                uint64_t l_srv_id_ui64;
+                if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_id_ui64)){
+                    // Default service DAP_CHAIN_NET_SRV_VPN_ID
+                    l_srv_uid.uint64 = 0x0000000000000001;
+                } else {
+                    l_srv_uid.uint64 = l_srv_id_ui64;
+                }
+
+                // From "wallet" or "cert"
+                dap_pkey_t *l_pkey = s_json_get_pkey(l_json_item_obj);
+                if(!l_pkey) {
+                    log_it(L_ERROR, "Json TX: bad pkey in OUT_COND_SUBTYPE_SRV_PAY");
+                    break;
+                }
+                const char *l_params_str = s_json_get_text(l_json_item_obj, "params");
+                size_t l_params_size = dap_strlen(l_params_str);
+                dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_pay(l_pkey, l_srv_uid, l_value, l_value_max_per_unit,
+                        l_price_unit, l_params_str, l_params_size);
+                l_item = (const uint8_t*) l_out_cond_item;
+                // Save value for using in In item
+                if(l_item) {
+                    SUM_256_256(l_value_need, l_value, &l_value_need);
+                } else {
+                    char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                        "can of type %s described in item %zu.\n", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                }
+                DAP_DELETE(l_pkey);
+            }
+                break;
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
+
+                dap_chain_srv_uid_t l_srv_uid;
+                uint64_t l_srv_id_ui64;
+                if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_id_ui64)) {
+                    // Default service DAP_CHAIN_NET_SRV_XCHANGE_ID
+                    l_srv_uid.uint64 = 0x2;
+                } else {
+                    l_srv_uid.uint64 = l_srv_id_ui64;
+                }
+                dap_chain_net_t *l_net = dap_chain_net_by_name(s_json_get_text(l_json_item_obj, "net"));
+                if(!l_net) {
+                    log_it(L_ERROR, "Json TX: bad net in OUT_COND_SUBTYPE_SRV_XCHANGE");
+                    break;
+                }
+                const char *l_token = s_json_get_text(l_json_item_obj, "token");
+                if(!l_token) {
+                    log_it(L_ERROR, "Json TX: bad token in OUT_COND_SUBTYPE_SRV_XCHANGE");
+                    break;
+                }
+                uint256_t l_value = { };
+                if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) {
+                    log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_XCHANGE");
+                    break;
+                }
+                //const char *l_params_str = s_json_get_text(l_json_item_obj, "params");
+                //size_t l_params_size = dap_strlen(l_params_str);
+                dap_chain_tx_out_cond_t *l_out_cond_item = NULL; //dap_chain_datum_tx_item_out_cond_create_srv_xchange(l_srv_uid, l_net->pub.id, l_token, l_value, l_params_str, l_params_size);
+                l_item = (const uint8_t*) l_out_cond_item;
+                // Save value for using in In item
+                if(l_item) {
+                    SUM_256_256(l_value_need, l_value, &l_value_need);
+                } else {
+                    char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                         "can of type %s described in item %zu.", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                }
+            }
+                break;
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:{
+                dap_chain_srv_uid_t l_srv_uid;
+                uint64_t l_uid_ui64 = 0;
+                if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_uid_ui64)){
+                    // Default service DAP_CHAIN_NET_SRV_VPN_ID
+                    l_srv_uid.uint64 = 0x12;
+                } else {
+                    l_srv_uid.uint64 = l_uid_ui64;
+                }
+                uint256_t l_value = { };
+                if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) {
+                    log_it(L_ERROR, "Json TX: bad value in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+                const char* l_time_staking_str = NULL;
+                if((l_time_staking_str = s_json_get_text(l_json_item_obj, "time_staking")) == NULL || dap_strlen(l_time_staking_str) != 6)  {
+                    log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+                    
+                char l_time_staking_month_str[3] = {l_time_staking_str[2], l_time_staking_str[3], 0};
+                int l_time_staking_month = atoi(l_time_staking_month_str);
+                if (l_time_staking_month < 1 || l_time_staking_month > 12){
+                    log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+                    
+
+                char l_time_staking_day_str[3] = {l_time_staking_str[4], l_time_staking_str[5], 0};
+                int l_time_staking_day = atoi(l_time_staking_day_str);
+                if (l_time_staking_day < 1 || l_time_staking_day > 31){
+                    log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+
+                dap_time_t l_time_staking = 0;
+                l_time_staking = dap_time_from_str_simplified(l_time_staking_str);
+                if (0 == l_time_staking){
+                    log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+                dap_time_t l_time_now = dap_time_now();
+                if (l_time_staking < l_time_now){
+                    log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                    break;
+                }
+                l_time_staking -= l_time_now;
+
+                uint256_t l_reinvest_percent = uint256_0;
+                const char* l_reinvest_percent_str = NULL;
+                if((l_reinvest_percent_str = s_json_get_text(l_json_item_obj, "reinvest_percent"))!=NULL) {
+                    l_reinvest_percent = dap_uint256_scan_decimal(l_reinvest_percent_str);
+                    if (compare256(l_reinvest_percent, dap_uint256_scan_decimal("100.0")) == 1){
+                    log_it(L_ERROR, "Json TX: bad reinvest percent in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                        break;
+                    }
+                    if (IS_ZERO_256(l_reinvest_percent)) {
+                        int l_reinvest_percent_int = atoi(l_reinvest_percent_str);
+                        if (l_reinvest_percent_int < 0 || l_reinvest_percent_int > 100){
+                            log_it(L_ERROR, "Json TX: bad reinvest percent in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK");
+                            break;
+                        }
+                        l_reinvest_percent = dap_chain_uint256_from(l_reinvest_percent_int);
+                        MULT_256_256(l_reinvest_percent, GET_256_FROM_64(1000000000000000000ULL), &l_reinvest_percent);
+                    }
+                }               
+
+                dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake_lock(l_srv_uid, l_value, l_time_staking, l_reinvest_percent,
+                                                                                                                                    DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_BY_TIME |
+                                                                                                                                    DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_EMIT);
+                l_item = (const uint8_t*) l_out_cond_item;
+                // Save value for using in In item
+                if(l_item) {
+                    SUM_256_256(l_value_need, l_value, &l_value_need);
+                } else {
+                    char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                         "can of type %s described in item %zu.", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                }
+            } 
+                break;
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:{
+                dap_chain_srv_uid_t l_srv_uid;
+                uint64_t l_srv_id_ui64 = 0;
+                if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_id_ui64)) {
+                    // Default service DAP_CHAIN_NET_SRV_STAKE_ID
+                    l_srv_uid.uint64 = 0x13;
+                } else {
+                    l_srv_uid.uint64 = l_srv_id_ui64;
+                }
+                uint256_t l_value = { };
+                if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) {
+                    log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE");
+                    break;
+                }
+                uint256_t l_fee_value = { };
+                if(!s_json_get_uint256(l_json_item_obj, "fee", &l_fee_value) || IS_ZERO_256(l_fee_value)) {
+                    break;
+                }
+                
+                const char *l_signing_addr_str = s_json_get_text(l_json_item_obj, "signing_addr");
+                dap_chain_addr_t *l_signing_addr = dap_chain_addr_from_str(l_signing_addr_str);
+                if(!l_signing_addr) {
+                {
+                    log_it(L_ERROR, "Json TX: bad signing_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE");
+                    break;
+                }
+                dap_chain_node_addr_t l_signer_node_addr;
+                const char *l_node_addr_str = s_json_get_text(l_json_item_obj, "node_addr");
+                if(!l_node_addr_str || dap_chain_node_addr_from_str(&l_signer_node_addr, l_node_addr_str)) {
+                    log_it(L_ERROR, "Json TX: bad node_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE");
+                    break;
+                }
+
+                dap_pkey_t *l_pkey = NULL;
+                const char *l_pkey_full_str = s_json_get_text(l_json_item_obj, "pkey_full");
+                if(l_pkey_full_str) { 
+                    l_pkey = dap_pkey_get_from_str(l_pkey_full_str);
+                    debug_if(!l_pkey, L_ERROR, "Json TX: bad pkey in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE");
+                }
+
+                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_pkey);
+                l_item = (const uint8_t*) l_out_cond_item;
+                // Save value for using in In item
+                if(l_item) {
+                    SUM_256_256(l_value_need, l_value, &l_value_need);
+                } else {
+                    char *l_err_str = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                        "can of type %s described in item %zu.", l_subtype_str, i);
+                    json_object *l_jobj_err = json_object_new_string(l_err_str);
+                    DAP_DELETE(l_err_str);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                }
+                }
+            }
+                break;
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: {
+                uint256_t l_value = { };
+                s_json_get_uint256(l_json_item_obj, "value", &l_value);
+                if(!IS_ZERO_256(l_value)) {
+                    dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_fee(l_value);
+                    l_item = (const uint8_t*) l_out_cond_item;
+                    // Save value for using in In item
+                    if(l_item) {
+                        SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee);
+                    } else {
+                        char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction "
+                                                            "can of type %s described in item %zu.", l_subtype_str, i);
+                        json_object *l_jobj_err = json_object_new_string(l_str_err);
+                        if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                        DAP_DELETE(l_str_err);
+                    }
+                }
+                else
+                    log_it(L_ERROR, "Json TX: zero value in OUT_COND_SUBTYPE_FEE");
+            }
+                break;
+            case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED:
+                log_it(L_WARNING, "Undefined subtype: '%s' of 'out_cond' item %zu ", l_subtype_str, i);
+                char *l_str_err = dap_strdup_printf("Specified unknown sub type %s of conditional out on item %zu.",
+                                                    l_subtype_str, i);
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                break;
+            }
+        }
+            break;
+        case TX_ITEM_TYPE_SIG:{          
+            const char *l_sign_type_str = s_json_get_text(l_json_item_obj, "sig_type");          
+            if (l_sign_type_str) {
+                dap_sign_type_t l_sign_type = dap_sign_type_from_str(l_sign_type_str);
+                if (l_sign_type.type == SIG_TYPE_NULL) {
+                    json_object *l_jobj_err = json_object_new_string("Can't define sign type");
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
+                    log_it(L_ERROR, "Json TX: Can't define sign type \"%s\"", l_sign_type_str);
+                    break;
+                }
+                int64_t l_pkey_size, l_sig_size, l_hash_type = 0;
+
+                s_json_get_int64(l_json_item_obj, "hash_type", &l_hash_type);
+                s_json_get_int64(l_json_item_obj, "pub_key_size", &l_pkey_size);
+                s_json_get_int64(l_json_item_obj, "sig_size", &l_sig_size);
+                debug_if(!l_pkey_size || !l_sig_size, L_WARNING,
+                         "\"pub_key_size\" or \"sig_size\" not provided! Will be calculated automatically");
+                
+                json_object *l_jobj_pub_key = json_object_object_get(l_json_item_obj, "pub_key_b64"),
+                            *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64");
+                if (!l_jobj_pub_key || !l_jobj_sign) {
+                    json_object *l_jobj_err = json_object_new_string("Can't get base64-encoded sign or pkey!");
+                    json_object_array_add(l_jobj_errors, l_jobj_err);
+                    log_it(L_ERROR, "Json TX: Can't get base64-encoded sign or pkey!");
+                    break;
+                }
+                const char *l_pub_key_str = json_object_get_string(l_jobj_pub_key),
+                           *l_sign_str = json_object_get_string(l_jobj_sign);
+                int64_t l_pkey_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_pub_key_str)),
+                        l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_sign_str));
+                
+                dap_sign_t *l_sign = DAP_NEW_SIZE(dap_sign_t, sizeof(dap_sign_t) + l_pkey_decoded_size + l_sign_decoded_size);
+                *l_sign = (dap_sign_t) {
+                    .header.type = l_sign_type,
+                    .header.hash_type = (uint8_t)l_hash_type,
+                };
+                l_pkey_decoded_size = dap_enc_base64_decode(l_pub_key_str, strlen(l_pub_key_str),
+                                                            l_sign->pkey_n_sign, DAP_ENC_DATA_TYPE_B64_URLSAFE);
+                debug_if(l_pkey_size != l_pkey_decoded_size, L_ERROR, "Json TX: pkey size mismatch, %zu != %zu",
+                                                                      l_pkey_size, l_pkey_decoded_size);
+
+                l_sign_decoded_size = dap_enc_base64_decode(l_sign_str, strlen(l_sign_str),
+                                                            l_sign->pkey_n_sign + l_pkey_decoded_size, DAP_ENC_DATA_TYPE_B64_URLSAFE);
+                debug_if(l_sig_size != l_sign_decoded_size, L_ERROR, "Json TX: sign size mismatch, %zu != %zu",
+                                                                     l_sig_size, l_sign_decoded_size);
+
+                l_sign->header.sign_size = l_sign_decoded_size;
+                l_sign->header.sign_pkey_size = l_pkey_decoded_size;
+                size_t l_sign_full_size = dap_sign_get_size(l_sign);
+                
+                dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, sizeof(dap_chain_tx_sig_t) + l_sign_full_size);
+                l_tx_sig->header.type = TX_ITEM_TYPE_SIG;
+                l_tx_sig->header.version = 1;
+                l_tx_sig->header.sig_size = (uint32_t)l_sign_full_size;
+                memcpy(l_tx_sig->sig, l_sign, l_sign_full_size);
+                l_item = (const uint8_t*)l_tx_sig;
+                DAP_DELETE(l_sign);
+                break;
+            } else              
+                l_sign_list = dap_list_append(l_sign_list,l_json_item_obj);
+        }
+            break;
+        case TX_ITEM_TYPE_RECEIPT: {
+            dap_chain_srv_uid_t l_srv_uid;
+            uint64_t l_srv_id_ui64 = 0;
+            if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_id_ui64)) {
+                log_it(L_ERROR, "Json TX: bad service_id in TYPE_RECEIPT");
+                break;
+            } else {
+                l_srv_uid.uint64 = l_srv_id_ui64;
+            }
+            dap_chain_net_srv_price_unit_uid_t l_price_unit;
+            if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) {
+                log_it(L_ERROR, "Json TX: bad price_unit in TYPE_RECEIPT");
+                break;
+            }
+            int64_t l_units;
+            if(!s_json_get_int64(l_json_item_obj, "units", &l_units)) {
+                log_it(L_ERROR, "Json TX: bad units in TYPE_RECEIPT");
+                break;
+            }
+            uint256_t l_value = { };
+            if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) {
+                log_it(L_ERROR, "Json TX: bad value in TYPE_RECEIPT");
+                break;
+            }
+            const char *l_params_str = s_json_get_text(l_json_item_obj, "params");
+            size_t l_params_size = dap_strlen(l_params_str);
+            dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size);
+            l_item = (const uint8_t*) l_receipt;
+            if (!l_item) {
+                char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction "
+                                                    "described by item %zu.", i);
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+            }
+        }
+            break;
+        case TX_ITEM_TYPE_TSD: {
+            int64_t l_tsd_type;
+            if(!s_json_get_int64(l_json_item_obj, "type_tsd", &l_tsd_type)) {
+                log_it(L_ERROR, "Json TX: bad type_tsd in TYPE_TSD");
+                break;
+            }
+            const char *l_tsd_data = s_json_get_text(l_json_item_obj, "data");
+            if (!l_tsd_data) {
+                log_it(L_ERROR, "Json TX: bad data in TYPE_TSD");
+                break;
+            }
+            size_t l_data_size = dap_strlen(l_tsd_data);
+            dap_chain_tx_tsd_t *l_tsd = dap_chain_datum_tx_item_tsd_create((void*)l_tsd_data, (int)l_tsd_type, l_data_size);
+            l_item = (const uint8_t*) l_tsd;
+            // l_tsd_list = dap_list_append(l_tsd_list, l_tsd);
+        }
+            break;
+            //case TX_ITEM_TYPE_PKEY:
+                //break;
+            //case TX_ITEM_TYPE_IN_EMS:
+                //break;
+            //case TX_ITEM_TYPE_IN_EMS_EXT:
+                //break;
+        }
+        // Add item to transaction
+        if(l_item) {
+            dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_item);
+            l_items_ready++;
+            DAP_DELETE(l_item);
+        }
+    }
+    
+    dap_list_t *l_list;
+    // Add In items
+    if(a_net){
+        l_list = l_in_list;
+        while(l_list) {
+            struct json_object *l_json_item_obj = (struct json_object*) l_list->data;
+
+            const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr_from");
+            const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token");
+            l_main_token = l_json_item_token;
+            dap_chain_addr_t *l_addr_from = NULL;
+            if(l_json_item_addr_str) {
+                l_addr_from = dap_chain_addr_from_str(l_json_item_addr_str);
+                if (!l_addr_from) {
+                    log_it(L_WARNING, "Invalid element 'in', unable to convert string representation of addr_from: '%s' "
+                                        "to binary.", l_json_item_addr_str);
+                    char *l_str_err = dap_strdup_printf("Invalid element 'to', unable to convert string representation "
+                                                        "of addr_from: '%s' to binary.", l_json_item_addr_str);
+                    json_object *l_jobj_err = json_object_new_string(l_str_err);
+                    DAP_DELETE(l_str_err);
+                    if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                    // Go to the next item
+                    l_list = dap_list_next(l_list);
+                    continue;
+                }
+            }
+            else {
+                log_it(L_WARNING, "Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]");
+                char *l_str_err = dap_strdup_printf("Invalid 'in' item, incorrect addr_from: '%s'",
+                                            l_json_item_addr_str ? l_json_item_addr_str : "[null]");
+                json_object *l_jobj_err = json_object_new_string(l_str_err);
+                DAP_DELETE(l_str_err);
+                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                // Go to the next item
+                l_list = dap_list_next(l_list);
+                continue;
+            }
+            if(!l_json_item_token) {
+                log_it(L_WARNING, "Invalid 'in' item, not found token name");
+                json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found token name");
+                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                // Go to the next item
+                l_list = dap_list_next(l_list);
+                continue;
+            }
+            if(IS_ZERO_256(l_value_need)) {
+                log_it(L_WARNING, "Invalid 'in' item, not found value in out items");
+                json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found value in out items");
+                if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                // Go to the next item
+                l_list = dap_list_next(l_list);
+                continue;
+            }
+
+            if(l_addr_from){
+                // find the transactions from which to take away coins
+                dap_list_t *l_list_used_out = NULL;
+                dap_list_t *l_list_used_out_fee = NULL;
+                uint256_t l_value_transfer = { }; // how many coins to transfer
+                uint256_t l_value_transfer_fee = { }; // how many coins to transfer
+                //SUM_256_256(a_value, a_value_fee, &l_value_need);
+                uint256_t l_value_need_check = {};
+                if (!dap_strcmp(l_native_token, l_main_token)) {
+                    SUM_256_256(l_value_need_check, l_value_need, &l_value_need_check);
+                    SUM_256_256(l_value_need_check, l_value_need_fee, &l_value_need_check);
+                    l_list_used_out = dap_chain_wallet_get_list_tx_outs_with_val(a_net->pub.ledger, l_json_item_token,
+                                                                                                l_addr_from, l_value_need_check, &l_value_transfer);
+                    if(!l_list_used_out) {
+                        log_it(L_WARNING, "Not enough funds in previous tx to transfer");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds in previous tx "
+                                                            "to transfer");
+                        if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                        // Go to the next item
+                        l_list = dap_list_next(l_list);
+                        continue;
+                    }
+                } else {
+                    //CHECK value need
+                    l_list_used_out = dap_chain_wallet_get_list_tx_outs_with_val(a_net->pub.ledger, l_json_item_token,
+                                                                                                l_addr_from, l_value_need, &l_value_transfer);
+                    if(!l_list_used_out) {
+                        log_it(L_WARNING, "Not enough funds in previous tx to transfer");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds "
+                                                                            "in previous tx to transfer");
+                        if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                        // Go to the next item
+                        l_list = dap_list_next(l_list);
+                        continue;
+                    }
+                    //CHECK value fee
+                    l_list_used_out_fee = dap_chain_wallet_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_token,
+                                                                                        l_addr_from, l_value_need_fee, &l_value_transfer_fee);
+                    if(!l_list_used_out_fee) {
+                        log_it(L_WARNING, "Not enough funds in previous tx to transfer");
+                        json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds "
+                                                                            "in previous tx to transfer");
+                        if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err);
+                        // Go to the next item
+                        l_list = dap_list_next(l_list);
+                        continue;
+                    }
+                }
+                // add 'in' items
+                uint256_t l_value_got = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out);
+                assert(EQUAL_256(l_value_got, l_value_transfer));
+                if (l_list_used_out_fee) {
+                    uint256_t l_value_got_fee = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out_fee);
+                    assert(EQUAL_256(l_value_got_fee, l_value_transfer_fee));
+                    dap_list_free_full(l_list_used_out_fee, free);
+                    // add 'out' item for coin fee back
+                    uint256_t  l_value_back;
+                    SUBTRACT_256_256(l_value_got_fee, l_value_need_fee, &l_value_back);
+                    if (!IS_ZERO_256(l_value_back)) {
+                        dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_native_token);
+                        l_items_ready++;
+                    }
+                } else {
+                    SUM_256_256(l_value_need, l_value_need_fee, &l_value_need);
+                }
+                dap_list_free_full(l_list_used_out, free);
+                if(!IS_ZERO_256(l_value_got)) {
+                    // add 'out' item for coin back
+                    uint256_t l_value_back;
+                    SUBTRACT_256_256(l_value_got, l_value_need, &l_value_back);
+                    if(!IS_ZERO_256(l_value_back)) {
+                        if (l_multichanel)
+                            dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_main_token);
+                        else
+                            dap_chain_datum_tx_add_out_item(&l_tx, l_addr_from, l_value_back);
+                        l_items_ready++;
+                    }
+                }   
+            }
+            // Go to the next 'in' item
+            l_list = dap_list_next(l_list);
+        }
+    }
+    dap_list_free(l_in_list);
+
+    // Add signs
+    l_list = l_sign_list;
+    while(l_list) {
+        struct json_object *l_json_item_obj = (struct json_object*) l_list->data;
+        dap_enc_key_t * l_enc_key  = NULL;
+        
+        //get wallet or cert
+        dap_chain_wallet_t *l_wallet = s_json_get_wallet(l_json_item_obj, "wallet");
+        const dap_cert_t *l_cert = s_json_get_cert(l_json_item_obj, "cert");
+
+        int64_t l_pkey_size;
+        int64_t l_sig_size;
+        uint8_t *l_pkey = NULL;
+        int64_t l_hash_type = 0;
+        dap_sign_t *l_sign = NULL;
+        
+
+        //wallet goes first
+        if (l_wallet) {
+            l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
+        } else if (l_cert && l_cert->enc_key) {
+            l_enc_key = l_cert->enc_key; 
+        } else { 
+            json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions.");
+            json_object_array_add(l_jobj_errors, l_jobj_err);
+            log_it(L_ERROR, "Json TX: Item sign has no wallet or cert of they are invalid ");
+            l_list = dap_list_next(l_list);
+            continue;
+        }
+
+        if (l_sign) {
+            size_t l_chain_sign_size = dap_sign_get_size(l_sign); // sign data
+            
+            dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t,
+                    sizeof(dap_chain_tx_sig_t) + l_chain_sign_size);
+            l_tx_sig->header.type = TX_ITEM_TYPE_SIG;
+            l_tx_sig->header.sig_size =(uint32_t) l_chain_sign_size;
+            memcpy(l_tx_sig->sig, l_sign, l_chain_sign_size);
+            dap_chain_datum_tx_add_item(&l_tx, l_tx_sig);
+            DAP_DELETE(l_sign);
+        }
+
+        if(l_enc_key && dap_chain_datum_tx_add_sign_item(&l_tx, l_enc_key) > 0) {
+            l_items_ready++;
+        } else {
+            log_it(L_ERROR, "Json TX: Item sign has invalid enc_key.");
+            l_list = dap_list_next(l_list);
+            continue;
+        }
+
+        if (l_wallet) {
+            dap_chain_wallet_close(l_wallet);  
+            dap_enc_key_delete(l_enc_key);
+        }  
+        l_list = dap_list_next(l_list);
+    }
+
+    dap_list_free(l_sign_list);
+    json_object_put(l_json);
+
+    *a_out_tx = l_tx;
+
+    if(a_items_count)
+        *a_items_count = l_items_count;
+
+    if(a_items_ready)
+        *a_items_ready = l_items_ready;
+
+    return DAP_CHAIN_NET_TX_CREATE_JSON_OK;
+}
+
+int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json)
+{
+    if(!a_tx || !a_out_json)
+        return log_it(L_ERROR, "Empty transaction"), DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS;
+
+    json_object* json_obj_out = a_out_json;
+    json_object* l_json_arr_reply = NULL;
+    dap_hash_fast_t l_hash_tmp = { };
+    byte_t *item; size_t l_size;
+    char *l_hash_str = NULL;
+    char l_tmp_buf[DAP_TIME_STR_SIZE];
+    json_object* json_arr_items = json_object_new_array();
+
+    char *l_tx_hash_str = dap_hash_fast_str_new(a_tx, dap_chain_datum_tx_get_size(a_tx));
+
+    json_object_object_add(json_obj_out, "datum_hash", json_object_new_string(l_tx_hash_str));
+    json_object_object_add(json_obj_out, "ts_created", json_object_new_int64(a_tx->header.ts_created));
+    json_object_object_add(json_obj_out, "datum_type", json_object_new_string("tx"));
+
+    TX_ITEM_ITER_TX(item, l_size, a_tx) {
+        json_object* json_obj_item = json_object_new_object();
+        switch (*item) {
+        case TX_ITEM_TYPE_IN:
+            l_hash_tmp = ((dap_chain_tx_in_t*)item)->header.tx_prev_hash;
+            l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp);
+            json_object_object_add(json_obj_item,"type", json_object_new_string("in"));
+            json_object_object_add(json_obj_item,"prev_hash", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_item,"out_prev_idx", json_object_new_uint64(((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx));
+            break;
+        case TX_ITEM_TYPE_OUT: { // 256
+            const char *l_coins_str,
+                    *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str),
+                    *l_addr_str = dap_chain_addr_to_str_static(&((dap_chain_tx_out_t*)item)->addr);
+            json_object_object_add(json_obj_item,"type", json_object_new_string("out"));
+            json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str));
+            json_object_object_add(json_obj_item,"addr", json_object_new_string(l_addr_str));            
+        } break;
+        case TX_ITEM_TYPE_SIG: {
+            dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item);
+            json_object_object_add(json_obj_item,"type", json_object_new_string("sign"));
+            dap_chain_hash_fast_t l_hash_pkey;
+            json_object_object_add(json_obj_item,"sig_type",json_object_new_string(dap_sign_type_to_str(l_sign->header.type)));
+            json_object_object_add(json_obj_item,"pub_key_size",json_object_new_uint64(l_sign->header.sign_pkey_size));
+            json_object_object_add(json_obj_item,"sig_size",json_object_new_uint64(l_sign->header.sign_size));
+            json_object_object_add(json_obj_item,"hash_type",json_object_new_uint64(l_sign->header.hash_type));
+            
+            char l_pkey_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_pkey_size) + 1];
+            size_t l_pkey_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign, l_sign->header.sign_pkey_size, l_pkey_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); 
+            l_pkey_base64[l_pkey_base64_size] = '\0';   
+            json_object_object_add(json_obj_item,"pub_key_b64", json_object_new_string(l_pkey_base64));     
+
+            char l_sign_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_size) + 1];
+            size_t l_sign_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign + l_sign->header.sign_pkey_size, l_sign->header.sign_size, l_sign_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); 
+            l_sign_base64[l_sign_base64_size] = '\0';
+            json_object_object_add(json_obj_item,"sig_b64", json_object_new_string(l_sign_base64));
+
+        } break;
+        case TX_ITEM_TYPE_TSD: {
+            json_object_object_add(json_obj_item,"type", json_object_new_string("data"));
+            json_object_object_add(json_obj_item,"type", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.type));
+            json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.size));            
+        } break;
+        case TX_ITEM_TYPE_IN_COND:
+            json_object_object_add(json_obj_item,"type", json_object_new_string("in_cond"));
+            l_hash_tmp = ((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash;
+            l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp);
+            json_object_object_add(json_obj_item,"receipt_idx", json_object_new_int(((dap_chain_tx_in_cond_t*)item)->header.receipt_idx));
+            json_object_object_add(json_obj_item,"out_prev_idx", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_item,"prev_hash", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx));
+            break;
+        case TX_ITEM_TYPE_OUT_COND: {
+            char l_tmp_buff[70]={0};
+            json_object_object_add(json_obj_item,"type", json_object_new_string("out_cond"));
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str);
+            dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires;
+            dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp);
+            json_object_object_add(json_obj_item,"ts_expires", l_ts_exp ? json_object_new_string(l_tmp_buf) : json_object_new_string("never"));
+            json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str));
+            sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64);
+            json_object_object_add(json_obj_item,"service_id", json_object_new_string(l_tmp_buff));
+            switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) {
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE:
+                    json_object_object_add(json_obj_item,"subtype", json_object_new_string("fee"));
+                    break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: {
+                    const char *l_coins_str, *l_value_str =
+                        dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str );
+                    l_hash_tmp = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash;
+                    l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp);
+                    sprintf(l_tmp_buff,"0x%08x",((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32);
+                    json_object_object_add(json_obj_item,"price_unit", json_object_new_string(l_tmp_buff));
+                    json_object_object_add(json_obj_item,"pkey", json_object_new_string(l_hash_str));
+                    json_object_object_add(json_obj_item,"value_max_per_unit", json_object_new_string(l_value_str));
+                    json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_pay"));
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: {
+                    dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr;
+                    dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr;
+                    l_hash_tmp = l_signing_addr->data.hash_fast;
+                    l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp);
+                    json_object_object_add(json_obj_item,"signing_addr", json_object_new_string(dap_chain_addr_to_str_static(l_signing_addr)));            
+                    sprintf(l_tmp_buff,""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS(l_signer_node_addr));
+                    json_object_object_add(json_obj_item,"signer_node_addr", json_object_new_string(l_tmp_buff));
+                    json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_stake_pos_delegate"));
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: {
+                    const char *l_rate_str, *l_tmp_str =
+                        dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str );
+                    sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64);
+                    json_object_object_add(json_obj_item,"net_id", json_object_new_string(l_tmp_buff));
+                    json_object_object_add(json_obj_item,"token", json_object_new_string(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token));
+                    json_object_object_add(json_obj_item,"rate", json_object_new_string(l_rate_str));
+                    json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_xchange"));
+                } break;
+                case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: {
+                    dap_time_t l_ts_unlock = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_lock.time_unlock;
+                    dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_unlock);
+                    json_object_object_add(json_obj_item,"time_unlock", json_object_new_string(l_tmp_buf));
+                    json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_stake_lock"));
+                } break;
+                default: break;
+            }
+        } break;
+        case TX_ITEM_TYPE_OUT_EXT: {
+            const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str );
+            json_object_object_add(json_obj_item,"type", json_object_new_string("out_ext"));
+            json_object_object_add(json_obj_item,"addr", json_object_new_string(dap_chain_addr_to_str_static(&((dap_chain_tx_out_ext_t*)item)->addr)));
+            json_object_object_add(json_obj_item,"token", json_object_new_string(((dap_chain_tx_out_ext_t*)item)->token));
+            json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str));
+            
+        } break;
+        case TX_ITEM_TYPE_VOTING:{
+            size_t l_tsd_size = 0;
+            dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_tx, NULL, (byte_t*)item + l_size, TX_ITEM_TYPE_TSD, &l_tsd_size);
+            if (!l_item || !l_tsd_size)
+                    break;
+            dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_datum_tx_voting_parse_tsd(a_tx);
+            json_object_object_add(json_obj_item,"type", json_object_new_string("voting"));
+            json_object_object_add(json_obj_item,"voting_question", json_object_new_string(l_voting_params->question));
+            json_object_object_add(json_obj_item,"answer_options", json_object_new_string(""));
+            
+            dap_list_t *l_temp = l_voting_params->options;
+            uint8_t l_index = 0;
+            while (l_temp) {
+                json_object_object_add(json_obj_item, dap_itoa(l_index), json_object_new_string((char *)l_temp->data));
+                l_index++;
+                l_temp = l_temp->next;
+            }
+            if (l_voting_params->voting_expire) {
+                dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting_params->voting_expire);
+                json_object_object_add(json_obj_item,"Voting expire", json_object_new_string(l_tmp_buf));                
+            }
+            if (l_voting_params->votes_max_count) {
+                json_object_object_add(json_obj_item, "Votes max count", json_object_new_uint64(l_voting_params->votes_max_count));
+            }
+            json_object_object_add(json_obj_item,"Changing vote is", l_voting_params->vote_changing_allowed ? json_object_new_string("available") : 
+                                    json_object_new_string("not available"));
+            l_voting_params->delegate_key_required ? 
+                json_object_object_add(json_obj_item,"Delegated key for participating in voting", json_object_new_string("required")):
+                json_object_object_add(json_obj_item,"Delegated key for participating in voting", json_object_new_string("not required"));                 
+
+            dap_list_free_full(l_voting_params->options, NULL);
+            DAP_DELETE(l_voting_params->question);
+            DAP_DELETE(l_voting_params);
+        } break;
+        case TX_ITEM_TYPE_VOTE:{
+            dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item;
+            const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash);
+            json_object_object_add(json_obj_item,"type", json_object_new_string("vote"));
+            json_object_object_add(json_obj_item,"voting_hash", json_object_new_string(l_hash_str));
+            json_object_object_add(json_obj_item,"vote_answer_idx", json_object_new_uint64(l_vote_item->answer_idx));
+
+        } break;
+        default:
+            json_object_object_add(json_obj_item,"type", json_object_new_string("This transaction have unknown item type"));
+            break;
+        }
+        json_object_array_add(json_arr_items, json_obj_item);
+    }
+
+    json_object_object_add(json_obj_out, "items", json_arr_items);
+
+    if(a_out_json)
+        a_out_json = json_obj_out;
+
+
+    return 0;
+}
diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h
index 3a189e7600ecad35a1e5c8bf4ce3228e02eb47fe..a0ab8d8e52a0c0a9b9960613eeedc44adbab7c65 100644
--- a/modules/net/include/dap_chain_net_tx.h
+++ b/modules/net/include/dap_chain_net_tx.h
@@ -26,6 +26,22 @@
 #include "dap_chain_net.h"
 #include "dap_chain_datum_tx_items.h"
 
+
+#include "dap_json_rpc_errors.h"
+
+typedef enum s_net_tx_create_json_err {
+    DAP_CHAIN_NET_TX_CREATE_JSON_OK = 0,
+    DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+    DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT,
+    DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
+    DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
+    DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
+    DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS,
+    DAP_CHAIN_NET_TX_CREATE_JSON_INVALID_ITEMS,
+    DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
+    DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS,
+}s_net_tx_create_json_err_t;
 typedef enum dap_chain_net_tx_search_type {
     /// Search local, in memory, possible load data from drive to memory
     TX_SEARCH_TYPE_LOCAL,
@@ -93,3 +109,28 @@ void dap_chain_datum_tx_spends_items_free(dap_chain_datum_tx_spends_items_t * a_
 
 bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr);
 bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr);
+
+
+/**
+ * @brief Compose transaction from json. If a_net is NULL it means offline tx creation and 
+ *          tx will be created from json as is without any checks and conversions.
+ * @param a_tx_json input json
+ * @param a_net network. If NULL it means offline tx creation
+ * @param a_json_obj_error json object for tx items errors messages
+ * @param a_out_tx pointer to output transaction pointer
+ * @param a_items_count count of total items in input json transaction
+ * @param a_items_ready count of valid items in output transaction
+ * 
+ * @return s_com_tx_create_json_err_t status code
+ */
+int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, 
+                                        dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready);
+
+/**
+ * @brief Convert binary transaction to json
+ * @param a_tx input transaction
+ * @param a_out_json pointer to json object created by json_object_new_object()
+ * 
+ * @return s_com_tx_create_json_err_t status code
+ */
+int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json);
diff --git a/modules/node-cli/dap_chain_node_cli.c b/modules/node-cli/dap_chain_node_cli.c
index ae766b5d5f4b47e70a9f24208f74c4fcba717768..dbccf955b4c863db20e6b99ac67ff91ef4ea0d96 100644
--- a/modules/node-cli/dap_chain_node_cli.c
+++ b/modules/node-cli/dap_chain_node_cli.c
@@ -324,7 +324,6 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
                 "\texample datoshi amount syntax (only integer) 1 20 0.4321e+4\n\n");
     dap_cli_server_cmd_add ("tx_create_json", com_tx_create_json, "Make transaction",
                 "tx_create_json -net <net_name> [-chain <chain_name>] -json <json_file_path>\n" );
-    dap_json_rpc_cli_handler_add("j_tx_create", json_rpc_tx_create);
     dap_cli_server_cmd_add ("tx_cond_create", com_tx_cond_create, "Make cond transaction",
                 "tx_cond_create -net <net_name> -token <token_ticker> -w <wallet_name>"
                 " -cert <pub_cert_name> -value <value> -fee <value> -unit {B | SEC} -srv_uid <numeric_uid>\n\n" 
diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c
index 54e1d2703b97a6b43baf1d185067afc3d372ad59..f7c9537df8a4755ecf36c7748a40489b766902c0 100644
--- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c
+++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c
@@ -49,6 +49,7 @@
 #include "dap_chain_wallet.h"
 #include "dap_chain_wallet_cache.h"
 #include "dap_enc_base64.h"
+#include "dap_chain_net_tx.h"
 
 #define LOG_TAG "chain_node_cli_cmd_tx"
 
@@ -1472,6 +1473,21 @@ static dap_pkey_t* s_json_get_pkey(struct json_object *a_json)
     return l_pub_key;
 }
 
+typedef enum s_com_tx_create_json_err {
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK = 0,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_CHECK_TX_ADD_LEDGER,
+    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ALLOC_MEMORY
+} s_com_tx_create_json_err_t;
+
 int s_json_rpc_tx_parse_json(dap_chain_net_t *a_net, dap_chain_t *a_chain, json_object *a_items,
                              dap_chain_datum_tx_t **a_out_tx, size_t *a_out_items_ready, json_object **a_out_jobj_error) {
     size_t l_items_count = json_object_array_length(a_items);
@@ -2316,27 +2332,39 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
     const char *l_net_name = NULL; // optional parameter
     const char *l_chain_name = NULL; // optional parameter
     const char *l_json_file_path = NULL;
+    const char *l_json_str = NULL;
 
     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_name); // optional parameter
     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-chain", &l_chain_name); // optional parameter
     dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json", &l_json_file_path);
+    dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tx_obj", &l_json_str);
 
-    if(!l_json_file_path) {
-        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON,
-                               "Command requires one of parameters '-json <json file path>'");
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON;
+    if(!l_json_file_path  && !l_json_str) {
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON,
+                               "Command requires one of parameters '-json <json file path>' or -tx_obj <string>'");
+        return DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON;
     }
     // Open json file
-    struct json_object *l_json = json_object_from_file(l_json_file_path);
-    if(!l_json) {
-        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
-                               "Can't open json file: %s", json_util_get_last_err());
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE;
+    struct json_object *l_json = NULL;
+    if (l_json_file_path){
+        l_json = json_object_from_file(l_json_file_path);
+        if(!l_json) {
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+                                "Can't open json file: %s", json_util_get_last_err());
+            return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE;
+        }
+    } else if (l_json_str) {
+        l_json = json_tokener_parse(l_json_str);
+        if(!l_json) {
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
+                                "Can't parse input JSON-string", json_util_get_last_err());
+            return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE;
+        }
     }
     if(!json_object_is_type(l_json, json_type_object)) {
-        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format");
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format");
         json_object_put(l_json);
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT;
+        return DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT;
     }
 
 
@@ -2347,19 +2375,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
             l_net_name = json_object_get_string(l_json_net);
         }
         if(!l_net_name) {
-            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
+            dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
                                    "Command requires parameter '-net' or set net in the json file");
             json_object_put(l_json);
-            return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET;
+            return DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET;
         }
     }
     dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_name);
     if(!l_net) {
         dap_json_rpc_error_add(*a_json_arr_reply,
-                               DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
+                               DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
                                "Not found net by name '%s'", l_net_name);
         json_object_put(l_json);
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME;
+        return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME;
     }
 
     // Read chain from json file
@@ -2375,37 +2403,39 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
     }
     if(!l_chain) {
         dap_json_rpc_error_add(*a_json_arr_reply,
-                               DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
+                               DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
                                "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name);
         json_object_put(l_json);
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME;
+        return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME;
     }
 
 
     // Read items from json file
-    struct json_object *l_json_items = json_object_object_get(l_json, "items");
+    json_object *l_jobj_errors = json_object_new_array();
+    size_t l_items_ready = 0, l_items_count = 0;
     dap_chain_datum_tx_t *l_tx = NULL;
-
-    size_t l_items_ready = 0;
-    json_object *l_jobj_errors = NULL;
-
-    int res = s_json_rpc_tx_parse_json(l_net, l_chain, l_json_items, &l_tx, &l_items_ready, &l_jobj_errors);
+    int l_ret = 0;
+    if((l_ret = dap_chain_net_tx_create_by_json(l_json, l_net, l_jobj_errors, &l_tx, &l_items_count, &l_items_ready)) != DAP_CHAIN_NET_TX_CREATE_JSON_OK) {
+        dap_json_rpc_error_add(*a_json_arr_reply, l_ret,
+                               "Can't create transaction from json file");
+        json_object_put(l_json);
+        return l_ret;
+    }
     json_object *l_jobj_ret = json_object_new_object();
 
-    if (res) {
-        json_object *l_jobj_tx_create = json_object_new_boolean(false);
-        json_object *l_jobj_items_ready = json_object_new_uint64(l_items_ready);
-        json_object *l_jobj_total_items = json_object_new_uint64(json_object_array_length(l_json_items));
-        json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_create);
-        json_object_object_add(l_jobj_ret, "ready_items", l_jobj_items_ready);
+    if(l_items_ready < l_items_count) {
+        json_object *l_tx_create = json_object_new_boolean(false);
+        json_object *l_jobj_valid_items = json_object_new_uint64(l_items_ready);
+        json_object *l_jobj_total_items = json_object_new_uint64(l_items_count);
+        json_object_object_add(l_jobj_ret, "tx_create", l_tx_create);
+        json_object_object_add(l_jobj_ret, "valid_items", l_jobj_valid_items);
         json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items);
         json_object_object_add(l_jobj_ret, "errors", l_jobj_errors);
-        json_object_array_add(*reply, l_jobj_ret);
         json_object_array_add(*a_json_arr_reply, l_jobj_ret);
         DAP_DELETE(l_tx);
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS;
+        return DAP_CHAIN_NET_TX_CREATE_JSON_INVALID_ITEMS;
     }
-
+    json_object_put(l_jobj_errors);
 
     // Pack transaction into the datum
     size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx);
@@ -2421,7 +2451,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
     if ((rc = dap_ledger_tx_add_check(l_net->pub.ledger, (dap_chain_datum_tx_t*)l_datum_tx->data, l_tx_size, &l_hf_tx))) {
         json_object *l_jobj_tx_create = json_object_new_boolean(false);
         json_object *l_jobj_hash = json_object_new_string(l_tx_hash_str);
-        json_object *l_jobj_total_items = json_object_new_uint64(json_object_array_length(l_json_items));
+        json_object *l_jobj_total_items = json_object_new_uint64(l_items_count);
         json_object *l_jobj_ledger_ret_code = json_object_new_object();
         json_object_object_add(l_jobj_ledger_ret_code, "code", json_object_new_int(rc));
         json_object_object_add(l_jobj_ledger_ret_code, "message",
@@ -2432,7 +2462,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
         json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items);
         json_object_array_add(*a_json_arr_reply, l_jobj_ret);
         DAP_DEL_Z(l_datum_tx);
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_CHECK_TX_ADD_LEDGER;
+        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION;
     }
 
     char *l_gdb_group_mempool_base_tx = dap_chain_mempool_group_new(l_chain);// get group name for mempool
@@ -2441,19 +2471,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
     DAP_DEL_Z(l_datum_tx);
     DAP_DELETE(l_gdb_group_mempool_base_tx);
     if(!l_placed) {
-        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
+        dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
                                "Can't add transaction to mempool");
-        return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL;
+        return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL;
     }
     // Completed successfully
     json_object *l_jobj_tx_create = json_object_new_boolean(true);
     json_object *l_jobj_hash = json_object_new_string(l_tx_hash_str);
-    json_object *l_jobj_total_items = json_object_new_uint64(json_object_array_length(l_json_items));
+    json_object *l_jobj_total_items = json_object_new_uint64(l_items_count);
     json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_create);
     json_object_object_add(l_jobj_ret, "hash", l_jobj_hash);
     json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items);
     json_object_array_add(*a_json_arr_reply, l_jobj_ret);
-    return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK;
+    return DAP_CHAIN_NET_TX_CREATE_JSON_OK;
 }
 
 /**
diff --git a/modules/node-cli/include/dap_chain_node_cli_cmd.h b/modules/node-cli/include/dap_chain_node_cli_cmd.h
index dc0450de5a287689db487a1df0eabcebc39efdd6..ecbac225873d2890dfa3301d0e0a1461472df2aa 100644
--- a/modules/node-cli/include/dap_chain_node_cli_cmd.h
+++ b/modules/node-cli/include/dap_chain_node_cli_cmd.h
@@ -205,20 +205,6 @@ typedef enum s_com_tx_create_err{
     DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS
 }s_com_tx_create_err_t;
 int com_tx_create(int a_argc, char **a_argv, void **a_str_reply);
-typedef enum s_com_tx_create_json_err {
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK = 0,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_CHECK_TX_ADD_LEDGER,
-    DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ALLOC_MEMORY
-}s_com_tx_create_json_err_t;
 void json_rpc_tx_create(json_object *a_param, json_object *a_reply);
 int com_tx_create_json(int a_argc, char **a_argv, void **reply);
 typedef enum s_com_tx_cond_create{
diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c
index 7e45804459b9c3ae01165d44b394bfe765494930..a6770c6aa15d0d5cbb74891ca4b4639ff09f23f0 100644
--- a/modules/type/blocks/dap_chain_cs_blocks.c
+++ b/modules/type/blocks/dap_chain_cs_blocks.c
@@ -209,7 +209,7 @@ int dap_chain_cs_blocks_init()
                 "\t\tComplete the current new round, verify it and if everything is ok - publish new blocks in chain\n\n"
 
         "Blockchain explorer:\n"
-            "block -net <net_name> [-chain <chain_name>] dump <block_hash>\n"
+            "block -net <net_name> [-chain <chain_name>] dump -hash <block_hash>\n"
                 "\t\tDump block info\n\n"
 
             "block -net <net_name> [-chain <chain_name>] list [{signed | first_signed}] [-limit] [-offset] [-head]"
@@ -732,6 +732,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
 
         case SUBCMD_DUMP:{
             const char *l_hash_out_type = NULL;
+            const char *l_hash_str = NULL;
             dap_chain_hash_fast_t l_block_hash={0};
             dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
             if(!l_hash_out_type)
@@ -739,15 +740,17 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply)
             if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) {
                 dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "invalid parameter -H, valid values: -H <hex | base58>");
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR;
-            }
-            if (!l_subcmd_str_arg) {
+            }           
+            dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_hash_str);
+            if (!l_hash_str) {
                 dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash ");
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR;
             }
-            dap_chain_hash_fast_from_str(l_subcmd_str_arg, &l_block_hash); // Convert argument to hash
+
+            dap_chain_hash_fast_from_str(l_hash_str, &l_block_hash);
             dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash);
             if (!l_block_cache) {
-                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_subcmd_str_arg);
+                dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_hash_str);
                 return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR;
             }
             dap_chain_block_t *l_block = l_block_cache->block;