diff --git a/dap-sdk/core/include/dap_time.h b/dap-sdk/core/include/dap_time.h
index 9554b3118ed12b48d1678e9a9eb0e6ba8d4d08ec..76a739898d160fc5c04c26e3458756ed158c4c33 100644
--- a/dap-sdk/core/include/dap_time.h
+++ b/dap-sdk/core/include/dap_time.h
@@ -42,7 +42,7 @@ void dap_usleep(dap_time_t a_microseconds);
  * @return
  */
 char* dap_ctime_r(dap_time_t *a_time, char* a_buf);
-char* dap_gdb_ctime_r(dap_nanotime_t *a_time, char* a_buf);
+char* dap_nanotime_to_str(dap_nanotime_t *a_time, char* a_buf);
 
 
 int dap_time_to_str_rfc822(char * out, size_t out_size_max, dap_time_t t);
diff --git a/dap-sdk/core/src/dap_time.c b/dap-sdk/core/src/dap_time.c
index 075e1961da4d760402a4b54c0af824ab201376b0..1b45fc2360c356d6081adac909bfb7d6a899f0c5 100644
--- a/dap-sdk/core/src/dap_time.c
+++ b/dap-sdk/core/src/dap_time.c
@@ -233,7 +233,7 @@ char* dap_ctime_r(dap_time_t *a_time, char* a_buf)
  * @param a_buf The minimum buffer size is 26 elements.
  * @return
  */
