aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/api/wallet.cpp58
-rw-r--r--src/wallet/api/wallet.h4
-rw-r--r--src/wallet/api/wallet_manager.cpp8
-rw-r--r--src/wallet/wallet2.cpp1
-rw-r--r--src/wallet/wallet2_api.h21
-rw-r--r--src/wallet/wallet_rpc_server.cpp20
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);
}