From b2ff67b36cdbab8b659aec5f73cbdeef01e2db51 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 5 Oct 2026 14:30:05 +0000 Subject: [PATCH] minor cleanups, variable renames, whitespace --- mmgen/help/help_notes.py | 2 +- mmgen/help/swaptxcreate.py | 8 +++---- mmgen/proto/xmr/tw/addresses.py | 1 - mmgen/tw/addresses.py | 37 +++++++++++++++++++++------------ mmgen/tx/new.py | 23 +++++++++++++------- mmgen/tx/new_swap.py | 19 +++++++++++------ 6 files changed, 58 insertions(+), 32 deletions(-) diff --git a/mmgen/help/help_notes.py b/mmgen/help/help_notes.py index d5668376..e63f7765 100755 --- a/mmgen/help/help_notes.py +++ b/mmgen/help/help_notes.py @@ -51,7 +51,7 @@ class help_notes: return 'ADDR,AMT [addr file ...]' def swaptxcreate_args(self): - return 'COIN1 [AMT CHG_ADDR] COIN2 [ADDR]' + return 'COIN1 [AMT CHG_ADDR] COIN2 [DEST_ADDR]' def acct_info_desc(self): return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info' diff --git a/mmgen/help/swaptxcreate.py b/mmgen/help/swaptxcreate.py index edc1e575..801ecd3f 100755 --- a/mmgen/help/swaptxcreate.py +++ b/mmgen/help/swaptxcreate.py @@ -53,10 +53,10 @@ user will be presented with a list of the lowest-indexed addresses of preferred type for each Seed ID and prompted to choose from among them. Change and destination addresses may also be specified manually with the -CHG_ADDR and ADDR arguments. These may be given as full MMGen IDs or in the -form ADDRTYPE_CODE or SEED_ID:ADDRTYPE_CODE (see EXAMPLES below and the -‘mmgen-txcreate’ help screen for details). For Ethereum, the CHG_ADDR -argument is not supported. +CHG_ADDR and DEST_ADDR arguments. These are given either as full MMGen IDs +or in the form [SEED_ID:]ADDRTYPE_CODE, with the following exception: for +Ethereum the CHG_ADDR argument is not supported. See EXAMPLES below and the +‘mmgen-txcreate’ help screen for details. While discouraged, sending change or swapping to non-wallet addresses is also supported, in which case the signing script (‘mmgen-txsign’ or ‘mmgen- diff --git a/mmgen/proto/xmr/tw/addresses.py b/mmgen/proto/xmr/tw/addresses.py index db0b0d25..0e2d1f0e 100755 --- a/mmgen/proto/xmr/tw/addresses.py +++ b/mmgen/proto/xmr/tw/addresses.py @@ -40,7 +40,6 @@ class MoneroTwAddresses(MoneroTwView, TwAddresses): include_empty = True has_used = True - prompt_fs_repl = {'XMR': ( (1, 'Filters: show [E]mpty addrs, [u]sed addrs, all [L]abels'), (3, 'Actions: [q]uit menu, add [l]abel, [N]ew acct, [n]ew addr, [R]efresh bals:'))} diff --git a/mmgen/tw/addresses.py b/mmgen/tw/addresses.py index 1773cd9c..0a112fe2 100755 --- a/mmgen/tw/addresses.py +++ b/mmgen/tw/addresses.py @@ -332,7 +332,15 @@ class TwAddresses(TwView): return e.is_used return None # addr not in tracking wallet - def get_change_address(self, al_id, *, bot=None, top=None, exclude=None, desc=None): + def get_change_address( + self, + key_in, + *, + bot = None, + top = None, + exclude = None, + desc = None): + """ Get lowest-indexed unused address in tracking wallet for requested AddrListID. Return values on failure: @@ -342,20 +350,22 @@ class TwAddresses(TwView): def get_start(bot, top): """ - bisecting algorithm to find first entry with requested al_id + bisecting algorithm to find first entry matching requested match key - Since 'btc' > 'F' and pre_target sorts below the first twmmid of the al_id + Since 'btc' > 'F' and target sorts below the first twmmid of the match key stringwise, we can just search on raw twmmids. """ - pre_target = al_id + ':0' + + # bisect target key sorts just below the desired target and never matches the bisect key + pre_target_key = key + ':0' n = top >> 1 while True: if bot == top: - return bot if data[bot].al_id == al_id else None + return bot if self.data[bot].al_id == key else None - if data[n].twmmid < pre_target: + if self.data[n].twmmid < pre_target_key: bot = n + 1 else: top = n @@ -365,18 +375,20 @@ class TwAddresses(TwView): assert self.sort_key == 'twmmid' assert self.reverse is False - data = self.data + key = key_in start = get_start( bot = 0 if bot is None else bot, - top = len(data) - 1 if top is None else top) + top = len(self.data) - 1 if top is None else top) if start is not None: - for d in data[start:]: - if d.al_id == al_id: + for d in self.data[start:]: + if d.al_id == key: if ( not d.is_used and not d.twmmid in exclude - and (self.cfg.autochg_ignore_labels or not d.comment) + and ( + self.cfg.autochg_ignore_labels or + not d.comment) ): if d.comment: msg('{} {} {} {}{}'.format( @@ -384,8 +396,7 @@ class TwAddresses(TwView): d.twmmid.hl(), yellow('has a label,'), d.comment.hl2(encl='‘’'), - yellow(f',\n but allowing it for {desc} anyway by user request') - )) + yellow(f',\n but allowing it for {desc} anyway by user request'))) return d else: break diff --git a/mmgen/tx/new.py b/mmgen/tx/new.py index 7c0300e9..e20d343d 100755 --- a/mmgen/tx/new.py +++ b/mmgen/tx/new.py @@ -89,6 +89,7 @@ class New(Base): chg_autoselected = False _funds_available = namedtuple('funds_available', ['is_positive', 'amt']) _net_fee = namedtuple('network_fee_estimate', ['fee', 'type']) + _cl_output = namedtuple('txcreate_cmdline_output', 'arg mmid addr amt data is_vault') def warn_insufficient_funds(self, amt, coin): msg(self.msg_insufficient_funds.format(amt.hl(), coin)) @@ -183,10 +184,8 @@ class New(Base): def parse_cmdline_arg(self, proto, arg_in, ad_f, ad_w): - _pa = namedtuple('txcreate_cmdline_output', ['arg', 'mmid', 'addr', 'amt', 'data', 'is_vault']) - if data := self.process_data_output_arg(arg_in): - return _pa(arg_in, None, None, None, data, False) + return self._cl_output(arg_in, None, None, None, data, False) arg, amt = arg_in.split(',', 1) if ',' in arg_in else (arg_in, None) @@ -205,13 +204,21 @@ class New(Base): else: die(2, f'{arg_in}: invalid command-line argument') - return _pa(arg, mmid or None, coin_addr, amt, None, is_vault) + return self._cl_output(arg, mmid or None, coin_addr, amt, None, is_vault) + + async def get_autochg_addr( + self, + proto, + arg, + *, + exclude, + desc, + match_all_addrtypes = False): - async def get_autochg_addr(self, proto, arg, *, exclude, desc, all_addrtypes=False): from ..tw.addresses import TwAddresses al = await TwAddresses(self.cfg, proto, get_data=True) - if all_addrtypes: + if match_all_addrtypes: res = al.get_change_address_by_addrtype(None, exclude=exclude, desc=desc) req_desc = 'of any allowed address type' elif obj := get_obj(MMGenAddrType, proto=proto, id_str=arg, silent=True): @@ -276,7 +283,9 @@ class New(Base): if self.chg_output is not None: if self.chg_autoselected and not self.is_swap: # swap TX, so user has already confirmed - self.confirm_autoselected_addr(self.chg_output.mmid, 'change address') + self.confirm_autoselected_addr( + self.chg_output.mmid, + 'change address') elif len(self.nondata_outputs) > 1: await self.warn_addr_used(self.proto, self.chg_output, 'change address') diff --git a/mmgen/tx/new_swap.py b/mmgen/tx/new_swap.py index eb4d0d55..747ddd24 100755 --- a/mmgen/tx/new_swap.py +++ b/mmgen/tx/new_swap.py @@ -49,16 +49,21 @@ class NewSwap(New): self.get_addrdata_from_files(proto, addrfiles), await TwAddrData(self.cfg, proto)) if pa.addr: - await self.warn_addr_used(proto, pa, desc) + await self.warn_addr_used(proto, pa, f'{desc} address') return ret(proto.coin, proto.network, pa.addr, pa.mmid) - full_desc = f'{desc} on the {proto.coin} {proto.network} network' - res = await self.get_autochg_addr(proto, arg, exclude=[], desc=full_desc, all_addrtypes=not arg) + full_desc = f'{desc} address on the {proto.coin} {proto.network} network' + res = await self.get_autochg_addr( + proto, + arg, + exclude = [], + desc = full_desc, + match_all_addrtypes = not arg) self.confirm_autoselected_addr(res.twmmid, full_desc) return ret(proto.coin, proto.network, res.addr, res.twmmid) async def get_chg_output(self, arg, addrfiles): - chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change address') + chg_output = await self.get_swap_output(self.proto, arg, addrfiles, 'change') self.check_addr_is_wallet_addr( chg_output, message = 'Change address is not an MMGen wallet address!') @@ -97,7 +102,9 @@ class NewSwap(New): arg = get_arg() # arg 3: chg_spec (change address spec) - if args.send_amt and not (self.proto.is_vm or arg in sa.recv): # is change arg + if args.send_amt and not ( + self.proto.is_vm or + arg in sa.recv): # is change arg nonlocal chg_output chg_output = await self.get_chg_output(arg, addrfiles) arg = get_arg() @@ -136,7 +143,7 @@ class NewSwap(New): self.recv_proto, args.recv_spec, addrfiles, - 'destination address') + 'destination') self.check_addr_is_wallet_addr( recv_output,