diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/api/wallet.cpp | 58 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 8 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 1 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 21 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 20 |
6 files changed, 84 insertions, 28 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index d72ebc8da..be379cb99 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -137,6 +137,12 @@ uint64_t Wallet::amountFromDouble(double amount) return amountFromString(ss.str()); } +std::string Wallet::genPaymentId() +{ + crypto::hash8 payment_id = crypto::rand<crypto::hash8>(); + return epee::string_tools::pod_to_hex(payment_id); + +} ///////////////////////// WalletImpl implementation //////////////////////// @@ -302,6 +308,15 @@ std::string WalletImpl::address() const return m_wallet->get_account().get_public_address_str(m_wallet->testnet()); } +std::string WalletImpl::integratedAddress(const std::string &payment_id) const +{ + crypto::hash8 pid; + if (!tools::wallet2::parse_short_payment_id(payment_id, pid)) { + pid = crypto::rand<crypto::hash8>(); + } + return m_wallet->get_account().get_public_integrated_address_str(pid, m_wallet->testnet()); +} + bool WalletImpl::store(const std::string &path) { clearStatus(); @@ -380,31 +395,58 @@ bool WalletImpl::refresh() // - payment_details; // - unconfirmed_transfer_details; // - confirmed_transfer_details) -PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64_t amount, uint32_t mixin_count) + +PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, uint64_t amount, uint32_t mixin_count) { clearStatus(); vector<cryptonote::tx_destination_entry> dsts; cryptonote::tx_destination_entry de; - bool has_payment_id; - crypto::hash8 new_payment_id; + // indicates if dst_addr is integrated address (address + payment_id) + bool has_payment_id; + crypto::hash8 payment_id_short; // TODO: (https://bitcointalk.org/index.php?topic=753252.msg9985441#msg9985441) - size_t fake_outs_count = mixin_count > 0 ? mixin_count : m_wallet->default_mixin(); if (fake_outs_count == 0) fake_outs_count = DEFAULT_MIXIN; - PendingTransactionImpl * transaction = new PendingTransactionImpl(this); + PendingTransactionImpl * transaction = new PendingTransactionImpl(*this); do { - - if(!cryptonote::get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), dst_addr)) { + if(!cryptonote::get_account_integrated_address_from_str(de.addr, has_payment_id, payment_id_short, m_wallet->testnet(), dst_addr)) { // TODO: copy-paste 'if treating as an address fails, try as url' from simplewallet.cpp:1982 m_status = Status_Error; m_errorString = "Invalid destination address"; break; } + + std::vector<uint8_t> extra; + // if dst_addr is not an integrated address, parse payment_id + if (!has_payment_id && !payment_id.empty()) { + // copy-pasted from simplewallet.cpp:2212 + crypto::hash payment_id_long; + bool r = tools::wallet2::parse_long_payment_id(payment_id, payment_id_long); + if (r) { + std::string extra_nonce; + cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, payment_id_long); + r = add_extra_nonce_to_tx_extra(extra, extra_nonce); + } else { + r = tools::wallet2::parse_short_payment_id(payment_id, payment_id_short); + if (r) { + std::string extra_nonce; + set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, payment_id_short); + r = add_extra_nonce_to_tx_extra(extra, extra_nonce); + } + } + + if (!r) { + m_status = Status_Error; + m_errorString = tr("payment id has invalid format, expected 16 or 64 character hex string: ") + payment_id; + break; + } + } + de.amount = amount; if (de.amount <= 0) { m_status = Status_Error; @@ -414,8 +456,6 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64 dsts.push_back(de); //std::vector<tools::wallet2::pending_tx> ptx_vector; - std::vector<uint8_t> extra; - try { transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 016116e96..164aede1a 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -60,6 +60,7 @@ public: std::string errorString() const; bool setPassword(const std::string &password); std::string address() const; + std::string integratedAddress(const std::string &payment_id) const; bool store(const std::string &path); std::string filename() const; std::string keysFilename() const; @@ -70,7 +71,8 @@ public: uint64_t balance() const; uint64_t unlockedBalance() const; bool refresh(); - PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount, uint32_t mixin_count); + PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, + uint64_t amount, uint32_t mixin_count); virtual void disposeTransaction(PendingTransaction * t); virtual TransactionHistory * history() const; virtual void setListener(WalletListener * l); diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index 3a97538b4..4ed6e09fb 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -85,7 +85,7 @@ bool WalletManagerImpl::walletExists(const std::string &path) std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path) { std::vector<std::string> result; - const boost::regex wallet_rx("(.*)\\.(address\\.txt)$"); // searching for <wallet_name>.address.txt files + const boost::regex wallet_rx("(.*)\\.(keys)$"); // searching for <wallet_name>.keys files boost::filesystem::recursive_directory_iterator end_itr; // Default ctor yields past-the-end boost::filesystem::path work_dir(path); @@ -100,11 +100,9 @@ std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path) bool matched = boost::regex_match(filename, what, wallet_rx); if (matched) { - // if address file found, checking if there's corresponding .keys file and wallet file itself + // if keys file found, checking if there's wallet file itself std::string wallet_file = (itr->path().parent_path() /= what[1]).string(); - std::string wallet_key_file = wallet_file + std::string(".keys"); - if (boost::filesystem::exists(wallet_file) - && boost::filesystem::exists(wallet_key_file)) { + if (boost::filesystem::exists(wallet_file)) { LOG_PRINT_L3("Found wallet: " << wallet_file); result.push_back(wallet_file); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 6f05929b4..02dd59862 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3081,7 +3081,6 @@ std::string wallet2::get_tx_note(const crypto::hash &txid) const return std::string(); return i->second; } - //---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) { if (m_testnet) diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index de0b50591..66987e4c5 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -134,6 +134,18 @@ struct Wallet virtual std::string errorString() const = 0; virtual bool setPassword(const std::string &password) = 0; virtual std::string address() const = 0; + + /*! + * \brief integratedAddress - returns integrated address for current wallet address and given payment_id. + * if passed "payment_id" param is an empty string or not-valid payment id string + * (16 characters hexadecimal string) - random payment_id will be generated + * + * \param payment_id - 16 characters hexadecimal string or empty string if new random payment id needs to be + * generated + * \return - 106 characters string representing integrated address + */ + virtual std::string integratedAddress(const std::string &payment_id) const = 0; + /*! * \brief store - stores wallet to file. * \param path - main filename to store wallet to. additionally stores address file and keys file. @@ -162,19 +174,24 @@ struct Wallet static std::string displayAmount(uint64_t amount); static uint64_t amountFromString(const std::string &amount); static uint64_t amountFromDouble(double amount); + static std::string genPaymentId(); // TODO? // virtual uint64_t unlockedDustBalance() const = 0; virtual bool refresh() = 0; /*! - * \brief createTransaction creates transaction + * \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored * \param dst_addr destination address as string + * \param payment_id optional payment_id, can be empty string * \param amount amount * \param mixin_count mixin count. if 0 passed, wallet will use default value * \return PendingTransaction object. caller is responsible to check PendingTransaction::status() * after object returned */ - virtual PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount, uint32_t mixin_count) = 0; + + virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, + uint64_t amount, uint32_t mixin_count) = 0; + virtual void disposeTransaction(PendingTransaction * t) = 0; virtual TransactionHistory * history() const = 0; virtual void setListener(WalletListener *) = 0; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a082f731b..5be9ae5b0 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -245,9 +245,9 @@ namespace tools m_wallet.commit_tx(ptx_vector); // populate response with tx hash - res.tx_hash = boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(ptx_vector.back().tx)); + res.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx_vector.back().tx)); if (req.get_tx_key) - res.tx_key = boost::lexical_cast<std::string>(ptx_vector.back().tx_key); + res.tx_key = epee::string_tools::pod_to_hex(ptx_vector.back().tx_key); return true; } catch (const tools::error::daemon_busy& e) @@ -308,9 +308,9 @@ namespace tools // populate response with tx hashes for (auto & ptx : ptx_vector) { - res.tx_hash_list.push_back(boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); if (req.get_tx_keys) - res.tx_key_list.push_back(boost::lexical_cast<std::string>(ptx.tx_key)); + res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } return true; @@ -354,9 +354,9 @@ namespace tools // populate response with tx hashes for (auto & ptx : ptx_vector) { - res.tx_hash_list.push_back(boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); if (req.get_tx_keys) - res.tx_key_list.push_back(boost::lexical_cast<std::string>(ptx.tx_key)); + res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } return true; @@ -413,9 +413,9 @@ namespace tools // populate response with tx hashes for (auto & ptx : ptx_vector) { - res.tx_hash_list.push_back(boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); if (req.get_tx_keys) - res.tx_key_list.push_back(boost::lexical_cast<std::string>(ptx.tx_key)); + res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } return true; @@ -493,7 +493,7 @@ namespace tools return false; } res.standard_address = get_account_address_as_str(m_wallet.testnet(),address); - res.payment_id = boost::lexical_cast<std::string>(payment_id); + res.payment_id = epee::string_tools::pod_to_hex(payment_id); return true; } catch (std::exception &e) @@ -686,7 +686,7 @@ namespace tools rpc_transfers.amount = td.amount(); rpc_transfers.spent = td.m_spent; rpc_transfers.global_index = td.m_global_output_index; - rpc_transfers.tx_hash = boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(td.m_tx)); + rpc_transfers.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(td.m_tx)); rpc_transfers.tx_size = txBlob.size(); res.transfers.push_back(rpc_transfers); } |