Skip to content

Commit d9d208d

Browse files
committed
add functions to Wallet API
1 parent 6f06684 commit d9d208d

15 files changed

+1931
-72
lines changed

src/wallet/api/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
3333
set(wallet_api_sources
3434
wallet.cpp
3535
wallet_manager.cpp
36+
enote_details.cpp
3637
transaction_info.cpp
3738
transaction_history.cpp
3839
pending_transaction.cpp
@@ -48,6 +49,7 @@ set(wallet_api_headers
4849
set(wallet_api_private_headers
4950
wallet.h
5051
wallet_manager.h
52+
enote_details.h
5153
transaction_info.h
5254
transaction_history.h
5355
pending_transaction.h

src/wallet/api/enote_details.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) 2014-2025, The Monero Project
2+
//
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without modification, are
6+
// permitted provided that the following conditions are met:
7+
//
8+
// 1. Redistributions of source code must retain the above copyright notice, this list of
9+
// conditions and the following disclaimer.
10+
//
11+
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12+
// of conditions and the following disclaimer in the documentation and/or other
13+
// materials provided with the distribution.
14+
//
15+
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16+
// used to endorse or promote products derived from this software without specific
17+
// prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22+
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26+
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27+
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
#include "enote_details.h"
30+
31+
32+
namespace Monero {
33+
34+
EnoteDetails::~EnoteDetails() {}
35+
36+
37+
EnoteDetailsImpl::EnoteDetailsImpl():
38+
m_block_height(0),
39+
m_internal_enote_index(0),
40+
m_global_enote_index(0),
41+
m_spent(false),
42+
m_frozen(false),
43+
m_spent_height(0),
44+
m_amount(0),
45+
m_protocol_version(TxProtocol_CryptoNote),
46+
m_key_image_known(false),
47+
m_key_image_request(false),
48+
m_pk_index(0),
49+
m_key_image_partial(false)
50+
{
51+
}
52+
53+
EnoteDetailsImpl::~EnoteDetailsImpl() {}
54+
55+
std::string EnoteDetailsImpl::onetimeAddress() const
56+
{ return m_onetime_address; }
57+
std::string EnoteDetailsImpl::viewTag() const
58+
{ return m_view_tag; }
59+
std::uint64_t EnoteDetailsImpl::blockHeight() const
60+
{ return m_block_height; }
61+
std::string EnoteDetailsImpl::txId() const
62+
{ return m_tx_id; }
63+
std::uint64_t EnoteDetailsImpl::internalEnoteIndex() const
64+
{ return m_internal_enote_index; }
65+
std::uint64_t EnoteDetailsImpl::globalEnoteIndex() const
66+
{ return m_global_enote_index; }
67+
bool EnoteDetailsImpl::isSpent() const
68+
{ return m_spent; }
69+
bool EnoteDetailsImpl::isFrozen() const
70+
{ return m_frozen; }
71+
std::uint64_t EnoteDetailsImpl::spentHeight() const
72+
{ return m_spent_height; }
73+
std::string EnoteDetailsImpl::keyImage() const
74+
{ return m_key_image; }
75+
std::string EnoteDetailsImpl::mask() const
76+
{ return m_mask; }
77+
std::uint64_t EnoteDetailsImpl::amount() const
78+
{ return m_amount; }
79+
EnoteDetails::TxProtocol EnoteDetailsImpl::protocolVersion() const
80+
{ return m_protocol_version; }
81+
bool EnoteDetailsImpl::isKeyImageKnown() const
82+
{ return m_key_image_known; }
83+
bool EnoteDetailsImpl::isKeyImageRequest() const
84+
{ return m_key_image_request; }
85+
std::uint64_t EnoteDetailsImpl::pkIndex() const
86+
{ return m_pk_index; }
87+
std::vector<std::pair<std::uint64_t, std::string>> EnoteDetailsImpl::uses() const
88+
{ return m_uses; }
89+
90+
// Multisig
91+
bool EnoteDetailsImpl::isKeyImagePartial() const
92+
{ return m_key_image_partial; }
93+
94+
} // namespace

src/wallet/api/enote_details.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) 2014-2025, The Monero Project
2+
//
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without modification, are
6+
// permitted provided that the following conditions are met:
7+
//
8+
// 1. Redistributions of source code must retain the above copyright notice, this list of
9+
// conditions and the following disclaimer.
10+
//
11+
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12+
// of conditions and the following disclaimer in the documentation and/or other
13+
// materials provided with the distribution.
14+
//
15+
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16+
// used to endorse or promote products derived from this software without specific
17+
// prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22+
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26+
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27+
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
#include "wallet/api/wallet2_api.h"
30+
31+
32+
namespace Monero {
33+
34+
class EnoteDetailsImpl : public EnoteDetails
35+
{
36+
public:
37+
EnoteDetailsImpl();
38+
~EnoteDetailsImpl() override;
39+
std::string onetimeAddress() const override;
40+
std::string viewTag() const override;
41+
std::uint64_t blockHeight() const override;
42+
std::string txId() const override;
43+
std::uint64_t internalEnoteIndex() const override;
44+
std::uint64_t globalEnoteIndex() const override;
45+
bool isSpent() const override;
46+
bool isFrozen() const override;
47+
std::uint64_t spentHeight() const override;
48+
std::string keyImage() const override;
49+
std::string mask() const override;
50+
std::uint64_t amount() const override;
51+
TxProtocol protocolVersion() const override;
52+
bool isKeyImageKnown() const override;
53+
bool isKeyImageRequest() const override;
54+
std::uint64_t pkIndex() const override;
55+
std::vector<std::pair<std::uint64_t, std::string>> uses() const override;
56+
57+
// Multisig
58+
bool isKeyImagePartial() const override;
59+
60+
private:
61+
friend class WalletImpl;
62+
63+
// Ko
64+
std::string m_onetime_address;
65+
// view_tag
66+
std::string m_view_tag;
67+
// this enote was received at block height
68+
std::uint64_t m_block_height;
69+
// tx id in which tx enote was received
70+
std::string m_tx_id;
71+
// relative index in tx
72+
std::uint64_t m_internal_enote_index;
73+
// absolute index from `cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry.output_indices`
74+
std::uint64_t m_global_enote_index;
75+
// is spent
76+
bool m_spent;
77+
// is frozen
78+
bool m_frozen;
79+
// blockchain height, set if spent
80+
std::uint64_t m_spent_height;
81+
// key image
82+
std::string m_key_image;
83+
// x, blinding factor in amount commitment C = x G + a H
84+
std::string m_mask;
85+
// a
86+
std::uint64_t m_amount;
87+
// protocol version : TxProtocol_CryptoNote / TxProtocol_RingCT
88+
TxProtocol m_protocol_version;
89+
// is key image known
90+
bool m_key_image_known;
91+
// view wallets: we want to request it; cold wallets: it was requested
92+
bool m_key_image_request;
93+
// public key index in tx_extra
94+
std::uint64_t m_pk_index;
95+
// track uses of this enote in the blockchain in the format [ [block_height, tx_id], ... ] if `wallet2::m_track_uses` is true (default is false)
96+
std::vector<std::pair<std::uint64_t, std::string>> m_uses;
97+
98+
// Multisig
99+
bool m_key_image_partial;
100+
// NOTE : These multisig members are part of wallet2 transfer_details and may need to get added here.
101+
/*
102+
std::vector<rct::key> m_multisig_k;
103+
std::vector<multisig_info> m_multisig_info; // one per other participant
104+
*/
105+
};
106+
107+
} // namespace

src/wallet/api/pending_transaction.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,29 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
162162
return m_status == Status_Ok;
163163
}
164164

