Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d837147a0d | |||
| c4e09d99d6 | |||
| 235107fe5d | |||
| e79f77f0a6 | |||
| dd7d17fb23 | |||
| 5d5019d58f | |||
| fab66493eb | |||
| a4c301a9a9 |
@@ -16,3 +16,7 @@
|
||||
url = https://github.com/MrCyjaneK/wownero-seed
|
||||
branch = cyjan-namespace2
|
||||
shallow = true
|
||||
[submodule "salvium"]
|
||||
path = salvium
|
||||
url = https://github.com/salvium/salvium
|
||||
branch = rebase-v0.18
|
||||
|
||||
+4
-4
@@ -6,14 +6,14 @@ repo="$1"
|
||||
|
||||
if [[ "x$repo" == "x" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" ]];
|
||||
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" && "x$repo" != "xsalvium" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero"
|
||||
echo "Invalid target given, only monero and wownero are supported targets"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium"
|
||||
echo "Invalid target given, only monero, wownero,zano, and salvium are supported targets"
|
||||
fi
|
||||
|
||||
if [[ ! -d "$repo" ]]
|
||||
|
||||
+5
-5
@@ -20,13 +20,13 @@ set -e
|
||||
repo=$1
|
||||
if [[ "x$repo" == "x" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero/zano $(gcc -dumpmachine) -j$proccount"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" ]];
|
||||
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" && "x$repo" != "xsalvium" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero/zano $(gcc -dumpmachine) -j$proccount"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
|
||||
echo "Invalid target given"
|
||||
exit 1
|
||||
fi
|
||||
@@ -41,7 +41,7 @@ fi
|
||||
HOST_ABI="$2"
|
||||
if [[ "x$HOST_ABI" == "x" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -49,7 +49,7 @@ NPROC="$3"
|
||||
|
||||
if [[ "x$NPROC" == "x" ]];
|
||||
then
|
||||
echo "Usage: $0 monero/wownero $(gcc -dumpmachine) -j$proccount"
|
||||
echo "Usage: $0 monero/wownero/zano/salvium $(gcc -dumpmachine) -j$proccount"
|
||||
exit 1
|
||||
fi
|
||||
cd $(dirname $0)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 6e284a2ef552f1f47e8ca9edcf8651312c9e37dd Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Tue, 2 Apr 2024 16:51:56 +0200
|
||||
Subject: [PATCH 01/14] fix missing ___clear_cache when targetting iOS
|
||||
|
||||
---
|
||||
.gitmodules | 3 ++-
|
||||
external/randomx | 2 +-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/.gitmodules b/.gitmodules
|
||||
index 721cce3b4..ffb73fe9a 100644
|
||||
--- a/.gitmodules
|
||||
+++ b/.gitmodules
|
||||
@@ -9,7 +9,8 @@
|
||||
url = https://github.com/trezor/trezor-common.git
|
||||
[submodule "external/randomx"]
|
||||
path = external/randomx
|
||||
- url = https://github.com/tevador/RandomX
|
||||
+ url = https://github.com/MrCyjaneK/RandomX
|
||||
+ branch = cyjan-fix-ios
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://github.com/monero-project/supercop
|
||||
diff --git a/external/randomx b/external/randomx
|
||||
index 102f8acf9..ce72c9bb9 160000
|
||||
--- a/external/randomx
|
||||
+++ b/external/randomx
|
||||
@@ -1 +1 @@
|
||||
-Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da
|
||||
+Subproject commit ce72c9bb9cb799e0d9171094b9abb009e04c5bfc
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
From b4f4b38af1ab974872862fc20735e41941b955e9 Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Sat, 11 May 2024 16:25:10 +0200
|
||||
Subject: [PATCH 02/14] store crash fix
|
||||
|
||||
Monero wallet crashes (sometimes) when it is syncing,
|
||||
while the proper solution (that can be seen in feather)
|
||||
is to not store wallet while it is being synced, this is not
|
||||
acceptable for mobile wallets where OS can just come
|
||||
and kill the wallet because it felt like it.
|
||||
|
||||
This patch depends on the background-sync patch, but
|
||||
to use it as a standalone fix grabbing the definition for the
|
||||
LOCK_REFRESH macro should be enough.
|
||||
|
||||
tobtoht suggested:
|
||||
_say you want to store every 15 minutes during background sync. you stop the refresh every 15 minutes. then do something like this in the callback:_
|
||||
|
||||
```
|
||||
// Make sure this doesn't run in the refresh thread
|
||||
onRefreshed() {
|
||||
if (hasItBeen15MinutesSinceWeStored()) {
|
||||
store();
|
||||
}
|
||||
|
||||
if (shouldWeContinueRefreshing()) {
|
||||
startRefresh();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
which works for crashes after the wallet is initially synced
|
||||
but doesn't solve the issue for wallet that are syncing (it
|
||||
would just wait for it to finish before actually storing).
|
||||
|
||||
Also imo store() functin should store the wallet, no matter
|
||||
the current state.
|
||||
---
|
||||
src/wallet/api/wallet.cpp | 25 ++++++++++++-------------
|
||||
src/wallet/api/wallet.h | 1 -
|
||||
src/wallet/wallet2.cpp | 11 ++++++++++-
|
||||
src/wallet/wallet2.h | 3 +++
|
||||
4 files changed, 25 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index 8fda0bab7..67b170e3d 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -55,8 +55,8 @@ using namespace cryptonote;
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "WalletAPI"
|
||||
|
||||
#define LOCK_REFRESH() \
|
||||
- bool refresh_enabled = m_refreshEnabled; \
|
||||
- m_refreshEnabled = false; \
|
||||
+ bool refresh_enabled = m_wallet->get_refresh_enabled(); \
|
||||
+ m_wallet->set_refresh_enabled(false); \
|
||||
m_wallet->stop(); \
|
||||
m_refreshCV.notify_one(); \
|
||||
boost::mutex::scoped_lock lock(m_refreshMutex); \
|
||||
@@ -466,7 +466,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
|
||||
m_wallet2Callback.reset(new Wallet2CallbackImpl(this));
|
||||
m_wallet->callback(m_wallet2Callback.get());
|
||||
m_refreshThreadDone = false;
|
||||
- m_refreshEnabled = false;
|
||||
+ m_wallet->set_refresh_enabled(false);
|
||||
m_addressBook.reset(new AddressBookImpl(this));
|
||||
m_subaddress.reset(new SubaddressImpl(this));
|
||||
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
|
||||
@@ -962,6 +962,7 @@ void WalletImpl::stop()
|
||||
bool WalletImpl::store(const std::string &path)
|
||||
{
|
||||
clearStatus();
|
||||
+ LOCK_REFRESH();
|
||||
try {
|
||||
if (path.empty()) {
|
||||
m_wallet->store();
|
||||
@@ -2448,10 +2449,10 @@ void WalletImpl::refreshThreadFunc()
|
||||
}
|
||||
|
||||
LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired...");
|
||||
- LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled);
|
||||
+ LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_wallet->get_refresh_enabled());
|
||||
LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << status());
|
||||
LOG_PRINT_L3(__FUNCTION__ << ": m_refreshShouldRescan: " << m_refreshShouldRescan);
|
||||
- if (m_refreshEnabled) {
|
||||
+ if (m_wallet->get_refresh_enabled()) {
|
||||
LOG_PRINT_L3(__FUNCTION__ << ": refreshing...");
|
||||
doRefresh();
|
||||
}
|
||||
@@ -2481,12 +2482,12 @@ void WalletImpl::doRefresh()
|
||||
}
|
||||
m_wallet->find_and_save_rings(false);
|
||||
} else {
|
||||
- LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced");
|
||||
+ LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced");
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
setStatusError(e.what());
|
||||
break;
|
||||
- }while(!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
|
||||
+ }while(m_wallet->get_refresh_enabled() && !rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested
|
||||
|
||||
if (m_wallet2Callback->getListener()) {
|
||||
m_wallet2Callback->getListener()->refreshed();
|
||||
@@ -2496,9 +2497,9 @@ void WalletImpl::doRefresh()
|
||||
|
||||
void WalletImpl::startRefresh()
|
||||
{
|
||||
- if (!m_refreshEnabled) {
|
||||
+ if (!m_wallet->get_refresh_enabled()) {
|
||||
LOG_PRINT_L2(__FUNCTION__ << ": refresh started/resumed...");
|
||||
- m_refreshEnabled = true;
|
||||
+ m_wallet->set_refresh_enabled(true);
|
||||
m_refreshCV.notify_one();
|
||||
}
|
||||
}
|
||||
@@ -2508,7 +2509,7 @@ void WalletImpl::startRefresh()
|
||||
void WalletImpl::stopRefresh()
|
||||
{
|
||||
if (!m_refreshThreadDone) {
|
||||
- m_refreshEnabled = false;
|
||||
+ m_wallet->set_refresh_enabled(false);
|
||||
m_refreshThreadDone = true;
|
||||
m_refreshCV.notify_one();
|
||||
m_refreshThread.join();
|
||||
@@ -2519,9 +2520,7 @@ void WalletImpl::pauseRefresh()
|
||||
{
|
||||
LOG_PRINT_L2(__FUNCTION__ << ": refresh paused...");
|
||||
// TODO synchronize access
|
||||
- if (!m_refreshThreadDone) {
|
||||
- m_refreshEnabled = false;
|
||||
- }
|
||||
+ m_wallet->set_refresh_enabled(false);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
|
||||
index 1f199a72c..ac7ce2f6a 100644
|
||||
--- a/src/wallet/api/wallet.h
|
||||
+++ b/src/wallet/api/wallet.h
|
||||
@@ -273,7 +273,6 @@ private:
|
||||
std::unique_ptr<SubaddressAccountImpl> m_subaddressAccount;
|
||||
|
||||
// multi-threaded refresh stuff
|
||||
- std::atomic<bool> m_refreshEnabled;
|
||||
std::atomic<bool> m_refreshThreadDone;
|
||||
std::atomic<int> m_refreshIntervalMillis;
|
||||
std::atomic<bool> m_refreshShouldRescan;
|
||||
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
|
||||
index dfb8b23cb..c9c2dbc82 100644
|
||||
--- a/src/wallet/wallet2.cpp
|
||||
+++ b/src/wallet/wallet2.cpp
|
||||
@@ -1192,6 +1192,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
|
||||
m_upper_transaction_weight_limit(0),
|
||||
m_run(true),
|
||||
m_callback(0),
|
||||
+ m_refreshEnabled(false),
|
||||
m_trusted_daemon(false),
|
||||
m_nettype(nettype),
|
||||
m_multisig_rounds_passed(0),
|
||||
@@ -1412,6 +1413,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
|
||||
return ret;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
+bool wallet2::get_refresh_enabled() {
|
||||
+ return m_refreshEnabled;
|
||||
+}
|
||||
+//----------------------------------------------------------------------------------------------------
|
||||
+void wallet2::set_refresh_enabled(bool val) {
|
||||
+ m_refreshEnabled = val;
|
||||
+}
|
||||
+//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::set_proxy(const std::string &address)
|
||||
{
|
||||
return m_http_client->set_proxy(address);
|
||||
@@ -4107,7 +4116,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
|
||||
// infer when we get an incoming output
|
||||
|
||||
bool first = true, last = false;
|
||||
- while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks)
|
||||
+ while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks && m_refreshEnabled)
|
||||
{
|
||||
uint64_t next_blocks_start_height;
|
||||
std::vector<cryptonote::block_complete_entry> next_blocks;
|
||||
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
|
||||
index 2f4ad52f1..daad1e940 100644
|
||||
--- a/src/wallet/wallet2.h
|
||||
+++ b/src/wallet/wallet2.h
|
||||
@@ -1078,6 +1078,8 @@ private:
|
||||
epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect,
|
||||
const std::string &proxy = "");
|
||||
bool set_proxy(const std::string &address);
|
||||
+ bool get_refresh_enabled();
|
||||
+ void set_refresh_enabled(bool val);
|
||||
|
||||
void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); }
|
||||
|
||||
@@ -1989,6 +1991,7 @@ private:
|
||||
|
||||
boost::recursive_mutex m_daemon_rpc_mutex;
|
||||
|
||||
+ bool m_refreshEnabled;
|
||||
bool m_trusted_daemon;
|
||||
i_wallet2_callback* m_callback;
|
||||
hw::device::device_type m_key_device_type;
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From a74f616e3c1671a883182b0db1c6fc11a1242c01 Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Mon, 2 Sep 2024 16:40:31 +0200
|
||||
Subject: [PATCH 03/14] uint64_t missing definition fix
|
||||
|
||||
---
|
||||
contrib/epee/include/net/http_base.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h
|
||||
index 4af4da790..ae4c0d05e 100644
|
||||
--- a/contrib/epee/include/net/http_base.h
|
||||
+++ b/contrib/epee/include/net/http_base.h
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "memwipe.h"
|
||||
-
|
||||
+#include <stdint.h>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <string>
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
From f9b222f1611d7cfbaf0ac52cd6194724c7554def Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Mon, 24 Jun 2024 10:49:12 +0200
|
||||
Subject: [PATCH 04/14] use proper error handling in get_seed
|
||||
|
||||
---
|
||||
src/wallet/api/wallet.cpp | 17 ++++++++++++-----
|
||||
src/wallet/wallet2.cpp | 5 ++++-
|
||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index 67b170e3d..89df5c517 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -763,12 +763,19 @@ bool WalletImpl::close(bool store)
|
||||
|
||||
std::string WalletImpl::seed(const std::string& seed_offset) const
|
||||
{
|
||||
- if (checkBackgroundSync("cannot get seed"))
|
||||
+ if (checkBackgroundSync("cannot get seed")) {
|
||||
+ setStatusError("cannot get seed");
|
||||
return std::string();
|
||||
- epee::wipeable_string seed;
|
||||
- if (m_wallet)
|
||||
- m_wallet->get_seed(seed, seed_offset);
|
||||
- return std::string(seed.data(), seed.size()); // TODO
|
||||
+ }
|
||||
+ try {
|
||||
+ epee::wipeable_string seed;
|
||||
+ if (m_wallet)
|
||||
+ m_wallet->get_seed(seed, seed_offset);
|
||||
+ return std::string(seed.data(), seed.size()); // TODO
|
||||
+ } catch (const std::exception &e) {
|
||||
+ setStatusError(e.what());
|
||||
+ return std::string();
|
||||
+ }
|
||||
}
|
||||
|
||||
std::string WalletImpl::getSeedLanguage() const
|
||||
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
|
||||
index c9c2dbc82..b827b826f 100644
|
||||
--- a/src/wallet/wallet2.cpp
|
||||
+++ b/src/wallet/wallet2.cpp
|
||||
@@ -1428,11 +1428,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
|
||||
bool keys_deterministic = is_deterministic();
|
||||
if (!keys_deterministic)
|
||||
{
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "This is not a deterministic wallet");
|
||||
std::cout << "This is not a deterministic wallet" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (seed_language.empty())
|
||||
{
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "seed_language not set");
|
||||
std::cout << "seed_language not set" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -1444,8 +1446,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
|
||||
key = cryptonote::encrypt_key(key, passphrase);
|
||||
if (!crypto::ElectrumWords::bytes_to_words(key, electrum_words, seed_language))
|
||||
{
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, "Failed to create seed from key for language: "+seed_language+", falling back to English.");
|
||||
std::cout << "Failed to create seed from key for language: " << seed_language << std::endl;
|
||||
- return false;
|
||||
+ crypto::ElectrumWords::bytes_to_words(key, electrum_words, "English");
|
||||
}
|
||||
|
||||
return true;
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,986 @@
|
||||
From ff70c74c8b331758ace1f14df0ca107731dda49d Mon Sep 17 00:00:00 2001
|
||||
From: tobtoht <tob@featherwallet.org>
|
||||
Date: Tue, 12 Mar 2024 10:09:50 +0100
|
||||
Subject: [PATCH 05/14] UR functions
|
||||
|
||||
This commit adds UR functions for UR tasks,
|
||||
I believe that the right place to get
|
||||
UR strings is the wallet code itself,
|
||||
especially because it allows us to
|
||||
skip the part when we have to store
|
||||
things to file to encode them later.
|
||||
Now we are fully in memory
|
||||
|
||||
Things broken in the commit
|
||||
- ledger support.
|
||||
AUTO_LOCK_CMD macro causes compile time
|
||||
issues with this patch. I don't know why
|
||||
just yet, this is a issue that I'll fix
|
||||
later. However (considering the purpose
|
||||
of this patch) it is not a dealbreaker.
|
||||
---
|
||||
.gitmodules | 4 +
|
||||
CMakeLists.txt | 4 +-
|
||||
external/CMakeLists.txt | 1 +
|
||||
external/bc-ur | 1 +
|
||||
src/device/device_ledger.cpp | 5 +-
|
||||
src/wallet/CMakeLists.txt | 1 +
|
||||
src/wallet/api/pending_transaction.cpp | 33 +++
|
||||
src/wallet/api/pending_transaction.h | 1 +
|
||||
src/wallet/api/unsigned_transaction.cpp | 42 ++++
|
||||
src/wallet/api/unsigned_transaction.h | 1 +
|
||||
src/wallet/api/wallet.cpp | 309 +++++++++++++++++++++++-
|
||||
src/wallet/api/wallet.h | 8 +
|
||||
src/wallet/api/wallet2_api.h | 22 +-
|
||||
src/wallet/wallet2.cpp | 141 +++++++----
|
||||
src/wallet/wallet2.h | 3 +
|
||||
15 files changed, 519 insertions(+), 57 deletions(-)
|
||||
create mode 160000 external/bc-ur
|
||||
|
||||
diff --git a/.gitmodules b/.gitmodules
|
||||
index ffb73fe9a..72af74d55 100644
|
||||
--- a/.gitmodules
|
||||
+++ b/.gitmodules
|
||||
@@ -11,6 +11,10 @@
|
||||
path = external/supercop
|
||||
url = https://github.com/monero-project/supercop
|
||||
branch = monero
|
||||
+[submodule "external/bc-ur"]
|
||||
+ path = external/bc-ur
|
||||
+ url = https://github.com/MrCyjaneK/bc-ur
|
||||
+ branch = misc
|
||||
[submodule "external/miniupnp"]
|
||||
path = external/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index db69b1b04..c73b813d8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -100,6 +100,7 @@ enable_language(C ASM)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
+add_definitions(-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) # boost: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'?
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
@@ -367,6 +368,7 @@ if(NOT MANUAL_SUBMODULES)
|
||||
endfunction ()
|
||||
|
||||
message(STATUS "Checking submodules")
|
||||
+# check_submodule(external/bc-ur)
|
||||
check_submodule(external/miniupnp)
|
||||
check_submodule(external/rapidjson)
|
||||
check_submodule(external/trezor-common)
|
||||
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
|
||||
index 538e4d215..074e23f16 100644
|
||||
--- a/external/CMakeLists.txt
|
||||
+++ b/external/CMakeLists.txt
|
||||
@@ -69,4 +69,5 @@ endif()
|
||||
add_subdirectory(db_drivers)
|
||||
add_subdirectory(easylogging++)
|
||||
add_subdirectory(qrcodegen)
|
||||
+add_subdirectory(bc-ur)
|
||||
add_subdirectory(randomx EXCLUDE_FROM_ALL)
|
||||
diff --git a/external/bc-ur b/external/bc-ur
|
||||
new file mode 160000
|
||||
index 000000000..d82e7c753
|
||||
--- /dev/null
|
||||
+++ b/external/bc-ur
|
||||
@@ -0,0 +1,1 @@
|
||||
+Subproject commit d82e7c753e710b8000706dc3383b498438795208
|
||||
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
|
||||
index 6095f99d5..b163212b7 100644
|
||||
--- a/src/wallet/CMakeLists.txt
|
||||
+++ b/src/wallet/CMakeLists.txt
|
||||
@@ -50,6 +50,7 @@ monero_add_library(wallet
|
||||
target_link_libraries(wallet
|
||||
PUBLIC
|
||||
rpc_base
|
||||
+ bc-ur
|
||||
multisig
|
||||
common
|
||||
cryptonote_core
|
||||
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
|
||||
index 70a702796..9c3c26ee5 100644
|
||||
--- a/src/wallet/api/pending_transaction.cpp
|
||||
+++ b/src/wallet/api/pending_transaction.cpp
|
||||
@@ -42,6 +42,8 @@
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
+#include "bc-ur/src/bc-ur.hpp"
|
||||
+
|
||||
using namespace std;
|
||||
|
||||
namespace Monero {
|
||||
@@ -162,6 +164,37 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
|
||||
return m_status == Status_Ok;
|
||||
}
|
||||
|
||||
+std::string PendingTransactionImpl::commitUR(int max_fragment_length) {
|
||||
+
|
||||
+ LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size());
|
||||
+
|
||||
+ try {
|
||||
+ std::string ptx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx);
|
||||
+ m_status = Status_Ok;
|
||||
+ auto urMessage = ur::string_to_bytes(ptx);
|
||||
+ ur::ByteVector cbor;
|
||||
+ ur::CborLite::encodeBytes(cbor, urMessage);
|
||||
+ std::string type;
|
||||
+ if (m_wallet.watchOnly()) {
|
||||
+ type = "xmr-txunsigned";
|
||||
+ } else {
|
||||
+ type = "xmr-txsigned";
|
||||
+ }
|
||||
+ ur::UR urData = ur::UR(type, cbor);
|
||||
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
|
||||
+ std::string output;
|
||||
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
|
||||
+ output.append("\n"+encoder.next_part());
|
||||
+ }
|
||||
+ return output;
|
||||
+ } catch (const std::exception &e) {
|
||||
+ m_errorString = string(tr("Unknown exception: ")) + e.what();
|
||||
+ m_status = Status_Error;
|
||||
+ return "";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
uint64_t PendingTransactionImpl::amount() const
|
||||
{
|
||||
uint64_t result = 0;
|
||||
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
|
||||
index 0a9779c07..403bfe281 100644
|
||||
--- a/src/wallet/api/pending_transaction.h
|
||||
+++ b/src/wallet/api/pending_transaction.h
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
int status() const override;
|
||||
std::string errorString() const override;
|
||||
bool commit(const std::string &filename = "", bool overwrite = false) override;
|
||||
+ std::string commitUR(int max_fragment_length = 130) override;
|
||||
uint64_t amount() const override;
|
||||
uint64_t dust() const override;
|
||||
uint64_t fee() const override;
|
||||
diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp
|
||||
index 6165a2240..fd03e959d 100644
|
||||
--- a/src/wallet/api/unsigned_transaction.cpp
|
||||
+++ b/src/wallet/api/unsigned_transaction.cpp
|
||||
@@ -40,6 +40,8 @@
|
||||
#include <sstream>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
+#include "bc-ur/src/bc-ur.hpp"
|
||||
+
|
||||
using namespace std;
|
||||
|
||||
namespace Monero {
|
||||
@@ -96,6 +98,46 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName)
|
||||
return true;
|
||||
}
|
||||
|
||||
+std::string UnsignedTransactionImpl::signUR(int max_fragment_length)
|
||||
+{
|
||||
+ if(m_wallet.watchOnly())
|
||||
+ {
|
||||
+ m_errorString = tr("This is a watch only wallet");
|
||||
+ m_status = Status_Error;
|
||||
+ return "";
|
||||
+ }
|
||||
+ std::vector<tools::wallet2::pending_tx> ptx;
|
||||
+ try
|
||||
+ {
|
||||
+ tools::wallet2::signed_tx_set signed_txes;
|
||||
+ std::string signedTx = m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes);
|
||||
+ if (signedTx.empty())
|
||||
+ {
|
||||
+ m_errorString = tr("Failed to sign transaction");
|
||||
+ m_status = Status_Error;
|
||||
+ return "";
|
||||
+ }
|
||||
+ auto urMessage = ur::string_to_bytes(signedTx);
|
||||
+ ur::ByteVector cbor;
|
||||
+ ur::CborLite::encodeBytes(cbor, urMessage);
|
||||
+ std::string type = "xmr-txsigned";
|
||||
+ ur::UR urData = ur::UR(type, cbor);
|
||||
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
|
||||
+ std::string output;
|
||||
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
|
||||
+ output.append("\n"+encoder.next_part());
|
||||
+ }
|
||||
+ return output;
|
||||
+ }
|
||||
+ catch (const std::exception &e)
|
||||
+ {
|
||||
+ m_errorString = string(tr("Failed to sign transaction")) + e.what();
|
||||
+ m_status = Status_Error;
|
||||
+ return "";
|
||||
+ }
|
||||
+ return "";
|
||||
+}
|
||||
+
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
|
||||
{
|
||||
diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h
|
||||
index 30065a7fa..a94b23f75 100644
|
||||
--- a/src/wallet/api/unsigned_transaction.h
|
||||
+++ b/src/wallet/api/unsigned_transaction.h
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
uint64_t txCount() const override;
|
||||
// sign txs and save to file
|
||||
bool sign(const std::string &signedFileName) override;
|
||||
+ std::string signUR(int max_fragment_length = 130) override;
|
||||
std::string confirmationMessage() const override {return m_confirmationMessage;}
|
||||
uint64_t minMixinCount() const override;
|
||||
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index 89df5c517..3fcd6f332 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <boost/locale.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
+#include "bc-ur/src/bc-ur.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cryptonote;
|
||||
@@ -961,6 +962,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
|
||||
return m_wallet->unlocked_balance(accountIndex, asset, false);
|
||||
}
|
||||
|
||||
+uint64_t WalletImpl::viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images, const std::string& asset) const
|
||||
+{
|
||||
+ clearStatus();
|
||||
+
|
||||
+ std::vector<crypto::key_image> kis;
|
||||
+ for (const auto &key_image : key_images) {
|
||||
+ crypto::key_image ki;
|
||||
+ if (!epee::string_tools::hex_to_pod(key_image, ki))
|
||||
+ {
|
||||
+ setStatusError(tr("failed to parse key image"));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ kis.push_back(ki);
|
||||
+ }
|
||||
+
|
||||
+ return m_wallet->view_only_balance(accountIndex, kis, asset);
|
||||
+}
|
||||
+
|
||||
uint64_t WalletImpl::blockChainHeight() const
|
||||
{
|
||||
return m_wallet->get_blockchain_current_height();
|
||||
@@ -1139,6 +1158,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
|
||||
return transaction;
|
||||
}
|
||||
|
||||
+
|
||||
+UnsignedTransaction *WalletImpl::loadUnsignedTxUR(const std::string &input) {
|
||||
+ clearStatus();
|
||||
+ UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this);
|
||||
+ auto decoder = ur::URDecoder();
|
||||
+
|
||||
+ std::string delimiter = "\n";
|
||||
+ std::string inp = input;
|
||||
+ size_t pos = 0;
|
||||
+ std::string token;
|
||||
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
|
||||
+ token = inp.substr(0, pos);
|
||||
+ decoder.receive_part(token);
|
||||
+ inp.erase(0, pos + delimiter.length());
|
||||
+ }
|
||||
+ decoder.receive_part(inp);
|
||||
+
|
||||
+ if (decoder.is_failure()) {
|
||||
+ setStatusError(decoder.result_error().what());
|
||||
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
|
||||
+ transaction->m_errorString = errorString();
|
||||
+ return transaction;
|
||||
+ }
|
||||
+
|
||||
+ if (!decoder.is_complete()) {
|
||||
+ setStatusError("file ended but ur didn't complete");
|
||||
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
|
||||
+ transaction->m_errorString = errorString();
|
||||
+ return transaction;
|
||||
+ }
|
||||
+
|
||||
+ std::string data;
|
||||
+ auto cbor = decoder.result_ur().cbor();
|
||||
+ auto i = cbor.begin();
|
||||
+ auto end = cbor.end();
|
||||
+ ur::CborLite::decodeBytes(i, end, data);
|
||||
+
|
||||
+ if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){
|
||||
+ setStatusError(tr("Failed to load unsigned transactions"));
|
||||
+ transaction->m_status = UnsignedTransaction::Status::Status_Error;
|
||||
+ transaction->m_errorString = errorString();
|
||||
+
|
||||
+ return transaction;
|
||||
+ }
|
||||
+
|
||||
+ // Check tx data and construct confirmation message
|
||||
+ std::string extra_message;
|
||||
+ if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty())
|
||||
+ extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str();
|
||||
+ transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message);
|
||||
+ setStatus(transaction->status(), transaction->errorString());
|
||||
+
|
||||
+ return transaction;
|
||||
+}
|
||||
+
|
||||
bool WalletImpl::submitTransaction(const string &fileName) {
|
||||
clearStatus();
|
||||
if (checkBackgroundSync("cannot submit tx"))
|
||||
@@ -1159,6 +1233,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+
|
||||
+bool WalletImpl::submitTransactionUR(const string &input) {
|
||||
+ clearStatus();
|
||||
+ auto decoder = ur::URDecoder();
|
||||
+
|
||||
+ std::string delimiter = "\n";
|
||||
+ std::string inp = input;
|
||||
+ size_t pos = 0;
|
||||
+ std::string token;
|
||||
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
|
||||
+ token = inp.substr(0, pos);
|
||||
+ decoder.receive_part(token);
|
||||
+ inp.erase(0, pos + delimiter.length());
|
||||
+ }
|
||||
+ decoder.receive_part(inp);
|
||||
+
|
||||
+ if (decoder.is_failure()) {
|
||||
+ setStatusError(decoder.result_error().what());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!decoder.is_complete()) {
|
||||
+ setStatusError("file ended but ur didn't complete");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ std::string data;
|
||||
+ auto cbor = decoder.result_ur().cbor();
|
||||
+ auto i = cbor.begin();
|
||||
+ auto end = cbor.end();
|
||||
+ ur::CborLite::decodeBytes(i, end, data);
|
||||
+ if (checkBackgroundSync("cannot submit tx"))
|
||||
+ return false;
|
||||
+ std::unique_ptr<PendingTransactionImpl> transaction(new PendingTransactionImpl(*this));
|
||||
+
|
||||
+ bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL);
|
||||
+ if (!r) {
|
||||
+ setStatus(Status_Ok, tr("Failed to load transaction from file"));
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if(!transaction->commit()) {
|
||||
+ setStatusError(transaction->m_errorString);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+bool WalletImpl::hasUnknownKeyImages() const
|
||||
+{
|
||||
+ return m_wallet->has_unknown_key_images();
|
||||
+}
|
||||
+
|
||||
bool WalletImpl::exportKeyImages(const string &filename, bool all)
|
||||
{
|
||||
if (m_wallet->watch_only())
|
||||
@@ -1186,6 +1318,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
|
||||
return true;
|
||||
}
|
||||
|
||||
+std::string WalletImpl::exportKeyImagesUR(size_t max_fragment_length, bool all)
|
||||
+{
|
||||
+ if (m_wallet->watch_only())
|
||||
+ {
|
||||
+ setStatusError(tr("Wallet is view only"));
|
||||
+ return "";
|
||||
+ }
|
||||
+ if (checkBackgroundSync("cannot export key images"))
|
||||
+ return "";
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ std::string keyImages = m_wallet->export_key_images_str(all);
|
||||
+ auto urMessage = ur::string_to_bytes(keyImages);
|
||||
+ ur::ByteVector cbor;
|
||||
+ ur::CborLite::encodeBytes(cbor, urMessage);
|
||||
+ ur::UR urData = ur::UR("xmr-keyimage", cbor);
|
||||
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
|
||||
+ std::string output;
|
||||
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
|
||||
+ output.append("\n"+encoder.next_part());
|
||||
+ }
|
||||
+ return output;
|
||||
+ }
|
||||
+ catch (const std::exception &e)
|
||||
+ {
|
||||
+ LOG_ERROR("Error exporting key images: " << e.what());
|
||||
+ setStatusError(e.what());
|
||||
+ return "";
|
||||
+ }
|
||||
+ return "";
|
||||
+}
|
||||
+
|
||||
bool WalletImpl::importKeyImages(const string &filename)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import key images"))
|
||||
@@ -1211,6 +1373,62 @@ bool WalletImpl::importKeyImages(const string &filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
+
|
||||
+bool WalletImpl::importKeyImagesUR(const string &input)
|
||||
+{
|
||||
+ if (checkBackgroundSync("cannot import key images"))
|
||||
+ return false;
|
||||
+ if (!trustedDaemon()) {
|
||||
+ setStatusError(tr("Key images can only be imported with a trusted daemon"));
|
||||
+ return false;
|
||||
+ }
|
||||
+ try
|
||||
+ {
|
||||
+ auto decoder = ur::URDecoder();
|
||||
+ std::string delimiter = "\n";
|
||||
+ std::string inp = input;
|
||||
+ size_t pos = 0;
|
||||
+ std::string token;
|
||||
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
|
||||
+ token = inp.substr(0, pos);
|
||||
+ decoder.receive_part(token);
|
||||
+ inp.erase(0, pos + delimiter.length());
|
||||
+ }
|
||||
+ decoder.receive_part(inp);
|
||||
+
|
||||
+ if (decoder.is_failure()) {
|
||||
+ setStatusError(decoder.result_error().what());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!decoder.is_complete()) {
|
||||
+ setStatusError("file ended but ur didn't complete");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ std::string data;
|
||||
+ auto cbor = decoder.result_ur().cbor();
|
||||
+ auto i = cbor.begin();
|
||||
+ auto end = cbor.end();
|
||||
+ ur::CborLite::decodeBytes(i, end, data);
|
||||
+
|
||||
+ uint64_t spent = 0, unspent = 0;
|
||||
+
|
||||
+ uint64_t height = m_wallet->import_key_images_str(data, spent, unspent);
|
||||
+ LOG_PRINT_L2("Signed key images imported to height " << height << ", "
|
||||
+ << print_money(spent) << " spent, " << print_money(unspent) << " unspent");
|
||||
+ }
|
||||
+ catch (const std::exception &e)
|
||||
+ {
|
||||
+ LOG_ERROR("Error exporting key images: " << e.what());
|
||||
+ setStatusError(string(tr("Failed to import key images: ")) + e.what());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
bool WalletImpl::exportOutputs(const string &filename, bool all)
|
||||
{
|
||||
if (checkBackgroundSync("cannot export outputs"))
|
||||
@@ -1243,6 +1461,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
|
||||
return true;
|
||||
}
|
||||
|
||||
+std::string WalletImpl::exportOutputsUR(size_t max_fragment_length, bool all)
|
||||
+{
|
||||
+
|
||||
+ if (checkBackgroundSync("cannot export outputs"))
|
||||
+ return "";
|
||||
+ if (m_wallet->key_on_device())
|
||||
+ {
|
||||
+ setStatusError(string(tr("Not supported on HW wallets.")));
|
||||
+ return "";
|
||||
+ }
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ std::string data = m_wallet->export_outputs_to_str(all);
|
||||
+ auto urMessage = ur::string_to_bytes(data);
|
||||
+ ur::ByteVector cbor;
|
||||
+ ur::CborLite::encodeBytes(cbor, urMessage);
|
||||
+ ur::UR urData = ur::UR("xmr-output", cbor);
|
||||
+ auto encoder = ur::UREncoder(urData, max_fragment_length);
|
||||
+ std::string output;
|
||||
+ for(size_t i = 0; i < encoder.seq_len(); i++) {
|
||||
+ output.append("\n"+encoder.next_part());
|
||||
+ }
|
||||
+ return output;
|
||||
+ }
|
||||
+ catch (const std::exception &e)
|
||||
+ {
|
||||
+ LOG_ERROR("Error exporting outputs: " << e.what());
|
||||
+ setStatusError(string(tr("Error exporting outputs: ")) + e.what());
|
||||
+ return "";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
bool WalletImpl::importOutputs(const string &filename)
|
||||
{
|
||||
if (checkBackgroundSync("cannot import outputs"))
|
||||
@@ -1277,6 +1529,61 @@ bool WalletImpl::importOutputs(const string &filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
+
|
||||
+bool WalletImpl::importOutputsUR(const string &input)
|
||||
+{
|
||||
+ if (checkBackgroundSync("cannot import outputs"))
|
||||
+ return false;
|
||||
+ if (m_wallet->key_on_device())
|
||||
+ {
|
||||
+ setStatusError(string(tr("Not supported on HW wallets.")));
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ auto decoder = ur::URDecoder();
|
||||
+
|
||||
+ std::string delimiter = "\n";
|
||||
+ std::string inp = input;
|
||||
+ size_t pos = 0;
|
||||
+ std::string token;
|
||||
+ while ((pos = inp.find(delimiter)) != std::string::npos) {
|
||||
+ token = inp.substr(0, pos);
|
||||
+ decoder.receive_part(token);
|
||||
+ inp.erase(0, pos + delimiter.length());
|
||||
+ }
|
||||
+ decoder.receive_part(inp);
|
||||
+
|
||||
+ if (decoder.is_failure()) {
|
||||
+ setStatusError(decoder.result_error().what());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!decoder.is_complete()) {
|
||||
+ setStatusError("file ended but ur didn't complete");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ std::string data;
|
||||
+ auto cbor = decoder.result_ur().cbor();
|
||||
+ auto i = cbor.begin();
|
||||
+ auto end = cbor.end();
|
||||
+ ur::CborLite::decodeBytes(i, end, data);
|
||||
+ size_t n_outputs = m_wallet->import_outputs_from_str(std::string(data));
|
||||
+ LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
|
||||
+ }
|
||||
+ catch (const std::exception &e)
|
||||
+ {
|
||||
+ LOG_ERROR("Failed to import outputs: " << e.what());
|
||||
+ setStatusError(string(tr("Failed to import outputs: ")) + e.what());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
bool WalletImpl::scanTransactions(const std::vector<std::string> &txids)
|
||||
{
|
||||
if (checkBackgroundSync("cannot scan transactions"))
|
||||
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
|
||||
index ac7ce2f6a..edf8bb8ce 100644
|
||||
--- a/src/wallet/api/wallet.h
|
||||
+++ b/src/wallet/api/wallet.h
|
||||
@@ -113,6 +113,7 @@ public:
|
||||
bool setProxy(const std::string &address) override;
|
||||
uint64_t balance(const std::string& asset, uint32_t accountIndex = 0) const override;
|
||||
uint64_t unlockedBalance(const std::string& asset, uint32_t accountIndex = 0) const override;
|
||||
+ uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images, const std::string& asset = "SAL1") const override;
|
||||
uint64_t blockChainHeight() const override;
|
||||
uint64_t approximateBlockChainHeight() const override;
|
||||
uint64_t estimateBlockChainHeight() const override;
|
||||
@@ -177,11 +178,18 @@ public:
|
||||
std::set<uint32_t> subaddr_indices = {}) override;
|
||||
virtual PendingTransaction * createSweepUnmixableTransaction() override;
|
||||
bool submitTransaction(const std::string &fileName) override;
|
||||
+ bool submitTransactionUR(const std::string &input) override;
|
||||
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
|
||||
+ virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) override;
|
||||
+ bool hasUnknownKeyImages() const override;
|
||||
bool exportKeyImages(const std::string &filename, bool all = false) override;
|
||||
+ std::string exportKeyImagesUR(size_t max_fragment_length, bool all = false) override;
|
||||
bool importKeyImages(const std::string &filename) override;
|
||||
+ bool importKeyImagesUR(const std::string &input) override;
|
||||
bool exportOutputs(const std::string &filename, bool all = false) override;
|
||||
+ std::string exportOutputsUR(size_t max_fragment_length, bool all) override;
|
||||
bool importOutputs(const std::string &filename) override;
|
||||
+ bool importOutputsUR(const std::string &filename) override;
|
||||
bool scanTransactions(const std::vector<std::string> &txids) override;
|
||||
|
||||
bool setupBackgroundSync(const BackgroundSyncType background_sync_type, const std::string &wallet_password, const optional<std::string> &background_cache_password = optional<std::string>()) override;
|
||||
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
|
||||
index e349df176..764adbfbf 100644
|
||||
--- a/src/wallet/api/wallet2_api.h
|
||||
+++ b/src/wallet/api/wallet2_api.h
|
||||
@@ -92,6 +92,7 @@ struct PendingTransaction
|
||||
virtual std::string errorString() const = 0;
|
||||
// commit transaction or save to file if filename is provided.
|
||||
virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0;
|
||||
+ virtual std::string commitUR(int max_fragment_length = 130) = 0;
|
||||
virtual uint64_t amount() const = 0;
|
||||
virtual uint64_t dust() const = 0;
|
||||
virtual uint64_t fee() const = 0;
|
||||
@@ -195,7 +196,8 @@ struct UnsignedTransaction
|
||||
* @param signedFileName
|
||||
* return - true on success
|
||||
*/
|
||||
- virtual bool sign(const std::string &signedFileName) = 0;
|
||||
+ virtual bool sign(const std::string &signedFileName) = 0;
|
||||
+ virtual std::string signUR(int max_fragment_length = 130) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -668,6 +670,7 @@ struct Wallet
|
||||
result += unlockedBalance(asset, i);
|
||||
return result;
|
||||
}
|
||||
+ virtual uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images = {}, const std::string& asset = "SAL1") const = 0;
|
||||
|
||||
/**
|
||||
* @brief watchOnly - checks if wallet is watch only
|
||||
@@ -965,13 +968,15 @@ struct Wallet
|
||||
* after object returned
|
||||
*/
|
||||
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
|
||||
-
|
||||
- /*!
|
||||
+ virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) = 0;
|
||||
+
|
||||
+ /*!
|
||||
* \brief submitTransaction - submits transaction in signed tx file
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool submitTransaction(const std::string &fileName) = 0;
|
||||
-
|
||||
+ virtual bool submitTransactionUR(const std::string &input) = 0;
|
||||
+
|
||||
|
||||
/*!
|
||||
* \brief disposeTransaction - destroys transaction object
|
||||
@@ -987,6 +992,8 @@ struct Wallet
|
||||
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
|
||||
PendingTransaction::Priority priority) const = 0;
|
||||
|
||||
+ virtual bool hasUnknownKeyImages() const = 0;
|
||||
+
|
||||
/*!
|
||||
* \brief exportKeyImages - exports key images to file
|
||||
* \param filename
|
||||
@@ -994,20 +1001,22 @@ struct Wallet
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
|
||||
-
|
||||
+ virtual std::string exportKeyImagesUR(size_t max_fragment_length, bool all = false) = 0;
|
||||
/*!
|
||||
* \brief importKeyImages - imports key images from file
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool importKeyImages(const std::string &filename) = 0;
|
||||
+ virtual bool importKeyImagesUR(const std::string &input) = 0;
|
||||
|
||||
/*!
|
||||
- * \brief importOutputs - exports outputs to file
|
||||
+ * \brief exportOutputs - exports outputs to file
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
|
||||
+ virtual std::string exportOutputsUR(size_t max_fragment_length, bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputs - imports outputs from file
|
||||
@@ -1015,6 +1024,7 @@ struct Wallet
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool importOutputs(const std::string &filename) = 0;
|
||||
+ virtual bool importOutputsUR(const std::string &filename) = 0;
|
||||
|
||||
/*!
|
||||
* \brief scanTransactions - scan a list of transaction ids, this operation may reveal the txids to the remote node and affect your privacy
|
||||
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
|
||||
index b827b826f..765cefb32 100644
|
||||
--- a/src/wallet/wallet2.cpp
|
||||
+++ b/src/wallet/wallet2.cpp
|
||||
@@ -945,6 +945,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
|
||||
return idx + extra;
|
||||
}
|
||||
|
||||
+bool is_preferred_input(const std::vector<crypto::key_image>& preferred_input_list, const crypto::key_image& input) {
|
||||
+ if (!preferred_input_list.empty()) {
|
||||
+ auto it = std::find(preferred_input_list.begin(), preferred_input_list.end(), input);
|
||||
+ if (it == preferred_input_list.end()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void setup_shim(hw::wallet_shim * shim, tools::wallet2 * wallet)
|
||||
{
|
||||
shim->get_tx_pub_key_from_received_outs = std::bind(&tools::wallet2::get_tx_pub_key_from_received_outs, wallet, std::placeholders::_1);
|
||||
@@ -7088,6 +7098,29 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, const std::string& asse
|
||||
return amount;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
+uint64_t wallet2::view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs, const std::string& asset_type)
|
||||
+{
|
||||
+ uint64_t amount = 0;
|
||||
+ if (m_transfers_indices.count(asset_type) > 0) {
|
||||
+ for (const auto& idx: m_transfers_indices.at(asset_type))
|
||||
+ {
|
||||
+ const transfer_details& td = m_transfers[idx];
|
||||
+ if (is_preferred_input(selected_inputs, td.m_key_image) &&
|
||||
+ !is_spent(td, false) &&
|
||||
+ !td.m_frozen &&
|
||||
+ !td.m_key_image_partial &&
|
||||
+ td.m_key_image_known &&
|
||||
+ td.is_rct() &&
|
||||
+ is_transfer_unlocked(td) &&
|
||||
+ td.m_subaddr_index.major == index_major)
|
||||
+ {
|
||||
+ amount += td.m_amount;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return amount;
|
||||
+}
|
||||
+//----------------------------------------------------------------------------------------------------
|
||||
std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_major, const std::string& asset_type, bool strict) const
|
||||
{
|
||||
std::map<uint32_t, uint64_t> amount_per_subaddr;
|
||||
@@ -7963,9 +7992,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
|
||||
crypto::key_derivation derivation;
|
||||
std::vector<crypto::key_derivation> additional_derivations;
|
||||
|
||||
- // compute public keys from out secret keys
|
||||
- crypto::public_key tx_pub_key;
|
||||
- crypto::secret_key_to_public_key(txs[n].tx_key, tx_pub_key);
|
||||
+ crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
|
||||
std::vector<crypto::public_key> additional_tx_pub_keys;
|
||||
for (const crypto::secret_key &skey: txs[n].additional_tx_keys)
|
||||
{
|
||||
@@ -10880,7 +10907,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
|
||||
continue;
|
||||
}
|
||||
- if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
|
||||
+ if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && td.m_key_image_known && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
|
||||
{
|
||||
if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
|
||||
{
|
||||
@@ -10930,9 +10957,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
|
||||
LOG_PRINT_L2("Starting with " << num_nondust_outputs << " non-dust outputs and " << num_dust_outputs << " dust outputs");
|
||||
|
||||
- if (unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty())
|
||||
- return std::vector<wallet2::pending_tx>();
|
||||
+ // use tobotoht's code path on view-only wallet, otherwise default to upstream
|
||||
+ bool throwOnNoEnotes = m_account.get_device().device_protocol() == hw::device::PROTOCOL_COLD || m_watch_only || m_multisig || m_is_background_wallet;
|
||||
|
||||
+ if (throwOnNoEnotes) {
|
||||
+ THROW_WALLET_EXCEPTION_IF(unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty(), error::wallet_internal_error, "No enotes available to spend")
|
||||
+ } else {
|
||||
+ if (unused_dust_indices_per_subaddr.empty() && unused_transfers_indices_per_subaddr.empty())
|
||||
+ return std::vector<wallet2::pending_tx>();
|
||||
+ }
|
||||
// if empty, put dummy entry so that the front can be referenced later in the loop
|
||||
if (unused_dust_indices_per_subaddr.empty())
|
||||
unused_dust_indices_per_subaddr.push_back({});
|
||||
@@ -13742,33 +13775,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
|
||||
|
||||
bool wallet2::export_key_images(const std::string &filename, bool all) const
|
||||
{
|
||||
- PERF_TIMER(export_key_images);
|
||||
- std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all);
|
||||
- std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
|
||||
- const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||
- const uint32_t offset = ski.first;
|
||||
+ std::string data = export_key_images_str(all);
|
||||
+ return save_to_file(filename, data);
|
||||
+}
|
||||
|
||||
- std::string data;
|
||||
- data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key));
|
||||
- data.resize(4);
|
||||
- data[0] = offset & 0xff;
|
||||
- data[1] = (offset >> 8) & 0xff;
|
||||
- data[2] = (offset >> 16) & 0xff;
|
||||
- data[3] = (offset >> 24) & 0xff;
|
||||
- data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
|
||||
- data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
|
||||
- for (const auto &i: ski.second)
|
||||
- {
|
||||
- data += std::string((const char *)&i.first, sizeof(crypto::key_image));
|
||||
- data += std::string((const char *)&i.second, sizeof(crypto::signature));
|
||||
- }
|
||||
+std::string wallet2::export_key_images_str(bool all) const
|
||||
+{
|
||||
+ PERF_TIMER(export_key_images);
|
||||
+ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = export_key_images(all);
|
||||
+ std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
|
||||
+ const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||
+ const uint32_t offset = ski.first;
|
||||
|
||||
- // encrypt data, keep magic plaintext
|
||||
- PERF_TIMER(export_key_images_encrypt);
|
||||
- std::string ciphertext = encrypt_with_view_secret_key(data);
|
||||
- return save_to_file(filename, magic + ciphertext);
|
||||
+ std::string data;
|
||||
+ data.reserve(4 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)) + 2 * sizeof(crypto::public_key));
|
||||
+ data.resize(4);
|
||||
+ data[0] = offset & 0xff;
|
||||
+ data[1] = (offset >> 8) & 0xff;
|
||||
+ data[2] = (offset >> 16) & 0xff;
|
||||
+ data[3] = (offset >> 24) & 0xff;
|
||||
+ data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
|
||||
+ data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
|
||||
+ for (const auto &i: ski.second)
|
||||
+ {
|
||||
+ data += std::string((const char *)&i.first, sizeof(crypto::key_image));
|
||||
+ data += std::string((const char *)&i.second, sizeof(crypto::signature));
|
||||
+ }
|
||||
+
|
||||
+ // encrypt data, keep magic plaintext
|
||||
+ PERF_TIMER(export_key_images_encrypt);
|
||||
+ std::string ciphertext = encrypt_with_view_secret_key(data);
|
||||
+ return magic + ciphertext;
|
||||
}
|
||||
|
||||
+
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> wallet2::export_key_images(bool all) const
|
||||
{
|
||||
@@ -13828,53 +13868,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
|
||||
return std::make_pair(offset, ski);
|
||||
}
|
||||
|
||||
-uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent)
|
||||
+uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent) {
|
||||
+ std::string data;
|
||||
+
|
||||
+ bool r = load_from_file(filename, data);
|
||||
+
|
||||
+ THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
|
||||
+
|
||||
+ return import_key_images_str(data, spent, unspent);
|
||||
+}
|
||||
+
|
||||
+uint64_t wallet2::import_key_images_str(const std::string &data, uint64_t &spent, uint64_t &unspent)
|
||||
{
|
||||
PERF_TIMER(import_key_images_fsu);
|
||||
- std::string data;
|
||||
- bool r = load_from_file(filename, data);
|
||||
-
|
||||
- THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
|
||||
+ std::string data_local = data;
|
||||
|
||||
const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC);
|
||||
if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen))
|
||||
{
|
||||
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename);
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic"));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PERF_TIMER(import_key_images_decrypt);
|
||||
- data = decrypt_with_view_secret_key(std::string(data, magiclen));
|
||||
+ data_local = decrypt_with_view_secret_key(std::string(data, magiclen));
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what());
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + ": " + e.what());
|
||||
}
|
||||
|
||||
const size_t headerlen = 4 + 2 * sizeof(crypto::public_key);
|
||||
- THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename);
|
||||
- const uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24);
|
||||
- const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4];
|
||||
- const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)];
|
||||
+ THROW_WALLET_EXCEPTION_IF(data_local.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file "));
|
||||
+ const uint32_t offset = (uint8_t)data_local[0] | (((uint8_t)data_local[1]) << 8) | (((uint8_t)data_local[2]) << 16) | (((uint8_t)data_local[3]) << 24);
|
||||
+ const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data_local[4];
|
||||
+ const crypto::public_key &public_view_key = *(const crypto::public_key*)&data_local[4 + sizeof(crypto::public_key)];
|
||||
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||
if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key)
|
||||
{
|
||||
- THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account");
|
||||
+ THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + " are for a different account");
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(offset > m_transfers.size(), error::wallet_internal_error, "Offset larger than known outputs");
|
||||
|
||||
const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature);
|
||||
- THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size,
|
||||
- error::wallet_internal_error, std::string("Bad data size from file ") + filename);
|
||||
- size_t nki = (data.size() - headerlen) / record_size;
|
||||
+ THROW_WALLET_EXCEPTION_IF((data_local.size() - headerlen) % record_size,
|
||||
+ error::wallet_internal_error, std::string("Bad data size from file "));
|
||||
+ size_t nki = (data_local.size() - headerlen) / record_size;
|
||||
|
||||
std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
|
||||
ski.reserve(nki);
|
||||
for (size_t n = 0; n < nki; ++n)
|
||||
{
|
||||
- crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data[headerlen + n * record_size]);
|
||||
- crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data[headerlen + n * record_size + sizeof(crypto::key_image)]);
|
||||
+ crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data_local[headerlen + n * record_size]);
|
||||
+ crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data_local[headerlen + n * record_size + sizeof(crypto::key_image)]);
|
||||
|
||||
ski.push_back(std::make_pair(key_image, signature));
|
||||
}
|
||||
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
|
||||
index daad1e940..a752f15b9 100644
|
||||
--- a/src/wallet/wallet2.h
|
||||
+++ b/src/wallet/wallet2.h
|
||||
@@ -1112,6 +1112,7 @@ private:
|
||||
// locked & unlocked balance of given or current subaddress account
|
||||
uint64_t balance(uint32_t subaddr_index_major, const std::string& asset_type, bool strict) const;
|
||||
uint64_t unlocked_balance(uint32_t subaddr_index_major, const std::string& asset_type, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL);
|
||||
+ uint64_t view_only_balance(uint32_t index_major, const std::vector<crypto::key_image>& selected_inputs = {}, const std::string& asset_type = "SAL1");
|
||||
// locked & unlocked balance per subaddress of given or current subaddress account
|
||||
std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, const std::string& asset_type, bool strict) const;
|
||||
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, const std::string& asset_type, bool strict);
|
||||
@@ -1596,9 +1597,11 @@ private:
|
||||
std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> export_blockchain() const;
|
||||
void import_blockchain(const std::tuple<size_t, crypto::hash, std::vector<crypto::hash>> &bc);
|
||||
bool export_key_images(const std::string &filename, bool all = false) const;
|
||||
+ std::string export_key_images_str(bool all) const;
|
||||
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> export_key_images(bool all = false) const;
|
||||
uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true);
|
||||
uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent);
|
||||
+ uint64_t import_key_images_str(const std::string &data, uint64_t &spent, uint64_t &unspent);
|
||||
bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, boost::optional<std::unordered_set<size_t>> selected_transfers=boost::none);
|
||||
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
|
||||
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,606 @@
|
||||
From 904fe95204ba02d1a8c81fc46c1423ba1685c94f Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Wed, 26 Jun 2024 15:04:38 +0200
|
||||
Subject: [PATCH 06/14] add dummy device for ledger
|
||||
|
||||
---
|
||||
CMakeLists.txt | 6 +-
|
||||
src/device/CMakeLists.txt | 6 +-
|
||||
src/device/device.cpp | 10 ++-
|
||||
src/device/device.hpp | 12 +--
|
||||
src/device/device_io_dummy.cpp | 133 ++++++++++++++++++++++++++++++
|
||||
src/device/device_io_dummy.hpp | 74 +++++++++++++++++
|
||||
src/device/device_ledger.cpp | 6 +-
|
||||
src/device/device_ledger.hpp | 7 +-
|
||||
src/wallet/api/wallet.cpp | 94 +++++++++++++++++++++
|
||||
src/wallet/api/wallet.h | 18 ++++
|
||||
src/wallet/api/wallet2_api.h | 12 +++
|
||||
src/wallet/api/wallet_manager.cpp | 12 ++-
|
||||
12 files changed, 365 insertions(+), 25 deletions(-)
|
||||
create mode 100644 src/device/device_io_dummy.cpp
|
||||
create mode 100644 src/device/device_io_dummy.hpp
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index c73b813d8..5c0f31cb8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -692,8 +692,12 @@ include_directories(${LMDB_INCLUDE})
|
||||
include_directories(${LIBUNWIND_INCLUDE})
|
||||
link_directories(${LIBUNWIND_LIBRARY_DIRS})
|
||||
|
||||
+if (HIDAPI_DUMMY)
|
||||
+ add_definitions(-DHIDAPI_DUMMY)
|
||||
+endif()
|
||||
+
|
||||
# Final setup for hid
|
||||
-if (HIDAPI_FOUND)
|
||||
+if (HIDAPI_FOUND)
|
||||
message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
|
||||
add_definitions(-DHAVE_HIDAPI)
|
||||
include_directories(${HIDAPI_INCLUDE_DIR})
|
||||
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
|
||||
index e4f1159b5..14d398f87 100644
|
||||
--- a/src/device/CMakeLists.txt
|
||||
+++ b/src/device/CMakeLists.txt
|
||||
@@ -29,10 +29,11 @@
|
||||
set(device_sources
|
||||
device.cpp
|
||||
device_default.cpp
|
||||
+ device_io_dummy.cpp
|
||||
log.cpp
|
||||
)
|
||||
|
||||
-if(HIDAPI_FOUND)
|
||||
+if(HIDAPI_FOUND OR HIDAPI_DUMMY)
|
||||
set(device_sources
|
||||
${device_sources}
|
||||
device_ledger.cpp
|
||||
@@ -45,10 +46,11 @@ set(device_headers
|
||||
device_io.hpp
|
||||
device_default.hpp
|
||||
device_cold.hpp
|
||||
+ device_io_dummy.hpp
|
||||
log.hpp
|
||||
)
|
||||
|
||||
-if(HIDAPI_FOUND)
|
||||
+if(HIDAPI_FOUND OR HIDAPI_DUMMY)
|
||||
set(device_headers
|
||||
${device_headers}
|
||||
device_ledger.hpp
|
||||
diff --git a/src/device/device.cpp b/src/device/device.cpp
|
||||
index e6cd358b6..dd0701e0c 100644
|
||||
--- a/src/device/device.cpp
|
||||
+++ b/src/device/device.cpp
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "device.hpp"
|
||||
#include "device_default.hpp"
|
||||
-#ifdef WITH_DEVICE_LEDGER
|
||||
+#if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
|
||||
#include "device_ledger.hpp"
|
||||
#endif
|
||||
#include "misc_log_ex.h"
|
||||
@@ -57,7 +57,7 @@ namespace hw {
|
||||
|
||||
device_registry::device_registry(){
|
||||
hw::core::register_all(registry);
|
||||
- #ifdef WITH_DEVICE_LEDGER
|
||||
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
|
||||
hw::ledger::register_all(registry);
|
||||
#endif
|
||||
atexit(clear_device_registry);
|
||||
@@ -83,11 +83,13 @@ namespace hw {
|
||||
|
||||
auto device = registry.find(device_descriptor_lookup);
|
||||
if (device == registry.end()) {
|
||||
- MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: ");
|
||||
+ std::stringstream ss("Device not found in registry: '" + device_descriptor + "'. Known devices: ");
|
||||
+ MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: \n");
|
||||
for( const auto& sm_pair : registry ) {
|
||||
+ ss << "\n- " + sm_pair.first;
|
||||
MERROR(" - " << sm_pair.first);
|
||||
}
|
||||
- throw std::runtime_error("device not found: " + device_descriptor);
|
||||
+ throw std::runtime_error("device not found: " + device_descriptor + "\n" + ss.str());
|
||||
}
|
||||
return *device->second;
|
||||
}
|
||||
diff --git a/src/device/device.hpp b/src/device/device.hpp
|
||||
index 392703a24..ffd419779 100644
|
||||
--- a/src/device/device.hpp
|
||||
+++ b/src/device/device.hpp
|
||||
@@ -34,17 +34,7 @@
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "cryptonote_config.h"
|
||||
|
||||
-
|
||||
-#ifndef USE_DEVICE_LEDGER
|
||||
-#define USE_DEVICE_LEDGER 1
|
||||
-#endif
|
||||
-
|
||||
-#if !defined(HAVE_HIDAPI)
|
||||
-#undef USE_DEVICE_LEDGER
|
||||
-#define USE_DEVICE_LEDGER 0
|
||||
-#endif
|
||||
-
|
||||
-#if USE_DEVICE_LEDGER
|
||||
+#if defined(HAVE_HIDAPI) || defined(HIDAPI_DUMMY)
|
||||
#define WITH_DEVICE_LEDGER
|
||||
#endif
|
||||
|
||||
diff --git a/src/device/device_io_dummy.cpp b/src/device/device_io_dummy.cpp
|
||||
new file mode 100644
|
||||
index 000000000..edb4beea3
|
||||
--- /dev/null
|
||||
+++ b/src/device/device_io_dummy.cpp
|
||||
@@ -0,0 +1,133 @@
|
||||
+// Copyright (c) 2017-2022, The Monero Project
|
||||
+//
|
||||
+// All rights reserved.
|
||||
+//
|
||||
+// Redistribution and use in source and binary forms, with or without modification, are
|
||||
+// permitted provided that the following conditions are met:
|
||||
+//
|
||||
+// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
+// conditions and the following disclaimer.
|
||||
+//
|
||||
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
+// of conditions and the following disclaimer in the documentation and/or other
|
||||
+// materials provided with the distribution.
|
||||
+//
|
||||
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
+// used to endorse or promote products derived from this software without specific
|
||||
+// prior written permission.
|
||||
+//
|
||||
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+//
|
||||
+
|
||||
+// device_io_dummy
|
||||
+// Main goal of device_io_dummy is to emulate a hw::io::device_io without the need to actually
|
||||
+// connect a device.
|
||||
+// Many operating systems do not support giving raw USB access to a process (android), or don't
|
||||
+// support that at all (hi iOS), therefore other means of connection can be used, either USB
|
||||
+// abstraction provided by the OS (monerujo), or BLE (also monerujo).
|
||||
+// Monerujo implementation is written in Java, which makes it a nice fit for iOS, but makes the
|
||||
+// code extremely unportable, so for this reason the code in here is written in CPP.
|
||||
+// Data transport is made available in wallet2_api.h, so wallet developers can easily plug their
|
||||
+// own USB/BLE/other transport layer.
|
||||
+
|
||||
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
|
||||
+#include <boost/scope_exit.hpp>
|
||||
+#include "log.hpp"
|
||||
+#include "device_io_dummy.hpp"
|
||||
+#include "device_ledger.hpp"
|
||||
+
|
||||
+
|
||||
+bool hw::io::device_io_dummy::stateIsConnected = false;
|
||||
+unsigned char* hw::io::device_io_dummy::sendToDevice = {};
|
||||
+size_t hw::io::device_io_dummy::sendToDeviceLength = 0;
|
||||
+unsigned char* hw::io::device_io_dummy::receivedFromDevice = {};
|
||||
+size_t hw::io::device_io_dummy::receivedFromDeviceLength = 0;
|
||||
+bool hw::io::device_io_dummy::waitsForDeviceSend = false;
|
||||
+bool hw::io::device_io_dummy::waitsForDeviceReceive = false;
|
||||
+
|
||||
+namespace hw {
|
||||
+ namespace io {
|
||||
+
|
||||
+#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
+#define MONERO_DEFAULT_LOG_CATEGORY "device.io_dummy"
|
||||
+ device_io_dummy::device_io_dummy(int a, int b, int c, int d) {
|
||||
+ MDEBUG("device_io_dummy(a: " << a << ", b: " << b << ", c: " << c << ", d: " << d <<")");
|
||||
+ }
|
||||
+
|
||||
+ void device_io_dummy::init() {
|
||||
+ MDEBUG("init()");
|
||||
+ }
|
||||
+
|
||||
+ void device_io_dummy::connect(void *params) {
|
||||
+ MDEBUG("connect(" << params << ")");
|
||||
+ stateIsConnected = true;
|
||||
+ }
|
||||
+
|
||||
+ void device_io_dummy::connect(const std::vector<hw::io::hid_conn_params>& known_devices) {
|
||||
+ MDEBUG("connect([");
|
||||
+ for (const auto &item: known_devices) {
|
||||
+ MDEBUG("{ interface_number: " << item.interface_number);
|
||||
+ MDEBUG(" pid : " << item.pid);
|
||||
+ MDEBUG(" usage_page : " << item.usage_page);
|
||||
+ MDEBUG(" vid : " << item.vid << " },");
|
||||
+ }
|
||||
+ MDEBUG("])");
|
||||
+ stateIsConnected = true;
|
||||
+ }
|
||||
+
|
||||
+ bool device_io_dummy::connected() const {
|
||||
+ MDEBUG("connected()");
|
||||
+ return stateIsConnected;
|
||||
+ }
|
||||
+
|
||||
+ int device_io_dummy::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) {
|
||||
+ MDEBUG("exchange(): locking mutex");
|
||||
+ boost::unique_lock<boost::mutex> lock(mutex);
|
||||
+ sendToDevice = command;
|
||||
+ sendToDeviceLength = cmd_len;
|
||||
+ waitsForDeviceSend = true;
|
||||
+ waitsForDeviceReceive = true;
|
||||
+ MDEBUG("exchange(): waitsForDeviceSend");
|
||||
+ // NOTE: waitsForDeviceSend should be changed by external code
|
||||
+ while (waitsForDeviceSend) {
|
||||
+ usleep(1000);
|
||||
+ MDEBUG("exchange(): waitsForDeviceSend (still)");
|
||||
+ }
|
||||
+
|
||||
+ MDEBUG("exchange(): waitsForDeviceReceive");
|
||||
+ while (waitsForDeviceReceive) {
|
||||
+ usleep(1000);
|
||||
+ MDEBUG("exchange(): waitsForDeviceReceive (still)");
|
||||
+ }
|
||||
+
|
||||
+ if (receivedFromDeviceLength > max_resp_len) {
|
||||
+ MDEBUG("exchange(): receivedFromDeviceLength ("<<receivedFromDeviceLength<<") is larger than max_resp_len ("<<max_resp_len<<")");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ memset(response,0,max_resp_len);
|
||||
+ memcpy(response, receivedFromDevice, receivedFromDeviceLength);
|
||||
+ return receivedFromDeviceLength;
|
||||
+ }
|
||||
+
|
||||
+ void device_io_dummy::disconnect() {
|
||||
+ MDEBUG("disconnect()");
|
||||
+ }
|
||||
+
|
||||
+ void device_io_dummy::release() {
|
||||
+ MDEBUG("release()");
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
+#endif // HAVE_HIDAPI
|
||||
\ No newline at end of file
|
||||
diff --git a/src/device/device_io_dummy.hpp b/src/device/device_io_dummy.hpp
|
||||
new file mode 100644
|
||||
index 000000000..a1733616d
|
||||
--- /dev/null
|
||||
+++ b/src/device/device_io_dummy.hpp
|
||||
@@ -0,0 +1,74 @@
|
||||
+// Copyright (c) 2017-2022, The Monero Project
|
||||
+//
|
||||
+// All rights reserved.
|
||||
+//
|
||||
+// Redistribution and use in source and binary forms, with or without modification, are
|
||||
+// permitted provided that the following conditions are met:
|
||||
+//
|
||||
+// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
+// conditions and the following disclaimer.
|
||||
+//
|
||||
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
+// of conditions and the following disclaimer in the documentation and/or other
|
||||
+// materials provided with the distribution.
|
||||
+//
|
||||
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
+// used to endorse or promote products derived from this software without specific
|
||||
+// prior written permission.
|
||||
+//
|
||||
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+//
|
||||
+#ifdef HIDAPI_DUMMY
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "device_io.hpp"
|
||||
+#include "device_io_hid.hpp"
|
||||
+
|
||||
+namespace hw {
|
||||
+ namespace io {
|
||||
+ struct hid_conn_params {
|
||||
+ unsigned int vid;
|
||||
+ unsigned int pid;
|
||||
+ int interface_number;
|
||||
+ unsigned short usage_page;
|
||||
+ };
|
||||
+ class device_io_dummy : device_io {
|
||||
+ private:
|
||||
+ boost::mutex mutex;
|
||||
+
|
||||
+ public:
|
||||
+ static bool stateIsConnected;
|
||||
+ static unsigned char* sendToDevice;
|
||||
+ static size_t sendToDeviceLength;
|
||||
+ static unsigned char* receivedFromDevice;
|
||||
+ static size_t receivedFromDeviceLength;
|
||||
+ static bool waitsForDeviceSend;
|
||||
+ static bool waitsForDeviceReceive;
|
||||
+
|
||||
+ device_io_dummy() = default;
|
||||
+ device_io_dummy(int a, int b, int c, int d);
|
||||
+ ~device_io_dummy() = default;
|
||||
+
|
||||
+ void init();
|
||||
+ void release();
|
||||
+
|
||||
+ void connect(void *parms);
|
||||
+ void connect(const std::vector<hw::io::hid_conn_params>& known_devices);
|
||||
+ void disconnect();
|
||||
+ bool connected() const;
|
||||
+
|
||||
+ int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input);
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+#endif // HAVE_HIDAPI
|
||||
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
|
||||
index bb5b6f497..046201a1e 100644
|
||||
--- a/src/device/device_ledger.cpp
|
||||
+++ b/src/device/device_ledger.cpp
|
||||
@@ -41,7 +41,7 @@ namespace hw {
|
||||
|
||||
namespace ledger {
|
||||
|
||||
- #ifdef WITH_DEVICE_LEDGER
|
||||
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
|
||||
|
||||
namespace {
|
||||
bool apdu_verbose =true;
|
||||
@@ -300,7 +300,7 @@ namespace hw {
|
||||
|
||||
device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) {
|
||||
this->id = device_id++;
|
||||
- this->reset_buffer();
|
||||
+ this->reset_buffer();
|
||||
this->mode = NONE;
|
||||
this->has_view_key = false;
|
||||
this->tx_in_progress = false;
|
||||
@@ -533,7 +533,9 @@ namespace hw {
|
||||
|
||||
bool device_ledger::connect(void) {
|
||||
this->disconnect();
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
hw_device.connect(known_devices);
|
||||
+ #endif
|
||||
this->reset();
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
cryptonote::account_public_address pubkey;
|
||||
diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
|
||||
index 03058c4f1..39454ca6d 100644
|
||||
--- a/src/device/device_ledger.hpp
|
||||
+++ b/src/device/device_ledger.hpp
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "device.hpp"
|
||||
#include "log.hpp"
|
||||
#include "device_io_hid.hpp"
|
||||
+#include "device_io_dummy.hpp"
|
||||
#include <mutex>
|
||||
|
||||
namespace hw {
|
||||
@@ -56,7 +57,7 @@ namespace hw {
|
||||
|
||||
void register_all(std::map<std::string, std::unique_ptr<device>> ®istry);
|
||||
|
||||
- #ifdef WITH_DEVICE_LEDGER
|
||||
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
|
||||
|
||||
// Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
|
||||
#define SW_OK 0x9000
|
||||
@@ -143,7 +144,11 @@ namespace hw {
|
||||
mutable std::mutex command_locker;
|
||||
|
||||
//IO
|
||||
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
|
||||
+ hw::io::device_io_dummy hw_device;
|
||||
+#else
|
||||
hw::io::device_io_hid hw_device;
|
||||
+#endif
|
||||
unsigned int length_send;
|
||||
unsigned char buffer_send[BUFFER_SEND_SIZE];
|
||||
unsigned int length_recv;
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index 3fcd6f332..25ade04a7 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -48,6 +48,9 @@
|
||||
#include <boost/locale.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "bc-ur/src/bc-ur.hpp"
|
||||
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
|
||||
+#include "device/device_io_dummy.hpp"
|
||||
+#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace cryptonote;
|
||||
@@ -3186,6 +3189,97 @@ uint64_t WalletImpl::getBytesSent()
|
||||
return m_wallet->get_bytes_sent();
|
||||
}
|
||||
|
||||
+
|
||||
+// HIDAPI_DUMMY
|
||||
+bool WalletImpl::getStateIsConnected() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return false;
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::stateIsConnected;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+unsigned char* WalletImpl::getSendToDevice() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return {};
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::sendToDevice;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+size_t WalletImpl::getSendToDeviceLength() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return -1;
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::sendToDeviceLength;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+unsigned char* WalletImpl::getReceivedFromDevice() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return {};
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::receivedFromDevice;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+size_t WalletImpl::getReceivedFromDeviceLength() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return -1;
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::receivedFromDeviceLength;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+bool WalletImpl::getWaitsForDeviceSend() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return false;
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::receivedFromDeviceLength;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+bool WalletImpl::getWaitsForDeviceReceive() {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return false;
|
||||
+ #else
|
||||
+ return hw::io::device_io_dummy::waitsForDeviceReceive;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+void WalletImpl::setDeviceReceivedData(unsigned char* data, size_t len) {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return;
|
||||
+ #else
|
||||
+ hw::io::device_io_dummy::receivedFromDevice = static_cast<unsigned char *>(malloc(len));
|
||||
+ hw::io::device_io_dummy::receivedFromDeviceLength = len;
|
||||
+ memset(hw::io::device_io_dummy::receivedFromDevice, 0, len);
|
||||
+ memcpy(hw::io::device_io_dummy::receivedFromDevice, data, len);
|
||||
+ hw::io::device_io_dummy::waitsForDeviceReceive = false;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
+void WalletImpl::setDeviceSendData(unsigned char* data, size_t len) {
|
||||
+ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
|
||||
+ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
|
||||
+ return;
|
||||
+ #else
|
||||
+ hw::io::device_io_dummy::sendToDevice = static_cast<unsigned char *>(malloc(len));
|
||||
+ hw::io::device_io_dummy::sendToDeviceLength = len;
|
||||
+ memset(hw::io::device_io_dummy::sendToDevice, 0, len);
|
||||
+ memcpy(hw::io::device_io_dummy::sendToDevice, data, len);
|
||||
+ hw::io::device_io_dummy::waitsForDeviceSend = false;
|
||||
+ #endif
|
||||
+}
|
||||
+
|
||||
YieldInfo * WalletImpl::getYieldInfo()
|
||||
{
|
||||
auto yi = new YieldInfoImpl(*this);
|
||||
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
|
||||
index edf8bb8ce..4e9c21ecb 100644
|
||||
--- a/src/wallet/api/wallet.h
|
||||
+++ b/src/wallet/api/wallet.h
|
||||
@@ -301,6 +301,24 @@ private:
|
||||
// cache connection status to avoid unnecessary RPC calls
|
||||
mutable std::atomic<bool> m_is_connected;
|
||||
boost::optional<epee::net_utils::http::login> m_daemon_login{};
|
||||
+
|
||||
+ bool getStateIsConnected();
|
||||
+
|
||||
+ unsigned char *getSendToDevice();
|
||||
+
|
||||
+ size_t getSendToDeviceLength();
|
||||
+
|
||||
+ unsigned char *getReceivedFromDevice();
|
||||
+
|
||||
+ size_t getReceivedFromDeviceLength();
|
||||
+
|
||||
+ bool getWaitsForDeviceSend();
|
||||
+
|
||||
+ bool getWaitsForDeviceReceive();
|
||||
+
|
||||
+ void setDeviceReceivedData(unsigned char *data, size_t len);
|
||||
+
|
||||
+ void setDeviceSendData(unsigned char *data, size_t len);
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
|
||||
index 764adbfbf..53ec4abfc 100644
|
||||
--- a/src/wallet/api/wallet2_api.h
|
||||
+++ b/src/wallet/api/wallet2_api.h
|
||||
@@ -1150,6 +1150,18 @@ struct Wallet
|
||||
|
||||
//! get bytes sent
|
||||
virtual uint64_t getBytesSent() = 0;
|
||||
+
|
||||
+ // HIDAPI_DUMMY
|
||||
+ virtual bool getStateIsConnected() = 0;
|
||||
+ virtual unsigned char* getSendToDevice() = 0;
|
||||
+ virtual size_t getSendToDeviceLength() = 0;
|
||||
+ virtual unsigned char* getReceivedFromDevice() = 0;
|
||||
+ virtual size_t getReceivedFromDeviceLength() = 0;
|
||||
+ virtual bool getWaitsForDeviceSend() = 0;
|
||||
+ virtual bool getWaitsForDeviceReceive() = 0;
|
||||
+
|
||||
+ virtual void setDeviceReceivedData(unsigned char* data, size_t len) = 0;
|
||||
+ virtual void setDeviceSendData(unsigned char* data, size_t len) = 0;
|
||||
|
||||
//! get yield information
|
||||
virtual YieldInfo * getYieldInfo() = 0;
|
||||
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
|
||||
index e81b8f83a..277be6ac9 100644
|
||||
--- a/src/wallet/api/wallet_manager.cpp
|
||||
+++ b/src/wallet/api/wallet_manager.cpp
|
||||
@@ -188,10 +188,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name,
|
||||
|
||||
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;
|
||||
+ try {
|
||||
+ 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;
|
||||
+ } catch (...) {
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
From 0ba0339b11d8f7f66f2d5cd27075d438a76351b4 Mon Sep 17 00:00:00 2001
|
||||
From: M <m@cakewallet.com>
|
||||
Date: Fri, 21 Apr 2023 15:43:47 -0400
|
||||
Subject: [PATCH 09/14] Add hex encoding and tx key getter for
|
||||
PendingTransction in wallet api.
|
||||
|
||||
---
|
||||
src/wallet/api/pending_transaction.cpp | 16 ++++++++++++++++
|
||||
src/wallet/api/pending_transaction.h | 2 ++
|
||||
src/wallet/api/wallet2_api.h | 2 ++
|
||||
3 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
|
||||
index 9c3c26ee5..1f714d229 100644
|
||||
--- a/src/wallet/api/pending_transaction.cpp
|
||||
+++ b/src/wallet/api/pending_transaction.cpp
|
||||
@@ -80,6 +80,22 @@ std::vector<std::string> PendingTransactionImpl::txid() const
|
||||
return txid;
|
||||
}
|
||||
|
||||
+std::vector<std::string> PendingTransactionImpl::hex() const
|
||||
+{
|
||||
+ std::vector<std::string> hexs;
|
||||
+ for (const auto &pt: m_pending_tx)
|
||||
+ hexs.push_back(epee::string_tools::buff_to_hex_nodelimer(cryptonote::tx_to_blob(pt.tx)));
|
||||
+ return hexs;
|
||||
+}
|
||||
+
|
||||
+std::vector<std::string> PendingTransactionImpl::txKey() const
|
||||
+{
|
||||
+ std::vector<std::string> keys;
|
||||
+ for (const auto& pt: m_pending_tx)
|
||||
+ keys.push_back(epee::string_tools::pod_to_hex(pt.tx_key));
|
||||
+ return keys;
|
||||
+}
|
||||
+
|
||||
bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
|
||||
{
|
||||
|
||||
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
|
||||
index 403bfe281..0cc6c58e9 100644
|
||||
--- a/src/wallet/api/pending_transaction.h
|
||||
+++ b/src/wallet/api/pending_transaction.h
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
std::string multisigSignData() override;
|
||||
void signMultisigTx() override;
|
||||
std::vector<std::string> signersKeys() const override;
|
||||
+ std::vector<std::string> hex() const override;
|
||||
+ std::vector<std::string> txKey() const override;
|
||||
|
||||
private:
|
||||
friend class WalletImpl;
|
||||
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
|
||||
index 013b5bcba..f421fdc05 100644
|
||||
--- a/src/wallet/api/wallet2_api.h
|
||||
+++ b/src/wallet/api/wallet2_api.h
|
||||
@@ -127,6 +127,8 @@ struct PendingTransaction
|
||||
* @return vector of base58-encoded signers' public keys
|
||||
*/
|
||||
virtual std::vector<std::string> signersKeys() const = 0;
|
||||
+ virtual std::vector<std::string> hex() const = 0;
|
||||
+ virtual std::vector<std::string> txKey() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
From cb02355313d504e6a44f8f70b8eb2be64167ffd4 Mon Sep 17 00:00:00 2001
|
||||
From: Konstantin Ullrich <konstantinullrich12@gmail.com>
|
||||
Date: Wed, 11 Oct 2023 16:47:59 +0200
|
||||
Subject: [PATCH 10/14] Add recoverDeterministicWalletFromSpendKey
|
||||
|
||||
This function is used by Cake Wallet to enable polyseed (dart implementation)
|
||||
support.
|
||||
|
||||
Sourced from the following commit:
|
||||
https://github.com/cake-tech/monero/commit/cb6fb5ab218878702ed151c0e3d5d68eb2732788
|
||||
|
||||
Co-authored-by: Godwin Asuquo <godilite@gmail.com>
|
||||
---
|
||||
src/wallet/api/wallet.cpp | 29 +++++++++++++++++++++++++++++
|
||||
src/wallet/api/wallet.h | 4 ++++
|
||||
src/wallet/api/wallet2_api.h | 19 +++++++++++++++++++
|
||||
src/wallet/api/wallet_manager.cpp | 16 ++++++++++++++++
|
||||
src/wallet/api/wallet_manager.h | 7 +++++++
|
||||
5 files changed, 75 insertions(+)
|
||||
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index 933cc2531..d8fe108b4 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -824,6 +824,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
|
||||
return status() == Status_Ok;
|
||||
}
|
||||
|
||||
+bool WalletImpl::recoverDeterministicWalletFromSpendKey(const std::string &path, const std::string &password, const std::string &language, const std::string &spendkey_string)
|
||||
+{
|
||||
+ clearStatus();
|
||||
+ m_errorString.clear();
|
||||
+
|
||||
+ m_recoveringFromSeed = true;
|
||||
+ m_recoveringFromDevice = false;
|
||||
+
|
||||
+ // parse spend key
|
||||
+ crypto::secret_key spendkey;
|
||||
+ if (!spendkey_string.empty()) {
|
||||
+ cryptonote::blobdata spendkey_data;
|
||||
+ if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key))
|
||||
+ {
|
||||
+ setStatusError(tr("failed to parse secret spend key"));
|
||||
+ return false;
|
||||
+ }
|
||||
+ spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ m_wallet->generate(path, password, spendkey, true, false);
|
||||
+ setSeedLanguage(language);
|
||||
+ } catch (const std::exception &e) {
|
||||
+ setStatusCritical(e.what());
|
||||
+ }
|
||||
+ return status() == Status_Ok;
|
||||
+}
|
||||
+
|
||||
bool WalletImpl::close(bool store)
|
||||
{
|
||||
|
||||
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
|
||||
index a82f270e4..9e1fbb40b 100644
|
||||
--- a/src/wallet/api/wallet.h
|
||||
+++ b/src/wallet/api/wallet.h
|
||||
@@ -77,6 +77,10 @@ public:
|
||||
const std::string &address_string,
|
||||
const std::string &viewkey_string,
|
||||
const std::string &spendkey_string = "");
|
||||
+ bool recoverDeterministicWalletFromSpendKey(const std::string &path,
|
||||
+ const std::string &password,
|
||||
+ const std::string &language,
|
||||
+ const std::string &spendkey_string);
|
||||
bool recoverFromDevice(const std::string &path,
|
||||
const std::string &password,
|
||||
const std::string &device_name);
|
||||
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
|
||||
index f421fdc05..c8d6bb179 100644
|
||||
--- a/src/wallet/api/wallet2_api.h
|
||||
+++ b/src/wallet/api/wallet2_api.h
|
||||
@@ -1323,6 +1323,25 @@ struct WalletManager
|
||||
return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
|
||||
}
|
||||
|
||||
+ /*!
|
||||
+ * \brief recover deterministic wallet from spend key.
|
||||
+ * \param path Name of wallet file to be created
|
||||
+ * \param password Password of wallet file
|
||||
+ * \param language language
|
||||
+ * \param nettype Network type
|
||||
+ * \param restoreHeight restore from start height
|
||||
+ * \param spendKeyString spend key
|
||||
+ * \param kdf_rounds Number of rounds for key derivation function
|
||||
+ * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
||||
+ */
|
||||
+ virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path,
|
||||
+ const std::string &password,
|
||||
+ const std::string &language,
|
||||
+ NetworkType nettype,
|
||||
+ uint64_t restoreHeight,
|
||||
+ const std::string &spendKeyString,
|
||||
+ uint64_t kdf_rounds = 1) = 0;
|
||||
+
|
||||
/*!
|
||||
* \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead
|
||||
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
|
||||
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
|
||||
index da2056d8a..c200f52ae 100644
|
||||
--- a/src/wallet/api/wallet_manager.cpp
|
||||
+++ b/src/wallet/api/wallet_manager.cpp
|
||||
@@ -127,6 +127,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
|
||||
return wallet;
|
||||
}
|
||||
|
||||
+Wallet *WalletManagerImpl::createDeterministicWalletFromSpendKey(const std::string &path,
|
||||
+ const std::string &password,
|
||||
+ const std::string &language,
|
||||
+ NetworkType nettype,
|
||||
+ uint64_t restoreHeight,
|
||||
+ const std::string &spendkey_string,
|
||||
+ uint64_t kdf_rounds)
|
||||
+{
|
||||
+ WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
|
||||
+ if(restoreHeight > 0){
|
||||
+ wallet->setRefreshFromBlockHeight(restoreHeight);
|
||||
+ }
|
||||
+ wallet->recoverDeterministicWalletFromSpendKey(path, password, language, spendkey_string);
|
||||
+ return wallet;
|
||||
+}
|
||||
+
|
||||
Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
|
||||
const std::string &password,
|
||||
NetworkType nettype,
|
||||
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
|
||||
index 28fcd36c9..be3ff8184 100644
|
||||
--- a/src/wallet/api/wallet_manager.h
|
||||
+++ b/src/wallet/api/wallet_manager.h
|
||||
@@ -67,6 +67,13 @@ public:
|
||||
const std::string &addressString,
|
||||
const std::string &viewKeyString,
|
||||
const std::string &spendKeyString = "") override;
|
||||
+ virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path,
|
||||
+ const std::string &password,
|
||||
+ const std::string &language,
|
||||
+ NetworkType nettype,
|
||||
+ uint64_t restoreHeight,
|
||||
+ const std::string &spendkey_string,
|
||||
+ uint64_t kdf_rounds) override;
|
||||
virtual Wallet * createWalletFromDevice(const std::string &path,
|
||||
const std::string &password,
|
||||
NetworkType nettype,
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 846d3f60093add6653d9102d841288066fc08311 Mon Sep 17 00:00:00 2001
|
||||
From: cyan <cyjan@mrcyjanek.net>
|
||||
Date: Thu, 7 Nov 2024 16:46:24 +0000
|
||||
Subject: [PATCH 11/14] add monero submodule support
|
||||
|
||||
---
|
||||
CMakeLists.txt | 6 +++---
|
||||
cmake/CheckLinkerFlag.cmake | 2 +-
|
||||
src/wallet/wallet_rpc_server.cpp | 2 +-
|
||||
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index f0630ef9b..9406e57b4 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -226,9 +226,9 @@ function(forbid_undefined_symbols)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(test)
|
||||
option(EXPECT_SUCCESS "" ON)
|
||||
-file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
|
||||
+file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
|
||||
if (EXPECT_SUCCESS)
|
||||
- file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
|
||||
+ file(APPEND "${CMAKE_CURRENT_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
|
||||
endif()
|
||||
add_library(l0 SHARED incorrect_source.cpp)
|
||||
add_library(l1 MODULE incorrect_source.cpp)
|
||||
@@ -390,7 +390,7 @@ else()
|
||||
endif()
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0
|
||||
- "${CMAKE_SOURCE_DIR}/cmake")
|
||||
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
if (NOT DEFINED ENV{DEVELOPER_LOCAL_TOOLS})
|
||||
message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)")
|
||||
diff --git a/cmake/CheckLinkerFlag.cmake b/cmake/CheckLinkerFlag.cmake
|
||||
index 7ecf5f610..89fb9d167 100644
|
||||
--- a/cmake/CheckLinkerFlag.cmake
|
||||
+++ b/cmake/CheckLinkerFlag.cmake
|
||||
@@ -6,7 +6,7 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
|
||||
message(STATUS "Looking for ${flag} linker flag")
|
||||
endif()
|
||||
|
||||
- set(_cle_source ${CMAKE_SOURCE_DIR}/cmake/CheckLinkerFlag.c)
|
||||
+ set(_cle_source ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CheckLinkerFlag.c)
|
||||
|
||||
set(saved_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
|
||||
set(CMAKE_C_FLAGS "${flag}")
|
||||
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
|
||||
index 3188c88db..9fbdb3c05 100644
|
||||
--- a/src/wallet/wallet_rpc_server.cpp
|
||||
+++ b/src/wallet/wallet_rpc_server.cpp
|
||||
@@ -1286,7 +1286,7 @@ namespace tools
|
||||
{
|
||||
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
- std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, req.source_asset, req.dest_asset, type, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs);
|
||||
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, req.source_asset, req.dest_asset, type, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, {}, req.subtract_fee_from_outputs);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
From 53cc0482e55a39b5dbf2261fea11fcb160778800 Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Thu, 21 Nov 2024 06:05:03 -0500
|
||||
Subject: [PATCH 12/14] fix iOS depends build
|
||||
|
||||
---
|
||||
CMakeLists.txt | 4 ----
|
||||
src/checkpoints/CMakeLists.txt | 6 +++++-
|
||||
src/cryptonote_basic/CMakeLists.txt | 6 +++++-
|
||||
src/cryptonote_basic/miner.cpp | 8 ++++----
|
||||
4 files changed, 14 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 9406e57b4..1eac121db 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -39,10 +39,6 @@ include(CheckLibraryExists)
|
||||
endif()
|
||||
include(FindPythonInterp)
|
||||
|
||||
-if (IOS)
|
||||
- INCLUDE(CmakeLists_IOS.txt)
|
||||
-endif()
|
||||
-
|
||||
project(salvium)
|
||||
|
||||
option (USE_CCACHE "Use ccache if a usable instance is found" ON)
|
||||
diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt
|
||||
index 665441f62..841df3256 100644
|
||||
--- a/src/checkpoints/CMakeLists.txt
|
||||
+++ b/src/checkpoints/CMakeLists.txt
|
||||
@@ -28,7 +28,11 @@
|
||||
|
||||
if(APPLE)
|
||||
if(DEPENDS)
|
||||
- list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
|
||||
+ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
|
||||
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
+ else()
|
||||
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
|
||||
+ endif()
|
||||
else()
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
mark_as_advanced(IOKIT_LIBRARY)
|
||||
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
|
||||
index 414936a05..81c81767f 100644
|
||||
--- a/src/cryptonote_basic/CMakeLists.txt
|
||||
+++ b/src/cryptonote_basic/CMakeLists.txt
|
||||
@@ -28,7 +28,11 @@
|
||||
|
||||
if(APPLE)
|
||||
if(DEPENDS)
|
||||
- list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
|
||||
+ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
|
||||
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
+ else()
|
||||
+ list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
|
||||
+ endif()
|
||||
else()
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
mark_as_advanced(IOKIT_LIBRARY)
|
||||
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
|
||||
index 71b8f78cc..0f53f024e 100644
|
||||
--- a/src/cryptonote_basic/miner.cpp
|
||||
+++ b/src/cryptonote_basic/miner.cpp
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "boost/logic/tribool.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
-#ifdef __APPLE__
|
||||
+#if defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
|
||||
#include <sys/times.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/ps/IOPSKeys.h>
|
||||
@@ -883,7 +883,7 @@ namespace cryptonote
|
||||
|
||||
return true;
|
||||
|
||||
- #elif defined(__APPLE__)
|
||||
+ #elif defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
|
||||
|
||||
mach_msg_type_number_t count;
|
||||
kern_return_t status;
|
||||
@@ -949,7 +949,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
|
||||
- #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
+ #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || (defined(__APPLE__) && !defined(TARGET_OS_IPHONE)) || defined(__FreeBSD__)
|
||||
|
||||
struct tms tms;
|
||||
if ( times(&tms) != (clock_t)-1 )
|
||||
@@ -978,7 +978,7 @@ namespace cryptonote
|
||||
return boost::logic::tribool(power_status.ACLineStatus != 1);
|
||||
}
|
||||
|
||||
- #elif defined(__APPLE__)
|
||||
+ #elif defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
|
||||
|
||||
#if TARGET_OS_MAC && (!defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)
|
||||
return boost::logic::tribool(IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited);
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From 1eacd30724559749be5adeb31d763f44c3f221f9 Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Mon, 18 Nov 2024 10:57:37 -0500
|
||||
Subject: [PATCH 13/14] include locale only when targeting WIN32
|
||||
|
||||
|
||||
---
|
||||
src/wallet/api/wallet.cpp | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletion(-)
|
||||
|
||||
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
|
||||
index d8fe108b4..e3e838b13 100644
|
||||
--- a/src/wallet/api/wallet.cpp
|
||||
+++ b/src/wallet/api/wallet.cpp
|
||||
@@ -46,7 +46,9 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
+#ifdef WIN32
|
||||
#include <boost/locale.hpp>
|
||||
+#endif
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "bc-ur/src/bc-ur.hpp"
|
||||
#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 2d31234e859bff817d30d91b21d9412375668aae Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Wed, 29 Jan 2025 16:13:28 +0100
|
||||
Subject: [PATCH 14/14] change earliest fork height message
|
||||
|
||||
---
|
||||
src/wallet/wallet2.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
|
||||
index 8720e18b1..69da11d9c 100644
|
||||
--- a/src/wallet/wallet2.cpp
|
||||
+++ b/src/wallet/wallet2.cpp
|
||||
@@ -12365,7 +12365,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks)
|
||||
boost::optional<std::string> result = m_node_rpc_proxy.get_height(height);
|
||||
THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get height");
|
||||
result = m_node_rpc_proxy.get_earliest_height(version, earliest_height);
|
||||
- THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height");
|
||||
+ THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Failed to get earliest fork height. Please check your connection and/or switch node you are connected to currently.");
|
||||
|
||||
bool close_enough = (int64_t)height >= (int64_t)earliest_height - early_blocks && earliest_height != std::numeric_limits<uint64_t>::max(); // start using the rules that many blocks beforehand
|
||||
if (close_enough)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
From 71cf45cfbd571ec58e8b2a1d408ff74804bf7e1d Mon Sep 17 00:00:00 2001
|
||||
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
|
||||
Date: Thu, 20 Feb 2025 08:36:28 +0100
|
||||
Subject: [PATCH] remove trivially_copyable assert
|
||||
|
||||
---
|
||||
contrib/epee/include/span.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h
|
||||
index 01dc387d6..2ad733a2f 100644
|
||||
--- a/contrib/epee/include/span.h
|
||||
+++ b/contrib/epee/include/span.h
|
||||
@@ -162,7 +162,6 @@ namespace epee
|
||||
{
|
||||
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
|
||||
static_assert(std::is_standard_layout<T>(), "type must have standard layout");
|
||||
- static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
|
||||
static_assert(alignof(T) == 1, "type may have padding");
|
||||
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
||||
Submodule
+1
Submodule salvium added at 1f49c178ee
@@ -0,0 +1,179 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(wallet2_api_c)
|
||||
message(STATUS ABI_INFO = ${HOST_ABI})
|
||||
|
||||
set(MD_LIBRARY "")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-lto")
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-w64-mingw32")
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(CMAKE_LINKER "x86_64-w64-mingw32-ld")
|
||||
set(TARGET "x86_64-w64-mingw32")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lssp")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lssp")
|
||||
elseif(${HOST_ABI} STREQUAL "i686-w64-mingw32")
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(CMAKE_LINKER "i686-w64-mingw32-ld")
|
||||
set(TARGET "i686-w64-mingw32")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lssp")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lssp")
|
||||
elseif(${HOST_ABI} STREQUAL "host-apple-ios" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-apple-ios")
|
||||
set(CMAKE_SYSTEM_NAME iOS)
|
||||
elseif(${HOST_ABI} STREQUAL "host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
endif()
|
||||
|
||||
if (${HOST_ABI} STREQUAL "host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
|
||||
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE )
|
||||
if (NOT ${ARCHITECTURE} STREQUAL arm64)
|
||||
set(CMAKE_OSX_ARCHITECTURES x86_64)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "i686-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "armv7a-linux-androideabi")
|
||||
add_link_options(-stdlib=libc++ -static-libstdc++)
|
||||
set(EXTRA_LIBS_ANDROID log)
|
||||
endif()
|
||||
|
||||
add_library( wallet2_api_c
|
||||
SHARED
|
||||
src/main/cpp/helpers.cpp
|
||||
src/main/cpp/wallet2_api_c.cpp )
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "i686-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-linux-android" OR
|
||||
${HOST_ABI} STREQUAL "armv7a-linux-androideabi")
|
||||
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-z,noexecstack")
|
||||
endif()
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-linux-gnu" OR
|
||||
${HOST_ABI} STREQUAL "i686-linux-gnu" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-linux-gnu" OR
|
||||
${HOST_ABI} STREQUAL "armv7a-linux-gnu")
|
||||
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-z,noexecstack")
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
|
||||
|
||||
|
||||
set(MONERO_DIR ${CMAKE_SOURCE_DIR}/../${MONERO_FLAVOR})
|
||||
set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../contrib/depends/${HOST_ABI})
|
||||
|
||||
if (${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11")
|
||||
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" "-framework Cocoa" hidapi)
|
||||
# set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks")
|
||||
elseif(${HOST_ABI} STREQUAL "host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR
|
||||
${HOST_ABI} STREQUAL "aarch64-host-apple-darwin")
|
||||
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" "-framework Cocoa" apple_nghttp2)
|
||||
elseif(${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
|
||||
set(EXTRA_LIBS_APPLE "-framework IOKit" "-framework CoreFoundation" iconv )
|
||||
endif()
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-w64-mingw32" OR ${HOST_ABI} STREQUAL "i686-w64-mingw32")
|
||||
target_link_options(wallet2_api_c PRIVATE -static-libgcc -static-libstdc++)
|
||||
endif()
|
||||
|
||||
if(${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" OR ${HOST_ABI} STREQUAL "host-apple-darwin" OR ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "arm64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
|
||||
set_target_properties(wallet2_api_c PROPERTIES SUFFIX ".dylib")
|
||||
|
||||
set_target_properties(wallet2_api_c PROPERTIES NO_SONAME 1)
|
||||
endif()
|
||||
|
||||
if (${MONERO_FLAVOR} STREQUAL "monero")
|
||||
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_MONERO)
|
||||
set(BCUR_ENABLED bc-ur)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
|
||||
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_WOWNERO)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "zano")
|
||||
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_ZANO)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
|
||||
target_compile_definitions(wallet2_api_c PRIVATE FLAVOR_SALVIUM)
|
||||
set(BCUR_ENABLED bc-ur)
|
||||
endif()
|
||||
|
||||
if(NOT ${HOST_ABI} STREQUAL "x86_64-apple-darwin11" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "x86_64-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" AND NOT ${HOST_ABI} STREQUAL "host-apple-ios" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-ios" AND NOT ${HOST_ABI} STREQUAL "aarch64-apple-iossimulator" AND NOT ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
|
||||
set_target_properties(wallet2_api_c PROPERTIES LINK_FLAGS "-Wl,--exclude-libs,ALL")
|
||||
endif()
|
||||
|
||||
if (${MONERO_FLAVOR} STREQUAL "zano")
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/build/${HOST_ABI}/zano_build/contrib/zlib
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory("${CMAKE_SOURCE_DIR}/../${MONERO_FLAVOR}" ${CMAKE_BINARY_DIR}/${MONERO_FLAVOR}_build EXCLUDE_FROM_ALL)
|
||||
if(${HOST_ABI} STREQUAL "x86_64-apple-darwin11" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin11" OR ${HOST_ABI} STREQUAL "x86_64-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-darwin" OR ${HOST_ABI} STREQUAL "x86_64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "aarch64-host-apple-darwin" OR ${HOST_ABI} STREQUAL "host-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-ios" OR ${HOST_ABI} STREQUAL "aarch64-apple-iossimulator" OR ${HOST_ABI} STREQUAL "x86_64-apple-iossimulator")
|
||||
if (${MONERO_FLAVOR} STREQUAL "monero")
|
||||
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/monero_libwallet2_api_c.exp)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
|
||||
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/wownero_libwallet2_api_c.exp)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "zano")
|
||||
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/zano_libwallet2_api_c.exp)
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
|
||||
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/salvium_libwallet2_api_c.exp)
|
||||
endif()
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${EXPORTED_SYMBOLS_FILE}")
|
||||
set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS ${EXPORTED_SYMBOLS_FILE})
|
||||
endif()
|
||||
|
||||
if (${MONERO_FLAVOR} STREQUAL "monero")
|
||||
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "wownero")
|
||||
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "zano")
|
||||
find_package(Boost 1.71 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
set(WALLET_TARGETS
|
||||
wallet
|
||||
general
|
||||
tor-connect
|
||||
crypto
|
||||
currency_core
|
||||
common
|
||||
zlibstatic
|
||||
|
||||
${Boost_LIBRARIES}
|
||||
${OpenSSL_LIBRARIES})
|
||||
elseif(${MONERO_FLAVOR} STREQUAL "salvium")
|
||||
set(WALLET_TARGETS wallet_api ${wallet_api_LIB_DEPENDS}) # wallet_api_LIB_DEPENDS
|
||||
endif()
|
||||
|
||||
if(${MONERO_FLAVOR} STREQUAL "wownero")
|
||||
add_subdirectory(wownero-seed EXCLUDE_FROM_ALL)
|
||||
set(EXTRA_LIBS_WOWNEROSEED wownero-seed)
|
||||
endif()
|
||||
|
||||
#get_cmake_property(_variableNames VARIABLES)
|
||||
#list (SORT _variableNames)
|
||||
#foreach (_variableName ${_variableNames})
|
||||
# message(STATUS "${_variableName}=${${_variableName}}")
|
||||
#endforeach()
|
||||
#message(SEND_ERROR "${Boost_LIBRARIES}")
|
||||
#message(SEND_ERROR "${WALLET_TARGETS}
|
||||
# ${EXTRA_LIBS_WOWNEROSEED}
|
||||
# ${EXTRA_LIBS_ANDROID}")
|
||||
|
||||
target_link_libraries( wallet2_api_c
|
||||
|
||||
${WALLET_TARGETS}
|
||||
${EXTRA_LIBS_WOWNEROSEED}
|
||||
${EXTRA_LIBS_ANDROID}
|
||||
)
|
||||
@@ -0,0 +1,308 @@
|
||||
_SALVIUM_PendingTransaction_status
|
||||
_SALVIUM_PendingTransaction_errorString
|
||||
_SALVIUM_PendingTransaction_commit
|
||||
_SALVIUM_PendingTransaction_commitUR
|
||||
_SALVIUM_PendingTransaction_amount
|
||||
_SALVIUM_PendingTransaction_dust
|
||||
_SALVIUM_PendingTransaction_fee
|
||||
_SALVIUM_PendingTransaction_txid
|
||||
_SALVIUM_PendingTransaction_txCount
|
||||
_SALVIUM_PendingTransaction_subaddrAccount
|
||||
_SALVIUM_PendingTransaction_subaddrIndices
|
||||
_SALVIUM_PendingTransaction_multisigSignData
|
||||
_SALVIUM_PendingTransaction_signMultisigTx
|
||||
_SALVIUM_PendingTransaction_signersKeys
|
||||
_SALVIUM_PendingTransaction_hex
|
||||
_SALVIUM_UnsignedTransaction_status
|
||||
_SALVIUM_UnsignedTransaction_errorString
|
||||
_SALVIUM_UnsignedTransaction_amount
|
||||
_SALVIUM_UnsignedTransaction_fee
|
||||
_SALVIUM_UnsignedTransaction_mixin
|
||||
_SALVIUM_UnsignedTransaction_confirmationMessage
|
||||
_SALVIUM_UnsignedTransaction_paymentId
|
||||
_SALVIUM_UnsignedTransaction_recipientAddress
|
||||
_SALVIUM_UnsignedTransaction_minMixinCount
|
||||
_SALVIUM_UnsignedTransaction_txCount
|
||||
_SALVIUM_UnsignedTransaction_sign
|
||||
_SALVIUM_UnsignedTransaction_signUR
|
||||
_SALVIUM_TransactionInfo_direction
|
||||
_SALVIUM_TransactionInfo_isPending
|
||||
_SALVIUM_TransactionInfo_isFailed
|
||||
_SALVIUM_TransactionInfo_isCoinbase
|
||||
_SALVIUM_TransactionInfo_amount
|
||||
_SALVIUM_TransactionInfo_fee
|
||||
_SALVIUM_TransactionInfo_blockHeight
|
||||
_SALVIUM_TransactionInfo_description
|
||||
_SALVIUM_TransactionInfo_subaddrIndex
|
||||
_SALVIUM_TransactionInfo_subaddrAccount
|
||||
_SALVIUM_TransactionInfo_label
|
||||
_SALVIUM_TransactionInfo_confirmations
|
||||
_SALVIUM_TransactionInfo_unlockTime
|
||||
_SALVIUM_TransactionInfo_hash
|
||||
_SALVIUM_TransactionInfo_timestamp
|
||||
_SALVIUM_TransactionInfo_paymentId
|
||||
_SALVIUM_TransactionInfo_transfers_count
|
||||
_SALVIUM_TransactionInfo_transfers_amount
|
||||
_SALVIUM_TransactionInfo_transfers_address
|
||||
_SALVIUM_TransactionHistory_count
|
||||
_SALVIUM_TransactionHistory_transaction
|
||||
_SALVIUM_TransactionHistory_transactionById
|
||||
_SALVIUM_TransactionHistory_refresh
|
||||
_SALVIUM_TransactionHistory_setTxNote
|
||||
_SALVIUM_AddressBookRow_extra
|
||||
_SALVIUM_AddressBookRow_getAddress
|
||||
_SALVIUM_AddressBookRow_getDescription
|
||||
_SALVIUM_AddressBookRow_getPaymentId
|
||||
_SALVIUM_AddressBookRow_getRowId
|
||||
_SALVIUM_AddressBook_getAll_size
|
||||
_SALVIUM_AddressBook_getAll_byIndex
|
||||
_SALVIUM_AddressBook_addRow
|
||||
_SALVIUM_AddressBook_deleteRow
|
||||
_SALVIUM_AddressBook_setDescription
|
||||
_SALVIUM_AddressBook_refresh
|
||||
_SALVIUM_AddressBook_errorString
|
||||
_SALVIUM_AddressBook_errorCode
|
||||
_SALVIUM_AddressBook_lookupPaymentID
|
||||
_SALVIUM_CoinsInfo_blockHeight
|
||||
_SALVIUM_CoinsInfo_hash
|
||||
_SALVIUM_CoinsInfo_internalOutputIndex
|
||||
_SALVIUM_CoinsInfo_globalOutputIndex
|
||||
_SALVIUM_CoinsInfo_spent
|
||||
_SALVIUM_CoinsInfo_frozen
|
||||
_SALVIUM_CoinsInfo_spentHeight
|
||||
_SALVIUM_CoinsInfo_amount
|
||||
_SALVIUM_CoinsInfo_rct
|
||||
_SALVIUM_CoinsInfo_keyImageKnown
|
||||
_SALVIUM_CoinsInfo_pkIndex
|
||||
_SALVIUM_CoinsInfo_subaddrIndex
|
||||
_SALVIUM_CoinsInfo_subaddrAccount
|
||||
_SALVIUM_CoinsInfo_address
|
||||
_SALVIUM_CoinsInfo_addressLabel
|
||||
_SALVIUM_CoinsInfo_keyImage
|
||||
_SALVIUM_CoinsInfo_unlockTime
|
||||
_SALVIUM_CoinsInfo_unlocked
|
||||
_SALVIUM_CoinsInfo_pubKey
|
||||
_SALVIUM_CoinsInfo_coinbase
|
||||
_SALVIUM_CoinsInfo_description
|
||||
_SALVIUM_Coins_count
|
||||
_SALVIUM_Coins_coin
|
||||
_SALVIUM_Coins_getAll_size
|
||||
_SALVIUM_Coins_getAll_byIndex
|
||||
_SALVIUM_Coins_refresh
|
||||
_SALVIUM_Coins_setFrozenByPublicKey
|
||||
_SALVIUM_Coins_setFrozen
|
||||
_SALVIUM_Coins_thaw
|
||||
_SALVIUM_Coins_thawByPublicKey
|
||||
_SALVIUM_Coins_isTransferUnlocked
|
||||
_SALVIUM_Coins_setDescription
|
||||
_SALVIUM_SubaddressRow_extra
|
||||
_SALVIUM_SubaddressRow_getAddress
|
||||
_SALVIUM_SubaddressRow_getLabel
|
||||
_SALVIUM_SubaddressRow_getRowId
|
||||
_SALVIUM_Subaddress_getAll_size
|
||||
_SALVIUM_Subaddress_getAll_byIndex
|
||||
_SALVIUM_Subaddress_addRow
|
||||
_SALVIUM_Subaddress_setLabel
|
||||
_SALVIUM_Subaddress_refresh
|
||||
_SALVIUM_SubaddressAccountRow_extra
|
||||
_SALVIUM_SubaddressAccountRow_getAddress
|
||||
_SALVIUM_SubaddressAccountRow_getLabel
|
||||
_SALVIUM_SubaddressAccountRow_getBalance
|
||||
_SALVIUM_SubaddressAccountRow_getUnlockedBalance
|
||||
_SALVIUM_SubaddressAccountRow_getRowId
|
||||
_SALVIUM_SubaddressAccount_getAll_size
|
||||
_SALVIUM_SubaddressAccount_getAll_byIndex
|
||||
_SALVIUM_SubaddressAccount_addRow
|
||||
_SALVIUM_SubaddressAccount_setLabel
|
||||
_SALVIUM_SubaddressAccount_refresh
|
||||
_SALVIUM_MultisigState_isMultisig
|
||||
_SALVIUM_MultisigState_isReady
|
||||
_SALVIUM_MultisigState_threshold
|
||||
_SALVIUM_MultisigState_total
|
||||
_SALVIUM_DeviceProgress_progress
|
||||
_SALVIUM_DeviceProgress_indeterminate
|
||||
_SALVIUM_Wallet_seed
|
||||
_SALVIUM_Wallet_getSeedLanguage
|
||||
_SALVIUM_Wallet_setSeedLanguage
|
||||
_SALVIUM_Wallet_status
|
||||
_SALVIUM_Wallet_errorString
|
||||
_SALVIUM_Wallet_setPassword
|
||||
_SALVIUM_Wallet_getPassword
|
||||
_SALVIUM_Wallet_setDevicePin
|
||||
_SALVIUM_Wallet_setDevicePassphrase
|
||||
_SALVIUM_Wallet_address
|
||||
_SALVIUM_Wallet_path
|
||||
_SALVIUM_Wallet_nettype
|
||||
_SALVIUM_Wallet_useForkRules
|
||||
_SALVIUM_Wallet_integratedAddress
|
||||
_SALVIUM_Wallet_secretViewKey
|
||||
_SALVIUM_Wallet_publicViewKey
|
||||
_SALVIUM_Wallet_secretSpendKey
|
||||
_SALVIUM_Wallet_publicSpendKey
|
||||
_SALVIUM_Wallet_publicMultisigSignerKey
|
||||
_SALVIUM_Wallet_stop
|
||||
_SALVIUM_Wallet_store
|
||||
_SALVIUM_Wallet_filename
|
||||
_SALVIUM_Wallet_keysFilename
|
||||
_SALVIUM_Wallet_init
|
||||
_SALVIUM_Wallet_createWatchOnly
|
||||
_SALVIUM_Wallet_setRefreshFromBlockHeight
|
||||
_SALVIUM_Wallet_getRefreshFromBlockHeight
|
||||
_SALVIUM_Wallet_setRecoveringFromSeed
|
||||
_SALVIUM_Wallet_setRecoveringFromDevice
|
||||
_SALVIUM_Wallet_setSubaddressLookahead
|
||||
_SALVIUM_Wallet_connectToDaemon
|
||||
_SALVIUM_Wallet_connected
|
||||
_SALVIUM_Wallet_setTrustedDaemon
|
||||
_SALVIUM_Wallet_trustedDaemon
|
||||
_SALVIUM_Wallet_setProxy
|
||||
_SALVIUM_Wallet_balance
|
||||
_SALVIUM_Wallet_unlockedBalance
|
||||
_SALVIUM_Wallet_viewOnlyBalance
|
||||
_SALVIUM_Wallet_watchOnly
|
||||
_SALVIUM_Wallet_isDeterministic
|
||||
_SALVIUM_Wallet_blockChainHeight
|
||||
_SALVIUM_Wallet_approximateBlockChainHeight
|
||||
_SALVIUM_Wallet_estimateBlockChainHeight
|
||||
_SALVIUM_Wallet_daemonBlockChainHeight
|
||||
_SALVIUM_Wallet_daemonBlockChainTargetHeight
|
||||
_SALVIUM_Wallet_synchronized
|
||||
_SALVIUM_Wallet_displayAmount
|
||||
_SALVIUM_Wallet_amountFromString
|
||||
_SALVIUM_Wallet_amountFromDouble
|
||||
_SALVIUM_Wallet_genPaymentId
|
||||
_SALVIUM_Wallet_paymentIdValid
|
||||
_SALVIUM_Wallet_addressValid
|
||||
_SALVIUM_Wallet_keyValid
|
||||
_SALVIUM_Wallet_keyValid_error
|
||||
_SALVIUM_Wallet_paymentIdFromAddress
|
||||
_SALVIUM_Wallet_maximumAllowedAmount
|
||||
_SALVIUM_Wallet_init3
|
||||
_SALVIUM_Wallet_getPolyseed
|
||||
_SALVIUM_Wallet_createPolyseed
|
||||
_SALVIUM_Wallet_startRefresh
|
||||
_SALVIUM_Wallet_pauseRefresh
|
||||
_SALVIUM_Wallet_refresh
|
||||
_SALVIUM_Wallet_refreshAsync
|
||||
_SALVIUM_Wallet_rescanBlockchain
|
||||
_SALVIUM_Wallet_rescanBlockchainAsync
|
||||
_SALVIUM_Wallet_setAutoRefreshInterval
|
||||
_SALVIUM_Wallet_autoRefreshInterval
|
||||
_SALVIUM_Wallet_addSubaddressAccount
|
||||
_SALVIUM_Wallet_numSubaddressAccounts
|
||||
_SALVIUM_Wallet_numSubaddresses
|
||||
_SALVIUM_Wallet_addSubaddress
|
||||
_SALVIUM_Wallet_getSubaddressLabel
|
||||
_SALVIUM_Wallet_setSubaddressLabel
|
||||
_SALVIUM_Wallet_multisig
|
||||
_SALVIUM_Wallet_getMultisigInfo
|
||||
_SALVIUM_Wallet_makeMultisig
|
||||
_SALVIUM_Wallet_exchangeMultisigKeys
|
||||
_SALVIUM_Wallet_exportMultisigImages
|
||||
_SALVIUM_Wallet_importMultisigImages
|
||||
_SALVIUM_Wallet_hasMultisigPartialKeyImages
|
||||
_SALVIUM_Wallet_restoreMultisigTransaction
|
||||
_SALVIUM_Wallet_createTransactionMultDest
|
||||
_SALVIUM_Wallet_createTransaction
|
||||
_SALVIUM_Wallet_loadUnsignedTx
|
||||
_SALVIUM_Wallet_loadUnsignedTxUR
|
||||
_SALVIUM_Wallet_submitTransaction
|
||||
_SALVIUM_Wallet_submitTransactionUR
|
||||
_SALVIUM_Wallet_hasUnknownKeyImages
|
||||
_SALVIUM_Wallet_exportKeyImages
|
||||
_SALVIUM_Wallet_exportKeyImagesUR
|
||||
_SALVIUM_Wallet_importKeyImages
|
||||
_SALVIUM_Wallet_importKeyImagesUR
|
||||
_SALVIUM_Wallet_exportOutputs
|
||||
_SALVIUM_Wallet_exportOutputsUR
|
||||
_SALVIUM_Wallet_importOutputs
|
||||
_SALVIUM_Wallet_importOutputsUR
|
||||
_SALVIUM_Wallet_setupBackgroundSync
|
||||
_SALVIUM_Wallet_getBackgroundSyncType
|
||||
_SALVIUM_Wallet_startBackgroundSync
|
||||
_SALVIUM_Wallet_stopBackgroundSync
|
||||
_SALVIUM_Wallet_isBackgroundSyncing
|
||||
_SALVIUM_Wallet_isBackgroundWallet
|
||||
_SALVIUM_Wallet_history
|
||||
_SALVIUM_Wallet_addressBook
|
||||
_SALVIUM_Wallet_coins
|
||||
_SALVIUM_Wallet_subaddress
|
||||
_SALVIUM_Wallet_subaddressAccount
|
||||
_SALVIUM_Wallet_defaultMixin
|
||||
_SALVIUM_Wallet_setDefaultMixin
|
||||
_SALVIUM_Wallet_setCacheAttribute
|
||||
_SALVIUM_Wallet_getCacheAttribute
|
||||
_SALVIUM_Wallet_setUserNote
|
||||
_SALVIUM_Wallet_getUserNote
|
||||
_SALVIUM_Wallet_getTxKey
|
||||
_SALVIUM_Wallet_signMessage
|
||||
_SALVIUM_Wallet_verifySignedMessage
|
||||
_SALVIUM_Wallet_rescanSpent
|
||||
_SALVIUM_Wallet_setOffline
|
||||
_SALVIUM_Wallet_isOffline
|
||||
_SALVIUM_Wallet_segregatePreForkOutputs
|
||||
_SALVIUM_Wallet_segregationHeight
|
||||
_SALVIUM_Wallet_keyReuseMitigation2
|
||||
_SALVIUM_Wallet_lockKeysFile
|
||||
_SALVIUM_Wallet_unlockKeysFile
|
||||
_SALVIUM_Wallet_isKeysFileLocked
|
||||
_SALVIUM_Wallet_getDeviceType
|
||||
_SALVIUM_Wallet_coldKeyImageSync
|
||||
_SALVIUM_Wallet_deviceShowAddress
|
||||
_SALVIUM_Wallet_reconnectDevice
|
||||
_SALVIUM_Wallet_getBytesReceived
|
||||
_SALVIUM_Wallet_getBytesSent
|
||||
_SALVIUM_Wallet_getStateIsConnected
|
||||
_SALVIUM_Wallet_getSendToDevice
|
||||
_SALVIUM_Wallet_getSendToDeviceLength
|
||||
_SALVIUM_Wallet_getReceivedFromDevice
|
||||
_SALVIUM_Wallet_getReceivedFromDeviceLength
|
||||
_SALVIUM_Wallet_getWaitsForDeviceSend
|
||||
_SALVIUM_Wallet_getWaitsForDeviceReceive
|
||||
_SALVIUM_Wallet_setDeviceReceivedData
|
||||
_SALVIUM_Wallet_setDeviceSendData
|
||||
_SALVIUM_WalletManager_createWallet
|
||||
_SALVIUM_WalletManager_openWallet
|
||||
_SALVIUM_WalletManager_recoveryWallet
|
||||
_SALVIUM_WalletManager_createWalletFromKeys
|
||||
_SALVIUM_WalletManager_createDeterministicWalletFromSpendKey
|
||||
_SALVIUM_WalletManager_createWalletFromDevice
|
||||
_SALVIUM_WalletManager_createWalletFromPolyseed
|
||||
_SALVIUM_WalletManager_closeWallet
|
||||
_SALVIUM_WalletManager_walletExists
|
||||
_SALVIUM_WalletManager_verifyWalletPassword
|
||||
_SALVIUM_WalletManager_queryWalletDevice
|
||||
_SALVIUM_WalletManager_findWallets
|
||||
_SALVIUM_WalletManager_errorString
|
||||
_SALVIUM_WalletManager_setDaemonAddress
|
||||
_SALVIUM_WalletManager_blockchainHeight
|
||||
_SALVIUM_WalletManager_blockchainTargetHeight
|
||||
_SALVIUM_WalletManager_networkDifficulty
|
||||
_SALVIUM_WalletManager_miningHashRate
|
||||
_SALVIUM_WalletManager_blockTarget
|
||||
_SALVIUM_WalletManager_isMining
|
||||
_SALVIUM_WalletManager_startMining
|
||||
_SALVIUM_WalletManager_stopMining
|
||||
_SALVIUM_WalletManager_resolveOpenAlias
|
||||
_SALVIUM_WalletManager_setProxy
|
||||
_SALVIUM_WalletManagerFactory_getWalletManager
|
||||
_SALVIUM_WalletManagerFactory_setLogLevel
|
||||
_SALVIUM_WalletManagerFactory_setLogCategories
|
||||
_SALVIUM_DEBUG_test0
|
||||
_SALVIUM_DEBUG_test1
|
||||
_SALVIUM_DEBUG_test2
|
||||
_SALVIUM_DEBUG_test3
|
||||
_SALVIUM_DEBUG_test4
|
||||
_SALVIUM_DEBUG_test5
|
||||
_SALVIUM_DEBUG_test5_std
|
||||
_SALVIUM_DEBUG_isPointerNull
|
||||
_SALVIUM_cw_getWalletListener
|
||||
_SALVIUM_cw_WalletListener_resetNeedToRefresh
|
||||
_SALVIUM_cw_WalletListener_isNeedToRefresh
|
||||
_SALVIUM_cw_WalletListener_isNewTransactionExist
|
||||
_SALVIUM_cw_WalletListener_resetIsNewTransactionExist
|
||||
_SALVIUM_cw_WalletListener_height
|
||||
_SALVIUM_free
|
||||
_SALVIUM_checksum_wallet2_api_c_h
|
||||
_SALVIUM_checksum_wallet2_api_c_cpp
|
||||
_SALVIUM_checksum_wallet2_api_c_exp
|
||||
@@ -0,0 +1,265 @@
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "helpers.hpp"
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOG_TAG "moneroc"
|
||||
#define BUFFER_SIZE 1024*32
|
||||
|
||||
static int stdoutToLogcat(const char *buf, int size) {
|
||||
__android_log_write(ANDROID_LOG_INFO, LOG_TAG, buf);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int stderrToLogcat(const char *buf, int size) {
|
||||
__android_log_write(ANDROID_LOG_ERROR, LOG_TAG, buf);
|
||||
return size;
|
||||
}
|
||||
|
||||
void redirectStdoutThread(int pipe_stdout[2]) {
|
||||
char bufferStdout[BUFFER_SIZE];
|
||||
while (true) {
|
||||
int read_size = read(pipe_stdout[0], bufferStdout, sizeof(bufferStdout) - 1);
|
||||
if (read_size > 0) {
|
||||
bufferStdout[read_size] = '\0';
|
||||
stdoutToLogcat(bufferStdout, read_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void redirectStderrThread(int pipe_stderr[2]) {
|
||||
char bufferStderr[BUFFER_SIZE];
|
||||
while (true) {
|
||||
int read_size = read(pipe_stderr[0], bufferStderr, sizeof(bufferStderr) - 1);
|
||||
if (read_size > 0) {
|
||||
bufferStderr[read_size] = '\0';
|
||||
stderrToLogcat(bufferStderr, read_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupAndroidLogging() {
|
||||
static int pfdStdout[2];
|
||||
static int pfdStderr[2];
|
||||
|
||||
pipe(pfdStdout);
|
||||
pipe(pfdStderr);
|
||||
|
||||
dup2(pfdStdout[1], STDOUT_FILENO);
|
||||
dup2(pfdStderr[1], STDERR_FILENO);
|
||||
|
||||
std::thread stdoutThread(redirectStdoutThread, pfdStdout);
|
||||
std::thread stderrThread(redirectStderrThread, pfdStderr);
|
||||
|
||||
stdoutThread.detach();
|
||||
stderrThread.detach();
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
||||
__attribute__((constructor))
|
||||
void library_init() {
|
||||
#ifdef __ANDROID__
|
||||
setupAndroidLogging(); // This will now run automatically when the library is loaded
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* vectorToString(const std::vector<std::string>& vec, const std::string separator) {
|
||||
// Check if the vector is empty
|
||||
if (vec.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Concatenate all strings in the vector
|
||||
std::string result;
|
||||
for (size_t i = 0; i < vec.size() - 1; ++i) {
|
||||
result += vec[i];
|
||||
result += separator;
|
||||
}
|
||||
result += vec.back(); // Append the last string without the separator
|
||||
|
||||
std::string str = result;
|
||||
const std::string::size_type size = str.size();
|
||||
char *buffer = new char[size + 1]; //we need extra char for NUL
|
||||
memcpy(buffer, str.c_str(), size + 1);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char* vectorToString(const std::vector<uint32_t>& vec, const std::string separator) {
|
||||
// Calculate the size needed for the result string
|
||||
size_t size = 0;
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
// Calculate the number of digits in each element
|
||||
size += snprintf(nullptr, 0, "%u", vec[i]);
|
||||
// Add comma and space for all elements except the last one
|
||||
if (i < vec.size() - 1) {
|
||||
size += separator.size(); // comma and space
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate memory for the result string
|
||||
char* result = static_cast<char*>(malloc(size + 1));
|
||||
if (result == nullptr) {
|
||||
// Handle memory allocation failure
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Fill in the result string
|
||||
char* current = result;
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
// Convert each element to string and copy to the result string
|
||||
int written = snprintf(current, size + 1, "%u", vec[i]);
|
||||
current += written;
|
||||
// Add comma and space for all elements except the last one
|
||||
if (i < vec.size() - 1) {
|
||||
strcpy(current, separator.c_str());
|
||||
current += separator.size();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* vectorToString(const std::vector<uint64_t>& vec, const std::string separator) {
|
||||
// Calculate the size needed for the result string
|
||||
size_t size = 0;
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
// Calculate the number of digits in each element
|
||||
size += snprintf(nullptr, 0, "%llu", vec[i]);
|
||||
// Add comma and space for all elements except the last one
|
||||
if (i < vec.size() - 1) {
|
||||
size += separator.size(); // comma and space
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate memory for the result string
|
||||
char* result = static_cast<char*>(malloc(size + 1));
|
||||
if (result == nullptr) {
|
||||
// Handle memory allocation failure
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Fill in the result string
|
||||
char* current = result;
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
// Convert each element to string and copy to the result string
|
||||
int written = snprintf(current, size + 1, "%llu", vec[i]);
|
||||
current += written;
|
||||
// Add comma and space for all elements except the last one
|
||||
if (i < vec.size() - 1) {
|
||||
strcpy(current, separator.c_str());
|
||||
current += separator.size();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* vectorToString(const std::vector<std::set<uint32_t>>& vec, const std::string separator) {
|
||||
// Check if the vector is empty
|
||||
if (vec.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Use a stringstream to concatenate sets with commas and individual elements with spaces
|
||||
std::ostringstream oss;
|
||||
oss << "{";
|
||||
for (auto it = vec.begin(); it != vec.end(); ++it) {
|
||||
if (it != vec.begin()) {
|
||||
oss << separator;
|
||||
}
|
||||
|
||||
oss << "{";
|
||||
for (auto setIt = it->begin(); setIt != it->end(); ++setIt) {
|
||||
if (setIt != it->begin()) {
|
||||
oss << separator;
|
||||
}
|
||||
oss << *setIt;
|
||||
}
|
||||
oss << "}";
|
||||
}
|
||||
oss << "}";
|
||||
std::string str = oss.str();
|
||||
const std::string::size_type size = str.size();
|
||||
char *buffer = new char[size + 1]; //we need extra char for NUL
|
||||
memcpy(buffer, str.c_str(), size + 1);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Function to convert std::set<uint32_t> to a string
|
||||
const char* vectorToString(const std::set<uint32_t>& intSet, const std::string separator) {
|
||||
// Check if the set is empty
|
||||
if (intSet.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Use a stringstream to concatenate elements with commas
|
||||
std::ostringstream oss;
|
||||
auto it = intSet.begin();
|
||||
oss << *it;
|
||||
for (++it; it != intSet.end(); ++it) {
|
||||
oss << ", " << *it;
|
||||
}
|
||||
|
||||
std::string str = oss.str();
|
||||
const std::string::size_type size = str.size();
|
||||
char *buffer = new char[size + 1]; //we need extra char for NUL
|
||||
memcpy(buffer, str.c_str(), size + 1);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::set<std::string> splitString(const std::string& str, const std::string& delim) {
|
||||
std::set<std::string> tokens;
|
||||
if (str.empty()) return tokens;
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
std::string content = str; // Copy of str so we can safely erase content
|
||||
while ((pos = content.find(delim)) != std::string::npos) {
|
||||
token = content.substr(0, pos);
|
||||
tokens.insert(token);
|
||||
content.erase(0, pos + delim.length());
|
||||
}
|
||||
tokens.insert(content); // Inserting the last token
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<std::string> splitStringVector(const std::string& str, const std::string& delim) {
|
||||
std::vector<std::string> tokens;
|
||||
if (str.empty()) return tokens;
|
||||
size_t pos = 0;
|
||||
std::string content = str; // Copy of str so we can safely erase content
|
||||
while ((pos = content.find(delim)) != std::string::npos) {
|
||||
tokens.push_back(content.substr(0, pos));
|
||||
content.erase(0, pos + delim.length());
|
||||
}
|
||||
tokens.push_back(content); // Inserting the last token
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> splitStringUint(const std::string& str, const std::string& delim) {
|
||||
std::vector<uint64_t> tokens;
|
||||
if (str.empty()) return tokens;
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
std::string content = str; // Copy of str so we can safely erase content
|
||||
while ((pos = content.find(delim)) != std::string::npos) {
|
||||
token = content.substr(0, pos);
|
||||
tokens.push_back(std::stoull(token)); // Convert string to uint64_t and push to vector
|
||||
content.erase(0, pos + delim.length());
|
||||
}
|
||||
tokens.push_back(std::stoull(content)); // Inserting the last token
|
||||
return tokens;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
// Debug macros
|
||||
#define DEBUG_START() \
|
||||
try {
|
||||
|
||||
#define DEBUG_END() \
|
||||
} catch (const std::exception &e) { \
|
||||
std::cerr << "Exception caught in function: " << __FUNCTION__ \
|
||||
<< " at " << __FILE__ << ":" << __LINE__ << std::endl \
|
||||
<< "Message: " << e.what() << std::endl; \
|
||||
std::abort(); \
|
||||
} catch (...) { \
|
||||
std::cerr << "Unknown exception caught in function: " << __FUNCTION__ \
|
||||
<< " at " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
std::abort(); \
|
||||
}
|
||||
|
||||
|
||||
const char* vectorToString(const std::vector<std::string>& vec, const std::string separator);
|
||||
const char* vectorToString(const std::vector<uint32_t>& vec, const std::string separator);
|
||||
const char* vectorToString(const std::vector<uint64_t>& vec, const std::string separator);
|
||||
const char* vectorToString(const std::vector<std::set<uint32_t>>& vec, const std::string separator);
|
||||
const char* vectorToString(const std::set<uint32_t>& intSet, const std::string separator);
|
||||
std::set<std::string> splitString(const std::string& str, const std::string& delim);
|
||||
std::vector<uint64_t> splitStringUint(const std::string& str, const std::string& delim);
|
||||
std::vector<std::string> splitStringVector(const std::string& str, const std::string& delim);
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef SALVIUMC_CHECKSUMS
|
||||
#define SALVIUMC_CHECKSUMS
|
||||
const char * SALVIUM_wallet2_api_c_h_sha256 = "9e80c4b59a0509aa02fbf01e8df2881b89f82225d1765bfa7856cbdbaf7af116";
|
||||
const char * SALVIUM_wallet2_api_c_cpp_sha256 = "d229507db508e574bd2badf4819a38dbead8c16a84311ad32c22c887a6003439-0232839913b13cf0ab0bb7ad25fff0c05f37d2fe";
|
||||
const char * SALVIUM_wallet2_api_c_exp_sha256 = "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d";
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user