From 85f636788568ae878b9a60e9a4466f770c29403b Mon Sep 17 00:00:00 2001 From: woodser Date: Thu, 27 Jun 2019 10:53:13 -0400 Subject: [PATCH] implement getIntegratedAddress(), decodeIntegratedAddress() --- src/wallet/MoneroWallet.cpp | 46 ++++++++++++++++++++++++++++++++ src/wallet/MoneroWallet.h | 32 +++++++++++----------- src/wallet/MoneroWalletModel.cpp | 10 +++++++ src/wallet/MoneroWalletModel.h | 11 ++++++++ todo.txt | 1 + 5 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/wallet/MoneroWallet.cpp b/src/wallet/MoneroWallet.cpp index 4459661..3b66acb 100644 --- a/src/wallet/MoneroWallet.cpp +++ b/src/wallet/MoneroWallet.cpp @@ -349,6 +349,52 @@ namespace monero { return subaddress; } + MoneroIntegratedAddress MoneroWallet::getIntegratedAddress(const string& standardAddress, const string& paymentId) const { + cout << "getIntegratedAddress(" << standardAddress << ", " << paymentId << ")" << endl; + + // TODO monero-core: this logic is based on wallet_rpc_server::on_make_integrated_address() and should be moved to wallet so this is unecessary for api users + + // randomly generate payment id if not given, else validate + crypto::hash8 paymentIdH8; + if (paymentId.empty()) { + paymentIdH8 = crypto::rand(); + } else { + if (!tools::wallet2::parse_short_payment_id(paymentId, paymentIdH8)) throw runtime_error("Invalid payment ID: " + paymentId); + } + + // use primary address if standard address not given, else validate + if (standardAddress.empty()) { + return decodeIntegratedAddress(wallet2->get_integrated_address_as_str(paymentIdH8)); + } else { + + // validate standard address + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, wallet2->nettype(), standardAddress)) throw runtime_error("Invalid address: " + standardAddress); + if (info.is_subaddress) throw runtime_error("Subaddress shouldn't be used"); + if (info.has_payment_id) throw runtime_error("Already integrated address"); + if (paymentId.empty()) throw runtime_error("Payment ID shouldn't be left unspecified"); + + // create integrated address from given standard address + return decodeIntegratedAddress(cryptonote::get_account_integrated_address_as_str(wallet2->nettype(), info.address, paymentIdH8)); + } + } + + MoneroIntegratedAddress MoneroWallet::decodeIntegratedAddress(const string& integratedAddress) const { + cout << "decodeIntegratedAddress(" << integratedAddress << ")" << endl; + + // validate integrated address + cryptonote::address_parse_info info; + if (!cryptonote::get_account_address_from_str(info, wallet2->nettype(), integratedAddress)) throw runtime_error("Invalid integrated address: " + integratedAddress); + if (!info.has_payment_id) throw runtime_error("Address is not an integrated address"); + + // initialize and return result + MoneroIntegratedAddress result; + result.standardAddress = cryptonote::get_account_address_as_str(wallet2->nettype(), info.is_subaddress, info.address); + result.paymentId = epee::string_tools::pod_to_hex(info.payment_id); + result.integratedAddress = integratedAddress; + return result; + } + string MoneroWallet::getMnemonic() const { epee::wipeable_string wipeablePassword; wallet2->get_seed(wipeablePassword); diff --git a/src/wallet/MoneroWallet.h b/src/wallet/MoneroWallet.h index c63d80a..bcc9e95 100644 --- a/src/wallet/MoneroWallet.h +++ b/src/wallet/MoneroWallet.h @@ -245,22 +245,22 @@ namespace monero { */ MoneroSubaddress getAddressIndex(const string& address) const; -// /** -// * Get an integrated address based on this wallet's primary address and the -// * given payment ID. Generates a random payment ID if none is given. -// * -// * @param paymentId is the payment ID to generate an integrated address from (randomly generated if null) -// * @return the integrated address -// */ -// virtual MoneroIntegratedAddress getIntegratedAddress(const string& paymentId = "") const; -// -// /** -// * Decode an integrated address to get its standard address and payment id. -// * -// * @param integratedAddress is an integrated address to decode -// * @return the decoded integrated address including standard address and payment id -// */ -// virtual MoneroIntegratedAddress decodeIntegratedAddress(const string& integratedAddress = "") const; + /** + * Get an integrated address from a standard address and a payment id. + * + * @param standardAddress is the integrated addresse's standard address (defaults to wallet's primary address) + * @param paymentId is the integrated addresse's payment id (defaults to randomly generating new payment id) + * @return the integrated address + */ + MoneroIntegratedAddress getIntegratedAddress(const string& standardAddress = "", const string& paymentId = "") const; + + /** + * Decode an integrated address to get its standard address and payment id. + * + * @param integratedAddress is an integrated address to decode + * @return the decoded integrated address including standard address and payment id + */ + MoneroIntegratedAddress decodeIntegratedAddress(const string& integratedAddress) const; void setListener(boost::optional listener); diff --git a/src/wallet/MoneroWalletModel.cpp b/src/wallet/MoneroWalletModel.cpp index e40c3cd..448eb9e 100644 --- a/src/wallet/MoneroWalletModel.cpp +++ b/src/wallet/MoneroWalletModel.cpp @@ -376,4 +376,14 @@ namespace monero { // output meets request return true; } + + // -------------------------- MONERO INTEGRATED ADDRESS ----------------------------- + + boost::property_tree::ptree MoneroIntegratedAddress::toPropertyTree() const { + boost::property_tree::ptree node; + node.put("standardAddress", standardAddress); + node.put("paymentId", paymentId); + node.put("integratedAddress", integratedAddress); + return node; + } } diff --git a/src/wallet/MoneroWalletModel.h b/src/wallet/MoneroWalletModel.h index 297f7b3..712bbc4 100644 --- a/src/wallet/MoneroWalletModel.h +++ b/src/wallet/MoneroWalletModel.h @@ -207,4 +207,15 @@ namespace monero { boost::property_tree::ptree toPropertyTree() const; bool meetsCriteria(MoneroTxWallet* tx) const; }; + + /** + * Monero integrated address model. + */ + struct MoneroIntegratedAddress : public SerializableStruct { + string standardAddress; + string paymentId; + string integratedAddress; + + boost::property_tree::ptree toPropertyTree() const; + }; } diff --git a/todo.txt b/todo.txt index e987c6e..5c46e41 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,4 @@ +toPropertyTree() should take node as parameter; optimize memory elsewhere cannot reconcile integrals on getTransfers() test, need to add reconcile debug info including vals and pass error message re-usable debug trace statements DaemonConnection is its own object