-char* dap_gdb_ctime_r(dap_nanotime_t *a_chain_time, char* a_buf){
+char* dap_nanotime_to_str(dap_nanotime_t *a_chain_time, char* a_buf){
     dap_time_t l_time = dap_gdb_time_to_sec(*a_chain_time);
     return dap_ctime_r(&l_time, a_buf);
 }
diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h
index 226fe77eb32b2b09e66e4724b1ed9a4f62969ff6..c4b29bba1aa08363882771b207aaf0499c06f1ac 100644
--- a/modules/common/include/dap_chain_datum_tx.h
+++ b/modules/common/include/dap_chain_datum_tx.h
@@ -26,6 +26,7 @@
 #include "dap_list.h"
 #include "dap_enc_key.h"
 #include "dap_chain_common.h"
+#include "dap_time.h"
 
 typedef enum dap_chain_tx_cond_type {
     COND_SERVICE_PROVIDE = 0x20, //
@@ -39,7 +40,7 @@ typedef enum dap_chain_tx_cond_type {
   */
 typedef struct dap_chain_datum_tx{
     struct {
-        uint64_t ts_created;
+        dap_time_t ts_created;
         uint32_t tx_items_size; // size of next sequencly lying tx_item sections would be decided to belong this transaction
     } DAP_ALIGN_PACKED header;
     uint8_t tx_items[];
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index a387eb04d7c37a2d6c0805427ac730eee6e08f5d..563f88e0df658b3d989c83525c453a3bd362ebbb 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -26,6 +26,10 @@
 
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
+#include "dap_chain.h"
+#include "dap_chain_datum_tx_out_cond.h"
+#include "dap_list.h"
+#include "dap_time.h"
 #endif
 #ifndef  _XOPEN_SOURCE
 #define _XOPEN_SOURCE       /* See feature_test_macros(7) */
@@ -3288,6 +3292,131 @@ void dap_chain_net_proc_mempool (dap_chain_net_t * a_net)
     }
 }
 
+/**
+ * @brief dap_chain_net_get_tx_cond_all_by_srv_uid
+ * @param a_net
+ * @param a_srv_uid
+ * @param a_search_type
+ * @return
+ */
+dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, const dap_chain_net_srv_uid_t a_srv_uid,
+                                                      const dap_time_t a_time_from, const dap_time_t a_time_to,
+                                                     const dap_chain_net_tx_search_type_t a_search_type)
+{
+    dap_ledger_t * l_ledger = a_net->pub.ledger;
+    dap_list_t * l_ret = NULL;
+
+    switch (a_search_type) {
+        case TX_SEARCH_TYPE_NET:
+        case TX_SEARCH_TYPE_CELL:
+        case TX_SEARCH_TYPE_LOCAL:
+        case TX_SEARCH_TYPE_CELL_SPENT:
+        case TX_SEARCH_TYPE_NET_SPENT: {
+            // pass all chains
+            for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){
+                dap_chain_cell_t * l_cell, *l_cell_tmp;
+                // Go through all cells
+                HASH_ITER(hh,l_chain->cells,l_cell, l_cell_tmp){
+                    dap_chain_atom_iter_t * l_atom_iter = l_chain->callback_atom_iter_create(l_chain,l_cell->id, false  );
+                    // try to find transaction in chain ( inside shard )
+                    size_t l_atom_size = 0;
+                    dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get_first(l_atom_iter, &l_atom_size);
+
+                    // Check atoms in chain
+                    while(l_atom && l_atom_size) {
+                        dap_chain_datum_t *l_datum = (dap_chain_datum_t*) l_atom;
+                        // transaction
+                        dap_chain_datum_tx_t *l_tx = NULL;
+
+                        // Check if its transaction
+                        if ( l_datum && (l_datum->header.type_id == DAP_CHAIN_DATUM_TX)) {
+                            l_tx = (dap_chain_datum_tx_t*) l_datum->data;
+                        }
+
+                        // If found TX
+                        if (l_tx){
+                            // Check for time from
+                            if(a_time_from && l_tx->header.ts_created < a_time_from)
+                                    continue;
+
+                            // Check for time to
+                            if(a_time_to && l_tx->header.ts_created > a_time_to)
+                                    continue;
+
+                            if(a_search_type == TX_SEARCH_TYPE_CELL_SPENT || a_search_type == TX_SEARCH_TYPE_NET_SPENT ){
+                                dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
+                                bool l_is_spent = dap_chain_ledger_tx_spent_find_by_hash(l_ledger,l_tx_hash);
+                                DAP_DELETE(l_tx_hash);
+                                if(!l_is_spent)
+                                    continue;
+                            }
+                            // Check for OUT_COND items
+                            dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND , NULL);
+                            if(l_list_out_cond_items){
+                                dap_list_t *l_list_cur = l_list_out_cond_items;
+                                while(l_list_cur){ // Go through all cond items
+                                    l_list_cur = dap_list_next(l_list_cur);
+                                    dap_chain_tx_out_cond_t * l_tx_out_cond = (dap_chain_tx_out_cond_t *)l_list_cur->data;
+                                    if(l_tx_out_cond) // If we found cond out with target srv_uid
+                                        if(l_tx_out_cond->header.srv_uid.uint64 == a_srv_uid.uint64)
+                                            l_ret = dap_list_append(l_ret,l_tx);
+                                }
+                                dap_list_free(l_list_out_cond_items);
+                            }
+                        }
+
+                        // go to next atom
+                        l_atom = l_chain->callback_atom_iter_get_next(l_atom_iter, &l_atom_size);
+
+                    }
+                }
+            }
+        } break;
+
+        case TX_SEARCH_TYPE_NET_UNSPENT:
+        case TX_SEARCH_TYPE_CELL_UNSPENT:
+            l_ret = dap_chain_ledger_tx_cache_find_out_cond_all(l_ledger, a_srv_uid);
+            break;
+    }
+    return l_ret;
+
+}
+
+/**
+ * @brief Summarize all tx inputs
+ * @param a_net
+ * @param a_tx
+ * @return
+ */
+uint256_t dap_chain_net_get_tx_total_value(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx)
+{
+    uint256_t l_ret = {0};
+    int l_item_idx = 0;
+    dap_chain_tx_in_t *l_in_item = NULL;
+    do {
+        l_in_item = (dap_chain_tx_in_t*) dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN , NULL);
+        l_item_idx++;
+        if(l_in_item ) {
+            //const char *token = l_out_cond_item->subtype.srv_xchange.token;
+            dap_chain_datum_tx_t * l_tx_prev = dap_chain_net_get_tx_by_hash(a_net,&l_in_item->header.tx_prev_hash, TX_SEARCH_TYPE_NET_SPENT);
+            if(l_tx_prev){
+                int l_tx_prev_out_index = l_in_item->header.tx_out_prev_idx;
+                dap_chain_tx_out_t *  l_tx_prev_out =(dap_chain_tx_out_t *)
+                        dap_chain_datum_tx_item_get(l_tx_prev,&l_tx_prev_out_index, TX_ITEM_TYPE_OUT,NULL);
+                if( l_tx_prev_out_index == l_in_item->header.tx_out_prev_idx && l_tx_prev_out){
+                    uint256_t l_in_value = l_tx_prev_out->header.value;
+                    if(SUM_256_256(l_in_value,l_ret, &l_ret )!= 0)
+                        log_it(L_ERROR, "Overflow on inputs values calculation (summing)");
+                }else{
+                    log_it(L_WARNING, "Can't find item with index %d in prev tx hash", l_tx_prev_out_index);
+                }
+            }else
+                log_it(L_WARNING, "Can't find prev tx hash");
+        }
+    } while(l_in_item);
+    return l_ret;
+}
+
 /**
  * @brief dap_chain_net_tx_get_by_hash
  * @param a_net
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 96a05c6e9ec051a01ab40ee5eef8619778942638..dd277fab5cdbabf2037f4fb17c69db0ac8d76337 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -27,6 +27,8 @@ along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/lic
 
 #include <stdint.h>
 #include <string.h>
+#include "dap_chain_datum_tx.h"
+#include "dap_math_ops.h"
 #include "dap_net.h"
 #include "dap_stream_ch.h"
 #include "dap_strfuncs.h"
@@ -157,6 +159,13 @@ typedef enum dap_chain_net_tx_search_type {
 dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash,
                                                      dap_chain_net_tx_search_type_t a_search_type);
 
+uint256_t dap_chain_net_get_tx_total_value(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx);
+
+dap_list_t * dap_chain_net_get_tx_cond_all_by_srv_uid(dap_chain_net_t * a_net, const dap_chain_net_srv_uid_t a_srv_uid,
+                                                      const dap_time_t a_time_from, const dap_time_t a_time_to,
+                                                     const dap_chain_net_tx_search_type_t a_search_type);
+
+
 dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net);
 
 /**
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 45bc1a6653a46d37aa835a5929ea1f79fb9ef79e..673d9a0ce6b83e0fda462731baa3c13dccc91e80 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -23,17 +23,29 @@
 */
 
 #include <math.h>
