From 2a64c55fe59a026966b9d54571c2d25106b74f28 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Mon, 6 Jan 2025 15:12:12 +0300
Subject: [PATCH 01/10] [*] Fix addr history with wallet cache in exchanger

---
 .../xchange/dap_chain_net_srv_xchange.c       | 20 ++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 4473edadad..3f44485422 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1470,7 +1470,6 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 if(l_from_wallet_cache){  
                     dap_string_t * l_str_reply = dap_string_new("");
 
-                    dap_chain_datum_tx_t *l_datum_tx = NULL;
                     xchange_orders_cache_net_t* l_cache = NULL;
                     if(s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                         l_cache = s_get_xchange_cache_by_net_id(l_net->pub.id);
@@ -1480,8 +1479,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                         }
                     }
                     dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*l_addr);
-                    l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST);
-                    while((l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) != NULL)
+                    for(dap_chain_datum_tx_t *l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST);
+                            l_datum_tx; l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT))
                     {
                         if (l_iter->ret_code != 0)
                             continue; 
@@ -2153,11 +2152,14 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
                 l_tx_count++;
         }
     } else {
-        dap_chain_datum_tx_t *l_datum_tx = NULL;
         int l_ret_code = 0;
-        dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr);
-        l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST);
-        while( (l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT)) != NULL)
+        dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr);// TODO add check l_iter != NULL
+        if(!l_iter){
+            log_it(L_ERROR, "Can't create iterator item for wallet %s", dap_chain_addr_to_str_static(a_addr));
+            return -1;
+        }
+        for(dap_chain_datum_tx_t *l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_FIRST);
+            l_datum_tx; l_datum_tx = dap_chain_wallet_cache_iter_get(l_iter, DAP_CHAIN_WALLET_CACHE_GET_NEXT))
         {
             if (l_iter->ret_code != 0)
                 continue; 
@@ -2168,8 +2170,8 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
             if ( a_before && (l_datum_tx->header.ts_created > a_before) )
                 continue;
 
-            if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
-                l_tx_count++;
+            if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, l_iter->cur_hash, a_opt_status, false, true, true))
+                l_tx_count++;            
         }
         dap_chain_wallet_cache_iter_delete(l_iter);
     }
-- 
GitLab


From b8c79fd2e3c125e9ca1141711ca795c2fb886802 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Mon, 6 Jan 2025 18:56:33 +0300
Subject: [PATCH 02/10] [+] Add initial proposal into orders info output in
 srv_xchange

---
 .../xchange/dap_chain_net_srv_xchange.c       | 37 ++++++++++++++-----
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 3f44485422..0a781ee28e 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1695,10 +1695,11 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             char* l_status_order = NULL;
             const char *l_token_buy = NULL;
             const char *l_token_sell = NULL;
-            const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL;
+            const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL, 
+                        *l_proposed_coins_str = NULL, *l_proposed_datoshi_str = NULL;
             uint64_t l_percent_completed = 0;
             dap_chain_datum_tx_t *l_tx = NULL;
-            uint256_t l_amount, l_rate;
+            uint256_t l_amount, l_rate, l_proposed;
 
             if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                 xchange_orders_cache_net_t* l_cache = NULL;
@@ -1730,6 +1731,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 
                 l_token_sell = l_item->sell_token;
                 l_token_buy = l_item->buy_token;
+                l_proposed = l_item->tx_info.order_info.value;
                 
                 uint256_t l_completed = {};
                 SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed);
@@ -1780,7 +1782,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
 
                 l_token_sell = l_price->token_sell;
                 l_token_buy = l_price->token_buy;
-                
+                l_proposed = l_price->datoshi_sell;
                 l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0;
                 l_rate = l_price->rate;
 
@@ -1804,10 +1806,15 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
 
             l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount);
             l_amount_coins_str = dap_uint256_decimal_to_char(l_amount);
+            l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); 
+            l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed);
             l_cp_rate = dap_chain_balance_to_coins(l_rate); 
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n",
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s(%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n",
                                      l_order_hash_str,
-                                     l_tmp_buf, l_status_order,
+                                     l_tmp_buf, l_status_order, 
+                                     l_proposed_coins_str ? l_proposed_coins_str : "0.0", 
+                                     l_proposed_datoshi_str ? l_proposed_datoshi_str : "0.0", 
+                                     l_token_sell,
                                      l_amount_coins_str ? l_amount_coins_str : "0.0",
                                      l_amount_datoshi_str ? l_amount_datoshi_str : "0",
                                      l_token_sell, l_percent_completed,
@@ -1819,6 +1826,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             DAP_DEL_Z(l_cp_rate);
             DAP_DEL_Z(l_amount_coins_str);
             DAP_DEL_Z(l_amount_datoshi_str);
+            DAP_DEL_Z(l_proposed_coins_str);
+            DAP_DEL_Z(l_proposed_datoshi_str);
         } break;
 
         default: {
@@ -2331,9 +2340,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 dap_chain_net_srv_xchange_order_status_t l_order_status = XCHANGE_ORDER_STATUS_UNKNOWN;
                 dap_hash_fast_t l_tx_hash = {};
                 uint64_t l_percent_completed = 0;
-                uint256_t l_amount = {};
-                const char *l_amount_coins_str = NULL;
-                const char *l_amount_datoshi_str = NULL;
+                uint256_t l_amount = {}, l_proposed;
+                const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL, 
+                        *l_proposed_coins_str = NULL, *l_proposed_datoshi_str = NULL;
 
                 if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                     xchange_tx_cache_t *l_item = (xchange_tx_cache_t*)it->data;
@@ -2346,7 +2355,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     l_order_status = l_item->tx_info.order_info.order_status;
                     l_rate = l_item->rate;
                     l_amount = l_item->tx_info.order_info.value_ammount;
-
+                    l_proposed = l_item->tx_info.order_info.value;
                     uint256_t l_completed = {};
                     SUBTRACT_256_256(l_item->tx_info.order_info.value, l_item->tx_info.order_info.value_ammount, &l_completed);
                     DIV_256_COIN(l_completed, l_item->tx_info.order_info.value, &l_completed);
@@ -2398,6 +2407,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     l_rate = l_price->rate;
                     l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_tx_hash);
                     l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0;
+                    l_proposed = l_price->datoshi_sell;
                     DAP_DEL_Z(l_price);
                 }
 
@@ -2433,9 +2443,14 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 l_cp_rate = dap_uint256_decimal_to_char(l_rate);
                 l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount);
                 l_amount_coins_str = dap_uint256_decimal_to_char(l_amount);
