diff options
Diffstat (limited to 'src/wallet/api/wallet.cpp')
-rw-r--r-- | src/wallet/api/wallet.cpp | 165 |
1 files changed, 163 insertions, 2 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 9a9638b40..6c1c1fea2 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -545,6 +545,8 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const { clearStatus(); + // Pause refresh thread while creating transaction + pauseRefresh(); vector<cryptonote::tx_destination_entry> dsts; cryptonote::tx_destination_entry de; @@ -678,6 +680,100 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const transaction->m_status = m_status; transaction->m_errorString = m_errorString; + // Resume refresh thread + startRefresh(); + return transaction; +} + +PendingTransaction *WalletImpl::createSweepUnmixableTransaction() + +{ + clearStatus(); + vector<cryptonote::tx_destination_entry> dsts; + cryptonote::tx_destination_entry de; + + PendingTransactionImpl * transaction = new PendingTransactionImpl(*this); + + do { + try { + transaction->m_pending_tx = m_wallet->create_unmixable_sweep_transactions(m_trustedDaemon); + + } catch (const tools::error::daemon_busy&) { + // TODO: make it translatable with "tr"? + m_errorString = tr("daemon is busy. Please try again later."); + m_status = Status_Error; + } catch (const tools::error::no_connection_to_daemon&) { + m_errorString = tr("no connection to daemon. Please make sure daemon is running."); + m_status = Status_Error; + } catch (const tools::error::wallet_rpc_error& e) { + m_errorString = tr("RPC error: ") + e.to_string(); + m_status = Status_Error; + } catch (const tools::error::get_random_outs_error&) { + m_errorString = tr("failed to get random outputs to mix"); + m_status = Status_Error; + + } catch (const tools::error::not_enough_money& e) { + m_status = Status_Error; + std::ostringstream writer; + + writer << boost::format(tr("not enough money to transfer, available only %s, sent amount %s")) % + print_money(e.available()) % + print_money(e.tx_amount()); + m_errorString = writer.str(); + + } catch (const tools::error::tx_not_possible& e) { + m_status = Status_Error; + std::ostringstream writer; + + writer << boost::format(tr("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)")) % + print_money(e.available()) % + print_money(e.tx_amount() + e.fee()) % + print_money(e.tx_amount()) % + print_money(e.fee()); + m_errorString = writer.str(); + + } catch (const tools::error::not_enough_outs_to_mix& e) { + std::ostringstream writer; + writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; + for (const std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) { + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.second; + } + m_errorString = writer.str(); + m_status = Status_Error; + } catch (const tools::error::tx_not_constructed&) { + m_errorString = tr("transaction was not constructed"); + m_status = Status_Error; + } catch (const tools::error::tx_rejected& e) { + std::ostringstream writer; + writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); + m_errorString = writer.str(); + m_status = Status_Error; + } catch (const tools::error::tx_sum_overflow& e) { + m_errorString = e.what(); + m_status = Status_Error; + } catch (const tools::error::zero_destination&) { + m_errorString = tr("one of destinations is zero"); + m_status = Status_Error; + } catch (const tools::error::tx_too_big& e) { + m_errorString = tr("failed to find a suitable way to split transactions"); + m_status = Status_Error; + } catch (const tools::error::transfer_error& e) { + m_errorString = string(tr("unknown transfer error: ")) + e.what(); + m_status = Status_Error; + } catch (const tools::error::wallet_internal_error& e) { + m_errorString = string(tr("internal error: ")) + e.what(); + m_status = Status_Error; + } catch (const std::exception& e) { + m_errorString = string(tr("unexpected error: ")) + e.what(); + m_status = Status_Error; + } catch (...) { + m_errorString = tr("unknown error"); + m_status = Status_Error; + } + } while (false); + + transaction->m_status = m_status; + transaction->m_errorString = m_errorString; return transaction; } @@ -707,6 +803,63 @@ void WalletImpl::setDefaultMixin(uint32_t arg) m_wallet->default_mixin(arg); } +bool WalletImpl::setUserNote(const std::string &txid, const std::string ¬e) +{ + cryptonote::blobdata txid_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data)) + return false; + const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); + + m_wallet->set_tx_note(htxid, note); + return true; +} + +std::string WalletImpl::getUserNote(const std::string &txid) const +{ + cryptonote::blobdata txid_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data)) + return ""; + const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); + + return m_wallet->get_tx_note(htxid); +} + +std::string WalletImpl::getTxKey(const std::string &txid) const +{ + cryptonote::blobdata txid_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data)) + { + return ""; + } + const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); + + crypto::secret_key tx_key; + if (m_wallet->get_tx_key(htxid, tx_key)) + { + return epee::string_tools::pod_to_hex(tx_key); + } + else + { + return ""; + } +} + +std::string WalletImpl::signMessage(const std::string &message) +{ + return m_wallet->sign(message); +} + +bool WalletImpl::verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const +{ + cryptonote::account_public_address addr; + bool has_payment_id; + crypto::hash8 payment_id; + + if (!cryptonote::get_account_integrated_address_from_str(addr, has_payment_id, payment_id, m_wallet->testnet(), address)) + return false; + + return m_wallet->verify(message, addr, signature); +} bool WalletImpl::connectToDaemon() { @@ -720,9 +873,15 @@ bool WalletImpl::connectToDaemon() return result; } -bool WalletImpl::connected() const +Wallet::ConnectionStatus WalletImpl::connected() const { - return m_wallet->check_connection(); + bool same_version = false; + bool is_connected = m_wallet->check_connection(&same_version); + if (!is_connected) + return Wallet::ConnectionStatus_Disconnected; + if (!same_version) + return Wallet::ConnectionStatus_WrongVersion; + return Wallet::ConnectionStatus_Connected; } void WalletImpl::setTrustedDaemon(bool arg) @@ -798,6 +957,7 @@ void WalletImpl::doRefresh() void WalletImpl::startRefresh() { + LOG_PRINT_L2(__FUNCTION__ << ": refresh started/resumed..."); if (!m_refreshEnabled) { m_refreshEnabled = true; m_refreshCV.notify_one(); @@ -818,6 +978,7 @@ void WalletImpl::stopRefresh() void WalletImpl::pauseRefresh() { + LOG_PRINT_L2(__FUNCTION__ << ": refresh paused..."); // TODO synchronize access if (!m_refreshThreadDone) { m_refreshEnabled = false; |