summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCzarek Nakamoto <cyjan@mrcyjanek.net>2026-05-13 11:36:18 -0400
committerCzarek Nakamoto <cyjan@mrcyjanek.net>2026-05-13 11:36:18 -0400
commit070be20afb2231c09b4dc5908d96d388929e7d18 (patch)
treed5077ae771699576af6e9e49f62416a0b18e701f
parent5181f2990b955f4b9446c88bfb7eec68cc4df776 (diff)
wip
-rw-r--r--impls/monero.dart/lib/monero.dart14
-rw-r--r--impls/monero.dart/lib/src/generated_bindings_monero.g.dart36
-rw-r--r--monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.cpp16
-rw-r--r--monero_libwallet2_api_c/src/main/cpp/monero_wallet2_api_c.h2
-rw-r--r--patches/monero/0021-trezor-import-export-sign-functions.patch157
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);