+                l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); 
+                l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed);
 
-                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str,
+                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s (%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str,
                                          l_tmp_buf, l_status_order_str,
+                                         l_proposed_coins_str ? l_proposed_coins_str : "0.0",
+                                         l_proposed_datoshi_str ? l_proposed_datoshi_str : "0",
+                                         l_sell_token, 
                                          l_amount_coins_str ? l_amount_coins_str : "0.0",
                                          l_amount_datoshi_str ? l_amount_datoshi_str : "0",
                                          l_sell_token, l_percent_completed,
@@ -2446,6 +2461,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 DAP_DEL_Z(l_cp_rate);
                 DAP_DEL_Z(l_amount_datoshi_str);
                 DAP_DEL_Z(l_amount_coins_str);
+                DAP_DEL_Z(l_proposed_coins_str);
+                DAP_DEL_Z(l_proposed_datoshi_str);
             }
             if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                 dap_list_free(l_list);
-- 
GitLab


From b482d98cf64530b6ae0833992c3fec01afcd64c3 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Wed, 8 Jan 2025 18:02:23 +0300
Subject: [PATCH 03/10] [+] Add addr filter in orders command for xchange [+]
 Add owner and buyer wallet addr in tx dump for xchange [+] Start of
 development traiding value printing in token_pair rate history command for
 exchange

---
 .../xchange/dap_chain_net_srv_xchange.c       | 160 +++++++++++++++---
 1 file changed, 135 insertions(+), 25 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 4473edadad..93649b068a 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -69,6 +69,7 @@ typedef struct xchange_tx_cache {
     dap_chain_hash_fast_t hash;
     dap_chain_datum_tx_t *tx;
     xchange_tx_type_t tx_type;
+    dap_chain_addr_t seller_addr;
     char buy_token[DAP_CHAIN_TICKER_SIZE_MAX];
     char sell_token[DAP_CHAIN_TICKER_SIZE_MAX];
     uint256_t rate;
@@ -77,7 +78,6 @@ typedef struct xchange_tx_cache {
             dap_chain_net_srv_xchange_order_status_t order_status;
             uint256_t value;
             uint256_t value_ammount;
-            dap_chain_addr_t seller_addr;
             dap_hash_fast_t next_hash;
         } order_info;
         struct {
@@ -119,7 +119,7 @@ static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_us
 static int s_callback_response_error(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_receipt_next_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);
 static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx);
-static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
+static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_addr_t *a_owner_addr, dap_chain_addr_t *a_buyer_addr, dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts);
 dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, dap_hash_fast_t *a_order_hash, uint256_t *a_fee, bool a_ret_is_invalid);
 static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chan_ledger_notify_opcodes_t a_opcode);
 
@@ -224,7 +224,7 @@ int dap_chain_net_srv_xchange_init()
          "\tShows transaction history for the selected order\n"
     "srv_xchange order status -net <net_name> -order <order_hash>\n"
          "\tShows current amount of unselled coins from the selected order and percentage of its completion\n"
-    "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>] [-limit <limit>] [-offset <offset>]\n"
+    "srv_xchange orders -net <net_name> [-status {opened|closed|all}] [-token_from <token_ticker>] [-token_to <token_ticker>] [-addr <wallet_addr>] [-limit <limit>] [-offset <offset>]\n"
          "\tGet the exchange orders list within specified net name\n"
 
     "srv_xchange purchase -order <order hash> -net <net_name> -w <wallet_name> -value <value> -fee <value>\n"
@@ -1486,15 +1486,22 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                         if (l_iter->ret_code != 0)
                             continue; 
 
+                        
                         if(s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                             xchange_tx_cache_t* l_item = NULL;
                             HASH_FIND(hh, l_cache->cache, l_iter->cur_hash, sizeof(dap_hash_fast_t), l_item); 
                             if (!l_item)
                                 continue;
+                                
+                            if (s_string_append_tx_cond_info(l_str_reply, l_net, &l_item->seller_addr, 
+                                l_item->tx_type == TX_TYPE_EXCHANGE ?  &l_item->tx_info.exchange_info.buyer_addr : NULL, 
+                                l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false))
+                                
+                                l_total++;
+                        } else {
+                            if (s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false))
+                                l_total++;
                         }
-
-                        if (s_string_append_tx_cond_info(l_str_reply, l_net, l_datum_tx, l_iter->cur_hash, TX_STATUS_ALL, true, true, false))
-                            l_total++;
                     }
                     dap_chain_wallet_cache_iter_delete(l_iter);
                     
@@ -1515,7 +1522,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                             dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
                             dap_hash_fast_t l_hash = {};
                             dap_hash_fast(l_tx_cur, dap_chain_datum_tx_get_size(l_tx_cur), &l_hash);
-                            if (s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false))
+                            if (s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false))
                                 l_total++;
                             l_tx_list_temp = l_tx_list_temp->next;
                         }
@@ -1553,7 +1560,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                                     dap_chain_datum_tx_t * l_tx_cur = (dap_chain_datum_tx_t*) l_tx_list_temp->data;
                                     dap_hash_fast_t l_hash = {};
                                     dap_hash_fast(l_tx_cur, dap_chain_datum_tx_get_size(l_tx_cur), &l_hash);
-                                    s_string_append_tx_cond_info(l_str_reply, l_net, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false);
+                                    s_string_append_tx_cond_info(l_str_reply, l_net, NULL, NULL, l_tx_cur, &l_hash, TX_STATUS_ALL, true, true, false);
                                     l_tx_list_temp = l_tx_list_temp->next;
                                 }
                                 dap_list_free(l_tx_list);
