diff --git a/src/monero_wallet_wrapper/MoneroErrors.hh b/src/monero_wallet_wrapper/MoneroErrors.hh index 8bfdb97db..22c9c9675 100644 --- a/src/monero_wallet_wrapper/MoneroErrors.hh +++ b/src/monero_wallet_wrapper/MoneroErrors.hh @@ -50,7 +50,7 @@ namespace Monero { public: virtual const char* what() const throw() { - return "Payment ID should be a Hex of 32 bits"; + return "Payment ID should be a Hex of 32 bits (64 chars hex string)"; } } iInvalidPaymentID; @@ -65,5 +65,27 @@ namespace Monero { } } iInvalidNonce; + + + class NoDaemonConnection: public std::exception + { + public: + virtual const char* what() const throw() + { + return "No connection to daemon. Use 'connect()' first. And check that 'bitmonerod' is running"; + } + + } iNoDaemonConnection; + + + class DaemonBusy: public std::exception + { + public: + virtual const char* what() const throw() + { + return "Daemon is busy. Please wait for blockchain operations and try again"; + } + + } iDaemonBusy; } } diff --git a/src/monero_wallet_wrapper/MoneroWallet.cc b/src/monero_wallet_wrapper/MoneroWallet.cc index 7de7ba6bd..804c35235 100644 --- a/src/monero_wallet_wrapper/MoneroWallet.cc +++ b/src/monero_wallet_wrapper/MoneroWallet.cc @@ -51,8 +51,31 @@ amount_mini_t toMini(amount_t pAmount) { return pAmount * pow(10,12); } +const Transfer transferFromRawTransferDetails(const tools::wallet2::transfer_details& pTransferDetails) +{ + Transfer lTransfer; + lTransfer.transaction_id = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(pTransferDetails.m_tx)); + lTransfer.block_height = pTransferDetails.m_block_height; + lTransfer.global_output_index = pTransferDetails.m_global_output_index; + lTransfer.local_output_index = pTransferDetails.m_internal_output_index; + lTransfer.spent = pTransferDetails.m_spent; + lTransfer.amount_mini = pTransferDetails.amount(); + lTransfer.amount = fromMini(lTransfer.amount_mini); + return lTransfer; +} +const Payment paymentFromRawPaymentDetails(const tools::wallet2::payment_details& pPaymentDetails) +{ + Payment lPayment; + lPayment.transaction_id = epee::string_tools::pod_to_hex(pPaymentDetails.m_tx_hash); + lPayment.block_height = pPaymentDetails.m_block_height; + lPayment.unlock_time = pPaymentDetails.m_unlock_time; + lPayment.amount_mini = pPaymentDetails.m_amount; + lPayment.amount = fromMini(lPayment.amount_mini); + + return lPayment; +} static amount_mini_t default_fee = DEFAULT_FEE; @@ -112,25 +135,14 @@ amount_t Wallet::getUnlockedBalance() const { const std::vector Wallet::getIncomingTransfers() const { - std::vector lTransfers; - - tools::wallet2::transfer_container lIncomingTransfers; - - /* TODO : Throw exception */ + tools::wallet2::transfer_container lIncomingTransfers; wallet_impl->get_transfers(lIncomingTransfers); + std::vector lTransfers; for(tools::wallet2::transfer_details lTransferDetail : lIncomingTransfers) { - Transfer lTransfer; - lTransfer.block_height = lTransferDetail.m_block_height; - lTransfer.global_output_index = lTransferDetail.m_global_output_index; - lTransfer.local_output_index = lTransferDetail.m_internal_output_index; - lTransfer.spent = lTransferDetail.m_spent; - lTransfer.amount_mini = lTransferDetail.amount(); - - lTransfer.amount = fromMini(lTransfer.amount_mini); - + const Transfer& lTransfer = transferFromRawTransferDetails(lTransferDetail); lTransfers.push_back(lTransfer); } @@ -138,6 +150,45 @@ const std::vector Wallet::getIncomingTransfers() const } +const std::list Wallet::getPayments(const std::string& pPaymentId) const +{ + + crypto::hash lPaymentIdBytes; + + /* Parse payment ID */ + if (!tools::wallet2::parse_payment_id(pPaymentId, lPaymentIdBytes)) { + throw(Errors::iInvalidPaymentID); + } + + std::list oPaymentsDetails; + wallet_impl->get_payments(lPaymentIdBytes, oPaymentsDetails); + + std::cout << "Got " << oPaymentsDetails.size() << " payments for '" << pPaymentId << "'" << std::endl; + + std::list lPayments; + for (const tools::wallet2::payment_details lPaymentDetails : oPaymentsDetails) { + const Payment& lPayment = paymentFromRawPaymentDetails(lPaymentDetails); + lPayments.push_back(lPayment); + } + + return lPayments; +} + +const std::multimap Wallet::getAllPayments() const { + + std::multimap lPaymentsMap; + const tools::wallet2::payment_container& lPaymentsContainer = wallet_impl->get_all_payments(); + + for (const std::pair lHashPaymentDetails : lPaymentsContainer) { + const std::string& lPaymentId = epee::string_tools::pod_to_hex(lHashPaymentDetails.first); + const Payment& lPayment = paymentFromRawPaymentDetails(lHashPaymentDetails.second); + lPaymentsMap.emplace(lPaymentId, lPayment); + } + + return lPaymentsMap; + +} + bool Wallet::refresh() { size_t lFetchedBlocks; @@ -161,23 +212,26 @@ bool Wallet::connect(const std::string pDaemonRPCEndpoint) { } +void Wallet::store() { + wallet_impl->store(); +} -const std::string Wallet::transferMini(const std::multimap pDestsToAmountMini, const std::string& pPaymentId = "") +const std::string Wallet::transferMini(const std::multimap pDestsToAmountMini, const std::string& pPaymentId) { return transferMini(pDestsToAmountMini, getDefaultFee(), pPaymentId); } -const std::string Wallet::transferMini(const std::multimap pDestsToAmountMini, amount_mini_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = "") +const std::string Wallet::transferMini(const std::multimap pDestsToAmountMini, amount_mini_t pFee, const std::string& pPaymentId) { return transferMini(pDestsToAmountMini, 0, 0, pFee, pPaymentId); } -const std::string Wallet::transferMini(const std::string& pDestAddress, amount_mini_t pAmount, const std::string& pPaymentId = "") +const std::string Wallet::transferMini(const std::string& pDestAddress, amount_mini_t pAmount, const std::string& pPaymentId) { return transferMini(pDestAddress, pAmount, getDefaultFee(), pPaymentId); } -const std::string Wallet::transferMini(const std::string& pDestAddress, amount_mini_t pAmount, amount_mini_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = "") +const std::string Wallet::transferMini(const std::string& pDestAddress, amount_mini_t pAmount, amount_mini_t pFee, const std::string& pPaymentId) { std::multimap lDestsMap; lDestsMap.emplace(pDestAddress, pAmount); @@ -185,13 +239,13 @@ const std::string Wallet::transferMini(const std::string& pDestAddress, amount_m } -const std::string transfer(const std::string& pDestAddress, amount_t pAmount, const std::string& pPaymentId = "") +const std::string Wallet::transfer(const std::string& pDestAddress, amount_t pAmount, const std::string& pPaymentId) { return transferMini(pDestAddress, toMini(pAmount), pPaymentId); } -const std::string transfer(const std::string& pDestAddress, amount_t pAmount, amount_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = "") +const std::string Wallet::transfer(const std::string& pDestAddress, amount_t pAmount, amount_t pFee, const std::string& pPaymentId) { return transferMini(pDestAddress, toMini(pAmount), toMini(pFee), pPaymentId); } @@ -237,7 +291,15 @@ const std::string Wallet::transferMini(const std::multimaptransfer(lDestinations, pFakeOutputsCount, pUnlockTime, pFee, lExtra, lTransaction); + try { + wallet_impl->transfer(lDestinations, pFakeOutputsCount, pUnlockTime, pFee, lExtra, lTransaction); + } + catch(tools::error::no_connection_to_daemon) { + throw(Errors::iNoDaemonConnection); + } + catch(tools::error::daemon_busy) { + throw(Errors::iDaemonBusy); + } const std::string& lTransactionId = boost::lexical_cast(get_transaction_hash(lTransaction)); diff --git a/src/monero_wallet_wrapper/MoneroWallet.hh b/src/monero_wallet_wrapper/MoneroWallet.hh index d1ea3591d..130f94ea5 100644 --- a/src/monero_wallet_wrapper/MoneroWallet.hh +++ b/src/monero_wallet_wrapper/MoneroWallet.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include "MoneroErrors.hh" @@ -18,6 +19,7 @@ typedef long double amount_t; struct Transfer { + std::string transaction_id; uint64_t block_height; uint64_t global_output_index; size_t local_output_index; @@ -26,6 +28,16 @@ struct Transfer { amount_t amount; }; +struct Payment { + std::string transaction_id; + uint64_t block_height; + uint64_t unlock_time; + amount_mini_t amount_mini; + amount_t amount; +}; + + + /** * @class Wallet Represents a Wallet instance or can be used with static methods for checking Wallets. * @@ -67,6 +79,8 @@ public: */ bool connect(const std::string pDaemonRPCEndpoint = "http://localhost:18081"); + void store(); + /* Offline methods */ /** * @brîef Returns the address of the Wakket account. @@ -104,6 +118,10 @@ public: */ const std::vector getIncomingTransfers() const; + const std::list getPayments(const std::string& pPaymentId) const; + + const std::multimap getAllPayments() const; + /** * @brief Performs a transfer to one of multiple destinations * @@ -116,10 +134,10 @@ public: const std::string transferMini(const std::multimap pDestsToAmountMini, size_t pFakeOutputsCount, uint64_t pUnlockTime, amount_mini_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = ""); const std::string transferMini(const std::multimap pDestsToAmountMini, const std::string& pPaymentId = ""); - const std::string transferMini(const std::multimap pDestsToAmountMini, amount_mini_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = ""); + const std::string transferMini(const std::multimap pDestsToAmountMini, amount_mini_t pFee, const std::string& pPaymentId = ""); const std::string transferMini(const std::string& pDestAddress, amount_mini_t pAmount, const std::string& pPaymentId = ""); - const std::string transferMini(const std::string& pDestAddress, amount_mini_t pAmount, amount_mini_t pFee = Wallet::getDefaultFee(), const std::string& pPaymentId = ""); + const std::string transferMini(const std::string& pDestAddress, amount_mini_t pAmount, amount_mini_t pFee, const std::string& pPaymentId = ""); /** * @brief Performs a transfer to one destination diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a63eb4be7..f724a4fe4 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -579,6 +579,11 @@ void wallet2::get_payments(const crypto::hash& payment_id, std::list& payments) const; + const payment_container& get_all_payments() const; uint64_t get_blockchain_current_height() const { return m_local_bc_height; } template inline void serialize(t_archive &a, const unsigned int ver)