aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/api')
-rw-r--r--src/wallet/api/wallet.cpp83
-rw-r--r--src/wallet/api/wallet.h4
-rw-r--r--src/wallet/api/wallet2_api.h29
-rw-r--r--src/wallet/api/wallet_manager.cpp8
-rw-r--r--src/wallet/api/wallet_manager.h1
5 files changed, 101 insertions, 24 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 3780d7271..8b25096a2 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -376,7 +376,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
, m_rebuildWalletCache(false)
, m_is_connected(false)
{
- m_wallet = new tools::wallet2(static_cast<cryptonote::network_type>(nettype), kdf_rounds);
+ m_wallet = new tools::wallet2(static_cast<cryptonote::network_type>(nettype), kdf_rounds, true);
m_history = new TransactionHistoryImpl(this);
m_wallet2Callback = new Wallet2CallbackImpl(this);
m_wallet->callback(m_wallet2Callback);
@@ -629,7 +629,7 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
m_recoveringFromDevice = true;
try
{
- m_wallet->restore(path, password, device_name);
+ m_wallet->restore(path, password, device_name, false);
LOG_PRINT_L1("Generated new wallet from device: " + device_name);
}
catch (const std::exception& e) {
@@ -639,6 +639,11 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
return true;
}
+Wallet::Device WalletImpl::getDeviceType() const
+{
+ return static_cast<Wallet::Device>(m_wallet->get_device_type());
+}
+
bool WalletImpl::open(const std::string &path, const std::string &password)
{
clearStatus();
@@ -1244,6 +1249,20 @@ size_t WalletImpl::importMultisigImages(const vector<string>& images) {
return 0;
}
+bool WalletImpl::hasMultisigPartialKeyImages() const {
+ try {
+ clearStatus();
+ checkMultisigWalletReady(m_wallet);
+
+ return m_wallet->has_multisig_partial_key_images();
+ } catch (const exception& e) {
+ LOG_ERROR("Error on checking for partial multisig key images: ") << e.what();
+ setStatusError(string(tr("Failed to check for partial multisig key images: ")) + e.what());
+ }
+
+ return false;
+}
+
PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signData) {
try {
clearStatus();
@@ -1381,8 +1400,8 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
setStatusError(tr("no connection to daemon. Please make sure daemon is running."));
} catch (const tools::error::wallet_rpc_error& e) {
setStatusError(tr("RPC error: ") + e.to_string());
- } catch (const tools::error::get_random_outs_error &e) {
- setStatusError((boost::format(tr("failed to get random outputs to mix: %s")) % e.what()).str());
+ } catch (const tools::error::get_outs_error &e) {
+ setStatusError((boost::format(tr("failed to get outputs to mix: %s")) % e.what()).str());
} catch (const tools::error::not_enough_unlocked_money& e) {
std::ostringstream writer;
@@ -1463,8 +1482,8 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
setStatusError(tr("no connection to daemon. Please make sure daemon is running."));
} catch (const tools::error::wallet_rpc_error& e) {
setStatusError(tr("RPC error: ") + e.to_string());
- } catch (const tools::error::get_random_outs_error&) {
- setStatusError(tr("failed to get random outputs to mix"));
+ } catch (const tools::error::get_outs_error&) {
+ setStatusError(tr("failed to get outputs to mix"));
} catch (const tools::error::not_enough_unlocked_money& e) {
setStatusError("");
std::ostringstream writer;
@@ -2033,7 +2052,7 @@ bool WalletImpl::isNewWallet() const
bool WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit, bool ssl)
{
// claim RPC so there's no in-memory encryption for now
- if (!m_wallet->init(true, daemon_address, m_daemon_login, upper_transaction_size_limit, ssl))
+ if (!m_wallet->init(daemon_address, m_daemon_login, upper_transaction_size_limit, ssl))
return false;
// in case new wallet, this will force fast-refresh (pulling hashes instead of blocks)
@@ -2095,21 +2114,36 @@ bool WalletImpl::useForkRules(uint8_t version, int64_t early_blocks) const
return m_wallet->use_fork_rules(version,early_blocks);
}
-bool WalletImpl::blackballOutputs(const std::vector<std::string> &pubkeys, bool add)
+bool WalletImpl::blackballOutputs(const std::vector<std::string> &outputs, bool add)
{
- std::vector<crypto::public_key> raw_pubkeys;
- raw_pubkeys.reserve(pubkeys.size());
- for (const std::string &str: pubkeys)
+ std::vector<std::pair<uint64_t, uint64_t>> raw_outputs;
+ raw_outputs.reserve(outputs.size());
+ uint64_t amount = std::numeric_limits<uint64_t>::max(), offset, num_offsets;
+ for (const std::string &str: outputs)
{
- crypto::public_key pkey;
- if (!epee::string_tools::hex_to_pod(str, pkey))
+ if (sscanf(str.c_str(), "@%" PRIu64, &amount) == 1)
+ continue;
+ if (amount == std::numeric_limits<uint64_t>::max())
{
- setStatusError(tr("Failed to parse output public key"));
- return false;
+ setStatusError("First line is not an amount");
+ return true;
+ }
+ if (sscanf(str.c_str(), "%" PRIu64 "*%" PRIu64, &offset, &num_offsets) == 2 && num_offsets <= std::numeric_limits<uint64_t>::max() - offset)
+ {
+ while (num_offsets--)
+ raw_outputs.push_back(std::make_pair(amount, offset++));
+ }
+ else if (sscanf(str.c_str(), "%" PRIu64, &offset) == 1)
+ {
+ raw_outputs.push_back(std::make_pair(amount, offset));
+ }
+ else
+ {
+ setStatusError(tr("Invalid output: ") + str);
+ return false;
}
- raw_pubkeys.push_back(pkey);
}
- bool ret = m_wallet->set_blackballed_outputs(raw_pubkeys, add);
+ bool ret = m_wallet->set_blackballed_outputs(raw_outputs, add);
if (!ret)
{
setStatusError(tr("Failed to set blackballed outputs"));
@@ -2118,15 +2152,20 @@ bool WalletImpl::blackballOutputs(const std::vector<std::string> &pubkeys, bool
return true;
}
-bool WalletImpl::unblackballOutput(const std::string &pubkey)
+bool WalletImpl::unblackballOutput(const std::string &amount, const std::string &offset)
{
- crypto::public_key raw_pubkey;
- if (!epee::string_tools::hex_to_pod(pubkey, raw_pubkey))
+ uint64_t raw_amount, raw_offset;
+ if (!epee::string_tools::get_xtype_from_string(raw_amount, amount))
+ {
+ setStatusError(tr("Failed to parse output amount"));
+ return false;
+ }
+ if (!epee::string_tools::get_xtype_from_string(raw_offset, offset))
{
- setStatusError(tr("Failed to parse output public key"));
+ setStatusError(tr("Failed to parse output offset"));
return false;
}
- bool ret = m_wallet->unblackball_output(raw_pubkey);
+ bool ret = m_wallet->unblackball_output(std::make_pair(raw_amount, raw_offset));
if (!ret)
{
setStatusError(tr("Failed to unblackball output"));
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 0f3b1ce04..e3a300317 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -79,6 +79,7 @@ public:
bool recoverFromDevice(const std::string &path,
const std::string &password,
const std::string &device_name);
+ Device getDeviceType() const;
bool close(bool store = true);
std::string seed() const override;
std::string getSeedLanguage() const override;
@@ -139,6 +140,7 @@ public:
bool finalizeMultisig(const std::vector<std::string>& extraMultisigInfo) override;
bool exportMultisigImages(std::string& images) override;
size_t importMultisigImages(const std::vector<std::string>& images) override;
+ bool hasMultisigPartialKeyImages() const override;
PendingTransaction* restoreMultisigTransaction(const std::string& signData) override;
PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
@@ -181,7 +183,7 @@ public:
virtual bool lightWalletLogin(bool &isNewWallet) const override;
virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override;
virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) override;
- virtual bool unblackballOutput(const std::string &pubkey) override;
+ virtual bool unblackballOutput(const std::string &amount, const std::string &offset) override;
virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const override;
virtual bool getRings(const std::string &txid, std::vector<std::pair<std::string, std::vector<uint64_t>>> &rings) const override;
virtual bool setRing(const std::string &key_image, const std::vector<uint64_t> &ring, bool relative) override;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 5a52c6b17..e0d491705 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -373,6 +373,10 @@ struct WalletListener
*/
struct Wallet
{
+ enum Device {
+ Device_Software = 0,
+ Device_Ledger = 1
+ };
enum Status {
Status_Ok,
@@ -720,6 +724,11 @@ struct Wallet
* @return number of imported images
*/
virtual size_t importMultisigImages(const std::vector<std::string>& images) = 0;
+ /**
+ * @brief hasMultisigPartialKeyImages - checks if wallet needs to import multisig key images from other participants
+ * @return true if there are partial key images
+ */
+ virtual bool hasMultisigPartialKeyImages() const = 0;
/**
* @brief restoreMultisigTransaction creates PendingTransaction from signData
@@ -875,7 +884,7 @@ struct Wallet
virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) = 0;
//! unblackballs an output
- virtual bool unblackballOutput(const std::string &pubkey) = 0;
+ virtual bool unblackballOutput(const std::string &amount, const std::string &offset) = 0;
//! gets the ring used for a key image, if any
virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const = 0;
@@ -906,6 +915,12 @@ struct Wallet
virtual bool unlockKeysFile() = 0;
//! returns true if the keys file is locked
virtual bool isKeysFileLocked() = 0;
+
+ /*!
+ * \brief Queries backing device for wallet keys
+ * \return Device they are on
+ */
+ virtual Device getDeviceType() const = 0;
};
/**
@@ -1092,6 +1107,18 @@ struct WalletManager
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0;
/*!
+ * \brief determine the key storage for the specified wallet file
+ * \param device_type (OUT) wallet backend as enumerated in Wallet::Device
+ * \param keys_file_name Keys file to verify password for
+ * \param password Password to verify
+ * \return true if password correct, else false
+ *
+ * for verification only - determines key storage hardware
+ *
+ */
+ virtual bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const = 0;
+
+ /*!
* \brief findWallets - searches for the wallet files by given path name recursively
* \param path - starting point to search
* \return - list of strings with found wallets (absolute paths);
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index 3851ca9cc..5b262f1b7 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -167,6 +167,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name,
return tools::wallet2::verify_password(keys_file_name, password, no_spend_key, hw::get_device("default"), kdf_rounds);
}
+bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const
+{
+ hw::device::device_type type;
+ bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
+ device_type = static_cast<Wallet::Device>(type);
+ return r;
+}
+
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
{
std::vector<std::string> result;
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 8b1c8be7f..573e80d1a 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -76,6 +76,7 @@ public:
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
+ bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const;
std::vector<std::string> findWallets(const std::string &path) override;
std::string errorString() const override;
void setDaemonAddress(const std::string &address) override;