@@ -1577,7 +1584,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                         return -18;
                     }
                     while(l_item){
-                        s_string_append_tx_cond_info(l_str_reply, l_net, l_item->tx, &l_item->hash, TX_STATUS_ALL, true, true, false);
+                        s_string_append_tx_cond_info(l_str_reply, l_net, &l_item->seller_addr, 
+                                l_item->tx_type == TX_TYPE_EXCHANGE ?  &l_item->tx_info.exchange_info.buyer_addr : NULL, 
+                                l_item->tx, &l_item->hash, TX_STATUS_ALL, true, true, false);
                         switch(l_item->tx_type){
                             case TX_TYPE_ORDER:{
                                 l_cur_hash = l_item->tx_info.order_info.next_hash;
@@ -1697,6 +1706,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             const char *l_token_buy = NULL;
             const char *l_token_sell = NULL;
             const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL;
+            const char *l_owner_addr = NULL;
             uint64_t l_percent_completed = 0;
             dap_chain_datum_tx_t *l_tx = NULL;
             uint256_t l_amount, l_rate;
@@ -1740,6 +1750,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                 l_percent_completed = dap_chain_balance_to_coins_uint64(l_completed);
 
                 l_amount_datoshi_str = dap_uint256_to_char(l_item->tx_info.order_info.value_ammount, &l_amount_coins_str);
+                l_owner_addr = dap_chain_addr_to_str_static(&l_item->seller_addr);
             } else {
                 l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order_tx_hash);
                 if (!l_tx){
@@ -1797,6 +1808,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                         l_status_order = "UNKNOWN";
                         break;
                 };
+
+                l_owner_addr = dap_chain_addr_to_str_static(&l_price->creator_addr);
                 DAP_DEL_Z(l_price);
             }
 
@@ -1806,15 +1819,15 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount);
             l_amount_coins_str = dap_uint256_decimal_to_char(l_amount);
             l_cp_rate = dap_chain_balance_to_coins(l_rate); 
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n",
-                                     l_order_hash_str,
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n"
+                                     "owner addr: %s\n\n", l_order_hash_str,
                                      l_tmp_buf, l_status_order,
                                      l_amount_coins_str ? l_amount_coins_str : "0.0",
                                      l_amount_datoshi_str ? l_amount_datoshi_str : "0",
                                      l_token_sell, l_percent_completed,
                                      l_token_buy, l_token_sell,
                                      l_cp_rate,
-                                     l_net->pub.name);
+                                     l_net->pub.name, l_owner_addr ? l_owner_addr : "unknown" );
 
 
             DAP_DEL_Z(l_cp_rate);
@@ -1967,8 +1980,8 @@ static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_ch
  * @param a_net
  * @param a_tx
  */
-static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
-                                         dap_chain_net_t * a_net,
+static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net,
+                                         dap_chain_addr_t *a_owner_addr, dap_chain_addr_t *a_buyer_addr,
                                          dap_chain_datum_tx_t * a_tx, dap_hash_fast_t *a_tx_hash,
                                          tx_opt_status_t a_filter_by_status,
                                          bool a_print_prev_hash, bool a_print_status, bool a_print_ts)
@@ -2015,6 +2028,14 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
                 dap_string_append_printf(a_reply_str, "  Status: %s,", l_is_closed ? "inactive" : "active");
             dap_string_append_printf(a_reply_str, "  proposed %s (%s) %s for exchange to %s,", l_amount_str, l_amount_datoshi_str, l_tx_input_ticker, l_out_cond_item->subtype.srv_xchange.buy_token);
             dap_string_append_printf(a_reply_str, "  rate (%s/%s): %s, net: %s", l_out_cond_item->subtype.srv_xchange.buy_token, l_tx_input_ticker, l_rate_str, a_net->pub.name);
+            dap_chain_addr_t l_owner_addr = {};
+            if (!a_owner_addr){
+                l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0});
+            } else {
+                l_owner_addr = *a_owner_addr;
+            }
+
+            dap_string_append_printf(a_reply_str, "\nowner addr %s \n", dap_chain_addr_to_str_static(&l_owner_addr));
 
             DAP_DELETE(l_rate_str);
         } break;
@@ -2068,6 +2089,27 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
                                                                         l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name);
             if (a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
+
+
+            dap_chain_addr_t l_owner_addr = {};
+            if (!a_owner_addr){
+                l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0});
+            } else {
+                l_owner_addr = *a_owner_addr;
+            }
+            dap_string_append_printf(a_reply_str, "\nowner addr: %s \n", dap_chain_addr_to_str_static(&l_owner_addr));
+
+            dap_chain_addr_t l_buyer_addr = {};
+            if(!a_buyer_addr){
+                dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
+                dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
+                dap_enc_key_t *l_key_buyer = dap_sign_to_enc_key(l_sign);
+                dap_chain_addr_fill_from_key(&l_buyer_addr, l_key_buyer, a_net->pub.id);
+                dap_enc_key_delete(l_key_buyer);
+            } else 
+                l_buyer_addr = *a_buyer_addr;
+            dap_string_append_printf(a_reply_str, "buyer addr: %s \n", dap_chain_addr_to_str_static(&l_buyer_addr));
+
         } break;
         case TX_TYPE_INVALIDATE:{
             dap_chain_tx_in_cond_t * l_in_cond = (dap_chain_tx_in_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_IN_COND , NULL);
@@ -2111,6 +2153,14 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str,
             if(a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
 
+            dap_chain_addr_t l_owner_addr = {};
+            if (!a_owner_addr){
+                l_owner_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0});
+            } else {
+                l_owner_addr = *a_owner_addr;
+            }
+            dap_string_append_printf(a_reply_str, "owner addr %s \n", dap_chain_addr_to_str_static(&l_owner_addr));
+
             DAP_DELETE(l_value_from_str);
             DAP_DELETE(l_value_from_datoshi_str);
         } break;
@@ -2149,7 +2199,7 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
             if ( a_before && (l_datum_tx->header.ts_created > a_before) )
                 continue;
 
-            if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
+            if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
                 l_tx_count++;
         }
     } else {
@@ -2168,7 +2218,7 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
             if ( a_before && (l_datum_tx->header.ts_created > a_before) )
                 continue;
 
-            if (s_string_append_tx_cond_info(l_reply_str, a_net, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
+            if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
                 l_tx_count++;
         }
         dap_chain_wallet_cache_iter_delete(l_iter);
@@ -2297,6 +2347,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 }
             }
 
+            dap_chain_addr_t *l_addr = NULL;
+            const char *l_addr_str = NULL;
+            dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_addr_str);
+            if (l_addr_str) 
+                l_addr = dap_chain_addr_from_str(l_addr_str);
+
             uint64_t l_printed_orders_count = 0;
             const char *l_limit_str = NULL;
             const char *l_offset_str = NULL;
@@ -2332,11 +2388,17 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 uint256_t l_amount = {};
                 const char *l_amount_coins_str = NULL;
                 const char *l_amount_datoshi_str = NULL;
+                const char *l_owner_addr = NULL;
 
                 if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                     xchange_tx_cache_t *l_item = (xchange_tx_cache_t*)it->data;
                     if (l_item->tx_type != TX_TYPE_ORDER)
                         continue;
+
+                    if (l_addr && dap_chain_addr_compare(&l_item->seller_addr, l_addr) == 0)
+                        continue;
+                    
+                    l_owner_addr = dap_chain_addr_to_str_static(&l_item->seller_addr);
                     l_tx = l_item->tx;
                     l_tx_hash = l_item->hash;
                     memcpy(l_buy_token, l_item->buy_token, strlen(l_item->buy_token));
