From e69dfbe8f3ccc3cba8cab5cca57e3df8ee9fa3aa Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 28 Jan 2026 12:24:36 +0000 Subject: [PATCH] XMR compat: transaction status support Examples: # after sending XMR transaction: $ mmgen-txsend --status $ mmgen-txsend --status --verbose Testing/demo: $ test/cmdtest.py --coin=xmr -e -X alice_txstatus3 xmr_compat --- mmgen/data/version | 2 +- mmgen/proto/xmr/tx/online.py | 27 ++++++++++++++++++++++++--- test/cmdtest_d/xmr_autosign.py | 26 ++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/mmgen/data/version b/mmgen/data/version index fdd016f6..4e1b80df 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -16.1.dev26 +16.1.dev27 diff --git a/mmgen/proto/xmr/tx/online.py b/mmgen/proto/xmr/tx/online.py index 2f1b1d44..ff2fdf28 100755 --- a/mmgen/proto/xmr/tx/online.py +++ b/mmgen/proto/xmr/tx/online.py @@ -18,9 +18,30 @@ class OnlineSigned(Completed): async def compat_send(self): from ....xmrwallet import op as xmrwallet_op - op = xmrwallet_op('submit', self.cfg, self.filename, None, compat_call=True) - await op.restart_wallet_daemon() - return await op.main() + op_name = 'daemon' if self.cfg.status else 'submit' + op = xmrwallet_op(op_name, self.cfg, self.filename, None, compat_call=True) + if self.cfg.status: + from ....util import msg, ymsg, suf + txid = self.compat_tx.data.txid + if self.cfg.verbose: + msg(self.compat_tx.get_info()) + elif not self.cfg.quiet: + from ....obj import CoinTxID + msg('TxID: {}'.format(CoinTxID(txid).hl())) + res = op.dc.call_raw('get_transactions', txs_hashes=[txid]) + if res['status'] == 'OK': + tx = res['txs'][0] + if tx['in_pool']: + msg('Transaction is in mempool') + else: + confs = tx['confirmations'] + msg('Transaction has {} confirmation{}'.format(confs, suf(confs))) + else: + ymsg('An RPC error occurred while fetching transaction data') + return False + else: + await op.restart_wallet_daemon() + return await op.main() class Sent(OnlineSigned): pass diff --git a/test/cmdtest_d/xmr_autosign.py b/test/cmdtest_d/xmr_autosign.py index 9d6b3703..d51d6af6 100755 --- a/test/cmdtest_d/xmr_autosign.py +++ b/test/cmdtest_d/xmr_autosign.py @@ -548,7 +548,10 @@ class CmdTestXMRCompat(CmdTestXMRAutosign): ('alice_txcreate3', 'recreating the transaction'), ('wait_loop_start_ltc', 'starting autosign wait loop in XMR compat mode [--coins=ltc,xmr]'), ('alice_txsend1', 'sending the transaction'), + ('alice_txstatus1', 'getting the transaction status (in mempool)'), ('mine_blocks_10', 'mining some blocks'), + ('alice_txstatus2', 'getting the transaction status (confirmations)'), + ('alice_txstatus3', 'getting the transaction status (verbose)'), ('alice_twview_chk2', 'viewing Alice’s tracking wallets (check balances)'), ('alice_txcreate_sweep1', 'creating a sweep transaction (account sweep)'), ('alice_txsend2', 'sending the transaction'), @@ -797,6 +800,22 @@ class CmdTestXMRCompat(CmdTestXMRAutosign): alice_txsend1 = alice_txsend2 = alice_txsend3 = _alice_txsend + def alice_txstatus1(self): + return self._alice_txstatus(expect_str='TxID: .* in mempool') + + def alice_txstatus2(self): + return self._alice_txstatus(['--quiet'], expect_str='confirmations') + + def alice_txstatus3(self): + return self._alice_txstatus(['--verbose'], expect_str='Info for transaction .* confirmations') + + def _alice_txstatus(self, add_opts=[], expect_str=None): + return self._alice_txops( + 'txsend', + opts = ['--alice', '--status'], + add_opts = self.alice_daemon_opts + add_opts, + expect_str = expect_str) + def wait_signed1(self): self.spawn(msg_only=True) oqmsg('') @@ -815,7 +834,8 @@ class CmdTestXMRCompat(CmdTestXMRAutosign): wait_signed = False, sweep_type = None, sweep_menu = '', - signable_desc = 'transaction'): + signable_desc = 'transaction', + expect_str = None): if wait_signed: self._wait_signed(signable_desc) self.insert_device_online() @@ -834,8 +854,10 @@ class CmdTestXMRCompat(CmdTestXMRAutosign): t.expect(self.menu_prompt, ch) t.expect('to spend from: ', f'{acct_num}\n') t.expect('(y/N): ', 'y') # save? - elif op == 'txsend': + elif op == 'txsend' and not '--status' in opts: t.expect('(y/N): ', 'y') # view? + if expect_str: + t.expect(expect_str, regex=True) t.read() # required! self.remove_device_online() return t