diff options
| author | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-05-13 11:36:18 -0400 |
|---|---|---|
| committer | Czarek Nakamoto <cyjan@mrcyjanek.net> | 2026-05-13 11:36:18 -0400 |
| commit | 070be20afb2231c09b4dc5908d96d388929e7d18 (patch) | |
| tree | d5077ae771699576af6e9e49f62416a0b18e701f | |
| parent | 5181f2990b955f4b9446c88bfb7eec68cc4df776 (diff) | |
wip
5 files changed, 134 insertions, 91 deletions
diff --git a/impls/monero.dart/lib/monero.dart b/impls/monero.dart/lib/monero.dart index 9057f18..ef1da28 100644 --- a/impls/monero.dart/lib/monero.dart +++ b/impls/monero.dart/lib/monero.dart @@ -570,21 +570,21 @@ String UnsignedTransaction_signUR( } @Deprecated("TODO") -String UnsignedTransaction_commitTrezor( +String PendingTransaction_commitTrezor( PendingTransaction ptr, int tx_index) { - debugStart?.call('MONERO_UnsignedTransaction_commitTrezor'); + debugStart?.call('MONERO_PendingTransaction_commitTrezor'); lib ??= MoneroC(DynamicLibrary.open(libPath)); - final txid = lib!.MONERO_UnsignedTransaction_commitTrezor(ptr, tx_index); - debugEnd?.call('MONERO_UnsignedTransaction_commitTrezor'); + final txid = lib!.MONERO_PendingTransaction_commitTrezor(ptr, tx_index); + debugEnd?.call('MONERO_PendingTransaction_commitTrezor'); try { final strPtr = txid.cast<Utf8>(); final str = strPtr.toDartString(); MONERO_free(strPtr.cast()); - debugEnd?.call('MONERO_UnsignedTransaction_commitTrezor'); + debugEnd?.call('MONERO_PendingTransaction_commitTrezor'); return str; } catch (e) { - errorHandler?.call('MONERO_UnsignedTransaction_commitTrezor', e); - debugEnd?.call('MONERO_UnsignedTransaction_commitTrezor'); + errorHandler?.call('MONERO_PendingTransaction_commitTrezor', e); + debugEnd?.call('MONERO_PendingTransaction_commitTrezor'); return ""; } } diff --git a/impls/monero.dart/lib/src/generated_bindings_monero.g.dart b/impls/monero.dart/lib/src/generated_bindings_monero.g.dart index adf04da..36736d3 100644 --- a/impls/monero.dart/lib/src/generated_bindings_monero.g.dart +++ b/impls/monero.dart/lib/src/generated_bindings_monero.g.dart @@ -88,6 +88,24 @@ class MoneroC { _MONERO_PendingTransaction_commitURPtr.asFunction< ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, int)>(); + ffi.Pointer<ffi.Char> MONERO_PendingTransaction_commitTrezor( + ffi.Pointer<ffi.Void> pendingTx_ptr, + int tx_index, + ) { + return _MONERO_PendingTransaction_commitTrezor( + pendingTx_ptr, + tx_index, + ); + } + + late final _MONERO_PendingTransaction_commitTrezorPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, + ffi.Int)>>('MONERO_PendingTransaction_commitTrezor'); + late final _MONERO_PendingTransaction_commitTrezor = + _MONERO_PendingTransaction_commitTrezorPtr.asFunction< + ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, int)>(); + int MONERO_PendingTransaction_amount( ffi.Pointer<ffi.Void> pendingTx_ptr, ) { @@ -484,24 +502,6 @@ class MoneroC { _MONERO_UnsignedTransaction_signURPtr.asFunction< ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, int)>(); - ffi.Pointer<ffi.Char> MONERO_UnsignedTransaction_commitTrezor( - ffi.Pointer<ffi.Void> unsignedTx_ptr, - int tx_index, - ) { - return _MONERO_UnsignedTransaction_commitTrezor( - unsignedTx_ptr, - tx_index, - ); - } - - late final _MONERO_UnsignedTransaction_commitTrezorPtr = _lookup< - ffi.NativeFunction< - ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, - ffi.Int)>>('MONERO_UnsignedTransaction_commitTrezor'); - late final _MONERO_UnsignedTransaction_commitTrezor = - _MONERO_UnsignedTransaction_commitTrezorPtr.asFunction< - ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, int)>(); - int MONERO_TransactionInfo_direction( ffi.Pointer<ffi.Void> txInfo_ptr, ) { diff --git a/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.cpp b/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.cpp index a800ad5..391cb65 100644 --- a/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.cpp +++ b/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.cpp @@ -102,6 +102,15 @@ const char* MONERO_PendingTransaction_commitUR(void* pendingTx_ptr, int max_frag DEBUG_END() } + +const char* MONERO_PendingTransaction_commitTrezor(void* pendingTx_ptr, int tx_index) { + DEBUG_START() + Monero::PendingTransaction *pendingTx = reinterpret_cast<Monero::PendingTransaction*>(pendingTx_ptr); + std::string str = pendingTx->commitTrezor(tx_index); + return strdup(str.c_str()); + DEBUG_END() +} + uint64_t MONERO_PendingTransaction_amount(void* pendingTx_ptr) { DEBUG_START() Monero::PendingTransaction *pendingTx = reinterpret_cast<Monero::PendingTransaction*>(pendingTx_ptr); @@ -266,13 +275,6 @@ const char* MONERO_UnsignedTransaction_signUR(void* unsignedTx_ptr, int max_frag DEBUG_END() } -const char* MONERO_UnsignedTransaction_commitTrezor(void* unsignedTx_ptr, int tx_index) { - DEBUG_START() - Monero::UnsignedTransaction *unsignedTx = reinterpret_cast<Monero::UnsignedTransaction*>(unsignedTx_ptr); - std::string str = unsignedTx->commitTrezor(tx_index); - return strdup(str.c_str()); - DEBUG_END() -} // TransactionInfo const int MONERO_TransactionInfoDirection_In = 0; diff --git a/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.h b/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.h index fdaf228..f30d233 100644 --- a/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.h +++ b/monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.h @@ -84,6 +84,7 @@ extern ADDAPI const char* MONERO_PendingTransaction_errorString(void* pendingTx_ // virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; extern ADDAPI bool MONERO_PendingTransaction_commit(void* pendingTx_ptr, const char* filename, bool overwrite); extern ADDAPI const char* MONERO_PendingTransaction_commitUR(void* pendingTx_ptr, int max_fragment_length); +extern ADDAPI const char* MONERO_PendingTransaction_commitTrezor(void* pendingTx_ptr, int tx_index); // virtual uint64_t amount() const = 0; extern ADDAPI uint64_t MONERO_PendingTransaction_amount(void* pendingTx_ptr); // virtual uint64_t dust() const = 0; @@ -144,7 +145,6 @@ extern ADDAPI uint64_t MONERO_UnsignedTransaction_txCount(void* unsignedTx_ptr); // virtual bool sign(const std::string &signedFileName) = 0; extern ADDAPI bool MONERO_UnsignedTransaction_sign(void* unsignedTx_ptr, const char* signedFileName); extern ADDAPI const char* MONERO_UnsignedTransaction_signUR(void* unsignedTx_ptr, int max_fragment_length); -extern ADDAPI const char* MONERO_UnsignedTransaction_commitTrezor(void* unsignedTx_ptr, int tx_index); // }; // struct TransactionInfo // { diff --git a/patches/monero/0021-trezor-import-export-sign-functions.patch b/patches/monero/0021-trezor-import-export-sign-functions.patch index 80a10f5..b990692 100644 --- a/patches/monero/0021-trezor-import-export-sign-functions.patch +++ b/patches/monero/0021-trezor-import-export-sign-functions.patch @@ -1,19 +1,20 @@ -From f3f83fa435bf5ce6b54bd724eb934ce27007e8db Mon Sep 17 00:00:00 2001 +From 7c128c7a2392419a9d5c6fd3b27ad982586aba64 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto <cyjan@mrcyjanek.net> -Date: Fri, 8 May 2026 21:40:35 -0400 +Date: Wed, 13 May 2026 11:35:01 -0400 Subject: [PATCH] trezor import/export/sign functions --- src/device_trezor/trezor/protocol.cpp | 220 ++++++++++++++++++++++++ src/device_trezor/trezor/protocol.hpp | 8 + - src/wallet/api/unsigned_transaction.cpp | 60 +++++++ - src/wallet/api/unsigned_transaction.h | 1 + + 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 | 31 +++- src/wallet/api/wallet.h | 2 + src/wallet/api/wallet2_api.h | 14 ++ - src/wallet/wallet2.cpp | 144 ++++++++++++++++ - src/wallet/wallet2.h | 3 +- - 9 files changed, 481 insertions(+), 2 deletions(-) + src/wallet/wallet2.cpp | 158 +++++++++++++++++ + src/wallet/wallet2.h | 5 +- + 10 files changed, 499 insertions(+), 2 deletions(-) diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp index 0e59a16ba..afd1498d2 100644 @@ -287,21 +288,11 @@ index 7ffadd9aa..7899e60d0 100644 // TX Key decryption void load_tx_key_data(hw::device_cold::tx_key_data_t & res, const std::string & data); -diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp -index fd03e959d..d45723bb5 100644 ---- a/src/wallet/api/unsigned_transaction.cpp -+++ b/src/wallet/api/unsigned_transaction.cpp -@@ -34,14 +34,21 @@ - - #include "cryptonote_basic/cryptonote_format_utils.h" - #include "cryptonote_basic/cryptonote_basic_impl.h" -+#include "cryptonote_config.h" - - #include <memory> - #include <vector> - #include <sstream> - #include <boost/format.hpp> -+#include <functional> +diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp +index 1f714d229..22c09483d 100644 +--- a/src/wallet/api/pending_transaction.cpp ++++ b/src/wallet/api/pending_transaction.cpp +@@ -44,6 +44,11 @@ #include "bc-ur/src/bc-ur.hpp" @@ -313,11 +304,11 @@ index fd03e959d..d45723bb5 100644 using namespace std; namespace Monero { -@@ -138,6 +145,59 @@ std::string UnsignedTransactionImpl::signUR(int max_fragment_length) - return ""; +@@ -210,6 +215,61 @@ std::string PendingTransactionImpl::commitUR(int max_fragment_length) { + } } -+std::string UnsignedTransactionImpl::commitTrezor(uint64_t tx_index) ++std::string PendingTransactionImpl::commitTrezor(uint64_t tx_index) +{ +#if !defined(DEVICE_TREZOR_READY) || !DEVICE_TREZOR_READY + (void)tx_index; @@ -325,21 +316,23 @@ index fd03e959d..d45723bb5 100644 + m_status = Status_Error; + return ""; +#else -+ if (tx_index >= m_unsigned_tx_set.txes.size()) ++ if (tx_index >= m_pending_tx.size()) + { + m_errorString = tr("Invalid transaction index"); + m_status = Status_Error; + return ""; + } -+ if (std::get<0>(m_unsigned_tx_set.transfers) != 0) -+ { -+ m_errorString = tr("Unsupported unsigned transaction transfer offset"); -+ m_status = Status_Error; -+ return ""; -+ } + try + { + tools::wallet2 *w = m_wallet.m_wallet.get(); ++ tools::wallet2::unsigned_tx_set utx; ++ w->construct_unsigned_tx_set_for_signing(m_pending_tx, utx); ++ if (std::get<0>(utx.transfers) != 0) ++ { ++ m_errorString = tr("Unsupported unsigned transaction transfer offset"); ++ m_status = Status_Error; ++ return ""; ++ } + hw::tx_aux_data aux_data; + const int bpv = w->use_fork_rules(HF_VERSION_BULLETPROOF_PLUS, -10) ? 4 + : (w->use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 @@ -353,7 +346,7 @@ index fd03e959d..d45723bb5 100644 + + const std::string json = hw::trezor::protocol::tx::trezor_connect_monero_sign_transaction_to_json( + &shim, -+ &m_unsigned_tx_set, ++ &utx, + static_cast<size_t>(tx_index), + &aux_data, + w->nettype()); @@ -370,20 +363,38 @@ index fd03e959d..d45723bb5 100644 +#endif +} + - //---------------------------------------------------------------------------------------------------- - 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) + + uint64_t PendingTransactionImpl::amount() const { -diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h -index a94b23f75..e2f250565 100644 ---- a/src/wallet/api/unsigned_transaction.h -+++ b/src/wallet/api/unsigned_transaction.h -@@ -54,6 +54,7 @@ public: - // sign txs and save to file - bool sign(const std::string &signedFileName) override; - std::string signUR(int max_fragment_length = 130) override; +diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h +index 0cc6c58e9..9c9097cd1 100644 +--- a/src/wallet/api/pending_transaction.h ++++ b/src/wallet/api/pending_transaction.h +@@ -47,6 +47,7 @@ public: + std::string errorString() const override; + bool commit(const std::string &filename = "", bool overwrite = false) override; + std::string commitUR(int max_fragment_length = 130) override; + std::string commitTrezor(uint64_t tx_index = 0) override; - std::string confirmationMessage() const override {return m_confirmationMessage;} - uint64_t minMixinCount() const override; + uint64_t amount() const override; + uint64_t dust() const override; + uint64_t fee() const override; +diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp +index fd03e959d..7232e518f 100644 +--- a/src/wallet/api/unsigned_transaction.cpp ++++ b/src/wallet/api/unsigned_transaction.cpp +@@ -34,11 +34,13 @@ + + #include "cryptonote_basic/cryptonote_format_utils.h" + #include "cryptonote_basic/cryptonote_basic_impl.h" ++#include "cryptonote_config.h" + + #include <memory> + #include <vector> + #include <sstream> + #include <boost/format.hpp> ++#include <functional> + + #include "bc-ur/src/bc-ur.hpp" diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index c24b4a97d..cc85398ca 100644 @@ -446,17 +457,17 @@ index 98c03b9c1..5248badb8 100644 diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h -index 3d11929f9..faea404dc 100644 +index 3d11929f9..ee9edd68e 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h -@@ -165,6 +165,7 @@ struct UnsignedTransaction - */ - virtual bool sign(const std::string &signedFileName) = 0; - virtual std::string signUR(int max_fragment_length = 130) = 0; -+ virtual std::string commitTrezor(uint64_t tx_index = 0) = 0; - }; - - /** +@@ -92,6 +92,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; ++ virtual std::string commitTrezor(uint64_t tx_index = 0) = 0; + virtual uint64_t amount() const = 0; + virtual uint64_t dust() const = 0; + virtual uint64_t fee() const = 0; @@ -1220,6 +1221,19 @@ struct Wallet //! serialize wallet cache to JSON @@ -478,7 +489,7 @@ index 3d11929f9..faea404dc 100644 /** diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp -index a7532d7ec..7f931c4c9 100644 +index a7532d7ec..bb0ada04d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -98,6 +98,7 @@ extern "C" @@ -489,7 +500,28 @@ index a7532d7ec..7f931c4c9 100644 } using namespace std; using namespace crypto; -@@ -16384,4 +16385,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i +@@ -7838,6 +7839,20 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c + return std::string(UNSIGNED_TX_PREFIX) + ciphertext; + } + //---------------------------------------------------------------------------------------------------- ++void wallet2::construct_unsigned_tx_set_for_signing(const std::vector<pending_tx>& ptx_vector, unsigned_tx_set &utx) const ++{ ++ utx.txes.clear(); ++ utx.txes.reserve(ptx_vector.size()); ++ for (const auto &tx : ptx_vector) ++ utx.txes.push_back(get_construction_data_with_decrypted_short_payment_id(tx, m_account.get_device())); ++ ++ utx.new_transfers = std::make_tuple(static_cast<uint64_t>(0), static_cast<uint64_t>(0), std::vector<exported_transfer_details>()); ++ ++ transfer_container transfers_copy; ++ get_transfers(transfers_copy); ++ utx.transfers = std::make_tuple(static_cast<uint64_t>(0), static_cast<uint64_t>(transfers_copy.size()), std::move(transfers_copy)); ++} ++//---------------------------------------------------------------------------------------------------- + bool wallet2::load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const + { + std::string s; +@@ -16384,4 +16399,147 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i return std::make_pair(size, weight); } //---------------------------------------------------------------------------------------------------- @@ -638,10 +670,19 @@ index a7532d7ec..7f931c4c9 100644 +//---------------------------------------------------------------------------------------------------- } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h -index 37a2447d2..e2016945b 100644 +index 37a2447d2..a1ca49e90 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h -@@ -1717,7 +1717,8 @@ private: +@@ -1207,6 +1207,8 @@ private: + void commit_tx(std::vector<pending_tx>& ptx_vector); + bool save_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename) const; + std::string dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) const; ++ //! Populate \p utx from pending txs for cold/device signing (uses live transfer indices). ++ void construct_unsigned_tx_set_for_signing(const std::vector<pending_tx>& ptx_vector, unsigned_tx_set &utx) const; + 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 +1719,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); |