@@ -2365,6 +2427,10 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                         log_it(L_WARNING,"Can't create price from order");
                         continue;
                     }
+
+                    if(l_addr && dap_chain_addr_compare(&l_price->creator_addr, l_addr) == 0)
+                        continue;
+
                     memcpy(l_buy_token, l_price->token_buy, strlen(l_price->token_buy));
                     memcpy(l_sell_token, l_price->token_sell, strlen(l_price->token_sell));
 
@@ -2396,6 +2462,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     l_rate = l_price->rate;
                     l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_tx_hash);
                     l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0;
+                    l_owner_addr = dap_chain_addr_to_str_static(&l_price->creator_addr);
                     DAP_DEL_Z(l_price);
                 }
 
@@ -2432,14 +2499,15 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 l_amount_datoshi_str = dap_uint256_uninteger_to_char(l_amount);
                 l_amount_coins_str = dap_uint256_decimal_to_char(l_amount);
 
-                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str,
+                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n"
+                                         "owner addr: %s\n\n", l_tx_hash_str,
                                          l_tmp_buf, l_status_order_str,
                                          l_amount_coins_str ? l_amount_coins_str : "0.0",
                                          l_amount_datoshi_str ? l_amount_datoshi_str : "0",
                                          l_sell_token, l_percent_completed,
                                          l_buy_token, l_sell_token,
                                          l_cp_rate,
-                                         l_net->pub.name);
+                                         l_net->pub.name, l_owner_addr ? l_owner_addr : "unknown");
                 l_printed_orders_count++;
                 DAP_DEL_Z(l_cp_rate);
                 DAP_DEL_Z(l_amount_datoshi_str);
@@ -2611,11 +2679,13 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     if (l_time[1] && l_item->tx->header.ts_created > l_time[1])
                         break;
 
-                    if (s_string_append_tx_cond_info(l_reply_str, l_net, l_item->tx, &l_item->hash, l_opt_status, false, true, true))
+                    if (s_string_append_tx_cond_info(l_reply_str, l_net,  &l_item->seller_addr, 
+                                l_item->tx_type == TX_TYPE_EXCHANGE ?  &l_item->tx_info.exchange_info.buyer_addr : NULL,
+                                l_item->tx, &l_item->hash, l_opt_status, false, true, true))
                         l_show_tx_nr++;
                 }
             } else {
-                dap_list_t *l_datum_list0 = dap_chain_datum_list(l_net, NULL, s_filter_tx_list, l_time);
+                dap_list_t *l_datum_list0 = dap_chain_datum_list(l_net,  NULL, s_filter_tx_list, l_time);
                 size_t l_datum_num = dap_list_length(l_datum_list0);
 
                 if (l_datum_num > 0) {
@@ -2630,7 +2700,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                         dap_hash_fast_t l_hash = {};
                         dap_hash_fast(l_datum_tx, dap_chain_datum_tx_get_size(l_datum_tx), &l_hash);
-                        if (s_string_append_tx_cond_info(l_reply_str, l_net, l_datum_tx, &l_hash, l_opt_status, false, true, true))
+                        if (s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_datum_tx, &l_hash, l_opt_status, false, true, true))
                             l_show_tx_nr++;
                         l_datum_list = dap_list_next(l_datum_list);
                     } 
@@ -2815,6 +2885,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                     size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
                     size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
 
+                    uint256_t l_token_from_value = {}, l_token_to_value = {};
+
                     dap_string_t *l_reply_str = dap_string_new("");
                     dap_list_t *l_list = NULL;
                     dap_time_t l_time[2];
@@ -2873,6 +2945,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                             l_tx = l_item->tx;
                             l_tx_sell_ticker = l_item->sell_token;
                             l_tx_buy_ticker = l_item->buy_token;
+
                         } else {
                             l_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_cur->data)->data;
                             if(!l_tx){
@@ -2894,8 +2967,22 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                                                                                                             &l_prev_cond_idx) : NULL;
 
                                 l_tx_buy_ticker = l_out_prev_cond_item->subtype.srv_xchange.buy_token;
+
+
                             } else 
                                 l_tx_buy_ticker = l_out_cond_item->subtype.srv_xchange.buy_token;
+
+
+                            uint256_t l_rate = l_out_cond_item 
+                                ? l_out_cond_item->subtype.srv_xchange.rate
+                                : l_out_prev_cond_item->subtype.srv_xchange.rate,
+                                    l_value_from = {}, l_value_to = {};
+
+                            if (l_out_cond_item)
+                                SUBTRACT_256_256(l_out_prev_cond_item->header.value, l_out_cond_item->header.value, &l_value_from);
+                            else
+                                l_value_from = l_out_prev_cond_item->header.value;
+                            MULT_256_COIN(l_value_from, l_rate, &l_value_to);
                         }   
 
 
@@ -2919,13 +3006,32 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                         i_tmp++; 
 
-                        if(s_string_append_tx_cond_info(l_reply_str, l_net, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true))
+                        
+
+                        if(s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true))
                             l_total++;
 
                         l_cur = dap_list_next(l_cur);
                     }
                     dap_list_free(l_list);
                     dap_string_append_printf(l_reply_str, "Found %"DAP_UINT64_FORMAT_U" transactions\n", l_total);
+
+                    const char *l_token_from_value_coins_str = NULL, *l_token_from_value_datoshi_str = NULL,
+                                *l_token_to_value_coins_str = NULL, *l_token_to_value_datoshi_str = NULL;
+
+                    l_token_from_value_datoshi_str = dap_chain_balance_print(l_token_from_value);
+                    l_token_from_value_coins_str = dap_chain_balance_to_coins_str(l_token_from_value);
+                    l_token_to_value_datoshi_str = dap_chain_balance_print(l_token_to_value);
+                    l_token_to_value_coins_str = dap_chain_balance_to_coins_str(l_token_to_value);
+
+                    dap_string_append_printf(l_reply_str, "Traiding value:\n\t%s (%s) %s\n\t%s (%s) %s\n", l_token_from_value_coins_str, l_token_from_value_datoshi_str, l_token_from_str,
+                                                                                                    l_token_to_value_coins_str, l_token_to_value_datoshi_str, l_token_to_str);
+
+                    DAP_DEL_Z(l_token_from_value_datoshi_str);
+                    DAP_DEL_Z(l_token_from_value_coins_str);
+                    DAP_DEL_Z(l_token_to_value_datoshi_str);
+                    DAP_DEL_Z(l_token_to_value_coins_str);
+
                     *a_str_reply = dap_string_free(l_reply_str, false);
                     break;
 