165+
std::string PendingTransactionImpl::convertTxToStr()
166+
{
167+
std::string tx;
168+
LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size());
169+
170+
try {
171+
tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx);
172+
m_status = Status_Ok;
173+
return tx;
174+
} catch (const tools::error::wallet_internal_error&) {
175+
m_errorString = tr("Wallet internal eror.");
176+
m_status = Status_Error;
177+
} catch (const std::exception &e) {
178+
m_errorString = string(tr("Unknown exception: ")) + e.what();
179+
m_status = Status_Error;
180+
} catch (...) {
181+
m_errorString = tr("Unhandled exception");
182+
LOG_ERROR(m_errorString);
183+
m_status = Status_Error;
184+
}
185+
return ""; // m_status != Status_Ok
186+
}
187+
165188
uint64_t PendingTransactionImpl::amount() const
166189
{
167190
uint64_t result = 0;

src/wallet/api/pending_transaction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class PendingTransactionImpl : public PendingTransaction
5858
std::string multisigSignData() override;
5959
void signMultisigTx() override;
6060
std::vector<std::string> signersKeys() const override;
61+
std::string convertTxToStr() override;
6162

6263
private:
6364
friend class WalletImpl;
@@ -69,6 +70,8 @@ class PendingTransactionImpl : public PendingTransaction
6970
std::unordered_set<crypto::public_key> m_signers;
7071
std::vector<std::string> m_tx_device_aux;
7172
std::vector<crypto::key_image> m_key_images;
73+
// wallet2 m_cold_key_images
74+
std::unordered_map<crypto::public_key, crypto::key_image> m_tx_key_images;
7275
};
7376

7477

src/wallet/api/transaction_history.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ void TransactionHistoryImpl::refresh()
150150
ti->m_timestamp = pd.m_timestamp;
151151
ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
152152
ti->m_unlock_time = pd.m_unlock_time;
153+
// not used for payment_details
154+
ti->m_change = 0;
155+
ti->m_tx_state = TransactionInfo::TxState_Confirmed;
156+
// not used for payment_details
157+
ti->m_double_spend_seen = false;
153158
m_history.push_back(ti);
154159

