#!/usr/bin/env python3 # # MMGen Wallet, a terminal-based cryptocurrency wallet # Copyright (C)2013-2026 The MMGen Project # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ tool.file: Address and transaction file routines for the 'mmgen-tool' utility """ from .common import tool_cmd_base, options_annot_str class tool_cmd(tool_cmd_base): "utilities for viewing/checking MMGen address and transaction files" need_proto = True def __init__(self, cfg, *, cmdname=None, proto=None, mmtype=None): if cmdname == 'txview': self.need_amt = True super().__init__(cfg=cfg, cmdname=cmdname, proto=proto, mmtype=mmtype) def _file_chksum(self, mmgen_addrfile, obj): kwargs = {'skip_chksum_msg': True} if not obj.__name__ == 'PasswordList': kwargs.update({'key_address_validity_check': False}) ret = obj(self.cfg, self.proto, infile=mmgen_addrfile, **kwargs) if self.cfg.verbose: from ..util import msg, capfirst if ret.al_id.mmtype.name == 'password': msg('Passwd fmt: {}\nPasswd len: {}\nID string: {}'.format( capfirst(ret.pw_info[ret.pw_fmt].desc), ret.pw_len, ret.pw_id_str)) else: msg(f'Base coin: {ret.base_coin} {capfirst(ret.network)}') msg(f'MMType: {capfirst(ret.al_id.mmtype.name)}') msg(f'List length: {len(ret.data)}') return ret.chksum def addrfile_chksum(self, mmgen_addrfile: str): "compute checksum for MMGen address file" from ..addrlist import AddrList return self._file_chksum(mmgen_addrfile, AddrList) def keyaddrfile_chksum(self, mmgen_keyaddrfile: str): "compute checksum for MMGen key-address file" from ..addrlist import KeyAddrList return self._file_chksum(mmgen_keyaddrfile, KeyAddrList) def viewkeyaddrfile_chksum(self, mmgen_viewkeyaddrfile: str): "compute checksum for MMGen key-address file" from ..addrlist import ViewKeyAddrList return self._file_chksum(mmgen_viewkeyaddrfile, ViewKeyAddrList) def passwdfile_chksum(self, mmgen_passwdfile: str): "compute checksum for MMGen password file" from ..passwdlist import PasswordList return self._file_chksum(mmgen_passwdfile, PasswordList) async def txview( self, varargs_call_sig = { # hack to allow for multiple filenames - must be second argument! 'args': ( 'mmgen_tx_file(s)', 'pager', 'terse', 'sort', 'filesort'), 'dfls': (False, False, 'addr', 'mtime'), 'annots': { 'mmgen_tx_file(s)': str, 'pager': 'send output to pager', 'terse': 'produce compact tabular output', 'sort': 'sort order for transaction inputs and outputs ' + options_annot_str(['addr', 'raw']), 'filesort': 'file sort order ' + options_annot_str(['mtime', 'ctime', 'atime'])}}, *infiles, **kwargs): "display specified raw or signed MMGen transaction files in human-readable form" terse = bool(kwargs.get('terse')) tx_sort = kwargs.get('sort') or 'addr' file_sort = kwargs.get('filesort') or 'mtime' from ..filename import MMGenFileList from ..tx import completed, CompletedTX flist = MMGenFileList(infiles, base_class=completed.Completed, proto=self.proto) flist.sort_by_age(key=file_sort) # in-place sort async def process_file(f): return (await CompletedTX( cfg = self.cfg, filename = f.name, quiet_open = True)).info.format(terse=terse, sort=tx_sort) return ('—'*77+'\n').join([await process_file(f) for f in flist]).rstrip()