@@ -3267,12 +3373,11 @@ static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chai
                                         l_out_prev_cond_item->subtype.srv_xchange.buy_token,
                                         sizeof(l_cache->buy_token));
 
+        l_cache->seller_addr = l_out_cond_item ? l_out_cond_item->subtype.srv_xchange.seller_addr : (l_out_prev_cond_item ? l_out_prev_cond_item->subtype.srv_xchange.seller_addr : (dap_chain_addr_t){0});
         
         if (l_tx_type == TX_TYPE_ORDER){
             l_cache->rate = l_out_cond_item->subtype.srv_xchange.rate;
-            
             l_cache->tx_info.order_info.order_status = XCHANGE_ORDER_STATUS_OPENED;
-            l_cache->tx_info.order_info.seller_addr = l_out_cond_item->subtype.srv_xchange.seller_addr;
             l_cache->tx_info.order_info.value = l_out_cond_item->header.value;
             l_cache->tx_info.order_info.value_ammount = l_cache->tx_info.order_info.value;
         } else if (l_tx_type == TX_TYPE_EXCHANGE){
@@ -3288,7 +3393,12 @@ static void s_ledger_tx_add_notify(void *a_arg, dap_ledger_t *a_ledger, dap_chai
             
             l_cache->tx_info.exchange_info.order_hash = s_get_order_from_cache(l_cache_net->cache, &l_cache->tx_info.exchange_info.prev_hash);
             dap_hash_fast_is_blank(&l_cache->tx_info.exchange_info.order_hash);
-            // l_cache->tx_info.exchange_info.buyer_addr = ;
+
+            dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
+            dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig);
+            dap_enc_key_t *l_key_buyer = dap_sign_to_enc_key(l_sign);
+            dap_chain_addr_fill_from_key(&l_cache->tx_info.exchange_info.buyer_addr, l_key_buyer, a_ledger->net->pub.id);
+            dap_enc_key_delete(l_key_buyer);
             // find order in cache and change it state
             xchange_tx_cache_t* l_cache_order = NULL;
             HASH_FIND(hh, l_cache_net->cache, &l_cache->tx_info.exchange_info.order_hash, sizeof(dap_hash_fast_t), l_cache_order);
-- 
GitLab


From cfcf280921a844b6c1297f914946c96c549c65f9 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Thu, 9 Jan 2025 13:42:55 +0300
Subject: [PATCH 04/10] [+] Add order hash in exchange transactions output. [+]
 Add traiding value into token_pair rate history comand. [+] Add wallet
 address for owner and byuer into tx command in xchange. [+] Add wallet
 address filter into orders command.

---
 .../xchange/dap_chain_net_srv_xchange.c       | 77 ++++++++++---------
 1 file changed, 40 insertions(+), 37 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 93649b068a..0602d62fc8 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -992,20 +992,8 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_
         SUBTRACT_256_256(l_out_cond->header.value, l_out_cond_last_tx->header.value, &l_percent_completed);
         DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
         MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed);
-    } else {
-        // dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
-        // xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, l_last_tx, NULL, NULL, &l_out_prev_cond_item);
-        // if (tx_type == TX_TYPE_EXCHANGE){
-        //     l_percent_completed = l_out_cond->header.value;
-        //     DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
-        //     MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed);
-        // } else if (tx_type == TX_TYPE_INVALIDATE){
-        //     SUBTRACT_256_256(l_out_cond->header.value, l_out_prev_cond_item->header.value, &l_percent_completed);
-        //     DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed);
-        //     MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed);
-        // }
+    } else 
         l_percent_completed = dap_chain_coins_to_balance("100.0");
-    }
 
     return dap_chain_balance_to_coins_uint64(l_percent_completed);
 }
@@ -2090,6 +2078,13 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
             if (a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
 
+            dap_chain_tx_out_cond_subtype_t l_cond_type = l_out_cond_item ? l_out_cond_item->header.subtype : l_out_prev_cond_item->header.subtype;
+            dap_hash_fast_t l_order_hash = dap_ledger_get_first_chain_tx_hash(a_net->pub.ledger, a_tx, l_cond_type);
+            if ( dap_hash_fast_is_blank(&l_order_hash) )
+                l_order_hash = l_in_cond->header.tx_prev_hash;
+            char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
+            dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str));            
+            dap_string_append_printf(a_reply_str, "\norder hash: %s\n", l_order_hash_str);
 
             dap_chain_addr_t l_owner_addr = {};
             if (!a_owner_addr){
@@ -2097,7 +2092,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
             } else {
                 l_owner_addr = *a_owner_addr;
             }
-            dap_string_append_printf(a_reply_str, "\nowner addr: %s \n", dap_chain_addr_to_str_static(&l_owner_addr));
+            dap_string_append_printf(a_reply_str, "owner addr: %s \n", dap_chain_addr_to_str_static(&l_owner_addr));
 
             dap_chain_addr_t l_buyer_addr = {};
             if(!a_buyer_addr){
@@ -2149,7 +2144,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_
 
             char l_order_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
             dap_hash_fast_to_str(&l_order_hash, l_order_hash_str, sizeof(l_order_hash_str));
-            dap_string_append_printf(a_reply_str, "  returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str);
+            dap_string_append_printf(a_reply_str, "  returned %s(%s) %s to owner from order %s\n", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str);
             if(a_print_prev_hash)
                 dap_string_append_printf(a_reply_str, "\n  Prev cond: %s", l_tx_prev_cond_hash_str);
 
@@ -2915,10 +2910,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                     size_t l_datum_num = dap_list_length(l_list);
 
-                    if (l_datum_num == 0){
-                        dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find transactions");
-                        return -6;
-                    }
                     size_t l_arr_start = 0;
                     size_t l_arr_end  = l_datum_num;
                     if (l_offset > 0) {
@@ -2939,6 +2930,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                         const char * l_tx_sell_ticker = NULL;
                         const char * l_tx_buy_ticker = NULL;
 
+                        uint256_t l_token_curr_from_value = {}, l_token_curr_to_value = {};
+
                         if (s_xchange_cache_state == XCHANGE_CACHE_ENABLED){
                             xchange_tx_cache_t* l_item = (xchange_tx_cache_t*)l_cur->data;
                             l_tx_hash = l_item->hash;
@@ -2946,6 +2939,10 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                             l_tx_sell_ticker = l_item->sell_token;
                             l_tx_buy_ticker = l_item->buy_token;
 
+                            if (l_item->tx_type == TX_TYPE_EXCHANGE){
+                                l_token_curr_from_value = l_item->tx_info.exchange_info.buy_value;
+                                MULT_256_COIN(l_item->rate, l_item->tx_info.exchange_info.buy_value, &l_token_curr_to_value);
+                            }
                         } else {
                             l_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_cur->data)->data;
                             if(!l_tx){
@@ -2954,24 +2951,26 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                             }
                             dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash);
                             l_tx_sell_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_net->pub.ledger, &l_tx_hash);
-                            
-
-                            dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, NULL);
-                            if(!l_out_cond_item){
-                                int l_item_idx = 0;
-                                byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
-                                dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL;
-                                int l_prev_cond_idx = 0;
-                                dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL;
-                                dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
-                                                                                                                            &l_prev_cond_idx) : NULL;
+                            dap_chain_tx_out_cond_t *l_out_cond_item = NULL;
+                            dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL;
 
