add 'send to many' function

pull/223/head
larteyoh 4 months ago
parent 419fc6223e
commit e23e8bae35

2
.gitmodules vendored

@ -1,6 +1,6 @@
[submodule "external/monero-cpp"]
path = external/monero-cpp
url = https://github.com/monero-ecosystem/monero-cpp.git
url = https://github.com/woodser/monero-cpp.git
[submodule "external/QR-Code-generator"]
path = external/QR-Code-generator
url = https://github.com/nayuki/QR-Code-generator.git

@ -94,7 +94,7 @@ Page {
TextField {
id: balanceLockedText
visible: (settingsDialog.balanceDisplay == 2) ? false : true
property double balance: !Wallet.opened ? 0.000000000000 : Wallet.balanceLocked
property double balance: !Wallet.opened || (Wallet.balanceLocked == Wallet.balanceUnlocked) ? 0.000000000000 : Wallet.balanceLocked - Wallet.balanceUnlocked
text: balance.toFixed(settingsDialog.balanceAmountPrecision)
font.bold: !balanceUnlockedText.visible ? true : false
font.pointSize: !balanceUnlockedText.visible ? 48 : 24

@ -271,6 +271,7 @@ void neroshop::Wallet::transfer(const std::string& address, double amount) {
//uint64_t deducted_amount = (monero_to_piconero + fee);
std::string tx_hash = monero_wallet_obj->relay_tx(*sent_tx); // recipient receives notification within 5 seconds
std::cout << "Tx hash: " << tx_hash << "\n";
monero_utils::free(sent_tx);
});
std::future<void> future_result = transfer_task.get_future();
@ -279,6 +280,51 @@ void neroshop::Wallet::transfer(const std::string& address, double amount) {
worker.detach(); // join may block but detach won't//void transfer_result = future_result.get();
}
//-------------------------------------------------------
void neroshop::Wallet::transfer(const std::vector<std::pair<std::string, double>>& payment_addresses) { // untested
if(!monero_wallet_obj.get()) throw std::runtime_error("monero_wallet_full is not opened");
if(!monero_wallet_obj.get()->is_synced()) throw std::runtime_error("wallet is not synced with a daemon");
monero_tx_config tx_config = monero_tx_config();
tx_config.m_account_index = 0; // withdraw funds from this account
tx_config.m_relay = false; // create transaction and relay to the network if true
double piconero = 0.000000000001;
// Calculate the total amount owed
double total_amount = 0.000000000000;
for (const auto& address : payment_addresses) {
total_amount += address.second;
}
std::cout << "Total amount to pay: " << total_amount << " (xmr)\n";
// Check if balance is sufficient
uint64_t total_to_piconero = total_amount / piconero;
std::cout << "Wallet balance (spendable): " << monero_wallet_obj->get_unlocked_balance() << " (picos)\n";
std::cout << "Amount to send: " << total_to_piconero << " (picos)\n";
if(monero_wallet_obj->get_unlocked_balance() < total_to_piconero) {
neroshop::print("Wallet balance is insufficient", 1); return;
}
// Add each destination
std::vector<std::shared_ptr<monero_destination>> destinations; // specify the recipients and their amounts
for(const auto& address : payment_addresses) {
// Check if address is valid
if(!monero_utils::is_valid_address(address.first, monero_wallet_obj->get_network_type())) {
neroshop::print(address.first + " is not a valid Monero address", 1);
continue; // skip to the next address
}
// Convert monero to piconero
uint64_t monero_to_piconero = address.second / piconero; //std::cout << neroshop::string::precision(address.second, 12) << " xmr to piconero: " << monero_to_piconero << "\n";
destinations.push_back(std::make_shared<monero_destination>(address.first, monero_to_piconero));
// Print address and amount
std::cout << "Address: " << address.first << ", Amount: " << address.second << std::endl;
}
tx_config.m_destinations = destinations;
// Create the transaction, confirm with the user, and relay to the network
std::shared_ptr<monero_tx_wallet> created_tx = monero_wallet_obj->create_tx(tx_config);
uint64_t fee = created_tx->m_fee.get(); // "Are you sure you want to send ...?"
monero_wallet_obj->relay_tx(*created_tx); // recipient receives notification within 5 seconds
monero_utils::free(created_tx);
}
//-------------------------------------------------------
std::string neroshop::Wallet::sign_message(const std::string& message, monero_message_signature_type signature_type) const {
if(!monero_wallet_obj.get()) throw std::runtime_error("monero_wallet_full is not opened");
return monero_wallet_obj->sign_message(message, signature_type, 0, 0);
@ -301,12 +347,6 @@ monero::monero_subaddress neroshop::Wallet::create_subaddress(unsigned int accou
}
//-------------------------------------------------------
//-------------------------------------------------------
void neroshop::Wallet::sweep_all(const std::string& address) {
if(!monero_wallet_obj.get()) throw std::runtime_error("monero_wallet_full is not opened");
//std::vector< std::shared_ptr< monero_tx_wallet > > monero::monero_wallet_full::sweep_dust ( bool relay = false )
} // sends entire balance, including dust to an address // "sweep_all <address>"
//-------------------------------------------------------
//-------------------------------------------------------
// NOTE: It is IMPOSSIBLE to change the network type of a pre-existing monero wallet, but it can be set before its creation
void neroshop::Wallet::set_network_type(monero::monero_network_type network_type) {
if(get_network_type() == network_type) return;

@ -56,7 +56,8 @@ public:
monero::monero_subaddress create_subaddress(unsigned int account_idx, const std::string & label = "") const; // generates a new subaddress from main account // monero addresses start with 4 or 8
void transfer(const std::string& address, double amount); // "transfer" will be used for sending refunds
void sweep_all(const std::string& address); // sends entire balance, including dust to an address // "sweep_all <address>"
void transfer(const std::vector<std::pair<std::string, double>>& payment_addresses);
std::string address_new() const; // this function has been replaced by create_subaddress() and is deprecated. Will be removed soon
unsigned int address_book_add(const std::string& address, std::string description = ""); // "address_book add <address> <description>"
void address_book_delete(unsigned int index); // "address_book delete 0"

@ -25,15 +25,7 @@ class WalletController : public QObject, public monero_wallet_listener
Q_PROPERTY(double balanceUnlocked READ getBalanceUnlocked NOTIFY balanceChanged);
Q_PROPERTY(QVariantList transfers READ getTransfers NOTIFY transfersChanged);
//Q_PROPERTY(<type> <variable_name> READ <get_function_name> NOTIFY)
public:
// I don't know how to use or compare enums in QML. It never works, but oh well :|
enum KeyfileStatus {
KeyfileStatus_Ok = 0,
KeyfileStatus_Wrong_Password,
KeyfileStatus_No_Matching_Passwords,
KeyfileStatus_Exists,
};
Q_ENUM(KeyfileStatus)
public:
// functions (for use in QML)
Q_INVOKABLE int createRandomWallet(const QString& password, const QString& confirm_pwd, const QString& path);
Q_INVOKABLE int restoreFromSeed(const QString& seed);

@ -17,7 +17,7 @@ set(neroshop_database_src
set(neroshop_network_src
${NEROSHOP_CORE_SRC_DIR}/network/i2p.cpp
${NEROSHOP_CORE_SRC_DIR}/network/tor.cpp
#[[${NEROSHOP_CORE_SRC_DIR}/network/tor.cpp]]
)
set(neroshop_price_src
@ -429,7 +429,7 @@ set(lua_src liblua.a)
# network_test
set(test_network "network_test")
add_executable(${test_network} network_test.cpp ${neroshop_srcs})
target_link_libraries(${test_network} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_network} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# network_uv test
#[[set(test_network_uv "network_uv_test")
add_executable(${test_network_uv} network_test_uv.cpp ${neroshop_srcs})
@ -437,30 +437,30 @@ target_link_libraries(${test_network_uv} ${monero_cpp_src} ${sqlite_src} ${qr_co
# utility test
set(test_utility "utility_test")
add_executable(${test_utility} utility_test.cpp ${neroshop_srcs})
target_link_libraries(${test_utility} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_utility} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# auth_test
set(test_auth "auth_test")
add_executable(${test_auth} auth_test.cpp ${neroshop_srcs})
target_link_libraries(${test_auth} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_auth} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# uuid_test
set(test_uuid "uuid_test")
add_executable(${test_uuid} uuid_test.cpp)
# qr_code_test
set(test_qr_code "qr_test")
add_executable(${test_qr_code} qr_test.cpp ${neroshop_srcs})
target_link_libraries(${test_qr_code} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_qr_code} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# encryption_test
set(test_crypt "encryption_test")
add_executable(${test_crypt} encryption_test.cpp ${neroshop_srcs})
target_link_libraries(${test_crypt} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_crypt} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# signing_test
set(test_sign "signing_test")
add_executable(${test_sign} signing_test.cpp ${neroshop_srcs})
target_link_libraries(${test_sign} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_sign} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# sign_verify_test
set(test_sign_verify "sign_verify_test")
add_executable(${test_sign_verify} sign_verify_test.cpp ${neroshop_srcs})
target_link_libraries(${test_sign_verify} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_sign_verify} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# Qt gui_test
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
@ -471,17 +471,21 @@ add_executable(${test_gui_qt} main_window.ui main_window.cpp gui_qt_test.cpp ${n
#[[target_]]
include_directories(#[[${test_gui_qt} ]] /usr/include/x86_64-linux-gnu/qt5/ /usr/include/x86_64-linux-gnu/qt5/QtWidgets/)
#target_compile_definitions(${test_gui_qt} PRIVATE )
target_link_libraries(${test_gui_qt} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_gui_qt} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
# escrow_test
set(test_escrow "escrow_test")
add_executable(${test_escrow} escrow.cpp ${neroshop_srcs})
target_link_libraries(${test_escrow} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_escrow} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
set(test_wallet "wallet_test")
add_executable(${test_wallet} wallet_test.cpp ${neroshop_srcs})
target_link_libraries(${test_wallet} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
#[[
set(test_ "")
add_executable(${test_} .cpp ${neroshop_srcs})
target_link_libraries(${test_} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${libuv_src} ${curl_src} ${monero_src} ${lua_src})
target_link_libraries(${test_} ${monero_cpp_src} ${sqlite_src} ${qr_code_generator_src} ${raft_src} ${curl_src} ${monero_src} ${lua_src})
]]
######################################
@ -501,8 +505,11 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(${test_auth} ${posix_src})
target_link_libraries(${test_qr_code} ${posix_src})
target_link_libraries(${test_crypt} ${posix_src})
target_link_libraries(${test_sign} ${posix_src})
target_link_libraries(${test_sign_verify} ${posix_src})
target_link_libraries(${test_gui_qt} ${posix_src})
target_link_libraries(${test_escrow} ${posix_src})
target_link_libraries(${test_wallet} ${posix_src})
#target_link_libraries(${test_} ${posix_src})
find_package(X11 REQUIRED)
if(X11_FOUND)

@ -0,0 +1,24 @@
#include <unistd.h>
#include "../src/core/wallet.hpp"
int main() {
neroshop::Wallet *wallet = new neroshop::Wallet();
wallet->create_random("", "", "random_wallet");
// This isn't working??
wallet->daemon_connect_remote("node2.monerodevs.org", "38089");
// Your vector of payment addresses
std::vector<std::pair<std::string, double>> payment_addresses = {
{"Address1", 1.0},
{"Address2", 0.5},
{"Address3", 0.25}
};
sleep(900); // wait for node to finish syncing?
wallet->transfer(payment_addresses);
return 0;
}
Loading…
Cancel
Save