diff --git a/html/js/cn_util.js b/html/js/cn_util.js
index 7bea2bd..5623465 100644
--- a/html/js/cn_util.js
+++ b/html/js/cn_util.js
@@ -40,6 +40,11 @@ var cnUtil = (function(initConfig) {
var ENCRYPTED_PAYMENT_ID_TAIL = 141;
var CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = config.addressPrefix;
var CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = config.integratedAddressPrefix;
+ if (config.testnet === true)
+ {
+ CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = config.addressPrefixTestnet;
+ CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = config.integratedAddressPrefixTestnet;
+ }
var UINT64_MAX = new JSBigInt(2).pow(64);
var CURRENT_TX_VERSION = 2;
var OLD_TX_VERSION = 1;
diff --git a/html/js/config.js b/html/js/config.js
index cb7f044..84275c8 100755
--- a/html/js/config.js
+++ b/html/js/config.js
@@ -1,6 +1,6 @@
var config = {
apiUrl: "http://127.0.0.1:1984/",
- testnet: false,
+ testnet: true,
coinUnitPlaces: 12,
txMinConfirms: 10,
coinSymbol: 'XMR',
diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp
index afd4aa7..ed2dd14 100644
--- a/src/CurrentBlockchainStatus.cpp
+++ b/src/CurrentBlockchainStatus.cpp
@@ -581,6 +581,8 @@ CurrentBlockchainStatus::start_tx_search_thread(XmrAccount acc)
return true;
}
+
+
bool
CurrentBlockchainStatus::ping_search_thread(const string& address)
{
@@ -589,7 +591,7 @@ CurrentBlockchainStatus::ping_search_thread(const string& address)
if (searching_threads.count(address) == 0)
{
// thread does not exist
- cout << "does not exist" << endl;
+ cout << "thread for " << address << " does not exist" << endl;
return false;
}
@@ -598,6 +600,28 @@ CurrentBlockchainStatus::ping_search_thread(const string& address)
return true;
}
+bool
+CurrentBlockchainStatus::get_xmr_address_viewkey(
+ const string& address_str,
+ account_public_address& address,
+ secret_key& viewkey)
+{
+ std::lock_guard lck (searching_threads_map_mtx);
+
+ if (searching_threads.count(address_str) == 0)
+ {
+ // thread does not exist
+ cout << "thread for " << address_str << " does not exist" << endl;
+ return false;
+ }
+
+ address = searching_threads[address_str].get()->get_xmr_address_viewkey().first;
+ viewkey = searching_threads[address_str].get()->get_xmr_address_viewkey().second;
+
+ return true;
+};
+
+
bool
CurrentBlockchainStatus::set_new_searched_blk_no(const string& address, uint64_t new_value)
{
diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h
index a031494..da69923 100644
--- a/src/CurrentBlockchainStatus.h
+++ b/src/CurrentBlockchainStatus.h
@@ -141,7 +141,8 @@ struct CurrentBlockchainStatus
get_payment_id_as_string(const transaction& tx);
static output_data_t
- get_output_key(uint64_t amount, uint64_t global_amount_index);
+ get_output_key(uint64_t amount,
+ uint64_t global_amount_index);
// definitions of these function are at the end of this file
// due to forward declaraions of TxSearch
@@ -152,7 +153,13 @@ struct CurrentBlockchainStatus
ping_search_thread(const string& address);
static bool
- set_new_searched_blk_no(const string& address, uint64_t new_value);
+ get_xmr_address_viewkey(const string& address_str,
+ account_public_address& address,
+ secret_key& viewkey);
+
+ static bool
+ set_new_searched_blk_no(const string& address,
+ uint64_t new_value);
static void
clean_search_thread_map();
diff --git a/src/TxSearch.cpp b/src/TxSearch.cpp
index 7ea48aa..8fc252d 100644
--- a/src/TxSearch.cpp
+++ b/src/TxSearch.cpp
@@ -159,7 +159,8 @@ TxSearch::search()
// can filter out false positives.
for (transaction& tx: blk_txs)
{
-
+ // Class that is resposnible for idenficitaction of our outputs
+ // and inputs in a given tx.
OutputInputIdentification oi_identification {&address, &viewkey, &tx};
// FIRSt step.
@@ -454,5 +455,10 @@ TxSearch::populate_known_outputs()
}
}
+pair
+TxSearch::get_xmr_address_viewkey() const
+{
+ return make_pair(address, viewkey);
+}
}
\ No newline at end of file
diff --git a/src/TxSearch.h b/src/TxSearch.h
index 614ed98..4d5660c 100644
--- a/src/TxSearch.h
+++ b/src/TxSearch.h
@@ -64,7 +64,7 @@ class TxSearch
shared_ptr xmr_accounts;
// address and viewkey for this search thread.
- cryptonote::account_public_address address;
+ account_public_address address;
secret_key viewkey;
public:
@@ -91,6 +91,9 @@ public:
void
populate_known_outputs();
+ pair
+ get_xmr_address_viewkey() const;
+
};
diff --git a/src/YourMoneroRequests.cpp b/src/YourMoneroRequests.cpp
index 7c1dbfe..8019178 100644
--- a/src/YourMoneroRequests.cpp
+++ b/src/YourMoneroRequests.cpp
@@ -7,6 +7,7 @@
#include "YourMoneroRequests.h"
#include "ssqlses.h"
+#include "OutputInputIdentification.h"
namespace xmreg
{
@@ -152,7 +153,8 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
{ "scanned_block_height", 0}, // taken from Accounts table
{ "start_height", 0}, // blockchain hieght when acc was created
{ "transaction_height", 0}, // not used. it is here to match mymonero
- { "blockchain_height", 0} // current blockchain height
+ { "blockchain_height", 0}, // current blockchain height
+ { "transactions", json::array()}
};
@@ -171,7 +173,8 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
vector txs;
- if (xmr_accounts->select_txs_for_account_spendability_check(acc.id, txs)) {
+ if (xmr_accounts->select_txs_for_account_spendability_check(acc.id, txs))
+ {
json j_txs = json::array();
@@ -225,11 +228,41 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
} // if (xmr_accounts->select(xmr_address, acc))
+
+ // append txs found in mempool to the json returned
+
+ account_public_address address_parsed;
+ secret_key viewkey_parsed;
+
+ if (CurrentBlockchainStatus::get_xmr_address_viewkey(
+ xmr_address, address_parsed, viewkey_parsed))
+ {
+ json j_mempool_tx = find_txs_in_mempool(&address_parsed, &viewkey_parsed);
+
+ if(!j_mempool_tx.empty())
+ {
+ uint64_t total_received_mempool {0};
+
+ for (json& j_tx: j_mempool_tx)
+ {
+ cout << "mempool j_tx[\"total_received\"]:"
+ << j_tx["total_received"]
+ << endl;
+ total_received_mempool += j_tx["total_received"].get();
+ j_response["transactions"].push_back(j_tx);
+ }
+
+ j_response["total_received"] = j_response["total_received"].get()
+ + total_received_mempool;
+ }
+
+ }
+
string response_body = j_response.dump();
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
- session->close( OK, response_body, response_headers);
+ session->close(OK, response_body, response_headers);
}
void
@@ -746,9 +779,62 @@ YourMoneroRequests::get_current_blockchain_height()
}
-// define static variables
+json
+YourMoneroRequests::find_txs_in_mempool(
+ const account_public_address* address,
+ const secret_key* viewkey)
+{
+ vector txs_to_check = CurrentBlockchainStatus::get_mempool_txs();
+
+ json j_transactions = json::array();
+
+ uint64_t current_height = CurrentBlockchainStatus::get_current_blockchain_height();
+
+ for (const transaction& tx: txs_to_check)
+ {
+ // Class that is resposnible for idenficitaction of our outputs
+ // and inputs in a given tx.
+ OutputInputIdentification oi_identification {address, viewkey, &tx};
+
+ // FIRSt step. to search for the incoming xmr, we use address, viewkey and
+ // outputs public key.
+ oi_identification.identify_outputs();
+
+ //vector amount_specific_indices;
+
+ // if we identified some outputs as ours,
+ // save them into json to be returned.
+ if (!oi_identification.identified_outputs.empty())
+ {
+ json j_tx;
+
+ j_tx["id"] = 0;
+ j_tx["hash"] = oi_identification.tx_hash_str;
+ j_tx["timestamp"] = get_current_time();
+ j_tx["total_received"] = oi_identification.total_received;
+ j_tx["total_sent"] = 0;
+ j_tx["unlock_time"] = 0;
+ j_tx["height"] = current_height; // put large value of height,
+ // just to indicate that we dont have
+ // height and that in frontend it will
+ // appear us unconfirmed.
+ j_tx["payment_id"] = "";
+ j_tx["coinbase"] = false;
+ j_tx["mixin"] = get_mixin_no(tx) - 1;
+
+ j_transactions.push_back(j_tx);
+ }
+
+ } // for (const transaction& tx: txs_to_check)
+ return j_transactions;
+
+}
+
+
+// define static variables
bool YourMoneroRequests::show_logs = false;
}
+
diff --git a/src/YourMoneroRequests.h b/src/YourMoneroRequests.h
index c7a3632..cd64bfb 100644
--- a/src/YourMoneroRequests.h
+++ b/src/YourMoneroRequests.h
@@ -60,7 +60,7 @@ public:
* and check mysql if address/account exist. If yes,
* it returns this account. If not, it creates new one.
*
- * Once this complites, a thread is tarted that looks
+ * Once this complites, a thread is started that looks
* for txs belonging to that account.
*
* @param session a Restbed session
@@ -106,6 +106,33 @@ public:
inline uint64_t
get_current_blockchain_height();
+
+private:
+
+ /**
+ * Search for our txs in the mempool
+ *
+ * The method searches for our txs (outputs and inputs)
+ * in the mempool. It does basically same what TxSearch class is
+ * doing. The difference is that TxSearch class searches in a thread
+ * in a blockchain. It does not scan for tx in mempool. This is because
+ * TxSearch writes what it finds into database for permament storage.
+ * However txs in mempool are not permament. Also since we want to
+ * give the end user quick update on incoming/outging tx, this method
+ * will be executed whenever frontend wants. By default it is every
+ * 10 seconds. TxSearch class is timed independetly of the frontend.
+ * Also since we dont write here anything to the database, we
+ * return a json that will be appended to json produced by get_address_tx
+ * and similar function. The outputs here cant be spent anyway. This is
+ * only for end user information. The txs found here will be written
+ * to database later on by TxSearch thread when they will be added
+ * to the blockchain.
+ *
+ * @return json
+ */
+ json
+ find_txs_in_mempool(const account_public_address* address,
+ const secret_key* viewkey);
};