+                            xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, &l_out_cond_item, NULL, &l_out_prev_cond_item);
+                            
+                            if(!l_out_cond_item && l_out_prev_cond_item){
                                 l_tx_buy_ticker = l_out_prev_cond_item->subtype.srv_xchange.buy_token;
-
-
-                            } else 
+                                if (tx_type == TX_TYPE_EXCHANGE){
+                                    l_token_curr_from_value = l_out_prev_cond_item->header.value;
+                                    MULT_256_COIN(l_out_prev_cond_item->subtype.srv_xchange.rate, l_out_prev_cond_item->header.value, &l_token_curr_to_value);
+                                }
+                            } else if (l_out_cond_item) {
                                 l_tx_buy_ticker = l_out_cond_item->subtype.srv_xchange.buy_token;
-
+                                if (tx_type == TX_TYPE_EXCHANGE){
+                                    uint256_t l_b_buy_value = {};
+                                    SUBTRACT_256_256(l_out_prev_cond_item->header.value, l_out_cond_item->header.value, &l_b_buy_value);
+                                    l_token_curr_from_value = l_b_buy_value;
+                                    MULT_256_COIN(l_out_cond_item->subtype.srv_xchange.rate, l_b_buy_value, &l_token_curr_to_value);
+                                }
+                            }
 
                             uint256_t l_rate = l_out_cond_item 
                                 ? l_out_cond_item->subtype.srv_xchange.rate
@@ -3008,8 +3007,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                         
 
-                        if(s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true))
+                        if(s_string_append_tx_cond_info(l_reply_str, l_net, NULL, NULL, l_tx, &l_tx_hash, TX_STATUS_ALL, false, false, true)){
                             l_total++;
+                            SUM_256_256(l_token_to_value, l_token_curr_to_value, &l_token_to_value);
+                            SUM_256_256(l_token_from_value, l_token_curr_from_value, &l_token_from_value);
+                        }
+
 
                         l_cur = dap_list_next(l_cur);
                     }
@@ -3020,9 +3023,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                 *l_token_to_value_coins_str = NULL, *l_token_to_value_datoshi_str = NULL;
 
                     l_token_from_value_datoshi_str = dap_chain_balance_print(l_token_from_value);
-                    l_token_from_value_coins_str = dap_chain_balance_to_coins_str(l_token_from_value);
+                    l_token_from_value_coins_str = dap_chain_balance_to_coins(l_token_from_value);
                     l_token_to_value_datoshi_str = dap_chain_balance_print(l_token_to_value);
-                    l_token_to_value_coins_str = dap_chain_balance_to_coins_str(l_token_to_value);
+                    l_token_to_value_coins_str = dap_chain_balance_to_coins(l_token_to_value);
 
                     dap_string_append_printf(l_reply_str, "Traiding value:\n\t%s (%s) %s\n\t%s (%s) %s\n", l_token_from_value_coins_str, l_token_from_value_datoshi_str, l_token_from_str,
                                                                                                     l_token_to_value_coins_str, l_token_to_value_datoshi_str, l_token_to_str);
-- 
GitLab


From a3547109e9c093c29622bfe1a9df1c42364953c3 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Thu, 9 Jan 2025 16:19:13 +0300
Subject: [PATCH 05/10] [*] Fix tiker printing in order status

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 0a781ee28e..f069dc972c 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1780,8 +1780,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             
                 l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_order_tx_hash);
 
-                l_token_sell = l_price->token_sell;
-                l_token_buy = l_price->token_buy;
+                l_token_sell = dap_strdup(l_price->token_sell);
+                l_token_buy = dap_strdup(l_price->token_buy);
+
                 l_proposed = l_price->datoshi_sell;
                 l_amount = l_out_cond_last_tx ? l_out_cond_last_tx->header.value : uint256_0;
                 l_rate = l_price->rate;
@@ -1822,7 +1823,10 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                                      l_cp_rate,
                                      l_net->pub.name);
 
-
+            if (s_xchange_cache_state != XCHANGE_CACHE_ENABLED){
+                DAP_DEL_Z(l_token_sell);
+                DAP_DEL_Z(l_token_buy);
+            }
             DAP_DEL_Z(l_cp_rate);
             DAP_DEL_Z(l_amount_coins_str);
             DAP_DEL_Z(l_amount_datoshi_str);
-- 
GitLab


From 097ee1b4d3f6f2de9e2134f60cb0393d6c079b33 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Fri, 10 Jan 2025 14:01:03 +0300
Subject: [PATCH 06/10] [*] srv_xchange command outputs fixes

---
 dap-sdk                                       |  2 +-
 modules/mempool/dap_chain_mempool.c           |  2 +-
 modules/net/dap_chain_ledger.c                |  4 +--
 modules/net/dap_chain_node_cli_cmd.c          |  2 +-
 modules/net/include/dap_chain_ledger.h        |  2 +-
 .../dap_chain_net_srv_emit_delegate.c         |  2 +-
 .../xchange/dap_chain_net_srv_xchange.c       | 29 ++++++++++++++-----
 modules/wallet/dap_chain_wallet_cache.c       |  2 +-
 8 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index d6b6934683..5931f83c88 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit d6b6934683168160e7d25647ceef59d9439de2c3
+Subproject commit 5931f83c8894be1f78e4888ef39873fc87aa4df2
diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c
index 4f8528e213..57f1d5602f 100644
--- a/modules/mempool/dap_chain_mempool.c
+++ b/modules/mempool/dap_chain_mempool.c
@@ -803,7 +803,7 @@ char* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t *a_net, dap_chain_h
             *a_ret_status = DAP_CHAIN_MEMPOOl_RET_STATUS_WRONG_ADDR;
         return NULL;
     }