155160
}
@@ -193,6 +198,11 @@ void TransactionHistoryImpl::refresh()
193198
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
194199
ti->m_timestamp = pd.m_timestamp;
195200
ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
201+
ti->m_unlock_time = pd.m_unlock_time;
202+
ti->m_change = pd.m_change;
203+
ti->m_tx_state = TransactionInfo::TxState_Confirmed;
204+
// not used for confirmed_transfer_details
205+
ti->m_double_spend_seen = false;
196206

197207
// single output transaction might contain multiple transfers
198208
for (const auto &d: pd.m_dests) {
@@ -229,6 +239,11 @@ void TransactionHistoryImpl::refresh()
229239
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
230240
ti->m_timestamp = pd.m_timestamp;
231241
ti->m_confirmations = 0;
242+
ti->m_unlock_time = pd.m_tx.unlock_time;
243+
ti->m_change = pd.m_change;
244+
ti->m_tx_state = (TransactionInfo::TxState) pd.m_state;
245+
// not used for unconfirmed_transfer_details
246+
ti->m_double_spend_seen = false;
232247
for (const auto &d : pd.m_dests)
233248
{
234249
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
@@ -258,6 +273,11 @@ void TransactionHistoryImpl::refresh()
258273
ti->m_label = m_wallet->m_wallet->get_subaddress_label(pd.m_subaddr_index);
259274
ti->m_timestamp = pd.m_timestamp;
260275
ti->m_confirmations = 0;
276+
ti->m_unlock_time = pd.m_unlock_time;
277+
// not used for pool_payment_details
278+
ti->m_change = 0;
279+
ti->m_tx_state = TransactionInfo::TxState_PendingInPool;
280+
ti->m_double_spend_seen = i->second.m_double_spend_seen;
261281
m_history.push_back(ti);
262282

263283
LOG_PRINT_L1(__FUNCTION__ << ": Unconfirmed payment found " << pd.m_amount);

src/wallet/api/transaction_info.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,19 @@ uint64_t TransactionInfoImpl::unlockTime() const
149149
return m_unlock_time;
150150
}
151151

152+
std::uint64_t TransactionInfoImpl::receivedChangeAmount() const
153+
{
154+
return m_change;
155+
}
156+
157+
TransactionInfo::TxState TransactionInfoImpl::txState() const
158+
{
159+
return m_tx_state;
160+
}
161+
162+
bool TransactionInfoImpl::isDoubleSpendSeen() const
163+
{
164+
return m_double_spend_seen;
165+
}
166+
152167
} // namespace

src/wallet/api/transaction_info.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class TransactionInfoImpl : public TransactionInfo
6363
virtual uint64_t confirmations() const override;
6464
virtual uint64_t unlockTime() const override;
6565

66+
std::uint64_t receivedChangeAmount() const override;
67+
TxState txState() const override;
68+
bool isDoubleSpendSeen() const override;
69+
6670
private:
6771
int m_direction;
6872
bool m_pending;
@@ -81,6 +85,12 @@ class TransactionInfoImpl : public TransactionInfo
8185
std::vector<Transfer> m_transfers;
8286
uint64_t m_confirmations;
8387
uint64_t m_unlock_time;
88+
// received change amount from outgoing transaction
89+
std::uint64_t m_change;
90+
// tx state : TxState_Pending / TxState_PendingInPool / TxState_Failed / TxState_Confirmed
91+
TxState m_tx_state;
92+
// is double spend seen
93+
bool m_double_spend_seen;
8494

8595
friend class TransactionHistoryImpl;
8696

src/wallet/api/unsigned_transaction.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,26 @@ uint64_t UnsignedTransactionImpl::minMixinCount() const
315315
return min_mixin;
316316
}
317317

318+
std::string UnsignedTransactionImpl::signAsString()
319+
{
320+
if(m_wallet.watchOnly())
321+
{
322+
m_errorString = tr("This is a watch only wallet");
323+
m_status = Status_Error;
324+
return "";
325+
}
326+
tools::wallet2::signed_tx_set signed_txes;
327+
std::vector<tools::wallet2::pending_tx> ptx;
328+
try
329+
{
330+
return m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes);
331+
}
332+
catch (const std::exception &e)
333+
{
334+
m_errorString = string(tr("Failed to sign transaction ")) + e.what();
335+
m_status = Status_Error;
336+
return "";
337+
}
338+
}
339+
318340
} // namespace

src/wallet/api/unsigned_transaction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class UnsignedTransactionImpl : public UnsignedTransaction
5555
bool sign(const std::string &signedFileName) override;
5656
std::string confirmationMessage() const override {return m_confirmationMessage;}
5757
uint64_t minMixinCount() const override;
58+
std::string signAsString() override;
5859

5960
private:
6061
// Callback function to check all loaded tx's and generate confirmationMessage

0 commit comments

Comments
 (0)