Skip to content

Commit

Permalink
[SimpleWalle] Allow using more than one subwallet for "transfer" command
Browse files Browse the repository at this point in the history
* If current subwallet doesn't have enough available balance but there is other subwallets that total up to needed
  amount, SimpleWallet will ask if user wants to use available balance from other subwallets. Subwallets are selected
  by index until total balance is higher than needed balance.
  • Loading branch information
mtl1979 committed Mar 31, 2024
1 parent e9429b0 commit 691b2de
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 13 deletions.
22 changes: 21 additions & 1 deletion src/SimpleWallet/SubWallet.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2021, The Talleo developers
Copyright (C) 2021-2024, The Talleo developers
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -17,6 +17,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "SubWallet.h"

uint64_t getTotalActualBalance(CryptoNote::WalletGreen &wallet) {
uint64_t balance = 0;
size_t numWallets = wallet.getAddressCount();
for (size_t i = 0; i < numWallets; i++) {
std::string address = wallet.getAddress(i);
balance += wallet.getActualBalance(address);
}
return balance;
}

uint64_t getTotalActualBalance(CryptoNote::WalletGreen &wallet, const std::vector<std::string> &addresses) {
uint64_t balance = 0;
for (auto address : addresses) {
Expand All @@ -25,6 +35,16 @@ uint64_t getTotalActualBalance(CryptoNote::WalletGreen &wallet, const std::vecto
return balance;
}

uint64_t getTotalPendingBalance(CryptoNote::WalletGreen &wallet) {
uint64_t balance = 0;
size_t numWallets = wallet.getAddressCount();
for (size_t i = 0; i < numWallets; i++) {
std::string address = wallet.getAddress(i);
balance += wallet.getPendingBalance(address);
}
return balance;
}

uint64_t getTotalPendingBalance(CryptoNote::WalletGreen &wallet, const std::vector<std::string> &addresses) {
uint64_t balance = 0;
for (auto address: addresses) {
Expand Down
4 changes: 3 additions & 1 deletion src/SimpleWallet/SubWallet.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2021, The Talleo developers
Copyright (C) 2021-2024, The Talleo developers
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -19,5 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "Wallet/WalletGreen.h"

uint64_t getTotalActualBalance(CryptoNote::WalletGreen &wallet);
uint64_t getTotalActualBalance(CryptoNote::WalletGreen &wallet, const std::vector<std::string> &addresses);
uint64_t getTotalPendingBalance(CryptoNote::WalletGreen &wallet);
uint64_t getTotalPendingBalance(CryptoNote::WalletGreen &wallet, const std::vector<std::string> &addresses);
40 changes: 32 additions & 8 deletions src/SimpleWallet/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ void fusionTX(CryptoNote::WalletGreen &wallet, CryptoNote::TransactionParameters

void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> walletInfo, std::vector<std::string> args) {
uint16_t mixin;
std::string sourceAddress = walletInfo->wallet.getAddress(subWallet);
std::vector<std::string> sourceAddresses;
sourceAddresses.push_back(sourceAddress);
std::string address;
uint64_t amount;
uint64_t fee = CryptoNote::parameters::MINIMUM_FEE;
Expand Down Expand Up @@ -607,7 +610,7 @@ void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> wallet
}
}

doTransfer(dispatcher, mixin, address, amount, fee, extra, walletInfo);
doTransfer(dispatcher, mixin, sourceAddresses, address, amount, fee, extra, walletInfo);
}

void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> walletInfo) {
Expand All @@ -616,6 +619,8 @@ void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> wallet

std::string sourceAddress = walletInfo->wallet.getAddress(subWallet);
uint64_t balance = walletInfo->wallet.getActualBalance(sourceAddress);
std::vector<std::string> sourceAddresses;
sourceAddresses.push_back(sourceAddress);

auto maybeAddress = getDestinationAddress(dispatcher);

Expand All @@ -635,6 +640,25 @@ void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> wallet

uint64_t amount = maybeAmount.x;

if (balance < amount && getTotalActualBalance(walletInfo->wallet) > amount) {
std::cout << WarningMsg("Current subwallet doesn't have enough funds to cover this transaction,") << std::endl;
if (confirm("do you want to use other subwallets?")) {
size_t numWallets = walletInfo->wallet.getAddressCount();
for (size_t i = 0; i < numWallets; i++) {
std::string subaddress = walletInfo->wallet.getAddress(i);
uint64_t subbalance = walletInfo->wallet.getActualBalance(subaddress);
if (subaddress != sourceAddress && subbalance > 0) {
balance += subbalance;
sourceAddresses.push_back(subaddress);
// We need at least amount + 0.01 TLO
if (balance > amount) {
break;
}
}
}
}
}

if (balance < amount) {
size_t totalLen = formatAmount(amount).length(); // Funds needed is always the widest string

Expand Down Expand Up @@ -680,12 +704,12 @@ void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> wallet

std::string extra = maybeExtra.x;

doTransfer(dispatcher, mixin, address, amount, fee, extra, walletInfo);
doTransfer(dispatcher, mixin, sourceAddresses, address, amount, fee, extra, walletInfo);
}

void doTransfer(System::Dispatcher& dispatcher, uint16_t mixin, std::string address, uint64_t amount, uint64_t fee, std::string extra, std::shared_ptr<WalletInfo> walletInfo) {
std::string sourceAddress = walletInfo->wallet.getAddress(subWallet);
uint64_t balance = walletInfo->wallet.getActualBalance(sourceAddress);
void doTransfer(System::Dispatcher& dispatcher, uint16_t mixin, std::vector<std::string> sourceAddresses, std::string address, uint64_t amount, uint64_t fee, std::string extra, std::shared_ptr<WalletInfo> walletInfo) {
std::string changeAddress = walletInfo->wallet.getAddress(subWallet);
uint64_t balance = getTotalActualBalance(walletInfo->wallet, sourceAddresses);
uint64_t remote_node_fee = 0;
if (!remote_fee_address.empty()) {
// Remote node fee is between 0.01 and 1.00 TLO depending on transfer amount
Expand Down Expand Up @@ -726,12 +750,12 @@ void doTransfer(System::Dispatcher& dispatcher, uint16_t mixin, std::string addr
}

CryptoNote::TransactionParameters p;
p.sourceAddresses.push_back(sourceAddress);
p.sourceAddresses = sourceAddresses;
p.destinations = transfers;
p.fee = fee;
p.mixIn = mixin;
p.extra = extra;
p.changeDestination = sourceAddress;
p.changeDestination = changeAddress;

if (!confirmTransaction(p, walletInfo)) {
std::cout << WarningMsg("Cancelling transaction.") << std::endl;
Expand Down Expand Up @@ -1088,4 +1112,4 @@ std::string resolveAddress(System::Dispatcher& dispatcher, const std::string& em

return address;

}
}
6 changes: 3 additions & 3 deletions src/SimpleWallet/Transfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> wallet
void transfer(System::Dispatcher& dispatcher, std::shared_ptr<WalletInfo> walletInfo,
std::vector<std::string> args);

void doTransfer(System::Dispatcher& dispatcher, uint16_t mixin, std::string address, uint64_t amount,
uint64_t fee, std::string extra,
void doTransfer(System::Dispatcher& dispatcher, uint16_t mixin, std::vector<std::string> sourceAddresses,
std::string address, uint64_t amount, uint64_t fee, std::string extra,
std::shared_ptr<WalletInfo> walletInfo);

void fusionTX(CryptoNote::WalletGreen &wallet,
Expand Down Expand Up @@ -107,4 +107,4 @@ Maybe<uint16_t> getMixin();
size_t makeFusionTransaction(CryptoNote::WalletGreen &wallet, const std::vector<std::string> &sourceAddresses,
const std::string &destinationAddress, uint64_t threshold);

std::string resolveAddress(System::Dispatcher& dispatcher, const std::string& email);
std::string resolveAddress(System::Dispatcher& dispatcher, const std::string& email);

0 comments on commit 691b2de

Please sign in to comment.