-    dap_chain_hash_fast_t l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash);
+    dap_chain_hash_fast_t l_tx_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, a_tx_prev_hash, true);
     if ( dap_hash_fast_is_blank(&l_tx_final_hash) ) {
         log_it(L_WARNING, "Requested conditional transaction is already used out");
         if (a_ret_status)
diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c
index df397c3da8..828fa53e42 100644
--- a/modules/net/dap_chain_ledger.c
+++ b/modules/net/dap_chain_ledger.c
@@ -3164,7 +3164,7 @@ dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_c
     return l_hash;
 }
 
-dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash)
+dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash, bool a_unspent_only)
 {
     dap_chain_hash_fast_t l_hash = { };
     dap_return_val_if_fail(a_ledger && a_tx_hash && !dap_hash_fast_is_blank(a_tx_hash), l_hash);
@@ -3174,7 +3174,7 @@ dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_c
     while (( l_tx = dap_ledger_tx_find_datum_by_hash(a_ledger, &l_hash, &l_item, false) )) {
         int l_out_num = 0;
         if (!dap_chain_datum_tx_out_cond_get(l_tx, a_cond_type, &l_out_num))
-            return (dap_hash_fast_t) { };
+            return a_unspent_only ? (dap_hash_fast_t){} : l_hash;
         else if ( dap_hash_fast_is_blank(&(l_item->cache_data.tx_hash_spent_fast[l_out_num])) )
             break;
         l_hash = l_item->cache_data.tx_hash_spent_fast[l_out_num];
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index b2c36368e2..fae1f1d09f 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -5477,7 +5477,7 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_json_arr_reply)
         }
 
         // get final tx 
-        dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash);
+        dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY, l_hash, true);
         dap_chain_datum_tx_t *l_final_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_final_hash);
         if (!l_final_tx) {
             log_it(L_WARNING, "Only get final tx hash or tx is already used out.");
diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h
index b0b3456a2a..b7caf03be8 100644
--- a/modules/net/include/dap_chain_ledger.h
+++ b/modules/net/include/dap_chain_ledger.h
@@ -403,7 +403,7 @@ dap_chain_datum_tx_t *dap_ledger_tx_find_datum_by_hash( dap_ledger_t *a_ledger,
 #define dap_ledger_tx_unspent_find_by_hash(a_ledger, a_tx_hash) \
     dap_ledger_tx_find_datum_by_hash(a_ledger, a_tx_hash, NULL, true)
     
-dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash);
+dap_hash_fast_t dap_ledger_get_final_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_cond_type, dap_chain_hash_fast_t *a_tx_hash, bool a_unspent_only);
 dap_hash_fast_t dap_ledger_get_first_chain_tx_hash(dap_ledger_t *a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_subtype_t a_cond_type);
 
  // Get the transaction in the cache by the addr in out item
diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c
index 5494b0ee71..508fa37e03 100644
--- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c
+++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c
@@ -318,7 +318,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje
     if (!EQUAL_256(l_value_fee_items, l_fee_transfer))
         m_tx_fail(ERROR_COMPOSE, "Can't compose the fee transaction input");
 
-    dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash);
+    dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash, true);
     if (dap_hash_fast_is_blank(&l_final_tx_hash))
         m_tx_fail(ERROR_FUNDS, "Nothing to emit (not enough funds)");
 
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index f069dc972c..7e021fc703 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -241,7 +241,7 @@ int dap_chain_net_srv_xchange_init()
         "\tGet average rate for token pair <token from>:<token to> from <From time> to <To time> \n"
     "srv_xchange token_pair -net <net_name> rate history -token_from <token_ticker> -token_to <token_ticker> [-time_from <From_time>] [-time_to <To_time>] [-limit <limit>] [-offset <offset>]\n"
         "\tPrint rate history for token pair <token from>:<token to> from <From time> to <To time>\n"
-        "\tAll times are in RFC822. For example: \"T7 Dec 2023 21:18:04\"\n"
+        "\tAll times are in RFC822. For example: \"7 Dec 2023 21:18:04\"\n"
 
     "srv_xchange enable\n"
          "\tEnable eXchange service\n"
@@ -973,7 +973,7 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_
         return 0;
     }
 
-    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false);
     if ( dap_hash_fast_is_blank(&l_last_tx_hash) ){
         log_it(L_ERROR, " Can't get last tx cond hash from order");
         return 0;
@@ -1030,7 +1030,7 @@ dap_chain_net_srv_xchange_order_status_t dap_chain_net_srv_xchange_get_order_sta
         return XCHANGE_ORDER_STATUS_UNKNOWN;
     }
 
-    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false);
     if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
         log_it(L_ERROR, " Can't get last tx cond hash from order");
         return XCHANGE_ORDER_STATUS_UNKNOWN;
@@ -1251,7 +1251,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
     l_price->creator_addr = l_out_cond->subtype.srv_xchange.seller_addr;
     l_price->rate = l_out_cond->subtype.srv_xchange.rate;
     dap_hash_fast_t l_final_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger,
-                                        DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->order_hash);
+                                        DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->order_hash, false);
     if ( !dap_hash_fast_is_blank(&l_final_hash) ) {
         l_price->tx_hash = l_final_hash;
         return l_price;
@@ -1748,6 +1748,19 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                     return -18;
                 }
 
+                // Find SRV_XCHANGE in_cond item
+                int l_item_idx = 0;
+                byte_t *l_tx_item = dap_chain_datum_tx_item_get(l_tx, &l_item_idx, NULL, TX_ITEM_TYPE_IN_COND , NULL);
+                dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL;
+                int l_prev_cond_idx = 0;
+                dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL;
+                dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE,
+                                                                                                &l_prev_cond_idx) : NULL;
+                if(l_out_prev_cond_item){
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order");
+                    return -18;
+                }
+
                 dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL);
                 if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID){
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order");
@@ -1763,7 +1776,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
 
                 dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name);
                 
-                dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+                dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false);
                 if( dap_hash_fast_is_blank(&l_last_tx_hash) ){
                     dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get last tx cond hash from order");
                     return -18;
@@ -1952,7 +1965,7 @@ static dap_chain_net_srv_xchange_order_status_t s_tx_check_for_open_close(dap_ch
 
     dap_hash_fast_t l_tx_hash = {};
     dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_tx_hash);
-    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash);
+    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_tx_hash, false);
     if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
         log_it(L_WARNING,"Can't get last tx cond hash from order");
         return XCHANGE_ORDER_STATUS_UNKNOWN;
