summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCzarek Nakamoto <cyjan@mrcyjanek.net>2026-07-23 09:51:20 +0200
committerCzarek Nakamoto <cyjan@mrcyjanek.net>2026-08-03 14:53:50 +0200
commitc765eca1fbbfde6165d5ed5e56276878b3496c77 (patch)
tree5b9ef6e90361595b70fb6076d92bc41b7c6b7abc
parent5952bef2ec01b0b7e57c11613cbdc081dcd727c5 (diff)
use FCMP branch, bump simplybs, rebase patchescyjan-fcmp-v2
-rw-r--r--.gitmodules2
-rwxr-xr-xbuild_single.sh16
-rw-r--r--contrib/depends/Makefile8
m---------monero0
-rw-r--r--monero_libwallet2_api_c/CMakeLists.txt3
-rw-r--r--patches/monero/0001-store-crash-fix.patch (renamed from patches/monero/0002-store-crash-fix.patch)75
-rw-r--r--patches/monero/0002-uint64_t-missing-definition-fix.patch (renamed from patches/monero/0003-uint64_t-missing-definition-fix.patch)8
-rw-r--r--patches/monero/0003-use-proper-error-handling-in-get_seed.patch (renamed from patches/monero/0004-use-proper-error-handling-in-get_seed.patch)16
-rw-r--r--patches/monero/0004-fix-missing-___clear_cache-when-targetting-iOS.patch (renamed from patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch)21
-rw-r--r--patches/monero/0005-UR-functions.patch144
-rw-r--r--patches/monero/0006-add-dummy-device-for-ledger.patch60
-rw-r--r--patches/monero/0007-polyseed.patch174
-rw-r--r--patches/monero/0008-coin-control.patch163
-rw-r--r--patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch16
-rw-r--r--patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch24
-rw-r--r--patches/monero/0011-add-monero-submodule-support.patch32
-rw-r--r--patches/monero/0012-fix-iOS-depends-build.patch65
-rw-r--r--patches/monero/0013-include-locale-only-when-targeting-WIN32.patch40
-rw-r--r--patches/monero/0014-change-earliest-fork-height-message.patch10
-rw-r--r--patches/monero/0015-remove-trivially_copyable-assert.patch30
-rw-r--r--patches/monero/0016-serialize-cache-to-JSON.patch141
-rw-r--r--patches/monero/0017-drop-generate_translations_header.c-requirement.patch14
-rw-r--r--patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch21
-rw-r--r--patches/monero/0019-fix-mingw-build-issues.patch10
-rw-r--r--patches/monero/0020-fix-remove-flaky-test.patch10
-rw-r--r--patches/monero/0021-trezor-import-export-sign-submit-functions.patch (renamed from patches/monero/0021-trezor-import-export-sign-functions.patch)308
-rw-r--r--patches/monero/0022-fix-use-apple-ios-rust-target-when-building-for-iOS.patch33
27 files changed, 759 insertions, 685 deletions
diff --git a/.gitmodules b/.gitmodules
index 5a3c641..4c6be37 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "monero"]
path = monero
- url = https://github.com/monero-project/monero
+ url = https://github.com/seraphis-migration/monero
branch = release-v0.18
shallow = true
[submodule "wownero"]
diff --git a/build_single.sh b/build_single.sh
index ec2d760..f130d97 100755
--- a/build_single.sh
+++ b/build_single.sh
@@ -63,8 +63,20 @@ pushd contrib/depends
env PATH="$PATH" make "$NPROC" HOST="$HOST_ABI" BOOST_VERSION="${sbs_BOOST_VERSION}"
popd
# source contrib/depends/_native/_source_me
-source contrib/depends/$HOST_ABI/_source_me
-export PATH="$(pwd)/contrib/depends/_native/bin/:$(pwd)/contrib/depends/$HOST_ABI/native/bin:$PATH"
+source ./contrib/depends/_native/_source_me_export@native____
+source ./contrib/depends/_native/_source_me_export@native__
+source ./contrib/depends/$HOST_ABI/_source_me_export@rust-std
+export PREFIX="$(pwd)/contrib/depends/$HOST_ABI"
+export HOST="$HOST_ABI"
+export TARGET="$HOST_ABI"
+export HOME="$(pwd)/contrib/depends/_native/home/user"
+
+export PATH="$(pwd)/contrib/depends/_native/bin/:$(pwd)/contrib/depends/_native/_/bin"
+
+pushd contrib/depends
+ env HOST=$HOST_ABI ./gen_toolchain.cmake.sh $HOST_ABI/share/toolchain.cmake
+popd
+# source contrib/depends/$HOST_ABI/_source_me
buildType=Release
diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile
index 11f0d82..e91cd0f 100644
--- a/contrib/depends/Makefile
+++ b/contrib/depends/Makefile
@@ -3,8 +3,8 @@
HOST ?=
BOOST_VERSION ?= 1_90_0
-PACKAGES = native/protobuf,native/cmake,native/python@3.14,native/git,native/_,native/make,native/cmake-toolchain,icu4c,boost@$(BOOST_VERSION),zeromq,unbound,sodium,openssl,libiconv,zlib,protobuf
-SIMPLYBS_HASH = f060b28a0cf32f9ae626a143a029f484bf7b31a6
+PACKAGES = native/_/_,native/libxml2,native/curl,native/libpsl,native/pkgconf,native/rust-toolchain,rust-std,native/protobuf,native/cmake,native/sed,native/python@3.14,native/git,native/_,native/make,native/cmake-toolchain,boost@$(BOOST_VERSION),zeromq,unbound,sodium,openssl,libiconv,zlib,protobuf
+SIMPLYBS_HASH = 91f33785859d30ccca13277ae1b6e442abea978b
all: simplybs $(if $(HOST),sbs-build-$(HOST),)
@if [ -z "$(HOST)" ]; then \
@@ -30,8 +30,8 @@ simplybs:
cd simplybs && git reset --hard
sbs-build-%:
- # cd simplybs && env SIMPLYBS_ENV_NATIVE_DIR=$(PWD)/_native SIMPLYBS_ENV_DIR=$(PWD)/$* go run . -cleanup
cd simplybs && env SIMPLYBS_NATIVE_ENV_DIR=$(PWD)/_native SIMPLYBS_ENV_DIR=$(PWD)/$* go run . -host $* -package $(PACKAGES) -build
cd simplybs && rm -rf $(PWD)/$*
+ cd simplybs && rm -rf $(PWD)/_native
cd simplybs && env SIMPLYBS_NATIVE_ENV_DIR=$(PWD)/_native SIMPLYBS_ENV_DIR=$(PWD)/$* go run . -host $* -package $(PACKAGES) -extract
- env HOST=$* ./gen_toolchain.cmake.sh $*/share/toolchain.cmake
+ echo ok
diff --git a/monero b/monero
-Subproject dbcc7d212c094bd1a45f7291dbb99a4b4627a96
+Subproject 70600ee4d6ef49d7d12de59811370f07792199d
diff --git a/monero_libwallet2_api_c/CMakeLists.txt b/monero_libwallet2_api_c/CMakeLists.txt
index ab6a3b4..ae5a2fc 100644
--- a/monero_libwallet2_api_c/CMakeLists.txt
+++ b/monero_libwallet2_api_c/CMakeLists.txt
@@ -4,7 +4,8 @@ message(STATUS HOST_ABI = ${HOST_ABI})
set(MD_LIBRARY "")
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(${HOST_ABI} STREQUAL "x86_64-w64-mingw32")
diff --git a/patches/monero/0002-store-crash-fix.patch b/patches/monero/0001-store-crash-fix.patch
index 8ecd8b1..430dd36 100644
--- a/patches/monero/0002-store-crash-fix.patch
+++ b/patches/monero/0001-store-crash-fix.patch
@@ -1,7 +1,7 @@
-From 94cf21261079d6d4ceb848be3863613e98c3bc89 Mon Sep 17 00:00:00 2001
+From e502b3a2a2c88e9518c96123d44d91e6b6218f29 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/20] store crash fix
+Subject: [PATCH 01/22] store crash fix
Monero wallet crashes (sometimes) when it is syncing,
while the proper solution (that can be seen in feather)
@@ -36,18 +36,17 @@ would just wait for it to finish before actually storing).
Also imo store() functin should store the wallet, no matter
the current state.
---
- external/randomx | 2 +-
src/wallet/api/wallet.cpp | 53 +++++++++++++++++++--------------------
src/wallet/api/wallet.h | 1 -
src/wallet/wallet2.cpp | 11 +++++++-
src/wallet/wallet2.h | 3 +++
- 5 files changed, 40 insertions(+), 30 deletions(-)
+ 4 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 165b21c9f..c2f4176e2 100644
+index 2a3919577..1da515120 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -55,8 +55,8 @@ using namespace cryptonote;
+@@ -59,8 +59,8 @@ using namespace cryptonote;
#define MONERO_DEFAULT_LOG_CATEGORY "WalletAPI"
#define LOCK_REFRESH() \
@@ -58,7 +57,7 @@ index 165b21c9f..c2f4176e2 100644
m_wallet->stop(); \
m_refreshCV.notify_one(); \
boost::mutex::scoped_lock lock(m_refreshMutex); \
-@@ -178,7 +178,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
+@@ -184,7 +184,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
virtual void on_new_block(uint64_t height, const cryptonote::block& block)
{
// Don't flood the GUI with signals. On fast refresh - send signal every 1000th block
@@ -67,7 +66,7 @@ index 165b21c9f..c2f4176e2 100644
// created or the restore height specified when wallet was recovered
if(height >= m_wallet->m_wallet->get_refresh_from_block_height() || height % 1000 == 0) {
// LOG_PRINT_L3(__FUNCTION__ << ": new block. height: " << height);
-@@ -379,7 +379,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a
+@@ -356,7 +356,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a
error = tr("Failed to parse address");
return false;
}
@@ -76,7 +75,7 @@ index 165b21c9f..c2f4176e2 100644
cryptonote::blobdata key_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(secret_key_string, key_data) || key_data.size() != sizeof(crypto::secret_key))
{
-@@ -404,7 +404,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a
+@@ -381,7 +381,7 @@ bool Wallet::keyValid(const std::string &secret_key_string, const std::string &a
error = tr("key does not match address");
return false;
}
@@ -85,7 +84,7 @@ index 165b21c9f..c2f4176e2 100644
return true;
}
-@@ -466,7 +466,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
+@@ -443,7 +443,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
m_wallet2Callback.reset(new Wallet2CallbackImpl(this));
m_wallet->callback(m_wallet2Callback.get());
m_refreshThreadDone = false;
@@ -94,7 +93,7 @@ index 165b21c9f..c2f4176e2 100644
m_addressBook.reset(new AddressBookImpl(this));
m_subaddress.reset(new SubaddressImpl(this));
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
-@@ -487,7 +487,7 @@ WalletImpl::~WalletImpl()
+@@ -464,7 +464,7 @@ WalletImpl::~WalletImpl()
m_wallet->callback(NULL);
// Pause refresh thread - prevents refresh from starting again
WalletImpl::pauseRefresh(); // Call the method directly (not polymorphically) to protect against UB in destructor.
@@ -103,7 +102,7 @@ index 165b21c9f..c2f4176e2 100644
close(false); // do not store wallet as part of the closing activities
// Stop refresh thread
stopRefresh();
-@@ -698,7 +698,7 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
+@@ -675,7 +675,7 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
setSeedLanguage(language);
LOG_PRINT_L1("Generated deterministic wallet from spend key with seed language: " + language);
}
@@ -112,7 +111,7 @@ index 165b21c9f..c2f4176e2 100644
}
catch (const std::exception& e) {
setStatusError(string(tr("failed to generate new wallet: ")) + e.what());
-@@ -962,6 +962,7 @@ void WalletImpl::stop()
+@@ -939,6 +939,7 @@ void WalletImpl::stop()
bool WalletImpl::store(const std::string &path)
{
clearStatus();
@@ -120,7 +119,7 @@ index 165b21c9f..c2f4176e2 100644
try {
if (path.empty()) {
m_wallet->store();
-@@ -1110,14 +1111,14 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const
+@@ -1047,14 +1048,14 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const
} else {
clearStatus();
}
@@ -137,7 +136,7 @@ index 165b21c9f..c2f4176e2 100644
if(connected() == Wallet::ConnectionStatus_Disconnected)
return false;
uint64_t blockChainHeight = daemonBlockChainHeight();
-@@ -1189,14 +1190,14 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
+@@ -1126,14 +1127,14 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}
@@ -154,7 +153,7 @@ index 165b21c9f..c2f4176e2 100644
return transaction;
}
-@@ -1211,7 +1212,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
+@@ -1148,7 +1149,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
setStatus(Status_Ok, tr("Failed to load transaction from file"));
return false;
}
@@ -163,7 +162,7 @@ index 165b21c9f..c2f4176e2 100644
if(!transaction->commit()) {
setStatusError(transaction->m_errorString);
return false;
-@@ -1220,7 +1221,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
+@@ -1157,7 +1158,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
@@ -172,7 +171,7 @@ index 165b21c9f..c2f4176e2 100644
{
if (m_wallet->watch_only())
{
-@@ -1229,7 +1230,7 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
+@@ -1166,7 +1167,7 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
}
if (checkBackgroundSync("cannot export key images"))
return false;
@@ -181,7 +180,7 @@ index 165b21c9f..c2f4176e2 100644
try
{
if (!m_wallet->export_key_images(filename, all))
-@@ -1664,7 +1665,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -1623,7 +1624,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
clearStatus();
// Pause refresh thread while creating transaction
pauseRefresh();
@@ -189,8 +188,8 @@ index 165b21c9f..c2f4176e2 100644
+
cryptonote::address_parse_info info;
- uint32_t adjusted_priority = m_wallet->adjust_priority(static_cast<uint32_t>(priority));
-@@ -2448,10 +2449,10 @@ void WalletImpl::refreshThreadFunc()
+ const auto adjusted_priority = m_wallet->adjust_priority(static_cast<uint32_t>(priority));
+@@ -2407,10 +2408,10 @@ void WalletImpl::refreshThreadFunc()
}
LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired...");
@@ -203,7 +202,7 @@ index 165b21c9f..c2f4176e2 100644
LOG_PRINT_L3(__FUNCTION__ << ": refreshing...");
doRefresh();
}
-@@ -2485,7 +2486,7 @@ void WalletImpl::doRefresh()
+@@ -2444,7 +2445,7 @@ void WalletImpl::doRefresh()
} catch (const std::exception &e) {
setStatusError(e.what());
break;
@@ -212,7 +211,7 @@ index 165b21c9f..c2f4176e2 100644
if (m_wallet2Callback->getListener()) {
m_wallet2Callback->getListener()->refreshed();
-@@ -2495,9 +2496,9 @@ void WalletImpl::doRefresh()
+@@ -2454,9 +2455,9 @@ void WalletImpl::doRefresh()
void WalletImpl::startRefresh()
{
@@ -224,7 +223,7 @@ index 165b21c9f..c2f4176e2 100644
m_refreshCV.notify_one();
}
}
-@@ -2507,7 +2508,7 @@ void WalletImpl::startRefresh()
+@@ -2466,7 +2467,7 @@ void WalletImpl::startRefresh()
void WalletImpl::stopRefresh()
{
if (!m_refreshThreadDone) {
@@ -233,7 +232,7 @@ index 165b21c9f..c2f4176e2 100644
m_refreshThreadDone = true;
m_refreshCV.notify_one();
m_refreshThread.join();
-@@ -2518,9 +2519,7 @@ void WalletImpl::pauseRefresh()
+@@ -2477,9 +2478,7 @@ void WalletImpl::pauseRefresh()
{
LOG_PRINT_L2(__FUNCTION__ << ": refresh paused...");
// TODO synchronize access
@@ -244,7 +243,7 @@ index 165b21c9f..c2f4176e2 100644
}
-@@ -2530,7 +2529,7 @@ bool WalletImpl::isNewWallet() const
+@@ -2489,7 +2488,7 @@ bool WalletImpl::isNewWallet() const
// it's the same case as if it created from scratch, i.e. we need "fast sync"
// with the daemon (pull hashes instead of pull blocks).
// If wallet cache is rebuilt, creation height stored in .keys is used.
@@ -253,7 +252,7 @@ index 165b21c9f..c2f4176e2 100644
return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_recoveringFromDevice || m_rebuildWalletCache) && !watchOnly();
}
-@@ -2642,7 +2641,7 @@ void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const
+@@ -2601,7 +2600,7 @@ void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const
m_wallet->get_hard_fork_info(version, earliest_height);
}
@@ -263,10 +262,10 @@ index 165b21c9f..c2f4176e2 100644
return m_wallet->use_fork_rules(version,early_blocks);
}
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index 1f199a72c..ac7ce2f6a 100644
+index d48d7f130..365025c6e 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -273,7 +273,6 @@ private:
+@@ -274,7 +274,6 @@ private:
std::unique_ptr<SubaddressAccountImpl> m_subaddressAccount;
// multi-threaded refresh stuff
@@ -275,10 +274,10 @@ index 1f199a72c..ac7ce2f6a 100644
std::atomic<int> m_refreshIntervalMillis;
std::atomic<bool> m_refreshShouldRescan;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
-index af1f03d2c..af876c9f3 100644
+index e818afe53..2ca99f63a 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -1195,6 +1195,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
+@@ -1222,6 +1222,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),
@@ -286,7 +285,7 @@ index af1f03d2c..af876c9f3 100644
m_trusted_daemon(false),
m_nettype(nettype),
m_multisig_rounds_passed(0),
-@@ -1415,6 +1416,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
+@@ -1432,6 +1433,14 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u
return ret;
}
//----------------------------------------------------------------------------------------------------
@@ -301,8 +300,8 @@ index af1f03d2c..af876c9f3 100644
bool wallet2::set_proxy(const std::string &address)
{
return m_http_client->set_proxy(address);
-@@ -4178,7 +4187,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
- // infer when we get an incoming output
+@@ -4461,7 +4470,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
+
bool first = true, last = false;
- while(m_run.load(std::memory_order_relaxed) && blocks_fetched < max_blocks)
@@ -311,10 +310,10 @@ index af1f03d2c..af876c9f3 100644
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 a765dc475..92f735f96 100644
+index c350f1da8..e78abda83 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -1078,6 +1078,8 @@ private:
+@@ -579,6 +579,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);
@@ -323,7 +322,7 @@ index a765dc475..92f735f96 100644
void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); }
-@@ -1997,6 +1999,7 @@ private:
+@@ -1591,6 +1593,7 @@ private:
boost::recursive_mutex m_daemon_rpc_mutex;
@@ -332,5 +331,5 @@ index a765dc475..92f735f96 100644
i_wallet2_callback* m_callback;
hw::device::device_type m_key_device_type;
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0003-uint64_t-missing-definition-fix.patch b/patches/monero/0002-uint64_t-missing-definition-fix.patch
index 87aef72..7d7654b 100644
--- a/patches/monero/0003-uint64_t-missing-definition-fix.patch
+++ b/patches/monero/0002-uint64_t-missing-definition-fix.patch
@@ -1,14 +1,14 @@
-From 3cdb4ef9bdf88936276b4c5286eb7f9d39f556d0 Mon Sep 17 00:00:00 2001
+From 97bb6fe8c11fe8a036f5808eef1a23c5c9febfb6 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/20] uint64_t missing definition fix
+Subject: [PATCH 02/22] 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 f32fdd9ae..a95a7d34f 100644
+index b53766780..05af46731 100644
--- a/contrib/epee/include/net/http_base.h
+++ b/contrib/epee/include/net/http_base.h
@@ -28,7 +28,7 @@
@@ -21,5 +21,5 @@ index f32fdd9ae..a95a7d34f 100644
#include <string>
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0004-use-proper-error-handling-in-get_seed.patch b/patches/monero/0003-use-proper-error-handling-in-get_seed.patch
index 154fa90..0021f3c 100644
--- a/patches/monero/0004-use-proper-error-handling-in-get_seed.patch
+++ b/patches/monero/0003-use-proper-error-handling-in-get_seed.patch
@@ -1,7 +1,7 @@
-From 9174c5ab87a00d16e2930616686de5e57f3e7539 Mon Sep 17 00:00:00 2001
+From c58a0dbf32dd048875c7d0a0193ddb0ecc1e71ac 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/20] use proper error handling in get_seed
+Subject: [PATCH 03/22] use proper error handling in get_seed
---
src/wallet/api/wallet.cpp | 17 ++++++++++++-----
@@ -9,10 +9,10 @@ Subject: [PATCH 04/20] use proper error handling in get_seed
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index c2f4176e2..6301bd1ef 100644
+index 1da515120..27d8716c3 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -826,12 +826,19 @@ bool WalletImpl::close(bool store)
+@@ -803,12 +803,19 @@ bool WalletImpl::close(bool store)
std::string WalletImpl::seed(const std::string& seed_offset) const
{
@@ -38,10 +38,10 @@ index c2f4176e2..6301bd1ef 100644
std::string WalletImpl::getSeedLanguage() const
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
-index af876c9f3..ac2a1fec3 100644
+index 2ca99f63a..ff8950fd4 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -1452,11 +1452,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
+@@ -1469,11 +1469,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
bool keys_deterministic = is_deterministic();
if (!keys_deterministic)
{
@@ -55,7 +55,7 @@ index af876c9f3..ac2a1fec3 100644
std::cout << "seed_language not set" << std::endl;
return false;
}
-@@ -1466,8 +1468,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
+@@ -1483,8 +1485,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))
{
@@ -67,5 +67,5 @@ index af876c9f3..ac2a1fec3 100644
return true;
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch b/patches/monero/0004-fix-missing-___clear_cache-when-targetting-iOS.patch
index 888a502..eb53dff 100644
--- a/patches/monero/0001-fix-missing-___clear_cache-when-targetting-iOS.patch
+++ b/patches/monero/0004-fix-missing-___clear_cache-when-targetting-iOS.patch
@@ -1,19 +1,18 @@
-From 41d9f755a1392dd116241acb32b887091669f090 Mon Sep 17 00:00:00 2001
+From 19864ece62a8a04299ddc9ffd47f108a1cd4dc3c 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/20] fix missing ___clear_cache when targetting iOS
-
+Date: Mon, 27 Jul 2026 13:03:32 +0200
+Subject: [PATCH 04/22] 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
+index 691444f97..9dcb71804 100644
--- a/.gitmodules
+++ b/.gitmodules
-@@ -9,7 +9,8 @@
- url = https://github.com/trezor/trezor-common.git
+@@ -3,7 +3,8 @@
+ url = https://github.com/Tencent/rapidjson
[submodule "external/randomx"]
path = external/randomx
- url = https://github.com/tevador/RandomX
@@ -23,12 +22,12 @@ index 721cce3b4..ffb73fe9a 100644
path = external/supercop
url = https://github.com/monero-project/supercop
diff --git a/external/randomx b/external/randomx
-index 102f8acf9..5dfeeb30e 160000
+index 6c4340ba4..328bb26fb 160000
--- a/external/randomx
+++ b/external/randomx
@@ -1 +1 @@
--Subproject commit 102f8acf90a7649ada410de5499a7ec62e49e1da
-+Subproject commit 5dfeeb30ec3446ec9d348153767abc324436c56c
+-Subproject commit 6c4340ba4561aec9a3611c1aedf9931239777fb3
++Subproject commit 328bb26fb4d3dd2c2d30453719dcc9b9febbd658
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0005-UR-functions.patch b/patches/monero/0005-UR-functions.patch
index 116d050..d86fec2 100644
--- a/patches/monero/0005-UR-functions.patch
+++ b/patches/monero/0005-UR-functions.patch
@@ -1,7 +1,7 @@
-From ccd02185be7d4a928776ff38111eb3ce9face61f Mon Sep 17 00:00:00 2001
+From 5ffd332c6a2943891d99895ca7ec70d96f23b445 Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 10:09:50 +0100
-Subject: [PATCH 05/20] UR functions
+Subject: [PATCH 05/22] UR functions
This commit adds UR functions for UR tasks,
I believe that the right place to get
@@ -20,7 +20,7 @@ Things broken in the commit
of this patch) it is not a dealbreaker.
---
.gitmodules | 4 +
- CMakeLists.txt | 4 +-
+ CMakeLists.txt | 2 +
external/CMakeLists.txt | 1 +
external/bc-ur | 1 +
src/device/device_ledger.cpp | 5 +-
@@ -32,55 +32,54 @@ Things broken in the commit
src/wallet/api/wallet.cpp | 307 ++++++++++++++++++++++++
src/wallet/api/wallet.h | 8 +
src/wallet/api/wallet2_api.h | 22 +-
- src/wallet/wallet2.cpp | 141 +++++++----
+ src/wallet/wallet2.cpp | 137 +++++++----
src/wallet/wallet2.h | 3 +
- 15 files changed, 518 insertions(+), 56 deletions(-)
+ 15 files changed, 516 insertions(+), 52 deletions(-)
create mode 160000 external/bc-ur
diff --git a/.gitmodules b/.gitmodules
-index ffb73fe9a..72af74d55 100644
+index 9dcb71804..57fdfbfc8 100644
--- a/.gitmodules
+++ b/.gitmodules
-@@ -15,3 +15,7 @@
- path = external/supercop
- url = https://github.com/monero-project/supercop
- branch = monero
+@@ -19,3 +19,7 @@
+ path = external/mx25519
+ url = https://github.com/jeffro256/mx25519
+ branch = unclamped
+[submodule "external/bc-ur"]
+ path = external/bc-ur
+ url = https://github.com/MrCyjaneK/bc-ur
+ branch = misc
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 9b922046e..268339201 100644
+index b829efaf0..4ba3b7557 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -96,7 +96,8 @@ enable_language(C ASM)
- set(CMAKE_C_STANDARD 11)
+@@ -122,6 +122,7 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
--set(CMAKE_CXX_STANDARD 14)
-+set(CMAKE_CXX_STANDARD 17)
+ 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)
-@@ -364,6 +365,7 @@ if(NOT MANUAL_SUBMODULES)
+@@ -385,6 +386,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)
+ check_submodule(external/randomx)
+ check_submodule(external/supercop)
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
-index 538e4d215..074e23f16 100644
+index 08e910a0a..900684b6d 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
-@@ -70,4 +70,5 @@ endif()
+@@ -31,5 +31,6 @@
add_subdirectory(db_drivers)
add_subdirectory(easylogging++)
add_subdirectory(qrcodegen)
+add_subdirectory(bc-ur)
add_subdirectory(randomx EXCLUDE_FROM_ALL)
+ add_subdirectory(mx25519)
diff --git a/external/bc-ur b/external/bc-ur
new file mode 160000
index 000000000..d82e7c753
@@ -89,10 +88,10 @@ index 000000000..d82e7c753
@@ -0,0 +1 @@
+Subproject commit d82e7c753e710b8000706dc3383b498438795208
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
-index 6dde4a564..7e4be6347 100644
+index f8631e42d..aa6e037a1 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
-@@ -313,12 +313,13 @@ namespace hw {
+@@ -314,12 +314,13 @@ namespace hw {
/* ======================================================================= */
/* LOCKER */
@@ -103,25 +102,25 @@ index 6dde4a564..7e4be6347 100644
+ #pragma message ("Warning AUTO_LOCK_CMD is intentionally left broken. This is yet to be fixed.")
#define AUTO_LOCK_CMD() \
/* lock both mutexes without deadlock*/ \
-- boost::lock(device_locker, command_locker); \
-+ /* boost::lock(device_locker, command_locker); */ \
+- std::lock(device_locker, command_locker); \
++ /* std::lock(device_locker, command_locker); */ \
/* make sure both already-locked mutexes are unlocked at the end of scope */ \
- boost::lock_guard<boost::recursive_mutex> lock1(device_locker, boost::adopt_lock); \
- boost::lock_guard<boost::mutex> lock2(command_locker, boost::adopt_lock)
+ std::lock_guard<std::recursive_mutex> lock1(device_locker, std::adopt_lock); \
+ std::lock_guard<std::mutex> lock2(command_locker, std::adopt_lock)
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
-index 6095f99d5..b163212b7 100644
+index 054a5e876..db7c3c06b 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
-@@ -50,6 +50,7 @@ monero_add_library(wallet
+@@ -52,6 +52,7 @@ monero_add_library(wallet
target_link_libraries(wallet
PUBLIC
rpc_base
+ bc-ur
multisig
+ carrot_impl
common
- cryptonote_core
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
-index 70a702796..9c3c26ee5 100644
+index 1618b915d..919e210f0 100644
--- a/src/wallet/api/pending_transaction.cpp
+++ b/src/wallet/api/pending_transaction.cpp
@@ -42,6 +42,8 @@
@@ -172,7 +171,7 @@ index 70a702796..9c3c26ee5 100644
{
uint64_t result = 0;
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
-index 0a9779c07..403bfe281 100644
+index 9d8d754c0..8a70d774d 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -46,6 +46,7 @@ public:
@@ -184,7 +183,7 @@ index 0a9779c07..403bfe281 100644
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
+index c549539e5..062df7f41 100644
--- a/src/wallet/api/unsigned_transaction.cpp
+++ b/src/wallet/api/unsigned_transaction.cpp
@@ -40,6 +40,8 @@
@@ -244,7 +243,7 @@ index 6165a2240..fd03e959d 100644
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
+index b07d43fb1..76165a230 100644
--- a/src/wallet/api/unsigned_transaction.h
+++ b/src/wallet/api/unsigned_transaction.h
@@ -53,6 +53,7 @@ public:
@@ -256,18 +255,18 @@ index 30065a7fa..a94b23f75 100644
uint64_t minMixinCount() const override;
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 6301bd1ef..d179e502b 100644
+index 27d8716c3..52bc7647a 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -47,6 +47,7 @@
+@@ -51,6 +51,7 @@
+ #endif
- #include <boost/locale.hpp>
#include <boost/filesystem.hpp>
+#include "bc-ur/src/bc-ur.hpp"
using namespace std;
using namespace cryptonote;
-@@ -1066,6 +1067,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
+@@ -1012,6 +1013,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
return m_wallet->unlocked_balance(accountIndex, false);
}
@@ -291,8 +290,8 @@ index 6301bd1ef..d179e502b 100644
+
uint64_t WalletImpl::blockChainHeight() const
{
- if(m_wallet->light_wallet()) {
-@@ -1208,6 +1227,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
+ return m_wallet->get_blockchain_current_height();
+@@ -1145,6 +1164,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}
@@ -354,7 +353,7 @@ index 6301bd1ef..d179e502b 100644
bool WalletImpl::submitTransaction(const string &fileName) {
clearStatus();
if (checkBackgroundSync("cannot submit tx"))
-@@ -1228,6 +1302,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
+@@ -1165,6 +1239,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
@@ -416,7 +415,7 @@ index 6301bd1ef..d179e502b 100644
bool WalletImpl::exportKeyImages(const string &filename, bool all)
{
if (m_wallet->watch_only())
-@@ -1255,6 +1384,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
+@@ -1192,6 +1321,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
return true;
}
@@ -456,7 +455,7 @@ index 6301bd1ef..d179e502b 100644
bool WalletImpl::importKeyImages(const string &filename)
{
if (checkBackgroundSync("cannot import key images"))
-@@ -1280,6 +1442,62 @@ bool WalletImpl::importKeyImages(const string &filename)
+@@ -1217,6 +1379,62 @@ bool WalletImpl::importKeyImages(const string &filename)
return true;
}
@@ -519,7 +518,7 @@ index 6301bd1ef..d179e502b 100644
bool WalletImpl::exportOutputs(const string &filename, bool all)
{
if (checkBackgroundSync("cannot export outputs"))
-@@ -1312,6 +1530,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
+@@ -1249,6 +1467,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
return true;
}
@@ -560,7 +559,7 @@ index 6301bd1ef..d179e502b 100644
bool WalletImpl::importOutputs(const string &filename)
{
if (checkBackgroundSync("cannot import outputs"))
-@@ -1346,6 +1598,61 @@ bool WalletImpl::importOutputs(const string &filename)
+@@ -1283,6 +1535,61 @@ bool WalletImpl::importOutputs(const string &filename)
return true;
}
@@ -623,10 +622,10 @@ index 6301bd1ef..d179e502b 100644
{
if (checkBackgroundSync("cannot scan transactions"))
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index ac7ce2f6a..edf8bb8ce 100644
+index 365025c6e..a50983a69 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -112,6 +112,7 @@ public:
+@@ -113,6 +113,7 @@ public:
bool setProxy(const std::string &address) override;
uint64_t balance(uint32_t accountIndex = 0) const override;
uint64_t unlockedBalance(uint32_t accountIndex = 0) const override;
@@ -634,7 +633,7 @@ index ac7ce2f6a..edf8bb8ce 100644
uint64_t blockChainHeight() const override;
uint64_t approximateBlockChainHeight() const override;
uint64_t estimateBlockChainHeight() const override;
-@@ -164,11 +165,18 @@ public:
+@@ -166,11 +167,18 @@ public:
std::set<uint32_t> subaddr_indices = {}) override;
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
@@ -654,10 +653,10 @@ index ac7ce2f6a..edf8bb8ce 100644
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
+index 534679820..a5164260f 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -91,6 +91,7 @@ struct PendingTransaction
+@@ -83,6 +83,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;
@@ -665,7 +664,7 @@ index e349df176..764adbfbf 100644
virtual uint64_t amount() const = 0;
virtual uint64_t dust() const = 0;
virtual uint64_t fee() const = 0;
-@@ -160,7 +161,8 @@ struct UnsignedTransaction
+@@ -152,7 +153,8 @@ struct UnsignedTransaction
* @param signedFileName
* return - true on success
*/
@@ -675,7 +674,7 @@ index e349df176..764adbfbf 100644
};
/**
-@@ -626,6 +628,7 @@ struct Wallet
+@@ -619,6 +621,7 @@ struct Wallet
result += unlockedBalance(i);
return result;
}
@@ -683,7 +682,7 @@ index e349df176..764adbfbf 100644
/**
* @brief watchOnly - checks if wallet is watch only
-@@ -884,13 +887,15 @@ struct Wallet
+@@ -886,13 +889,15 @@ struct Wallet
* after object returned
*/
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
@@ -702,7 +701,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief disposeTransaction - destroys transaction object
-@@ -906,6 +911,8 @@ struct Wallet
+@@ -908,6 +913,8 @@ struct Wallet
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
PendingTransaction::Priority priority) const = 0;
@@ -711,7 +710,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief exportKeyImages - exports key images to file
* \param filename
-@@ -913,20 +920,22 @@ struct Wallet
+@@ -915,20 +922,22 @@ struct Wallet
* \return - true on success
*/
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
@@ -736,7 +735,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief importOutputs - imports outputs from file
-@@ -934,6 +943,7 @@ struct Wallet
+@@ -936,6 +945,7 @@ struct Wallet
* \return - true on success
*/
virtual bool importOutputs(const std::string &filename) = 0;
@@ -745,10 +744,10 @@ index e349df176..764adbfbf 100644
/*!
* \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 ac2a1fec3..a8db99c3f 100644
+index ff8950fd4..79cab37a4 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -953,6 +953,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
+@@ -974,6 +974,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
return idx + extra;
}
@@ -765,7 +764,7 @@ index ac2a1fec3..a8db99c3f 100644
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);
-@@ -7065,6 +7075,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *
+@@ -7326,6 +7336,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *
return amount;
}
//----------------------------------------------------------------------------------------------------
@@ -791,18 +790,7 @@ index ac2a1fec3..a8db99c3f 100644
std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_major, bool strict) const
{
std::map<uint32_t, uint64_t> amount_per_subaddr;
-@@ -7916,9 +7945,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)
- {
-@@ -11261,7 +11288,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+@@ -10864,7 +10893,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
continue;
}
@@ -811,7 +799,7 @@ index ac2a1fec3..a8db99c3f 100644
{
if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
{
-@@ -11311,9 +11338,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+@@ -10914,9 +10943,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(
LOG_PRINT_L2("Starting with " << num_nondust_outputs << " non-dust outputs and " << num_dust_outputs << " dust outputs");
@@ -829,8 +817,8 @@ index ac2a1fec3..a8db99c3f 100644
// 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({});
-@@ -13949,33 +13982,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
-
+@@ -13501,33 +13536,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);
@@ -893,7 +881,7 @@ index ac2a1fec3..a8db99c3f 100644
//----------------------------------------------------------------------------------------------------
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> wallet2::export_key_images(bool all) const
{
-@@ -14030,53 +14070,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
+@@ -13582,53 +13624,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
return std::make_pair(offset, ski);
}
@@ -973,10 +961,10 @@ index ac2a1fec3..a8db99c3f 100644
ski.push_back(std::make_pair(key_image, signature));
}
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
-index 92f735f96..18e60d89a 100644
+index e78abda83..aa70d5662 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -1164,6 +1164,7 @@ private:
+@@ -667,6 +667,7 @@ private:
// locked & unlocked balance of given or current subaddress account
uint64_t balance(uint32_t subaddr_index_major, bool strict) const;
uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL);
@@ -984,7 +972,7 @@ index 92f735f96..18e60d89a 100644
// 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, 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, bool strict);
-@@ -1639,9 +1640,11 @@ private:
+@@ -1196,9 +1197,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;
@@ -997,5 +985,5 @@ index 92f735f96..18e60d89a 100644
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.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0006-add-dummy-device-for-ledger.patch b/patches/monero/0006-add-dummy-device-for-ledger.patch
index 816ad5d..5a8870a 100644
--- a/patches/monero/0006-add-dummy-device-for-ledger.patch
+++ b/patches/monero/0006-add-dummy-device-for-ledger.patch
@@ -1,7 +1,7 @@
-From eb9ffa912fb31dd2bddf96d7d55d5e5f9d8219b4 Mon Sep 17 00:00:00 2001
+From 8651523017eae94b5527ba599f6391077a6a6dd2 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 8 May 2025 13:14:23 +0200
-Subject: [PATCH 06/20] add dummy device for ledger
+Subject: [PATCH 06/22] add dummy device for ledger
---
CMakeLists.txt | 19 ++--
@@ -21,10 +21,10 @@ Subject: [PATCH 06/20] add dummy device for ledger
create mode 100644 src/device/device_io_dummy.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 268339201..eb0d12225 100644
+index 4ba3b7557..8451e7959 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE})
+@@ -663,16 +663,21 @@ include_directories(${LMDB_INCLUDE})
include_directories(${LIBUNWIND_INCLUDE})
link_directories(${LIBUNWIND_LIBRARY_DIRS})
@@ -54,7 +54,7 @@ index 268339201..eb0d12225 100644
include(CheckTrezor)
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
-index e4f1159b5..14d398f87 100644
+index e8901cd4c..a0cdcdd1d 100644
--- a/src/device/CMakeLists.txt
+++ b/src/device/CMakeLists.txt
@@ -29,10 +29,11 @@
@@ -84,7 +84,7 @@ index e4f1159b5..14d398f87 100644
${device_headers}
device_ledger.hpp
diff --git a/src/device/device.cpp b/src/device/device.cpp
-index e6cd358b6..dd0701e0c 100644
+index e6c39c0b4..8a5d14c41 100644
--- a/src/device/device.cpp
+++ b/src/device/device.cpp
@@ -29,7 +29,7 @@
@@ -122,7 +122,7 @@ index e6cd358b6..dd0701e0c 100644
return *device->second;
}
diff --git a/src/device/device.hpp b/src/device/device.hpp
-index 392703a24..ffd419779 100644
+index 81caec91b..2e67401d6 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -34,17 +34,7 @@
@@ -401,19 +401,19 @@ index 000000000..87a5f109f
+
+#endif // HAVE_HIDAPI
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
-index 7e4be6347..ee330ba59 100644
+index aa6e037a1..728b06c41 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
-@@ -41,7 +41,7 @@ namespace hw {
+@@ -38,7 +38,7 @@ namespace hw {
namespace ledger {
- #ifdef WITH_DEVICE_LEDGER
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
- #undef MONERO_DEFAULT_LOG_CATEGORY
- #define MONERO_DEFAULT_LOG_CATEGORY "device.ledger"
-@@ -299,7 +299,7 @@ namespace hw {
+ 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++;
@@ -422,7 +422,7 @@ index 7e4be6347..ee330ba59 100644
this->mode = NONE;
this->has_view_key = false;
this->tx_in_progress = false;
-@@ -534,7 +534,9 @@ namespace hw {
+@@ -535,7 +535,9 @@ namespace hw {
bool device_ledger::connect(void) {
this->disconnect();
@@ -433,7 +433,7 @@ index 7e4be6347..ee330ba59 100644
#ifdef DEBUG_HWDEVICE
cryptonote::account_public_address pubkey;
diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
-index 61ac6f9c8..44a1af6c8 100644
+index 2634454a7..da81a399f 100644
--- a/src/device/device_ledger.hpp
+++ b/src/device/device_ledger.hpp
@@ -35,6 +35,7 @@
@@ -441,10 +441,10 @@ index 61ac6f9c8..44a1af6c8 100644
#include "log.hpp"
#include "device_io_hid.hpp"
+#include "device_io_dummy.hpp"
- #include <boost/thread/mutex.hpp>
- #include <boost/thread/recursive_mutex.hpp>
+ #include <mutex>
-@@ -56,7 +57,7 @@ namespace hw {
+ namespace hw {
+@@ -55,7 +56,7 @@ namespace hw {
void register_all(std::map<std::string, std::unique_ptr<device>> &registry);
@@ -453,8 +453,8 @@ index 61ac6f9c8..44a1af6c8 100644
// Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
#define SW_OK 0x9000
-@@ -148,7 +149,11 @@ namespace hw {
- mutable boost::mutex command_locker;
+@@ -143,7 +144,11 @@ namespace hw {
+ mutable std::mutex command_locker;
//IO
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
@@ -466,11 +466,11 @@ index 61ac6f9c8..44a1af6c8 100644
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 d179e502b..fb71a0521 100644
+index 52bc7647a..98f36bdb6 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -48,6 +48,9 @@
- #include <boost/locale.hpp>
+@@ -52,6 +52,9 @@
+
#include <boost/filesystem.hpp>
#include "bc-ur/src/bc-ur.hpp"
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
@@ -479,7 +479,7 @@ index d179e502b..fb71a0521 100644
using namespace std;
using namespace cryptonote;
-@@ -3177,4 +3180,101 @@ uint64_t WalletImpl::getBytesSent()
+@@ -3136,4 +3139,101 @@ uint64_t WalletImpl::getBytesSent()
return m_wallet->get_bytes_sent();
}
@@ -582,10 +582,10 @@ index d179e502b..fb71a0521 100644
+
} // namespace
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index edf8bb8ce..6bfb61cb8 100644
+index a50983a69..194f21ebe 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -301,6 +301,20 @@ private:
+@@ -302,6 +302,20 @@ 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{};
@@ -607,10 +607,10 @@ index edf8bb8ce..6bfb61cb8 100644
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index 764adbfbf..f433b064f 100644
+index a5164260f..7d250bf8b 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -1150,6 +1150,19 @@ struct Wallet
+@@ -1146,6 +1146,19 @@ struct Wallet
//! get bytes sent
virtual uint64_t getBytesSent() = 0;
@@ -631,10 +631,10 @@ index 764adbfbf..f433b064f 100644
/**
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
-index e81b8f83a..277be6ac9 100644
+index b18333e8f..bd92f7829 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,
+@@ -184,10 +184,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
{
@@ -654,5 +654,5 @@ index e81b8f83a..277be6ac9 100644
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0007-polyseed.patch b/patches/monero/0007-polyseed.patch
index 5caf7c2..cda07eb 100644
--- a/patches/monero/0007-polyseed.patch
+++ b/patches/monero/0007-polyseed.patch
@@ -1,7 +1,7 @@
-From da0be39a81107060f032c8242c575f04ad61c59f Mon Sep 17 00:00:00 2001
+From 111adbce7b8231974d107c855383611489fbcd8d Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 09:42:37 +0100
-Subject: [PATCH 07/20] polyseed
+Subject: [PATCH 07/22] polyseed
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
---
@@ -27,9 +27,9 @@ Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
src/wallet/api/wallet2_api.h | 25 ++++
src/wallet/api/wallet_manager.cpp | 9 ++
src/wallet/api/wallet_manager.h | 10 ++
- src/wallet/wallet2.cpp | 100 ++++++++++++--
- src/wallet/wallet2.h | 30 +++-
- 24 files changed, 805 insertions(+), 18 deletions(-)
+ src/wallet/wallet2.cpp | 101 ++++++++++++--
+ src/wallet/wallet2.h | 31 ++++-
+ 24 files changed, 805 insertions(+), 20 deletions(-)
create mode 160000 external/polyseed
create mode 160000 external/utf8proc
create mode 100644 src/polyseed/CMakeLists.txt
@@ -39,10 +39,10 @@ Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
create mode 100644 src/polyseed/polyseed.hpp
diff --git a/.gitmodules b/.gitmodules
-index 72af74d55..b838e84e0 100644
+index 57fdfbfc8..d768ea541 100644
--- a/.gitmodules
+++ b/.gitmodules
-@@ -11,6 +11,12 @@
+@@ -5,6 +5,12 @@
path = external/randomx
url = https://github.com/MrCyjaneK/RandomX
branch = cyjan-fix-ios
@@ -56,29 +56,29 @@ index 72af74d55..b838e84e0 100644
path = external/supercop
url = https://github.com/monero-project/supercop
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index eb0d12225..390339523 100644
+index 8451e7959..7b8e9a965 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -371,6 +371,8 @@ if(NOT MANUAL_SUBMODULES)
- check_submodule(external/trezor-common)
+@@ -391,6 +391,8 @@ if(NOT MANUAL_SUBMODULES)
check_submodule(external/randomx)
check_submodule(external/supercop)
+ check_submodule(external/mx25519)
+ check_submodule(external/polyseed)
+ check_submodule(external/utf8proc)
endif()
endif()
-@@ -460,7 +462,7 @@ endif()
- # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
- # set(BSDI TRUE)
+@@ -462,7 +464,7 @@ elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
+ set(BSDI TRUE)
+ endif()
--include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
-+include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/polyseed/include external/utf8proc)
+-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include)
++include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include external/polyseed/include external/utf8proc)
- if(APPLE)
- cmake_policy(SET CMP0042 NEW)
+ if(MINGW)
+ set(DEFAULT_STATIC true)
diff --git a/contrib/epee/include/wipeable_string.h b/contrib/epee/include/wipeable_string.h
-index 65977cd97..594e15de4 100644
+index 0a324c159..16c4a8539 100644
--- a/contrib/epee/include/wipeable_string.h
+++ b/contrib/epee/include/wipeable_string.h
@@ -34,6 +34,7 @@
@@ -103,7 +103,7 @@ index 65977cd97..594e15de4 100644
private:
void grow(size_t sz, size_t reserved = 0);
diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp
-index b016f2f48..f2f365b1b 100644
+index 5d4d87d8e..ce1a3baf0 100644
--- a/contrib/epee/src/wipeable_string.cpp
+++ b/contrib/epee/src/wipeable_string.cpp
@@ -261,4 +261,14 @@ wipeable_string &wipeable_string::operator=(const wipeable_string &other)
@@ -122,10 +122,10 @@ index b016f2f48..f2f365b1b 100644
+
}
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
-index 074e23f16..f7e35f98f 100644
+index 900684b6d..3bb8186ca 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
-@@ -70,5 +70,7 @@ endif()
+@@ -31,6 +31,8 @@
add_subdirectory(db_drivers)
add_subdirectory(easylogging++)
add_subdirectory(qrcodegen)
@@ -133,6 +133,7 @@ index 074e23f16..f7e35f98f 100644
+add_subdirectory(utf8proc EXCLUDE_FROM_ALL)
add_subdirectory(bc-ur)
add_subdirectory(randomx EXCLUDE_FROM_ALL)
+ add_subdirectory(mx25519)
diff --git a/external/polyseed b/external/polyseed
new file mode 160000
index 000000000..bd79f5014
@@ -148,10 +149,10 @@ index 000000000..3de4596fb
@@ -0,0 +1 @@
+Subproject commit 3de4596fbe28956855df2ecb3c11c0bbc3535838
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 3335d3c21..06b708cf0 100644
+index bf8d1cb51..40b004bb7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
-@@ -95,6 +95,7 @@ add_subdirectory(net)
+@@ -96,6 +96,7 @@ add_subdirectory(net)
add_subdirectory(hardforks)
add_subdirectory(blockchain_db)
add_subdirectory(mnemonics)
@@ -160,19 +161,19 @@ index 3335d3c21..06b708cf0 100644
if(NOT IOS)
add_subdirectory(serialization)
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
-index 1414be1b2..414936a05 100644
+index 0b6bf9790..95d54d599 100644
--- a/src/cryptonote_basic/CMakeLists.txt
+++ b/src/cryptonote_basic/CMakeLists.txt
-@@ -71,6 +71,7 @@ target_link_libraries(cryptonote_basic
- checkpoints
+@@ -72,6 +72,7 @@ target_link_libraries(cryptonote_basic
cryptonote_format_utils_basic
device
+ ringct_basic
+ polyseed_wrapper
+ ${Boost_CHRONO_LIBRARY}
${Boost_DATE_TIME_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
- ${Boost_SERIALIZATION_LIBRARY}
diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp
-index 4e87d4477..2d556f285 100644
+index 3ba5638bf..aaacf08e4 100644
--- a/src/cryptonote_basic/account.cpp
+++ b/src/cryptonote_basic/account.cpp
@@ -87,12 +87,16 @@ DISABLE_VS_WARNINGS(4244 4345)
@@ -225,7 +226,7 @@ index 4e87d4477..2d556f285 100644
{
m_keys.m_account_address.m_spend_public_key = spend_public_key;
diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h
-index 93d1d28f0..1f76febce 100644
+index de5912032..ce6707b12 100644
--- a/src/cryptonote_basic/account.h
+++ b/src/cryptonote_basic/account.h
@@ -33,6 +33,7 @@
@@ -263,10 +264,10 @@ index 93d1d28f0..1f76febce 100644
const account_keys& get_keys() const;
std::string get_public_address_str(network_type nettype) const;
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
-index 82891b9de..26200bf34 100644
+index 476a79e25..556eef259 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
-@@ -211,6 +211,8 @@
+@@ -244,6 +244,8 @@
#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
@@ -507,7 +508,7 @@ index 000000000..231a48a94
+ }
+
+ result = utf8proc_reencode(buffer, result, options);
-+ if (result < 0 || result > POLYSEED_STR_SIZE) {
++ if (result < 0 || result > (POLYSEED_STR_SIZE - 1)) {
+ throw std::runtime_error("Unicode normalization failed");
+ }
+
@@ -814,10 +815,10 @@ index 000000000..2c8c777a7
+#endif //POLYSEED_HPP
\ No newline at end of file
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index fb71a0521..17a98c066 100644
+index 98f36bdb6..6eb63882c 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -728,6 +728,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
+@@ -705,6 +705,28 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
return true;
}
@@ -846,7 +847,7 @@ index fb71a0521..17a98c066 100644
Wallet::Device WalletImpl::getDeviceType() const
{
return static_cast<Wallet::Device>(m_wallet->get_device_type());
-@@ -845,6 +867,54 @@ std::string WalletImpl::seed(const std::string& seed_offset) const
+@@ -822,6 +844,54 @@ std::string WalletImpl::seed(const std::string& seed_offset) const
}
}
@@ -902,10 +903,10 @@ index fb71a0521..17a98c066 100644
{
return m_wallet->get_seed_language();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index 6bfb61cb8..e7873dd78 100644
+index 194f21ebe..179897da2 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -79,9 +79,19 @@ public:
+@@ -80,9 +80,19 @@ public:
bool recoverFromDevice(const std::string &path,
const std::string &password,
const std::string &device_name);
@@ -926,10 +927,10 @@ index 6bfb61cb8..e7873dd78 100644
void setSeedLanguage(const std::string &arg) override;
// void setListener(Listener *) {}
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index f433b064f..80bfdacb2 100644
+index 7d250bf8b..03597da4e 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -709,6 +709,10 @@ struct Wallet
+@@ -702,6 +702,10 @@ struct Wallet
static void warning(const std::string &category, const std::string &str);
static void error(const std::string &category, const std::string &str);
@@ -940,7 +941,7 @@ index f433b064f..80bfdacb2 100644
/**
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
*/
-@@ -1321,6 +1325,27 @@ struct WalletManager
+@@ -1317,6 +1321,27 @@ struct WalletManager
uint64_t kdf_rounds = 1,
WalletListener * listener = nullptr) = 0;
@@ -969,10 +970,10 @@ index f433b064f..80bfdacb2 100644
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
* \param wallet previously opened / created wallet instance
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
-index 277be6ac9..da2056d8a 100644
+index bd92f7829..4a50ec8cc 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
-@@ -156,6 +156,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
+@@ -152,6 +152,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
return wallet;
}
@@ -989,7 +990,7 @@ index 277be6ac9..da2056d8a 100644
{
WalletImpl * wallet_ = dynamic_cast<WalletImpl*>(wallet);
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
-index a223e1df9..28fcd36c9 100644
+index 45a9f010f..793ac492c 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -75,6 +75,16 @@ public:
@@ -1010,28 +1011,28 @@ index a223e1df9..28fcd36c9 100644
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
-index a8db99c3f..972310343 100644
+index 79cab37a4..a79ce5382 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -92,6 +92,7 @@ using namespace epee;
- #include "device/device_cold.hpp"
- #include "device_trezor/device_trezor.hpp"
- #include "net/socks_connect.h"
+@@ -106,6 +106,7 @@ using namespace epee;
+ #include "tx_builder.h"
+ #include "tx_builder_serialization.h"
+ #include "hot_cold_serialization.h" //! @TODO: remove line after #52 is merged
+#include "polyseed/include/polyseed.h"
extern "C"
{
-@@ -1281,7 +1282,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
- m_enable_multisig(false),
- m_pool_info_query_time(0),
+@@ -1299,7 +1300,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_has_ever_refreshed_from_node(false),
-- m_allow_mismatched_daemon_version(false)
-+ m_allow_mismatched_daemon_version(false),
+ m_allow_mismatched_daemon_version(false),
+ m_curve_trees(fcmp_pp::curve_trees::curve_trees_v1()),
+- m_tree_cache(fcmp_pp::curve_trees::TreeCacheV1(m_curve_trees, m_max_reorg_depth))
++ m_tree_cache(fcmp_pp::curve_trees::TreeCacheV1(m_curve_trees, m_max_reorg_depth)),
+ m_polyseed(false)
{
- set_rpc_client_secret_key(rct::rct2sk(rct::skGen()));
}
-@@ -1486,6 +1488,20 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
+
+@@ -1503,6 +1505,20 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -1051,8 +1052,8 @@ index a8db99c3f..972310343 100644
+//----------------------------------------------------------------------------------------------------
bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase) const
{
- bool ready;
-@@ -4877,6 +4893,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const crypt
+ const multisig::multisig_account_status ms_status{get_multisig_status()};
+@@ -5152,6 +5168,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const crypt
value2.SetInt(m_enable_multisig ? 1 : 0);
json.AddMember("enable_multisig", value2, json.GetAllocator());
@@ -1062,7 +1063,7 @@ index a8db99c3f..972310343 100644
if (m_background_sync_type == BackgroundSyncCustomPassword && !background_keys_file && m_custom_background_key)
{
value.SetString(reinterpret_cast<const char*>(m_custom_background_key.get().data()), m_custom_background_key.get().size());
-@@ -5116,6 +5135,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
+@@ -5385,6 +5404,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
m_enable_multisig = false;
m_allow_mismatched_daemon_version = false;
m_custom_background_key = boost::none;
@@ -1070,7 +1071,7 @@ index a8db99c3f..972310343 100644
}
else if(json.IsObject())
{
-@@ -5356,6 +5376,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
+@@ -5611,6 +5631,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, background_sync_type, BackgroundSyncType, Int, false, BackgroundSyncOff);
m_background_sync_type = field_background_sync_type;
@@ -1080,7 +1081,7 @@ index a8db99c3f..972310343 100644
// Load encryption key used to encrypt background cache
crypto::chacha_key custom_background_key;
m_custom_background_key = boost::none;
-@@ -5675,6 +5698,48 @@ void wallet2::init_type(hw::device::device_type device_type)
+@@ -5942,6 +5965,48 @@ void wallet2::init_type(hw::device::device_type device_type)
m_key_device_type = device_type;
}
@@ -1129,7 +1130,7 @@ index a8db99c3f..972310343 100644
/*!
* \brief Generates a wallet or restores one. Assumes the multisig setup
* has already completed for the provided multisig info.
-@@ -5802,7 +5867,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
+@@ -6069,7 +6134,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
return retval;
}
@@ -1138,7 +1139,7 @@ index a8db99c3f..972310343 100644
{
// -1 month for fluctuations in block time and machine date/time setup.
// avg seconds per block
-@@ -5826,7 +5891,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
+@@ -6093,7 +6158,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
// the daemon is currently syncing.
// If we use the approximate height we subtract one month as
// a safety margin.
@@ -1147,25 +1148,27 @@ index a8db99c3f..972310343 100644
uint64_t target_height = get_daemon_blockchain_target_height(err);
if (err.empty()) {
if (target_height < height)
-@@ -13661,7 +13726,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
+@@ -13227,7 +13292,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
return target_height;
}
-uint64_t wallet2::get_approximate_blockchain_height() const
+uint64_t wallet2::get_approximate_blockchain_height(uint64_t t) const
{
- // time of v2 fork
- const time_t fork_time = m_nettype == TESTNET ? 1448285909 : m_nettype == STAGENET ? 1520937818 : 1458748658;
-@@ -13670,7 +13735,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const
+ const size_t wallet_num_hard_forks = m_nettype == TESTNET ? num_testnet_hard_forks
+ : m_nettype == STAGENET ? num_stagenet_hard_forks
+@@ -13241,9 +13306,8 @@ uint64_t wallet2::get_approximate_blockchain_height() const
+ const uint64_t fork_block = wallet_hard_forks[wallet_num_hard_forks-1].height;
// avg seconds per block
const int seconds_per_block = DIFFICULTY_TARGET_V2;
- // Calculated blockchain height
-- uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block;
-+ uint64_t approx_blockchain_height = fork_block + ((t > 0 ? t : time(NULL)) - fork_time)/seconds_per_block;
+- // Calculated blockchain height
+ uint64_t approx_blockchain_height = fork_block;
+- const time_t now = time(NULL);
++ const time_t now = t > 0 ? static_cast<time_t>(t) : time(NULL);
+ if (now > fork_time)
+ approx_blockchain_height += (now - fork_time) / seconds_per_block;
// testnet and stagenet got some huge rollbacks, so the estimation is way off
- static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : m_nettype == STAGENET ? 60000 : 30000;
- if ((m_nettype == TESTNET || m_nettype == STAGENET) && approx_blockchain_height > approximate_rolled_back_blocks)
-@@ -15796,15 +15861,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
+@@ -15386,15 +15450,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day)
{
@@ -1181,7 +1184,7 @@ index a8db99c3f..972310343 100644
std::tm date = { 0, 0, 0, 0, 0, 0, 0, 0 };
date.tm_year = year - 1900;
date.tm_mon = month - 1;
-@@ -15813,7 +15869,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
+@@ -15403,7 +15458,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
{
throw std::runtime_error("month or day out of range");
}
@@ -1206,18 +1209,19 @@ index a8db99c3f..972310343 100644
uint64_t height_min = 0;
uint64_t height_max = get_daemon_blockchain_height(err) - 1;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
-index 18e60d89a..419272a54 100644
+index aa70d5662..9b0660a1c 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -72,6 +72,7 @@
+@@ -72,7 +72,7 @@
#include "message_store.h"
- #include "wallet_light_rpc.h"
- #include "wallet_rpc_helpers.h"
+ #include "fee_priority.h"
+ #include "fee_algorithm.h"
+-#include "wallet2_basic/wallet2_types.h"
+#include "polyseed/polyseed.hpp"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.wallet2"
-@@ -921,6 +922,20 @@ private:
+@@ -397,6 +397,20 @@ private:
void generate(const std::string& wallet_, const epee::wipeable_string& password,
const epee::wipeable_string& multisig_data, bool create_address_file = false);
@@ -1238,7 +1242,7 @@ index 18e60d89a..419272a54 100644
/*!
* \brief Generates a wallet or restores one.
* \param wallet_ Name of wallet file
-@@ -1095,6 +1110,15 @@ private:
+@@ -596,6 +610,15 @@ private:
bool is_deterministic() const;
bool get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase = epee::wipeable_string()) const;
@@ -1252,9 +1256,9 @@ index 18e60d89a..419272a54 100644
+ bool get_polyseed(epee::wipeable_string& seed, epee::wipeable_string &passphrase) const;
+
/*!
- * \brief Checks if light wallet. A light wallet sends view key to a server where the blockchain is scanned.
- */
-@@ -1570,8 +1594,8 @@ private:
+ * \brief Gets the seed language
+ */
+@@ -1127,8 +1150,8 @@ private:
/*!
* \brief Calculates the approximate blockchain height from current date/time.
*/
@@ -1265,7 +1269,7 @@ index 18e60d89a..419272a54 100644
std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct);
std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
std::vector<size_t> select_available_unmixable_outputs();
-@@ -1665,6 +1689,7 @@ private:
+@@ -1222,6 +1245,7 @@ private:
bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error);
uint64_t get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day); // 1<=month<=12, 1<=day<=31
@@ -1273,7 +1277,7 @@ index 18e60d89a..419272a54 100644
bool is_synced();
-@@ -2011,6 +2036,7 @@ private:
+@@ -1605,6 +1629,7 @@ private:
std::string seed_language; /*!< Language of the mnemonics (seed). */
bool is_old_file_format; /*!< Whether the wallet file is of an old file format */
bool m_watch_only; /*!< no spend key */
@@ -1282,5 +1286,5 @@ index 18e60d89a..419272a54 100644
uint32_t m_multisig_threshold;
std::vector<crypto::public_key> m_multisig_signers;
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0008-coin-control.patch b/patches/monero/0008-coin-control.patch
index 0ed4fb2..7f444b8 100644
--- a/patches/monero/0008-coin-control.patch
+++ b/patches/monero/0008-coin-control.patch
@@ -1,7 +1,7 @@
-From 6811bdac7b98fd29c0566e758fc2d4353b9c3cec Mon Sep 17 00:00:00 2001
+From 6999bacded86031ec5e517ffaaee5fa29784aa92 Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 11:07:57 +0100
-Subject: [PATCH 08/20] coin control
+Subject: [PATCH 08/22] coin control
---
src/simplewallet/simplewallet.cpp | 2 +-
@@ -13,19 +13,19 @@ Subject: [PATCH 08/20] coin control
src/wallet/api/wallet.cpp | 170 +++++++++++++++++++++------
src/wallet/api/wallet.h | 10 +-
src/wallet/api/wallet2_api.h | 52 ++++++++-
- src/wallet/wallet2.cpp | 46 +++++++-
- src/wallet/wallet2.h | 11 +-
- 11 files changed, 667 insertions(+), 51 deletions(-)
+ src/wallet/wallet2.cpp | 43 ++++++-
+ src/wallet/wallet2.h | 10 +-
+ 11 files changed, 665 insertions(+), 49 deletions(-)
create mode 100644 src/wallet/api/coins.cpp
create mode 100644 src/wallet/api/coins.h
create mode 100644 src/wallet/api/coins_info.cpp
create mode 100644 src/wallet/api/coins_info.h
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
-index 39bf169f3..40e25e1d0 100644
+index c0a47e6de..22f29f813 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
-@@ -6917,7 +6917,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
+@@ -6638,7 +6638,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
{
// figure out what tx will be necessary
auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra,
@@ -35,7 +35,7 @@ index 39bf169f3..40e25e1d0 100644
if (ptx_vector.empty())
{
diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt
-index af7948d8a..bb740e2ac 100644
+index 06d8db925..aaa465420 100644
--- a/src/wallet/api/CMakeLists.txt
+++ b/src/wallet/api/CMakeLists.txt
@@ -40,7 +40,9 @@ set(wallet_api_sources
@@ -504,7 +504,7 @@ index 000000000..c43e45abd
+
+#endif //FEATHER_COINS_INFO_H
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 17a98c066..1b86404be 100644
+index 6eb63882c..6a27168b5 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -35,6 +35,7 @@
@@ -515,7 +515,7 @@ index 17a98c066..1b86404be 100644
#include "subaddress_account.h"
#include "common_defines.h"
#include "common/util.h"
-@@ -473,6 +474,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
+@@ -450,6 +451,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
m_wallet->set_refresh_enabled(false);
m_addressBook.reset(new AddressBookImpl(this));
m_subaddress.reset(new SubaddressImpl(this));
@@ -523,7 +523,7 @@ index 17a98c066..1b86404be 100644
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
-@@ -2046,7 +2048,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat
+@@ -2005,7 +2007,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat
// - unconfirmed_transfer_details;
// - confirmed_transfer_details)
@@ -532,7 +532,7 @@ index 17a98c066..1b86404be 100644
{
clearStatus();
-@@ -2083,57 +2085,116 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -2042,57 +2044,116 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
break;
}
}
@@ -683,7 +683,7 @@ index 17a98c066..1b86404be 100644
}
pendingTxPostProcess(transaction);
-@@ -2157,6 +2218,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -2116,6 +2177,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
writer << boost::format(tr("not enough money to transfer, available only %s, sent amount %s")) %
print_money(e.available()) %
print_money(e.tx_amount());
@@ -700,7 +700,7 @@ index 17a98c066..1b86404be 100644
setStatusError(writer.str());
} catch (const tools::error::not_enough_money& e) {
std::ostringstream writer;
-@@ -2164,6 +2235,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -2123,6 +2194,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
writer << boost::format(tr("not enough money to transfer, overall balance only %s, sent amount %s")) %
print_money(e.available()) %
print_money(e.tx_amount());
@@ -717,7 +717,7 @@ index 17a98c066..1b86404be 100644
setStatusError(writer.str());
} catch (const tools::error::tx_not_possible& e) {
std::ostringstream writer;
-@@ -2173,6 +2254,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -2132,6 +2213,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
print_money(e.tx_amount() + e.fee()) %
print_money(e.tx_amount()) %
print_money(e.fee());
@@ -734,7 +734,7 @@ index 17a98c066..1b86404be 100644
setStatusError(writer.str());
} catch (const tools::error::not_enough_outs_to_mix& e) {
std::ostringstream writer;
-@@ -2214,10 +2305,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
+@@ -2173,10 +2264,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
}
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> amount, uint32_t mixin_count,
@@ -747,7 +747,7 @@ index 17a98c066..1b86404be 100644
}
PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
-@@ -2342,6 +2433,11 @@ AddressBook *WalletImpl::addressBook()
+@@ -2302,6 +2393,11 @@ AddressBook *WalletImpl::addressBook()
return m_addressBook.get();
}
@@ -760,10 +760,10 @@ index 17a98c066..1b86404be 100644
{
return m_subaddress.get();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index e7873dd78..bc782dd4a 100644
+index 179897da2..21af6f510 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -46,6 +46,7 @@ class PendingTransactionImpl;
+@@ -47,6 +47,7 @@ class PendingTransactionImpl;
class UnsignedTransactionImpl;
class AddressBookImpl;
class SubaddressImpl;
@@ -771,7 +771,7 @@ index e7873dd78..bc782dd4a 100644
class SubaddressAccountImpl;
struct Wallet2CallbackImpl;
-@@ -167,12 +168,14 @@ public:
+@@ -169,12 +170,14 @@ public:
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
@@ -788,7 +788,7 @@ index e7873dd78..bc782dd4a 100644
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
bool submitTransactionUR(const std::string &input) override;
-@@ -201,6 +204,7 @@ public:
+@@ -203,6 +206,7 @@ public:
PendingTransaction::Priority priority) const override;
virtual TransactionHistory * history() override;
virtual AddressBook * addressBook() override;
@@ -803,8 +803,8 @@ index e7873dd78..bc782dd4a 100644
+ friend class CoinsImpl;
friend class SubaddressImpl;
friend class SubaddressAccountImpl;
-
-@@ -288,6 +293,7 @@ private:
+ friend class ::WalletApiAccessorTest;
+@@ -289,6 +294,7 @@ private:
std::unique_ptr<Wallet2CallbackImpl> m_wallet2Callback;
std::unique_ptr<AddressBookImpl> m_addressBook;
std::unique_ptr<SubaddressImpl> m_subaddress;
@@ -813,10 +813,10 @@ index e7873dd78..bc782dd4a 100644
// multi-threaded refresh stuff
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index 80bfdacb2..97dd29bde 100644
+index 03597da4e..768a77a5d 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -263,6 +263,51 @@ struct AddressBook
+@@ -255,6 +255,51 @@ struct AddressBook
virtual int lookupPaymentID(const std::string &payment_id) const = 0;
};
@@ -868,7 +868,7 @@ index 80bfdacb2..97dd29bde 100644
struct SubaddressRow {
public:
SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label):
-@@ -856,7 +901,8 @@ struct Wallet
+@@ -858,7 +903,8 @@ struct Wallet
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
@@ -878,7 +878,7 @@ index 80bfdacb2..97dd29bde 100644
/*!
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
-@@ -875,7 +921,8 @@ struct Wallet
+@@ -877,7 +923,8 @@ struct Wallet
optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
@@ -888,7 +888,7 @@ index 80bfdacb2..97dd29bde 100644
/*!
* \brief createSweepUnmixableTransaction creates transaction with unmixable outputs.
-@@ -994,6 +1041,7 @@ struct Wallet
+@@ -996,6 +1043,7 @@ struct Wallet
virtual TransactionHistory * history() = 0;
virtual AddressBook * addressBook() = 0;
@@ -897,10 +897,10 @@ index 80bfdacb2..97dd29bde 100644
virtual SubaddressAccount * subaddressAccount() = 0;
virtual void setListener(WalletListener *) = 0;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
-index 972310343..c50a840b6 100644
+index a79ce5382..89009bc77 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -2136,12 +2136,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const
+@@ -2363,12 +2363,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const
return false;
}
@@ -922,7 +922,7 @@ index 972310343..c50a840b6 100644
void wallet2::thaw(const crypto::key_image &ki)
{
thaw(get_transfer_details(ki));
-@@ -2152,6 +2161,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const
+@@ -2379,6 +2388,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const
return frozen(get_transfer_details(ki));
}
//----------------------------------------------------------------------------------------------------
@@ -941,23 +941,7 @@ index 972310343..c50a840b6 100644
size_t wallet2::get_transfer_details(const crypto::key_image &ki) const
{
for (size_t idx = 0; idx < m_transfers.size(); ++idx)
-@@ -2563,6 +2584,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
- uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount;
- if (!pool)
- {
-+ boost::unique_lock<boost::shared_mutex> lock(m_transfers_mutex);
- m_transfers.push_back(transfer_details{});
- transfer_details& td = m_transfers.back();
- td.m_block_height = height;
-@@ -2666,6 +2688,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
- uint64_t extra_amount = amount - burnt;
- if (!pool)
- {
-+ boost::unique_lock<boost::shared_mutex> lock(m_transfers_mutex);
- transfer_details &td = m_transfers[kit->second];
- td.m_block_height = height;
- td.m_internal_output_index = o;
-@@ -10526,7 +10549,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
+@@ -10573,7 +10594,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("transfer_selected_rct done");
}
@@ -966,7 +950,7 @@ index 972310343..c50a840b6 100644
{
std::vector<size_t> picks;
float current_output_relatdness = 1.0f;
-@@ -10537,6 +10560,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
+@@ -10584,6 +10605,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t i = 0; i < m_transfers.size(); ++i)
{
const transfer_details& td = m_transfers[i];
@@ -976,7 +960,7 @@ index 972310343..c50a840b6 100644
if (!is_spent(td, false) && !td.m_frozen && td.is_rct() && td.amount() >= needed_money && 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)
-@@ -10557,6 +10583,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
+@@ -10604,6 +10628,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t i = 0; i < m_transfers.size(); ++i)
{
const transfer_details& td = m_transfers[i];
@@ -986,7 +970,7 @@ index 972310343..c50a840b6 100644
if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && 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)
-@@ -10568,6 +10597,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
+@@ -10615,6 +10642,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t j = i + 1; j < m_transfers.size(); ++j)
{
const transfer_details& td2 = m_transfers[j];
@@ -996,16 +980,15 @@ index 972310343..c50a840b6 100644
if (td2.amount() > m_ignore_outputs_above || td2.amount() < m_ignore_outputs_below)
{
MDEBUG("Ignoring output " << j << " of amount " << print_money(td2.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
-@@ -11140,7 +11172,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
- // This system allows for sending (almost) the entire balance, since it does
- // not generate spurious change in all txes, thus decreasing the instantaneous
- // usable balance.
--std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
-+std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs)
+@@ -10724,6 +10754,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(
+ const std::vector<uint8_t>& extra,
+ uint32_t subaddr_account,
+ std::set<uint32_t> subaddr_indices,
++ const std::vector<crypto::key_image>& preferred_input_list,
+ const unique_index_container& subtract_fee_from_outputs,
+ const std::size_t max_n_inputs)
{
- //ensure device is let in NONE mode in any case
- hw::device &hwdev = m_account.get_device();
-@@ -11348,6 +11380,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+@@ -10953,6 +10984,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(
for (size_t i = 0; i < m_transfers.size(); ++i)
{
const transfer_details& td = m_transfers[i];
@@ -1015,7 +998,7 @@ index 972310343..c50a840b6 100644
if (m_ignore_fractional_outputs && td.amount() < fractional_threshold)
{
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
-@@ -11439,7 +11474,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
+@@ -11044,7 +11078,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(
// will get us a known fee.
uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : estimated_fee);
@@ -1024,16 +1007,16 @@ index 972310343..c50a840b6 100644
if (!preferred_inputs.empty())
{
string s;
-@@ -11918,7 +11953,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
+@@ -11523,7 +11557,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
return true;
}
--std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
-+std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
+-std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
++std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
{
- std::vector<size_t> unused_transfers_indices;
- std::vector<size_t> unused_dust_indices;
-@@ -11947,6 +11982,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
+ boost::lock_guard refresh_lock(m_refresh_mutex);
+
+@@ -11575,6 +11609,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
for (size_t i = 0; i < m_transfers.size(); ++i)
{
const transfer_details& td = m_transfers[i];
@@ -1044,21 +1027,27 @@ index 972310343..c50a840b6 100644
{
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold));
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
-index 419272a54..d07dc7e8b 100644
+index 9b0660a1c..a46c2e341 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -1223,8 +1223,8 @@ private:
- bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const;
- bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
- bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
-- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
-- std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
-+ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
-+ std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
- std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
- std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
- bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const;
-@@ -1576,6 +1576,7 @@ private:
+@@ -745,6 +745,7 @@ private:
+ const std::vector<uint8_t>& extra,
+ uint32_t subaddr_account,
+ std::set<uint32_t> subaddr_indices, // pass subaddr_indices by value on purpose
++ const std::vector<crypto::key_image>& preferred_input_list = {},
+ const unique_index_container& subtract_fee_from_outputs = {},
+ const std::size_t max_n_inputs = 0);
+ /**
+@@ -762,7 +763,7 @@ private:
+ *
+ * Sweep-all-style means that transactions are added until all inputs <= amount `below` are spent.
+ */
+- std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
++ std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, fee_priority priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
+ /**
+ * brief: create_transactions_single: create "sweep-single" style txs (or tx proposals in hot/cold & multisig wallets)
+ * param: ki - the key image of the input that is to be spent
+@@ -1119,6 +1120,7 @@ private:
uint64_t get_num_rct_outputs();
size_t get_num_transfer_details() const { return m_transfers.size(); }
const transfer_details &get_transfer_details(size_t idx) const;
@@ -1066,7 +1055,7 @@ index 419272a54..d07dc7e8b 100644
uint8_t get_current_hard_fork();
void get_hard_fork_info(uint8_t version, uint64_t &earliest_height);
-@@ -1808,7 +1809,9 @@ private:
+@@ -1339,7 +1341,9 @@ private:
void freeze(size_t idx);
void thaw(size_t idx);
bool frozen(size_t idx) const;
@@ -1076,16 +1065,16 @@ index 419272a54..d07dc7e8b 100644
void thaw(const crypto::key_image &ki);
bool frozen(const crypto::key_image &ki) const;
bool frozen(const transfer_details &td) const;
-@@ -1849,6 +1852,8 @@ private:
-
+@@ -1378,6 +1382,8 @@ private:
static std::string get_default_daemon_address() { CRITICAL_REGION_LOCAL(default_daemon_address_lock); return default_daemon_address; }
-+ boost::shared_mutex m_transfers_mutex;
+ #ifndef IN_UNIT_TESTS
++ boost::shared_mutex m_transfers_mutex;
+
private:
+ #endif
/*!
- * \brief Stores wallet information to wallet file.
-@@ -1920,7 +1925,7 @@ private:
+@@ -1514,7 +1520,7 @@ private:
std::vector<uint64_t> get_unspent_amounts_vector(bool strict);
uint64_t get_dynamic_base_fee_estimate();
float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const;
@@ -1095,5 +1084,5 @@ index 419272a54..d07dc7e8b 100644
void set_unspent(size_t idx);
bool is_spent(const transfer_details &td, bool strict = true) const;
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch b/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch
index df3b9ad..e237ad5 100644
--- a/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch
+++ b/patches/monero/0009-Add-hex-encoding-and-tx-key-getter-for-PendingTransc.patch
@@ -1,7 +1,7 @@
-From 300a5110cccb1e3caf763b1f9bf5dc0ecc0973c8 Mon Sep 17 00:00:00 2001
+From b3c572ffb401da3aafddc72c9127701abcd70ff1 Mon Sep 17 00:00:00 2001
From: M <m@cakewallet.com>
Date: Fri, 21 Apr 2023 15:43:47 -0400
-Subject: [PATCH 09/20] Add hex encoding and tx key getter for
+Subject: [PATCH 09/22] Add hex encoding and tx key getter for
PendingTransction in wallet api.
---
@@ -11,7 +11,7 @@ Subject: [PATCH 09/20] Add hex encoding and tx key getter for
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
+index 919e210f0..796e7a50b 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
@@ -30,7 +30,7 @@ index 9c3c26ee5..1f714d229 100644
+{
+ std::vector<std::string> keys;
+ for (const auto& pt: m_pending_tx)
-+ keys.push_back(epee::string_tools::pod_to_hex(pt.tx_key));
++ keys.push_back(epee::string_tools::pod_to_hex(unwrap(unwrap(pt.tx_key))));
+ return keys;
+}
+
@@ -38,7 +38,7 @@ index 9c3c26ee5..1f714d229 100644
{
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
-index 403bfe281..0cc6c58e9 100644
+index 8a70d774d..eb5c75c5f 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -59,6 +59,8 @@ public:
@@ -51,10 +51,10 @@ index 403bfe281..0cc6c58e9 100644
private:
friend class WalletImpl;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index 97dd29bde..b5cccac40 100644
+index 768a77a5d..34df402e4 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -127,6 +127,8 @@ struct PendingTransaction
+@@ -119,6 +119,8 @@ struct PendingTransaction
* @return vector of base58-encoded signers' public keys
*/
virtual std::vector<std::string> signersKeys() const = 0;
@@ -64,5 +64,5 @@ index 97dd29bde..b5cccac40 100644
/**
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch b/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch
index e8f7538..de08b57 100644
--- a/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch
+++ b/patches/monero/0010-Add-recoverDeterministicWalletFromSpendKey.patch
@@ -1,7 +1,7 @@
-From 3e15968c13d2a7c0098d26e72168a5774d6cdd89 Mon Sep 17 00:00:00 2001
+From f26dc4ee8737fa57da58037134c2d2ed987834a5 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/20] Add recoverDeterministicWalletFromSpendKey
+Subject: [PATCH 10/22] Add recoverDeterministicWalletFromSpendKey
This function is used by Cake Wallet to enable polyseed (dart implementation)
support.
@@ -19,10 +19,10 @@ Co-authored-by: Godwin Asuquo <godilite@gmail.com>
5 files changed, 75 insertions(+)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 1b86404be..00918e357 100644
+index 6a27168b5..a61addbe4 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
+@@ -801,6 +801,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
return status() == Status_Ok;
}
@@ -59,10 +59,10 @@ index 1b86404be..00918e357 100644
{
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index bc782dd4a..bfe81c590 100644
+index 21af6f510..d4b11d96a 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -77,6 +77,10 @@ public:
+@@ -78,6 +78,10 @@ public:
const std::string &address_string,
const std::string &viewkey_string,
const std::string &spendkey_string = "");
@@ -74,10 +74,10 @@ index bc782dd4a..bfe81c590 100644
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 b5cccac40..fcb8187d4 100644
+index 34df402e4..68efcdaf8 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -1324,6 +1324,25 @@ struct WalletManager
+@@ -1320,6 +1320,25 @@ struct WalletManager
return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
}
@@ -104,10 +104,10 @@ index b5cccac40..fcb8187d4 100644
* \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
+index 4a50ec8cc..7ee87d04c 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,
+@@ -123,6 +123,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
return wallet;
}
@@ -131,7 +131,7 @@ index da2056d8a..c200f52ae 100644
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
+index 793ac492c..96373affb 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -67,6 +67,13 @@ public:
@@ -149,5 +149,5 @@ index 28fcd36c9..be3ff8184 100644
const std::string &password,
NetworkType nettype,
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0011-add-monero-submodule-support.patch b/patches/monero/0011-add-monero-submodule-support.patch
index fee1fba..89303c0 100644
--- a/patches/monero/0011-add-monero-submodule-support.patch
+++ b/patches/monero/0011-add-monero-submodule-support.patch
@@ -1,7 +1,7 @@
-From e06b0e86b6b6204bf20c0caadde64da1f0966da1 Mon Sep 17 00:00:00 2001
+From a3e5604fe761d64c7d55c6c9afe29c05c35883ed Mon Sep 17 00:00:00 2001
From: cyan <cyjan@mrcyjanek.net>
Date: Thu, 7 Nov 2024 16:46:24 +0000
-Subject: [PATCH 11/20] add monero submodule support
+Subject: [PATCH 11/22] add monero submodule support
---
CMakeLists.txt | 12 ++++++------
@@ -9,10 +9,10 @@ Subject: [PATCH 11/20] add monero submodule support
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 390339523..d0af390d0 100644
+index 7b8e9a965..2f1aa73b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -75,7 +75,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "nin
+@@ -100,7 +100,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.0.0" AND CMAKE_MAKE_PROGRAM MATCHES "nin
set(CMAKE_JOB_POOL_LINK link_job_pool)
endif ()
endif ()
@@ -21,8 +21,8 @@ index 390339523..d0af390d0 100644
option (USE_CLANG_TIDY_C "Lint the code with clang-tidy - variant C" OFF)
option (USE_CLANG_TIDY_CXX "Lint the code with clang-tidy - variant C++" OFF)
if (USE_CLANG_TIDY_C AND USE_CLANG_TIDY_CXX)
-@@ -223,9 +223,9 @@ function(forbid_undefined_symbols)
- cmake_minimum_required(VERSION 3.5)
+@@ -235,9 +235,9 @@ function(forbid_undefined_symbols)
+ cmake_minimum_required(VERSION 3.10)
project(test)
option(EXPECT_SUCCESS "" ON)
-file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
@@ -33,7 +33,7 @@ index 390339523..d0af390d0 100644
endif()
add_library(l0 SHARED incorrect_source.cpp)
add_library(l1 MODULE incorrect_source.cpp)
-@@ -363,7 +363,7 @@ if(NOT MANUAL_SUBMODULES)
+@@ -384,7 +384,7 @@ if(NOT MANUAL_SUBMODULES)
message(FATAL_ERROR "Submodule '${relative_path}' is not up-to-date. Please update all submodules with\ngit submodule update --init --force\nor run cmake with -DMANUAL_SUBMODULES=1\n")
endif()
endfunction ()
@@ -41,17 +41,17 @@ index 390339523..d0af390d0 100644
+
message(STATUS "Checking submodules")
# check_submodule(external/bc-ur)
- check_submodule(external/miniupnp)
-@@ -390,7 +390,7 @@ else()
+ check_submodule(external/rapidjson)
+@@ -405,7 +405,7 @@ if(PER_BLOCK_CHECKPOINT)
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)")
-@@ -1003,7 +1003,7 @@ else()
+ option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" OFF)
+ if (BOOST_IGNORE_SYSTEM_PATHS)
+@@ -864,7 +864,7 @@ include(CheckTrezor)
# random crash on startup when asan is on if pie is enabled
if(NOT SANITIZE AND ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON" OR IOS)
@@ -61,18 +61,18 @@ index 390339523..d0af390d0 100644
set(PIC_FLAG "")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
-index 0cf75a1c4..66def08ef 100644
+index 6727345ea..5f666ea61 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
-@@ -1261,7 +1261,7 @@ namespace tools
+@@ -1276,7 +1276,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);
+ const fee_priority priority = m_wallet->adjust_priority(fee_priority_utilities::from_integral(req.priority, fee_algo));
- std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, 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, mixin, priority, extra, req.account_index, req.subaddr_indices, {}, req.subtract_fee_from_outputs);
if (ptx_vector.empty())
{
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0012-fix-iOS-depends-build.patch b/patches/monero/0012-fix-iOS-depends-build.patch
index 2e4845e..6e8aea0 100644
--- a/patches/monero/0012-fix-iOS-depends-build.patch
+++ b/patches/monero/0012-fix-iOS-depends-build.patch
@@ -1,49 +1,56 @@
-From 92ca945665cab44adace3331685ae4270a14c07e Mon Sep 17 00:00:00 2001
+From eeab3324de1638a035b28b05d414e2d999c9331a 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/20] fix iOS depends build
+Subject: [PATCH 12/22] 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(-)
+ CMakeLists.txt | 3 ---
+ src/checkpoints/CMakeLists.txt | 14 ++++++++++++++
+ src/cryptonote_basic/CMakeLists.txt | 6 +++++-
+ src/cryptonote_basic/miner.cpp | 8 ++++----
+ 4 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index d0af390d0..b814c76b7 100644
+index 2f1aa73b4..133997f74 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -39,10 +39,6 @@ include(CheckLibraryExists)
- include(CheckFunctionExists)
- include(FindPythonInterp)
+@@ -52,9 +52,6 @@ if (POLICY CMP0179)
+ cmake_policy(SET CMP0179 NEW)
+ endif()
-if (IOS)
- INCLUDE(CmakeLists_IOS.txt)
-endif()
--
- cmake_minimum_required(VERSION 3.5)
- message(STATUS "CMake version ${CMAKE_VERSION}")
+
+ project(monero)
diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt
-index 665441f62..841df3256 100644
+index 5e680e736..939aa3b90 100644
--- a/src/checkpoints/CMakeLists.txt
+++ b/src/checkpoints/CMakeLists.txt
-@@ -28,7 +28,11 @@
+@@ -26,6 +26,20 @@
+ # 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.
- if(APPLE)
- if(DEPENDS)
-- list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework ApplicationServices -framework AppKit -framework IOKit")
++if(APPLE)
++ if(DEPENDS)
+ 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)
++ else()
++ find_library(IOKIT_LIBRARY IOKit)
++ mark_as_advanced(IOKIT_LIBRARY)
++ list(APPEND EXTRA_LIBRARIES ${IOKIT_LIBRARY})
++ endif()
++endif()
++
+ set(checkpoints_sources
+ checkpoints.cpp)
+
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
-index 414936a05..81c81767f 100644
+index 95d54d599..56fc6d274 100644
--- a/src/cryptonote_basic/CMakeLists.txt
+++ b/src/cryptonote_basic/CMakeLists.txt
@@ -28,7 +28,11 @@
@@ -60,10 +67,10 @@ index 414936a05..81c81767f 100644
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
+index 9f702a925..346ed6fd6 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
-@@ -45,7 +45,7 @@
+@@ -46,7 +46,7 @@
#include "boost/logic/tribool.hpp"
#include <boost/filesystem.hpp>
@@ -72,7 +79,7 @@ index 71b8f78cc..0f53f024e 100644
#include <sys/times.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPSKeys.h>
-@@ -883,7 +883,7 @@ namespace cryptonote
+@@ -885,7 +885,7 @@ namespace cryptonote
return true;
@@ -81,7 +88,7 @@ index 71b8f78cc..0f53f024e 100644
mach_msg_type_number_t count;
kern_return_t status;
-@@ -949,7 +949,7 @@ namespace cryptonote
+@@ -951,7 +951,7 @@ namespace cryptonote
return true;
}
@@ -90,7 +97,7 @@ index 71b8f78cc..0f53f024e 100644
struct tms tms;
if ( times(&tms) != (clock_t)-1 )
-@@ -978,7 +978,7 @@ namespace cryptonote
+@@ -980,7 +980,7 @@ namespace cryptonote
return boost::logic::tribool(power_status.ACLineStatus != 1);
}
@@ -100,5 +107,5 @@ index 71b8f78cc..0f53f024e 100644
#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.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch b/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch
index 56c8132..63fc7a8 100644
--- a/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch
+++ b/patches/monero/0013-include-locale-only-when-targeting-WIN32.patch
@@ -1,44 +1,26 @@
-From 60ef2d2a25b07aca8f25ef5016eb4b9b7c253a50 Mon Sep 17 00:00:00 2001
+From 3e83b0212fe9a824ff9e8c399ef86e25c73afa13 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/20] include locale only when targeting WIN32
+Subject: [PATCH 13/22] include locale only when targeting WIN32
---
- CMakeLists.txt | 6 +++++-
- src/wallet/api/wallet.cpp | 2 ++
- 2 files changed, 7 insertions(+), 1 deletion(-)
+ CMakeLists.txt | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index b814c76b7..cef44dd1b 100644
+index 133997f74..95326743c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -1090,7 +1090,11 @@ if(NOT Boost_FOUND)
- elseif(Boost_FOUND)
+@@ -953,7 +953,8 @@ elseif(Boost_FOUND)
message(STATUS "Found Boost Version: ${Boost_VERSION_STRING}")
-- set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options locale)
-+ set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options)
+ set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options)
+- if (WIN32)
+
+ if(WIN32)
-+ list(APPEND BOOST_COMPONENTS locale)
-+ endif()
+ list(APPEND BOOST_COMPONENTS locale)
+ endif()
- # Boost System is header-only since 1.69
- if (Boost_VERSION_STRING VERSION_LESS 1.69.0)
-diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 00918e357..107f516f3 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.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0014-change-earliest-fork-height-message.patch b/patches/monero/0014-change-earliest-fork-height-message.patch
index 3a4321b..5345e0d 100644
--- a/patches/monero/0014-change-earliest-fork-height-message.patch
+++ b/patches/monero/0014-change-earliest-fork-height-message.patch
@@ -1,17 +1,17 @@
-From 7c58eb392e94ff5b50bcb15b8d91038476743ba9 Mon Sep 17 00:00:00 2001
+From 513d714b87d2a00e1fcf84d2b0be88acdef32e76 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/20] change earliest fork height message
+Subject: [PATCH 14/22] 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 c50a840b6..a7532d7ec 100644
+index 89009bc77..06a732296 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -12380,7 +12380,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks)
+@@ -12053,7 +12053,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);
@@ -21,5 +21,5 @@ index c50a840b6..a7532d7ec 100644
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.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0015-remove-trivially_copyable-assert.patch b/patches/monero/0015-remove-trivially_copyable-assert.patch
index 8113bdd..d3293fe 100644
--- a/patches/monero/0015-remove-trivially_copyable-assert.patch
+++ b/patches/monero/0015-remove-trivially_copyable-assert.patch
@@ -1,24 +1,34 @@
-From dc67abfbc3dec2f4aa4c4157378509c9ee07cb0b Mon Sep 17 00:00:00 2001
+From 011bbbadc9388105e44524d59b7468ecf6c863a9 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 20 Feb 2025 08:36:28 +0100
-Subject: [PATCH 15/20] remove trivially_copyable assert
+Subject: [PATCH 15/22] remove trivially_copyable assert
---
- contrib/epee/include/span.h | 1 -
- 1 file changed, 1 deletion(-)
+ contrib/epee/include/span.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h
-index 01dc387d6..2ad733a2f 100644
+index ccc55db53..2774881a1 100644
--- a/contrib/epee/include/span.h
+++ b/contrib/epee/include/span.h
-@@ -162,7 +162,6 @@ namespace epee
+@@ -159,7 +159,7 @@ 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");
+ static_assert(std::is_standard_layout_v<T>, "type must have standard layout");
+- static_assert(std::has_unique_object_representations_v<T>, "type must be trivially copyable with no padding");
++ static_assert(alignof(T) == 1, "type may have padding");
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
}
+
+@@ -169,7 +169,7 @@ namespace epee
+ {
+ static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
+ static_assert(std::is_standard_layout_v<T>, "type must have standard layout");
+- static_assert(std::has_unique_object_representations_v<T>, "type must be trivially copyable with no padding");
++ static_assert(alignof(T) == 1, "type may have padding");
+ return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
+ }
+
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0016-serialize-cache-to-JSON.patch b/patches/monero/0016-serialize-cache-to-JSON.patch
index 38aaee4..b2171c2 100644
--- a/patches/monero/0016-serialize-cache-to-JSON.patch
+++ b/patches/monero/0016-serialize-cache-to-JSON.patch
@@ -1,7 +1,7 @@
-From e6785290c24eb48d6b6aec8e1831b96f65cd3bfd Mon Sep 17 00:00:00 2001
+From 0c287081f916066ba227fb24044d26950a767a59 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 12 Aug 2025 07:09:14 -0400
-Subject: [PATCH 16/20] serialize cache to JSON
+Subject: [PATCH 16/22] serialize cache to JSON
---
src/wallet/CMakeLists.txt | 1 +
@@ -9,27 +9,27 @@ Subject: [PATCH 16/20] serialize cache to JSON
src/wallet/api/wallet.h | 2 +
src/wallet/api/wallet2_api.h | 3 +
src/wallet/wallet2.h | 6 +
- src/wallet/wallet_cache_to_json.cpp | 368 ++++++++++++++++++++++++++++
- 6 files changed, 385 insertions(+)
+ src/wallet/wallet_cache_to_json.cpp | 334 ++++++++++++++++++++++++++++
+ 6 files changed, 351 insertions(+)
create mode 100644 src/wallet/wallet_cache_to_json.cpp
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
-index b163212b7..196ad671f 100644
+index db7c3c06b..4c80e64a4 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
-@@ -38,6 +38,7 @@ set(wallet_sources
- message_store.cpp
+@@ -40,6 +40,7 @@ set(wallet_sources
message_transporter.cpp
- wallet_rpc_payments.cpp
+ scanning_tools.cpp
+ tx_builder.cpp
+ wallet_cache_to_json.cpp
)
monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index 107f516f3..c24b4a97d 100644
+index a61addbe4..57f1203c6 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -3474,4 +3474,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command
+@@ -3431,4 +3431,9 @@ void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command
#endif
}
@@ -40,10 +40,10 @@ index 107f516f3..c24b4a97d 100644
+
} // namespace
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index bfe81c590..98c03b9c1 100644
+index d4b11d96a..8e4846e27 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -335,6 +335,8 @@ private:
+@@ -336,6 +336,8 @@ private:
bool getWaitsForDeviceSend();
bool getWaitsForDeviceReceive();
@@ -53,10 +53,10 @@ index bfe81c590..98c03b9c1 100644
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index fcb8187d4..3d11929f9 100644
+index 68efcdaf8..4552c02d0 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -1217,6 +1217,9 @@ struct Wallet
+@@ -1213,6 +1213,9 @@ struct Wallet
static void setDeviceReceivedData(unsigned char* data, size_t len);
static void setDeviceSendData(unsigned char* data, size_t len);
static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len));
@@ -67,11 +67,11 @@ index fcb8187d4..3d11929f9 100644
/**
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
-index d07dc7e8b..37a2447d2 100644
+index a46c2e341..42e1c02d9 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -1436,6 +1436,12 @@ private:
- FIELD(m_background_sync_data)
+@@ -993,6 +993,12 @@ private:
+ FIELD(m_tree_cache)
END_SERIALIZE()
+ /*!
@@ -85,16 +85,15 @@ index d07dc7e8b..37a2447d2 100644
* \param file_path Wallet file path
diff --git a/src/wallet/wallet_cache_to_json.cpp b/src/wallet/wallet_cache_to_json.cpp
new file mode 100644
-index 000000000..4743852ca
+index 000000000..cbeba044e
--- /dev/null
+++ b/src/wallet/wallet_cache_to_json.cpp
-@@ -0,0 +1,368 @@
+@@ -0,0 +1,334 @@
+#include "wallet2.h"
-+#include "serialization/binary_archive.h"
++#include "wallet2_basic/wallet2_serialization.h"
+#include "serialization/json_archive.h"
+#include "serialization/serialization.h"
+#include <sstream>
-+#include <iomanip>
+
+namespace tools
+{
@@ -182,11 +181,10 @@ index 000000000..4743852ca
+ try
+ {
+ std::stringstream oss;
-+ json_archive<true> ar(oss, true); // true for pretty printing
++ json_archive<true> ar(oss, true);
+
+ ar.begin_object();
+
-+ // MAGIC_FIELD("monero wallet cache")
+ std::string magic = "monero wallet cache";
+ ar.tag("magic");
+ ar.serialize_blob((void*)magic.data(), magic.size());
@@ -195,8 +193,7 @@ index 000000000..4743852ca
+ return json_result.c_str();
+ }
+
-+ // VERSION_FIELD(2)
-+ uint32_t version = 2;
++ uint32_t version = 3;
+ ar.tag("version");
+ ar.serialize_varint(version);
+ if (!ar.good()) {
@@ -204,112 +201,96 @@ index 000000000..4743852ca
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_blockchain) - hashchain type, has serialization support
+ ar.tag("m_blockchain");
+ if (!::serialization::serialize(ar, const_cast<hashchain&>(m_blockchain))) {
+ json_result = "{\"error\":\"Failed to serialize m_blockchain\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_transfers) - transfer_container (std::vector<transfer_details>)
+ ar.tag("m_transfers");
+ if (!::serialization::serialize(ar, const_cast<transfer_container&>(m_transfers))) {
+ json_result = "{\"error\":\"Failed to serialize m_transfers\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_account_public_address) - cryptonote::account_public_address
+ ar.tag("m_account_public_address");
+ if (!::serialization::serialize(ar, const_cast<cryptonote::account_public_address&>(m_account_public_address))) {
+ json_result = "{\"error\":\"Failed to serialize m_account_public_address\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_key_images) - serializable_unordered_map<crypto::key_image, size_t>
+ ar.tag("m_key_images");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::key_image, size_t>&>(m_key_images))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_key_images)&>(m_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_key_images\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_unconfirmed_txs) - serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>
+ ar.tag("m_unconfirmed_txs");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, unconfirmed_transfer_details>&>(m_unconfirmed_txs))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_unconfirmed_txs)&>(m_unconfirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_txs\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_payments) - payment_container (serializable_unordered_multimap<crypto::hash, payment_details>)
+ ar.tag("m_payments");
+ if (!::serialization::serialize(ar, const_cast<payment_container&>(m_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_payments\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_tx_keys) - serializable_unordered_map<crypto::hash, crypto::secret_key>
+ ar.tag("m_tx_keys");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, crypto::secret_key>&>(m_tx_keys))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_tx_keys)&>(m_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_keys\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_confirmed_txs) - serializable_unordered_map<crypto::hash, confirmed_transfer_details>
+ ar.tag("m_confirmed_txs");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, confirmed_transfer_details>&>(m_confirmed_txs))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_confirmed_txs)&>(m_confirmed_txs))) {
+ json_result = "{\"error\":\"Failed to serialize m_confirmed_txs\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_tx_notes) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_notes");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_notes))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_tx_notes)&>(m_tx_notes))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_notes\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_unconfirmed_payments) - serializable_unordered_multimap<crypto::hash, pool_payment_details>
+ ar.tag("m_unconfirmed_payments");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_multimap<crypto::hash, pool_payment_details>&>(m_unconfirmed_payments))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_unconfirmed_payments)&>(m_unconfirmed_payments))) {
+ json_result = "{\"error\":\"Failed to serialize m_unconfirmed_payments\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_pub_keys) - serializable_unordered_map<crypto::public_key, size_t>
+ ar.tag("m_pub_keys");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, size_t>&>(m_pub_keys))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_pub_keys)&>(m_pub_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_pub_keys\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_address_book) - std::vector<tools::wallet2::address_book_row>
+ ar.tag("m_address_book");
-+ if (!::serialization::serialize(ar, const_cast<std::vector<tools::wallet2::address_book_row>&>(m_address_book))) {
++ if (!::serialization::serialize(ar, const_cast<std::vector<address_book_row>&>(m_address_book))) {
+ json_result = "{\"error\":\"Failed to serialize m_address_book\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_scanned_pool_txs[0]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_0");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[0]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[0]\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_scanned_pool_txs[1]) - std::unordered_set<crypto::hash>
+ ar.tag("m_scanned_pool_txs_1");
+ if (!::serialization::serialize(ar, const_cast<std::unordered_set<crypto::hash>&>(m_scanned_pool_txs[1]))) {
+ json_result = "{\"error\":\"Failed to serialize m_scanned_pool_txs[1]\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_subaddresses) - serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>
+ ar.tag("m_subaddresses");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index>&>(m_subaddresses))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_subaddresses)&>(m_subaddresses))) {
+ json_result = "{\"error\":\"Failed to serialize m_subaddresses\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_subaddress_labels) - std::vector<std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_subaddress_labels\": [";
+ for (size_t i = 0; i < m_subaddress_labels.size(); ++i) {
+ if (i > 0) oss << ", ";
@@ -324,14 +305,12 @@ index 000000000..4743852ca
+ }
+ oss << "\n ]";
+
-+ // FIELD(m_additional_tx_keys) - serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>
+ ar.tag("m_additional_tx_keys");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>>&>(m_additional_tx_keys))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_additional_tx_keys)&>(m_additional_tx_keys))) {
+ json_result = "{\"error\":\"Failed to serialize m_additional_tx_keys\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_attributes) - serializable_unordered_map<std::string, std::string> - manual JSON serialization
+ oss << ", \n \"m_attributes\": {";
+ bool first_attr = true;
+ for (const auto& attr : m_attributes) {
@@ -345,7 +324,6 @@ index 000000000..4743852ca
+ }
+ oss << "\n }";
+
-+ // FIELD(m_account_tags) - std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> - manual JSON serialization
+ oss << ", \n \"m_account_tags\": {";
+ oss << "\n \"tags_map\": {";
+ bool first_tag = true;
@@ -369,15 +347,12 @@ index 000000000..4743852ca
+ oss << "\n ]";
+ oss << "\n }";
+
-+ // FIELD(m_ring_history_saved) - bool
-+ // ar.tag("m_ring_history_saved");
-+ // ar.serialize_blob(&m_ring_history_saved, sizeof(m_ring_history_saved));
-+ // if (!ar.good()) {
-+ // json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}";
-+ // return json_result.c_str();
-+ // }
++ ar.tag("m_ring_history_saved");
++ if (!::serialization::serialize(ar, const_cast<bool&>(m_ring_history_saved))) {
++ json_result = "{\"error\":\"Failed to serialize m_ring_history_saved\"}";
++ return json_result.c_str();
++ }
+
-+ // FIELD(m_last_block_reward) - uint64_t
+ ar.tag("m_last_block_reward");
+ ar.serialize_int(m_last_block_reward);
+ if (!ar.good()) {
@@ -385,14 +360,12 @@ index 000000000..4743852ca
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_tx_device) - serializable_unordered_map<crypto::hash, std::string>
+ ar.tag("m_tx_device");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::hash, std::string>&>(m_tx_device))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_tx_device)&>(m_tx_device))) {
+ json_result = "{\"error\":\"Failed to serialize m_tx_device\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_device_last_key_image_sync) - uint64_t
+ ar.tag("m_device_last_key_image_sync");
+ ar.serialize_int(m_device_last_key_image_sync);
+ if (!ar.good()) {
@@ -400,34 +373,21 @@ index 000000000..4743852ca
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_cold_key_images) - serializable_unordered_map<crypto::public_key, crypto::key_image>
+ ar.tag("m_cold_key_images");
-+ if (!::serialization::serialize(ar, const_cast<serializable_unordered_map<crypto::public_key, crypto::key_image>&>(m_cold_key_images))) {
++ if (!::serialization::serialize(ar, const_cast<decltype(m_cold_key_images)&>(m_cold_key_images))) {
+ json_result = "{\"error\":\"Failed to serialize m_cold_key_images\"}";
+ return json_result.c_str();
+ }
+
-+ // FIELD(m_rpc_client_secret_key) - crypto::secret_key
-+ // ar.tag("m_rpc_client_secret_key");
-+ // ar.serialize_blob(&m_rpc_client_secret_key, sizeof(m_rpc_client_secret_key));
-+ // if (!ar.good()) {
-+ // json_result = "{\"error\":\"Failed to serialize m_rpc_client_secret_key\"}";
-+ // return json_result.c_str();
-+ // }
-+
-+ // Version-dependent fields
+ if (version >= 1) {
-+ // FIELD(m_has_ever_refreshed_from_node) - bool
-+ // ar.tag("m_has_ever_refreshed_from_node");
-+ // ar.serialize_blob(&m_has_ever_refreshed_from_node, sizeof(m_has_ever_refreshed_from_node));
-+ // if (!ar.good()) {
-+ // json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}";
-+ // return json_result.c_str();
-+ // }
++ ar.tag("m_has_ever_refreshed_from_node");
++ if (!::serialization::serialize(ar, const_cast<bool&>(m_has_ever_refreshed_from_node))) {
++ json_result = "{\"error\":\"Failed to serialize m_has_ever_refreshed_from_node\"}";
++ return json_result.c_str();
++ }
+ }
+
+ if (version >= 2) {
-+ // FIELD(m_background_sync_data) - background_sync_data_t
+ ar.tag("m_background_sync_data");
+ if (!::serialization::serialize(ar, const_cast<background_sync_data_t&>(m_background_sync_data))) {
+ json_result = "{\"error\":\"Failed to serialize m_background_sync_data\"}";
@@ -435,6 +395,14 @@ index 000000000..4743852ca
+ }
+ }
+
++ if (version >= 3) {
++ ar.tag("m_tree_cache");
++ if (!::serialization::serialize(ar, const_cast<TreeCacheV1&>(m_tree_cache))) {
++ json_result = "{\"error\":\"Failed to serialize m_tree_cache\"}";
++ return json_result.c_str();
++ }
++ }
++
+ ar.end_object();
+
+ if (!ar.good()) {
@@ -443,8 +411,6 @@ index 000000000..4743852ca
+ }
+
+ json_result = oss.str();
-+
-+ // Post-process to fix malformed JSON
+ post_process_json(json_result);
+
+ return json_result.c_str();
@@ -457,7 +423,6 @@ index 000000000..4743852ca
+}
+
+} // namespace tools
-\ No newline at end of file
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0017-drop-generate_translations_header.c-requirement.patch b/patches/monero/0017-drop-generate_translations_header.c-requirement.patch
index f6549dc..dff4cdf 100644
--- a/patches/monero/0017-drop-generate_translations_header.c-requirement.patch
+++ b/patches/monero/0017-drop-generate_translations_header.c-requirement.patch
@@ -1,7 +1,7 @@
-From 6aa368c9613a1a7b7f2f1ce1f025962d40827c67 Mon Sep 17 00:00:00 2001
+From f307b6c8f31a538e8253ac472dc1a5037227f99e Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Fri, 20 Feb 2026 08:03:01 +0100
-Subject: [PATCH 17/20] drop generate_translations_header.c requirement
+Subject: [PATCH 17/22] drop generate_translations_header.c requirement
---
CMakeLists.txt | 9 +----
@@ -9,10 +9,10 @@ Subject: [PATCH 17/20] drop generate_translations_header.c requirement
2 files changed, 30 insertions(+), 58 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index cef44dd1b..ce5e1b557 100644
+index 95326743c..ccb2c34dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -666,16 +666,11 @@ endfunction ()
+@@ -638,16 +638,11 @@ endfunction ()
# Generate header for embedded translations
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
# lrelease and lupdate binaries from the host
@@ -32,10 +32,10 @@ index cef44dd1b..ce5e1b557 100644
include_directories(${UNBOUND_INCLUDE_DIR})
diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt
-index 3b43360f8..d88a78ced 100644
+index 4bc579aaa..ad37b8ba7 100644
--- a/translations/CMakeLists.txt
+++ b/translations/CMakeLists.txt
-@@ -30,54 +30,31 @@ cmake_minimum_required(VERSION 3.5)
+@@ -30,54 +30,31 @@ cmake_minimum_required(VERSION 3.10)
project(translations)
@@ -119,5 +119,5 @@ index 3b43360f8..d88a78ced 100644
+#endif /* TRANSLATION_FILES_H */
+")
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch b/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch
index 84b4b99..3baf893 100644
--- a/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch
+++ b/patches/monero/0018-depends-remove-icu4c-monero-project-monero-8880.patch
@@ -1,23 +1,24 @@
-From 960a5efe59725eab4c03ce8025de8fc0fbffaacf Mon Sep 17 00:00:00 2001
+From 4fa4cfd3bab65138532ca1a69ecee00baf93de35 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 3 Mar 2026 13:55:59 +0100
-Subject: [PATCH 18/20] depends: remove icu4c monero-project/monero#8880
+Subject: [PATCH 18/22] depends: remove icu4c monero-project/monero#8880
---
- CMakeLists.txt | 9 ++-------
- 1 file changed, 2 insertions(+), 7 deletions(-)
+ CMakeLists.txt | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index ce5e1b557..25e034301 100644
+index ccb2c34dc..cbc67f9fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -1117,20 +1117,15 @@ if(MINGW)
+@@ -981,19 +981,16 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
+ if(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt)
- if(DEPENDS)
-- set(ICU_LIBRARIES icuio icui18n icuuc icudata icutu iconv)
+- if(NOT DEPENDS)
++ if(DEPENDS)
+ set(ICU_LIBRARIES iconv)
- else()
++ else()
# This is an extremely ugly hack to get around Boost not being built with static ICU.
# We reported the issue, we are waiting for upstream to fix this issue: https://github.com/boostorg/boost/issues/1079#issue-3384962885
# This hack links shared ICU libs to avoid linker errors we get in MSYS2 compilation (undefined symbols to ICU).
@@ -35,5 +36,5 @@ index ce5e1b557..25e034301 100644
endif()
elseif(APPLE OR OPENBSD OR ANDROID)
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0019-fix-mingw-build-issues.patch b/patches/monero/0019-fix-mingw-build-issues.patch
index a9e7b5c..bfbfaef 100644
--- a/patches/monero/0019-fix-mingw-build-issues.patch
+++ b/patches/monero/0019-fix-mingw-build-issues.patch
@@ -1,7 +1,7 @@
-From 2d4ed0b13eea96b25a574e8a87644df75c16ffb0 Mon Sep 17 00:00:00 2001
+From 1dd43161a86eb8d887773ce3bcdaaad6c55f08fa Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Wed, 4 Mar 2026 14:52:14 +0100
-Subject: [PATCH 19/20] fix: mingw build issues
+Subject: [PATCH 19/22] fix: mingw build issues
---
contrib/epee/include/serialization/keyvalue_serialization.h | 1 +
@@ -9,7 +9,7 @@ Subject: [PATCH 19/20] fix: mingw build issues
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h
-index fbbddc7d2..5104f284d 100644
+index 73328919c..71111c1c0 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization.h
@@ -26,6 +26,7 @@
@@ -21,7 +21,7 @@ index fbbddc7d2..5104f284d 100644
#include <boost/utility/value_init.hpp>
#include <boost/foreach.hpp>
diff --git a/contrib/epee/src/abstract_http_client.cpp b/contrib/epee/src/abstract_http_client.cpp
-index ed4a193d9..2352c7d62 100644
+index bd9cb0dde..340a7cf85 100644
--- a/contrib/epee/src/abstract_http_client.cpp
+++ b/contrib/epee/src/abstract_http_client.cpp
@@ -3,6 +3,7 @@
@@ -42,5 +42,5 @@ index ed4a193d9..2352c7d62 100644
}
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0020-fix-remove-flaky-test.patch b/patches/monero/0020-fix-remove-flaky-test.patch
index 1075db5..35473e6 100644
--- a/patches/monero/0020-fix-remove-flaky-test.patch
+++ b/patches/monero/0020-fix-remove-flaky-test.patch
@@ -1,17 +1,17 @@
-From 81eb38a5add85266cc0d2aa39ecba9d62337f4b1 Mon Sep 17 00:00:00 2001
+From eeb6b98478bf25f794928800fe9cdd8801e964f3 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Thu, 5 Mar 2026 18:12:53 +0100
-Subject: [PATCH 20/20] fix: remove flaky test
+Subject: [PATCH 20/22] fix: remove flaky test
---
CMakeLists.txt | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 25e034301..19417f072 100644
+index cbc67f9fd..2377223de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -235,9 +235,7 @@ add_library(l3 OBJECT incorrect_source.cpp)
+@@ -248,9 +248,7 @@ add_library(l3 OBJECT incorrect_source.cpp)
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
"-DEXPECT_SUCCESS=${EXPECT}"
)
@@ -23,5 +23,5 @@ index 25e034301..19417f072 100644
endforeach()
endfunction()
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0021-trezor-import-export-sign-functions.patch b/patches/monero/0021-trezor-import-export-sign-submit-functions.patch
index d98cdd1..7488d68 100644
--- a/patches/monero/0021-trezor-import-export-sign-functions.patch
+++ b/patches/monero/0021-trezor-import-export-sign-submit-functions.patch
@@ -1,7 +1,7 @@
-From 8af15fadb4095f94145cfe5086a1f6796d1cc44a Mon Sep 17 00:00:00 2001
+From ece9b55a6c6c34a2aaf87e10e059cc4c38a0f1b8 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Wed, 13 May 2026 11:35:01 -0400
-Subject: [PATCH] trezor import/export/sign/submit functions
+Subject: [PATCH 21/22] trezor import/export/sign/submit functions
1) This PR fixes protobuf detection, by removing checks as they were
failing on some platforms, essentially removing Protobuf_COMPILE_TEST_PASSED
@@ -11,7 +11,6 @@ Exact JSON schema is shown below, path and networkType is ommited
https://connect.trezor.io/9/methods/monero/moneroKeyImageSync/
-
```json
{
tdis: [
@@ -49,7 +48,6 @@ Expects Trezor connect MoneroKeyImageSyncResult JSON
}
```
-
4) PendingTransaction::commitTrezor(0)
New method that returns std::string with Trezor connect compatible JSON, as
shown below and at the link
@@ -59,10 +57,10 @@ https://connect.trezor.io/9/methods/monero/moneroSignTransaction/
{
// REQUIRED: Hardened Monero account path (minimum 3 components)
path: "m/44'/128'/0'",
-
+
// REQUIRED: Network type
networkType: 0, // 0=MAINNET, 1=TESTNET, 2=STAGENET, 3=FAKECHAIN
-
+
// REQUIRED: Transaction data with outputs
tsx_data: {
version: 1,
@@ -93,7 +91,7 @@ https://connect.trezor.io/9/methods/monero/moneroSignTransaction/
grouping: [],
},
},
-
+
// REQUIRED: At least one input with ring members
inputs: [
{
@@ -135,70 +133,133 @@ https://connect.trezor.io/9/methods/monero/moneroSignTransaction/
is assembled you can call Wallet::submitTransactionHex("CAFEBABE")
That's it.
-
---
- cmake/CheckTrezor.cmake | 28 +--
- src/device_trezor/trezor/protocol.cpp | 220 ++++++++++++++++++++++
+ cmake/CheckTrezor.cmake | 79 +++-----
+ src/device_trezor/trezor/protocol.cpp | 220 +++++++++++++++++++++
src/device_trezor/trezor/protocol.hpp | 8 +
src/wallet/api/pending_transaction.cpp | 60 ++++++
src/wallet/api/pending_transaction.h | 1 +
src/wallet/api/unsigned_transaction.cpp | 2 +
- src/wallet/api/wallet.cpp | 70 ++++++-
- src/wallet/api/wallet.h | 9 +-
- src/wallet/api/wallet2_api.h | 71 ++++---
- src/wallet/wallet2.cpp | 234 ++++++++++++++++++++++++
- src/wallet/wallet2.h | 7 +-
- 11 files changed, 650 insertions(+), 60 deletions(-)
+ src/wallet/api/wallet.cpp | 68 +++++++
+ src/wallet/api/wallet.h | 3 +
+ src/wallet/api/wallet2_api.h | 15 ++
+ src/wallet/wallet2.cpp | 249 ++++++++++++++++++++++++
+ src/wallet/wallet2.h | 5 +-
+ 11 files changed, 661 insertions(+), 49 deletions(-)
diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake
-index 4fae15fad..57e3d4866 100644
+index 718760ace..08eaae58a 100644
--- a/cmake/CheckTrezor.cmake
+++ b/cmake/CheckTrezor.cmake
-@@ -40,9 +40,6 @@ if (USE_DEVICE_TREZOR)
- # Protobuf handling the cache variables set in docker.
- if(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
- message(STATUS "Could not find Protobuf")
-- elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}")
-- message(STATUS "Protobuf library not found: ${Protobuf_LIBRARY}")
-- unset(Protobuf_FOUND)
- elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
- message(STATUS "Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}")
- unset(Protobuf_FOUND)
-@@ -93,31 +90,8 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
- endif()
+@@ -53,6 +53,14 @@ if (USE_DEVICE_TREZOR)
+ # https://github.com/protocolbuffers/protobuf/issues/14576
+ find_program(Protobuf_PROTOC_EXECUTABLE protoc REQUIRED)
+ set(Protobuf_LIBRARY protobuf::libprotobuf) # Compatibility with FindProtobuf.cmake
++ elseif(NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
++ message(STATUS "Could not find Protobuf")
++ elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
++ message(STATUS "Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}")
++ unset(Protobuf_FOUND)
++ elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}")
++ message(STATUS "Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}")
++ unset(Protobuf_FOUND)
+ else()
+ # Look for FindProtobuf.cmake, provided by CMake
+ find_package(Protobuf)
+@@ -80,68 +88,43 @@ else()
+ message(STATUS "Trezor: support disabled by USE_DEVICE_TREZOR")
endif()
-# Protobuf compilation test
--if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
+ if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
- execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
- if(RET)
-- message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}")
-- endif()
--
-- try_compile(Protobuf_COMPILE_TEST_PASSED
-- "${CMAKE_BINARY_DIR}"
-- SOURCES
-- "${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
-- "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
-- CMAKE_FLAGS
-- "-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
-- "-DCMAKE_CXX_STANDARD=11"
-- LINK_LIBRARIES ${Protobuf_LIBRARY}
-- OUTPUT_VARIABLE OUTPUT
-- )
-- if(NOT Protobuf_COMPILE_TEST_PASSED)
-- message(STATUS "Protobuf Compilation test failed: ${OUTPUT}.")
-- endif()
--endif()
--
+- trezor_fatal_msg("Trezor: Protobuf test generation failed: ${OUT} ${ERR}")
++ if (NOT "$ENV{TREZOR_PYTHON}" STREQUAL "")
++ set(TREZOR_PYTHON "$ENV{TREZOR_PYTHON}" CACHE INTERNAL "Copied from environment variable TREZOR_PYTHON")
++ else()
++ find_package(Python QUIET COMPONENTS Interpreter)
++ if(Python_Interpreter_FOUND)
++ set(TREZOR_PYTHON "${Python_EXECUTABLE}")
++ endif()
+ endif()
+
+- if(ANDROID)
+- set(CMAKE_TRY_COMPILE_LINKER_FLAGS "${CMAKE_TRY_COMPILE_LINKER_FLAGS} -llog")
+- set(CMAKE_TRY_COMPILE_LINK_LIBRARIES "${CMAKE_TRY_COMPILE_LINK_LIBRARIES} log")
++ if(NOT TREZOR_PYTHON)
++ find_package(PythonInterp)
++ if(PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE)
++ set(TREZOR_PYTHON "${PYTHON_EXECUTABLE}")
++ endif()
+ endif()
+
+- if(USE_DEVICE_TREZOR_PROTOBUF_TEST)
+- if(PROTOBUF_LDFLAGS)
+- set(PROTOBUF_TRYCOMPILE_LINKER "${PROTOBUF_LDFLAGS}")
+- else()
+- set(PROTOBUF_TRYCOMPILE_LINKER "${Protobuf_LIBRARY}")
+- endif()
+-
+- try_compile(Protobuf_COMPILE_TEST_PASSED
+- "${CMAKE_BINARY_DIR}"
+- SOURCES
+- "${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
+- "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
+- CMAKE_FLAGS
+- CMAKE_EXE_LINKER_FLAGS ${CMAKE_TRY_COMPILE_LINKER_FLAGS}
+- "-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
+- "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
+- LINK_LIBRARIES "${PROTOBUF_TRYCOMPILE_LINKER}" ${CMAKE_TRY_COMPILE_LINK_LIBRARIES}
+- OUTPUT_VARIABLE OUTPUT
+- )
+- if(NOT Protobuf_COMPILE_TEST_PASSED)
+- trezor_fatal_msg("Trezor: Protobuf Compilation test failed: ${OUTPUT}.")
+- endif()
+- else ()
+- message(STATUS "Trezor: Protobuf Compilation test skipped, build may fail later")
++ if(NOT TREZOR_PYTHON)
++ message(STATUS "Trezor: Python not found")
+ endif()
+ endif()
+
# Try to build protobuf messages
--if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_TEST_PASSED)
+-if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
+- # .proto files to compile
+- set(_proto_files "messages.proto"
+- "messages-common.proto"
+- "messages-management.proto"
+- "messages-monero.proto")
+- if (TREZOR_DEBUG)
+- list(APPEND _proto_files "messages-debug.proto")
+- endif ()
+-
+- set(_proto_include_dir "${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor/protob")
+- set(_proto_files_absolute)
+- foreach(file IN LISTS _proto_files)
+- list(APPEND _proto_files_absolute "${_proto_include_dir}/${file}")
+- endforeach ()
+if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
- set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}")
- set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}")
- set(TREZOR_PROTOBUF_PARAMS "")
++ set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}")
++ set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}")
++ set(TREZOR_PROTOBUF_PARAMS "")
++ if (USE_DEVICE_TREZOR_DEBUG)
++ set(TREZOR_PROTOBUF_PARAMS "--debug")
++ endif()
+
+- set(_proto_out_dir "${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor/messages")
+- execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --cpp_out "${_proto_out_dir}" "-I${_proto_include_dir}" ${_proto_files_absolute} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
++ execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
+ if(RET)
+ trezor_fatal_msg("Trezor: protobuf messages could not be (re)generated (err=${RET}). OUT: ${OUT}, ERR: ${ERR}.")
+ endif()
+
++ set(_proto_out_dir "${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor/messages")
+ if(FREEBSD)
+ # FreeBSD defines `minor` in usr/include/sys/types.h which conflicts with this file
+ # https://github.com/trezor/trezor-firmware/issues/4460
diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp
-index 0e59a16ba..afd1498d2 100644
+index 52f02be3b..ec4e9cfe9 100644
--- a/src/device_trezor/trezor/protocol.cpp
+++ b/src/device_trezor/trezor/protocol.cpp
@@ -29,12 +29,17 @@
@@ -219,7 +280,7 @@ index 0e59a16ba..afd1498d2 100644
#include <crypto/hmac-keccak.h>
#include <ringct/rctSigs.h>
#include <ringct/bulletproofs.h>
-@@ -450,6 +455,10 @@ namespace tx {
+@@ -439,6 +444,10 @@ namespace tx {
}
}
@@ -229,8 +290,8 @@ index 0e59a16ba..afd1498d2 100644
+
void Signer::set_tx_input(MoneroTransactionSourceEntry * dst, size_t idx, bool need_ring_keys, bool need_ring_indices){
const cryptonote::tx_source_entry & src = cur_tx().sources[idx];
- const tools::wallet2::transfer_details & transfer = get_source_transfer(idx);
-@@ -1096,6 +1105,217 @@ namespace tx {
+ const wallet2_basic::transfer_details & transfer = get_source_transfer(idx);
+@@ -1085,6 +1094,217 @@ namespace tx {
memwipe(plaintext.get(), keys_len);
}
@@ -449,7 +510,7 @@ index 0e59a16ba..afd1498d2 100644
}
}
diff --git a/src/device_trezor/trezor/protocol.hpp b/src/device_trezor/trezor/protocol.hpp
-index 7ffadd9aa..7899e60d0 100644
+index 73bd0b902..2db4e8e16 100644
--- a/src/device_trezor/trezor/protocol.hpp
+++ b/src/device_trezor/trezor/protocol.hpp
@@ -340,8 +340,16 @@ namespace tx {
@@ -470,7 +531,7 @@ index 7ffadd9aa..7899e60d0 100644
void load_tx_key_data(hw::device_cold::tx_key_data_t & res, const std::string & data);
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
-index 1f714d229..22c09483d 100644
+index 796e7a50b..9109c8a32 100644
--- a/src/wallet/api/pending_transaction.cpp
+++ b/src/wallet/api/pending_transaction.cpp
@@ -44,6 +44,11 @@
@@ -548,7 +609,7 @@ index 1f714d229..22c09483d 100644
uint64_t PendingTransactionImpl::amount() const
{
diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h
-index 0cc6c58e9..9c9097cd1 100644
+index eb5c75c5f..c9c68fb03 100644
--- a/src/wallet/api/pending_transaction.h
+++ b/src/wallet/api/pending_transaction.h
@@ -47,6 +47,7 @@ public:
@@ -560,7 +621,7 @@ index 0cc6c58e9..9c9097cd1 100644
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 fd03e959d..7232e518f 100644
+index 062df7f41..560890f2c 100644
--- a/src/wallet/api/unsigned_transaction.cpp
+++ b/src/wallet/api/unsigned_transaction.cpp
@@ -34,11 +34,13 @@
@@ -578,10 +639,10 @@ index fd03e959d..7232e518f 100644
#include "bc-ur/src/bc-ur.hpp"
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
-index c24b4a97d..3a977d6d2 100644
+index 57f1203c6..c65ce8799 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
-@@ -1457,6 +1457,45 @@ bool WalletImpl::submitTransactionUR(const string &input) {
+@@ -1392,6 +1392,45 @@ bool WalletImpl::submitTransactionUR(const string &input) {
return true;
}
@@ -627,7 +688,7 @@ index c24b4a97d..3a977d6d2 100644
bool WalletImpl::hasUnknownKeyImages() const
{
-@@ -3479,4 +3518,33 @@ std::string WalletImpl::serializeCacheToJson() const
+@@ -3436,4 +3475,33 @@ std::string WalletImpl::serializeCacheToJson() const
return std::string(m_wallet->serialize_cache_to_json());
}
@@ -662,10 +723,10 @@ index c24b4a97d..3a977d6d2 100644
+
} // namespace
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
-index 98c03b9c1..45a3b6b2f 100644
+index 8e4846e27..ede41b46d 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
-@@ -183,6 +183,7 @@ public:
+@@ -185,6 +185,7 @@ public:
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
bool submitTransactionUR(const std::string &input) override;
@@ -673,7 +734,7 @@ index 98c03b9c1..45a3b6b2f 100644
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
virtual UnsignedTransaction * loadUnsignedTxUR(const std::string &input) override;
bool hasUnknownKeyImages() const override;
-@@ -337,6 +338,8 @@ private:
+@@ -338,6 +339,8 @@ private:
bool getWaitsForDeviceReceive();
virtual std::string serializeCacheToJson() const override;
@@ -683,10 +744,10 @@ index 98c03b9c1..45a3b6b2f 100644
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
-index 3d11929f9..ac1dd9fb0 100644
+index 4552c02d0..bead275bb 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
-@@ -92,6 +92,7 @@ struct PendingTransaction
+@@ -84,6 +84,7 @@ struct PendingTransaction
// 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;
@@ -694,7 +755,7 @@ index 3d11929f9..ac1dd9fb0 100644
virtual uint64_t amount() const = 0;
virtual uint64_t dust() const = 0;
virtual uint64_t fee() const = 0;
-@@ -948,6 +949,7 @@ struct Wallet
+@@ -950,6 +951,7 @@ struct Wallet
*/
virtual bool submitTransaction(const std::string &fileName) = 0;
virtual bool submitTransactionUR(const std::string &input) = 0;
@@ -702,7 +763,7 @@ index 3d11929f9..ac1dd9fb0 100644
/*!
-@@ -1220,6 +1222,19 @@ struct Wallet
+@@ -1216,6 +1218,19 @@ struct Wallet
//! serialize wallet cache to JSON
virtual std::string serializeCacheToJson() const = 0;
@@ -723,10 +784,10 @@ index 3d11929f9..ac1dd9fb0 100644
/**
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
-index a7532d7ec..0c3a628ed 100644
+index 06a732296..2a71e4751 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
-@@ -98,6 +98,7 @@ extern "C"
+@@ -112,6 +112,7 @@ extern "C"
{
#include "crypto/keccak.h"
#include "crypto/crypto-ops.h"
@@ -734,7 +795,50 @@ index a7532d7ec..0c3a628ed 100644
}
using namespace std;
using namespace crypto;
-@@ -7799,6 +7800,81 @@ void wallet2::commit_tx(std::vector<pending_tx>& ptx_vector)
+@@ -967,6 +968,42 @@ static tools::wallet2::tx_construction_data &get_construction_data(tools::wallet
+ return std::get<tools::wallet2::tx_construction_data>(ptx.construction_data);
+ }
+
++static bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
++{
++ std::vector<tx_extra_field> tx_extra_fields;
++ parse_tx_extra(ptx.tx.extra, tx_extra_fields);
++ cryptonote::tx_extra_nonce extra_nonce;
++ if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce))
++ {
++ if (get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8))
++ {
++ if (ptx.dests.empty())
++ {
++ MWARNING("Encrypted payment id found, but no destinations public key, cannot decrypt");
++ return false;
++ }
++ return hwdev.decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key);
++ }
++ }
++ return false;
++}
++
++static tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
++{
++ tools::wallet2::tx_construction_data construction_data = get_construction_data(ptx);
++ crypto::hash8 payment_id = crypto::null_hash8;
++ if (get_short_payment_id(payment_id, ptx, hwdev))
++ {
++ remove_field_from_tx_extra(construction_data.extra, typeid(cryptonote::tx_extra_nonce));
++ std::string extra_nonce;
++ set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, payment_id);
++ THROW_WALLET_EXCEPTION_IF(!add_extra_nonce_to_tx_extra(construction_data.extra, extra_nonce),
++ tools::error::wallet_internal_error, "Failed to add decrypted payment id to tx extra");
++ MDEBUG("Decrypted payment ID: " << payment_id);
++ }
++ return construction_data;
++}
++
+ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
+ {
+ static constexpr uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
+@@ -8080,6 +8117,61 @@ void wallet2::commit_tx(std::vector<pending_tx>& ptx_vector)
}
}
//----------------------------------------------------------------------------------------------------
@@ -748,36 +852,16 @@ index a7532d7ec..0c3a628ed 100644
+ transaction tx;
+ THROW_WALLET_EXCEPTION_IF(!parse_and_validate_tx_from_blob(tx_blob, tx), error::wallet_internal_error, "Failed to parse transaction");
+
-+ if (m_light_wallet)
-+ {
-+ COMMAND_RPC_SUBMIT_RAW_TX::request oreq;
-+ COMMAND_RPC_SUBMIT_RAW_TX::response ores;
-+ oreq.address = get_account().get_public_address_str(m_nettype);
-+ oreq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
-+ oreq.tx = tx_as_hex;
-+ {
-+ const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
-+ bool r = epee::net_utils::invoke_http_json("/submit_raw_tx", oreq, ores, *m_http_client, rpc_timeout, "POST");
-+ THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "submit_raw_tx");
-+ THROW_WALLET_EXCEPTION_IF(ores.status != "OK" && ores.status != "success", error::tx_rejected, tx, get_rpc_status(ores.status), ores.error);
-+ }
-+ }
-+ else
-+ {
-+ COMMAND_RPC_SEND_RAW_TX::request req;
-+ req.tx_as_hex = tx_as_hex;
-+ req.do_not_relay = false;
-+ req.do_sanity_checks = true;
-+ COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
++ COMMAND_RPC_SEND_RAW_TX::request req;
++ req.tx_as_hex = tx_as_hex;
++ req.do_not_relay = false;
++ req.do_sanity_checks = true;
++ COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
+
-+ {
-+ const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
-+ uint64_t pre_call_credits = m_rpc_payment_state.credits;
-+ req.client = get_client_signature();
-+ bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, *m_http_client, rpc_timeout);
-+ THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_send_resp, "sendrawtransaction", error::tx_rejected, tx, get_rpc_status(daemon_send_resp.status), get_text_reason(daemon_send_resp));
-+ check_rpc_cost("/sendrawtransaction", daemon_send_resp.credits, pre_call_credits, COST_PER_TX_RELAY);
-+ }
++ {
++ const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
++ bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, *m_http_client, rpc_timeout);
++ THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_send_resp, "sendrawtransaction", error::tx_rejected, tx, get_rpc_status(m_trusted_daemon, daemon_send_resp.status), get_text_reason(daemon_send_resp));
+ }
+
+ crypto::hash txid = get_transaction_hash(tx);
@@ -816,7 +900,7 @@ index a7532d7ec..0c3a628ed 100644
bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename) const
{
LOG_PRINT_L0("saving " << ptx_vector.size() << " transactions");
-@@ -7838,6 +7915,20 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c
+@@ -8117,6 +8209,20 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c
return std::string(UNSIGNED_TX_PREFIX) + ciphertext;
}
//----------------------------------------------------------------------------------------------------
@@ -837,7 +921,7 @@ index a7532d7ec..0c3a628ed 100644
bool wallet2::load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const
{
std::string s;
-@@ -16384,4 +16475,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i
+@@ -15946,4 +16052,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i
return std::make_pair(size, weight);
}
//----------------------------------------------------------------------------------------------------
@@ -986,10 +1070,10 @@ index a7532d7ec..0c3a628ed 100644
+//----------------------------------------------------------------------------------------------------
}
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
-index 37a2447d2..2e93f3dbf 100644
+index 42e1c02d9..7332459ae 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
-@@ -1205,8 +1205,10 @@ private:
+@@ -707,8 +707,10 @@ private:
void commit_tx(pending_tx& ptx_vector);
void commit_tx(std::vector<pending_tx>& ptx_vector);
@@ -1000,16 +1084,16 @@ index 37a2447d2..2e93f3dbf 100644
std::string save_multisig_tx(multisig_tx_set txs);
bool save_multisig_tx(const multisig_tx_set &txs, const std::string &filename);
std::string save_multisig_tx(const std::vector<pending_tx>& ptx_vector);
-@@ -1717,7 +1721,8 @@ private:
+@@ -1281,7 +1283,8 @@ private:
bool is_unattended() const { return m_unattended; }
std::pair<size_t, uint64_t> estimate_tx_size_and_weight(bool use_rct, int n_inputs, int ring_size, int n_outputs, size_t extra_size);
-
+ std::string export_trezor_tdis() const;
+ uint64_t import_trezor_encrypted_key_images_json(const std::string &json, uint64_t &spent, uint64_t &unspent, bool check_spent = true);
- bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);
- bool daemon_requires_payment();
- bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance);
+
+ /*
+ * "attributes" are a mechanism to store an arbitrary number of string values
--
-2.50.1 (Apple Git-155)
+2.54.0 (Apple Git-157)
diff --git a/patches/monero/0022-fix-use-apple-ios-rust-target-when-building-for-iOS.patch b/patches/monero/0022-fix-use-apple-ios-rust-target-when-building-for-iOS.patch
new file mode 100644
index 0000000..4f117eb
--- /dev/null
+++ b/patches/monero/0022-fix-use-apple-ios-rust-target-when-building-for-iOS.patch
@@ -0,0 +1,33 @@
+From cce457ba4807db3f0bb3b06dc512131fe0084b5d Mon Sep 17 00:00:00 2001
+From: Czarek Nakamoto <cyjan@mrcyjanek.net>
+Date: Mon, 27 Jul 2026 14:15:44 +0200
+Subject: [PATCH 22/22] fix: use correct rust target for iOS device and simulator
+
+---
+ src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt
+index 3e2229f07..f157bc12f 100644
+--- a/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt
++++ b/src/fcmp_pp/fcmp_pp_rust/CMakeLists.txt
+@@ -44,7 +44,15 @@ if(MINGW)
+ set(RUST_PLATFORM "pc-windows")
+ set(RUST_TOOLCHAIN "-gnu")
+ elseif(APPLE)
+- set(RUST_PLATFORM "apple-darwin")
++ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
++ if(CMAKE_OSX_SYSROOT MATCHES "i[pP]hone[sS]imulator")
++ set(RUST_PLATFORM "apple-ios-sim")
++ else()
++ set(RUST_PLATFORM "apple-ios")
++ endif()
++ else()
++ set(RUST_PLATFORM "apple-darwin")
++ endif()
+ set(RUST_TOOLCHAIN "")
+ elseif(FREEBSD)
+ set(RUST_PLATFORM "unknown-freebsd")
+--
+2.54.0 (Apple Git-157)
+