+#include <stdint.h>
 #include "dap_chain_datum_token.h"
+#include "dap_chain_datum_tx.h"
+#include "dap_chain_datum_tx_in.h"
 #include "dap_chain_ledger.h"
+#include "dap_chain_net.h"
 #include "dap_chain_node_cli.h"
+#include "dap_hash.h"
+#include "dap_list.h"
+#include "dap_math_ops.h"
+#include "dap_strfuncs.h"
 #include "dap_string.h"
 #include "dap_chain_common.h"
 #include "dap_chain_mempool.h"
 #include "dap_chain_net_srv.h"
 #include "dap_chain_net_srv_xchange.h"
+#include "dap_time.h"
 
 #define LOG_TAG "dap_chain_net_srv_xchange"
 
+const dap_chain_net_srv_uid_t c_dap_chain_net_srv_xchange_uid = {.uint64= DAP_CHAIN_NET_SRV_XCHANGE_ID};
+
+
 static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply);
 static int s_callback_requested(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
 static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size);
@@ -68,10 +80,12 @@ int dap_chain_net_srv_xchange_init()
         "\tList of exchange transactions\n"
     "srv_xchange token_pair -net <net name> list all\n"
         "\tList of all token pairs\n"
-    "srv_xchange token_pair -net <net name> price average -token1 <token 1> -token2 <token 2> [-interval <interval length>] [-time <Moment to calc>]  \n"
-        "\tGet average price for token pair <token 1>:<token 2> from time -time with interval length -interval \n"
+    "srv_xchange token_pair -net <net name> price average -token1 <token 1> -token2 <token 2> [-time_from <From time>] [-time_to <To time>]  \n"
+        "\tGet average price for token pair <token 1>:<token 2> from <From time> to <To time> \n"
+        "\tAll times are in RFC822"
     "srv_xchange token_pair -net <net name> price history -token1 <token 1> -token2 <token 2> [-time_from <From time>] [-time_to <To time>] \n"