@@ -2204,7 +2217,7 @@ void s_tx_is_order_check(UNUSED_ARG dap_chain_net_t* a_net, dap_chain_datum_tx_t
         l_list_item->hash = *a_tx_hash;
         l_list_item->tx = a_tx;
         *l_tx_list_ptr = dap_list_append(*l_tx_list_ptr, l_list_item);
-        }
+    }
        
 }
 
@@ -2385,7 +2398,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
 
                     dap_ledger_t * l_ledger = dap_ledger_by_net_name(l_net->pub.name);
                     
-                    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash);
+                    dap_hash_fast_t l_last_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_price->tx_hash, false);
                     if ( dap_hash_fast_is_blank(&l_last_tx_hash) ) {
                         log_it(L_WARNING,"Can't get last tx cond hash from order");
                         continue;
diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c
index 3b3f7ea6c0..79d8b3725e 100644
--- a/modules/wallet/dap_chain_wallet_cache.c
+++ b/modules/wallet/dap_chain_wallet_cache.c
@@ -946,7 +946,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
                 log_it(L_ERROR, "Can't find previous transactions (hash=%s)", dap_hash_fast_to_str_static(&l_prev_tx_hash));
                 continue;
             }
-            uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT, l_prev_idx);
+            uint8_t* l_prev_item = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_prev_idx);
             if (!l_prev_item){
                 log_it(L_ERROR, "Can't find out with index %d in transaction %s", l_prev_idx, dap_hash_fast_to_str_static(&l_prev_tx_hash));
                 continue;
-- 
GitLab


From 84bf3a03cc8c0a7c8abdc0cff96d3ebb74d346cd Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Fri, 10 Jan 2025 14:58:26 +0300
Subject: [PATCH 07/10] [*] Fix token_pair rate history command failing wthout
 cache

---
 dap-sdk                                             |  2 +-
 modules/service/xchange/dap_chain_net_srv_xchange.c | 11 -----------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/dap-sdk b/dap-sdk
index d6b6934683..5931f83c88 160000
--- a/dap-sdk
+++ b/dap-sdk
@@ -1 +1 @@
-Subproject commit d6b6934683168160e7d25647ceef59d9439de2c3
+Subproject commit 5931f83c8894be1f78e4888ef39873fc87aa4df2
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 0602d62fc8..55406b2844 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2971,17 +2971,6 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                                     MULT_256_COIN(l_out_cond_item->subtype.srv_xchange.rate, l_b_buy_value, &l_token_curr_to_value);
                                 }
                             }
-
-                            uint256_t l_rate = l_out_cond_item 
-                                ? l_out_cond_item->subtype.srv_xchange.rate
-                                : l_out_prev_cond_item->subtype.srv_xchange.rate,
-                                    l_value_from = {}, l_value_to = {};
-
-                            if (l_out_cond_item)
-                                SUBTRACT_256_256(l_out_prev_cond_item->header.value, l_out_cond_item->header.value, &l_value_from);
-                            else
-                                l_value_from = l_out_prev_cond_item->header.value;
-                            MULT_256_COIN(l_value_from, l_rate, &l_value_to);
                         }   
 
 
-- 
GitLab


From 006e3b11fef13ef972a247544bd80cfc3d22b159 Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Fri, 10 Jan 2025 15:14:14 +0300
Subject: [PATCH 08/10] [*] Fix warnings

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 6b7f964ddb..4fca985028 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1824,7 +1824,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
             l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); 
             l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed);
             l_cp_rate = dap_chain_balance_to_coins(l_rate); 
-            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n"
+            dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s(%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n"
                                      "owner addr: %s\n\n", l_order_hash_str,
                                      l_tmp_buf, l_status_order, 
                                      l_proposed_coins_str ? l_proposed_coins_str : "0.0", 
@@ -2525,7 +2525,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply)
                 l_proposed_coins_str = dap_uint256_decimal_to_char(l_proposed); 
                 l_proposed_datoshi_str = dap_uint256_uninteger_to_char(l_proposed);
 
-                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n"
+                dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s\n Status: %s, proposed: %s(%s) %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n"
                                          "owner addr: %s\n\n", l_tx_hash_str,
                                          l_tmp_buf, l_status_order_str,
                                          l_proposed_coins_str ? l_proposed_coins_str : "0.0",
-- 
GitLab


From dfd3c64b3df18f14b31ff1d6bee356ddc892942d Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Mon, 13 Jan 2025 10:24:06 +0300
Subject: [PATCH 09/10] [*] Fix tx_list iutput with wallets cache enabled

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 4fca985028..791442df8e 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -2224,7 +2224,7 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
         }
     } else {
         int l_ret_code = 0;
-        dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr);// TODO add check l_iter != NULL
+        dap_chain_wallet_cache_iter_t *l_iter = dap_chain_wallet_cache_iter_create(*a_addr);
         if(!l_iter){
             log_it(L_ERROR, "Can't create iterator item for wallet %s", dap_chain_addr_to_str_static(a_addr));
             return -1;
@@ -2241,7 +2241,7 @@ static int s_cli_srv_xchange_tx_list_addr(dap_chain_net_t *a_net, dap_time_t a_a
             if ( a_before && (l_datum_tx->header.ts_created > a_before) )
                 continue;
 
-            if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, &l_hash_curr, a_opt_status, false, true, true))
+            if (s_string_append_tx_cond_info(l_reply_str, a_net, NULL, NULL, l_datum_tx, l_iter->cur_hash, a_opt_status, false, true, true))
                 l_tx_count++;
         }
         dap_chain_wallet_cache_iter_delete(l_iter);
-- 
GitLab


From e6bfe8abb54ee99c374e98b214c23c52aef5023e Mon Sep 17 00:00:00 2001
From: "daniil.frolov" <daniil.frolov@demlabs.net>
Date: Mon, 13 Jan 2025 12:43:07 +0300
Subject: [PATCH 10/10] [*] Fix order status filter for xchange cache

---
 modules/service/xchange/dap_chain_net_srv_xchange.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 791442df8e..c38d0f19f1 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -1711,6 +1711,11 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v
                     return -18;
                 }
 
+                if (l_item->tx_type != TX_TYPE_ORDER){
+                    dap_cli_server_cmd_set_reply_text(a_str_reply, "It's not an order");
+                    return -18;
+                }
+
                 switch (l_item->tx_info.order_info.order_status)
                 {
                     case XCHANGE_ORDER_STATUS_OPENED:
-- 
GitLab