-        "\tPrint price history for token pair <token 1>:<token 2> from time -time with interval length -interval \n"
+        "\tPrint price history for token pair <token 1>:<token 2> from <From time> to <To time>\n"
+        "\tAll times are in RFC822"
     "srv_xchange enable\n"
          "\tEnable eXchange service\n"
     "srv_xchange disable\n"
@@ -862,6 +876,7 @@ static bool s_filter_tx_list(dap_chain_datum_t *a_datum, dap_chain_t *a_chain, v
     return false;
 }
 
+
 static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
 {
     enum {
@@ -1044,17 +1059,134 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     return -6;
                 }
 
+                // Read time_from
+                dap_time_t l_time_from = 0;
+                const char * l_time_from_str = NULL;
+                dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-time_from", &l_time_from_str);
+                l_time_from = dap_time_from_str_rfc822(l_time_from_str);
+
+                // Read time_to
+                dap_time_t l_time_to = 0;
+                const char * l_time_to_str = NULL;
+                dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-time_to", &l_time_to_str);
+                l_time_to = dap_time_from_str_rfc822(l_time_to_str);
+
+
                 // Check for price subcommand
                 if (strcmp(l_price_subcommand,"average") == 0){
+                    dap_string_t *l_reply_str = dap_string_new("");
+
+                    dap_list_t *l_tx_cond_list = dap_chain_net_get_tx_cond_all_by_srv_uid(l_net, c_dap_chain_net_srv_xchange_uid,
+                                                                                          l_time_from,l_time_to,TX_SEARCH_TYPE_NET );
+                    dap_list_t * l_cur = l_tx_cond_list;
+                    uint256_t l_total_rates = {0};
+                    uint256_t l_total_rates_count = {0};
+                    while(l_cur){
+                        dap_chain_datum_tx_t * l_tx =(dap_chain_datum_tx_t *) l_cur->data;
+                        if(l_tx){
+                            dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
+
+                            // Get input token ticker
+                            const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+                                        l_net->pub.ledger, l_tx_hash);
+
+                            // Compare with token1 and token2
+                            if( dap_strcmp(l_tx_input_ticker, l_token1) != 0 &&
+                                    dap_strcmp(l_tx_input_ticker, l_token2) != 0)
+                                continue;
+
+                            dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
+                            int l_item_idx = 0;
+                            do {
+                                l_out_cond_item = (dap_chain_tx_out_cond_t*) dap_chain_datum_tx_item_get(l_tx, &l_item_idx, TX_ITEM_TYPE_OUT_COND, NULL);
+                                l_item_idx++;
+                                if(l_out_cond_item && l_out_cond_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE) {
+                                    //const char *token = l_out_cond_item->subtype.srv_xchange.token;
+                                    uint256_t value = l_out_cond_item->subtype.srv_xchange.value;
+                                    uint256_t l_total_rates_old = l_total_rates;
+                                    if(SUM_256_256(l_out_cond_item->subtype.srv_xchange.value,l_total_rates_old, &l_total_rates )!= 0)
+                                        log_it(L_ERROR, "Overflow on avarage price calculation (summing)");
+                                    INCR_256(&l_total_rates_count);
+                                }
+                            }
+                            while(l_out_cond_item);
+
+                        }
+                        l_cur = dap_list_next(l_cur);
+                    }
+                    dap_list_free(l_tx_cond_list);
+                    uint256_t l_rate_average = {0};
+                    DIV_256(l_total_rates,l_total_rates_count,&l_rate_average);
+                    char *l_rate_average_str = dap_cvt_uint256_to_str(l_rate_average);
+                    dap_string_append_printf(l_reply_str,"Average rate: %s",l_rate_average_str);
+                    DAP_DELETE(l_rate_average_str);
 
+                    *a_str_reply = dap_string_free(l_reply_str, false);
+                    break;
                 }else if (strcmp(l_price_subcommand,"history") == 0){
+                    dap_string_t *l_reply_str = dap_string_new("");
 
+                    dap_list_t *l_tx_cond_list = dap_chain_net_get_tx_cond_all_by_srv_uid(l_net, c_dap_chain_net_srv_xchange_uid,
+                                                                                          l_time_from,l_time_to,TX_SEARCH_TYPE_NET_SPENT );
+                    dap_list_t * l_cur = l_tx_cond_list;
+                    while(l_cur){
+                        dap_chain_datum_tx_t * l_tx =(dap_chain_datum_tx_t *) l_cur->data;
+                        if(l_tx){
+                            dap_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(l_tx);
+
+                            // Get input token ticker
+                            const char * l_tx_input_ticker = dap_chain_ledger_tx_get_token_ticker_by_hash(
+                                        l_net->pub.ledger, l_tx_hash);
+
+                            // Compare with token1 and token2
+                            if( dap_strcmp(l_tx_input_ticker, l_token1) != 0 &&
+                                    dap_strcmp(l_tx_input_ticker, l_token2) != 0)
+                                continue;
+
+                            char * l_tx_hash_str = dap_chain_hash_fast_to_str_new(l_tx_hash);\
+
+                            char l_tx_ts_created_str[72];
+                            l_tx_ts_created_str[0] = '\0';
+                            dap_time_to_str_rfc822(l_tx_ts_created_str,sizeof(l_tx_ts_created_str),l_tx->header.ts_created);
+                            dap_string_append_printf(l_reply_str,"Tx hash: %s\n", l_tx_hash_str);
+                            dap_string_append_printf(l_reply_str,"\tts_created: %s\n", l_tx_ts_created_str);
+                            DAP_DEL_Z(l_tx_hash);
+                            DAP_DEL_Z(l_tx_hash_str);
+
+                            // Calc inputs
+                            uint256_t l_tx_input_values = dap_chain_net_get_tx_total_value(l_net, l_tx);
+
+                            // Find output
+                            int l_item_idx = 0;
+                            dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
+                            do {
+                                l_out_cond_item = (dap_chain_tx_out_cond_t*) dap_chain_datum_tx_item_get(l_tx, &l_item_idx, TX_ITEM_TYPE_OUT_COND, NULL);
+                                l_item_idx++;
+                                if(l_out_cond_item && l_out_cond_item->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE) {
+                                    //const char *token = l_out_cond_item->subtype.srv_xchange.token;
+                                    uint256_t l_value_to = l_out_cond_item->subtype.srv_xchange.value;
+                                    char * l_value_from_str = dap_cvt_uint256_to_str(l_tx_input_values);
+                                    char * l_value_to_str = dap_cvt_uint256_to_str(l_value_to);
+                                    dap_string_append_printf(l_reply_str,
+                                                             "\tFrom %s %s To %s %s\n",l_tx_input_ticker,l_value_from_str,
+                                                             l_value_to_str,l_out_cond_item->subtype.srv_xchange.token );
+                                    DAP_DELETE(l_value_from_str);
+                                    DAP_DELETE(l_value_to_str);
+                                }
+                            }
+                            while(l_out_cond_item);
 
+                        }
+                        // Delimiter between tx
+                        dap_string_append_printf(l_reply_str,"\n\n");
 
-                    dap_string_t *l_reply_str = dap_string_new("");
+                        l_cur = dap_list_next(l_cur);
+                    }
 
-                    // Find SRV_XCHANGE out_cond item
-                    dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
+                    dap_list_free(l_tx_cond_list);
+
+                    *a_str_reply = dap_string_free(l_reply_str, false);
+                    break;
 
                 }
             }
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 216f1ca0edfebb895a07ec57b0b032f1c4c924b8..2c2348e12369bf8341b99f3597afdd1bf14683d7 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -71,6 +71,8 @@ typedef struct dap_chain_net_srv_xchange {
     bool enabled;
 } dap_chain_net_srv_xchange_t;
 
+extern const dap_chain_net_srv_uid_t c_dap_chain_net_srv_xchange_uid;
+
 int dap_chain_net_srv_xchange_init();
 void dap_chain_net_srv_xchange_deinit();
 bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner);