Browse Source

mmgen-xmrwallet: new `dump-json` operation

The MMGen Project 1 week ago
parent
commit
8a750259b9

+ 5 - 2
mmgen/help/xmrwallet.py

@@ -59,8 +59,11 @@ abort     - abort the current transaction created with --autosign.  The
             transaction may be signed or unsigned
             transaction may be signed or unsigned
 txview    - display detailed information about a transaction file or files
 txview    - display detailed information about a transaction file or files
 txlist    - same as above, but display terse information in tabular format
 txlist    - same as above, but display terse information in tabular format
-dump      - produce JSON dumps of wallet metadata (accounts, addresses and
-            labels) for a list or range of wallets
+dump-json - dump wallet metadata (accounts, addresses, labels), plus address
+            balances, for a list or range of wallets, to standard output in
+            JSON format
+dump      - same as above, but dump metadata only and save the dumps to
+            separate files for each wallet
 restore   - same as ‘create’, but additionally restore wallet metadata from
 restore   - same as ‘create’, but additionally restore wallet metadata from
             the corresponding JSON dump files created with ‘dump’
             the corresponding JSON dump files created with ‘dump’
 export-outputs      - export outputs of watch-only wallets for import into
 export-outputs      - export outputs of watch-only wallets for import into

+ 2 - 2
mmgen/main_xmrwallet.py

@@ -28,7 +28,7 @@ opts_data = {
 		'desc': """Perform various Monero wallet and transacting operations for
 		'desc': """Perform various Monero wallet and transacting operations for
                    addresses in an MMGen XMR key-address file""",
                    addresses in an MMGen XMR key-address file""",
 		'usage2': [
 		'usage2': [
-			'[opts] create | sync | list | view | listview | dump | restore [xmr_keyaddrfile] [wallets]',
+			'[opts] create | sync | list | view | listview | dump-json | dump | restore [xmr_keyaddrfile] [wallets]',
 			'[opts] label    [xmr_keyaddrfile] LABEL_SPEC',
 			'[opts] label    [xmr_keyaddrfile] LABEL_SPEC',
 			'[opts] new      [xmr_keyaddrfile] NEW_ADDRESS_SPEC',
 			'[opts] new      [xmr_keyaddrfile] NEW_ADDRESS_SPEC',
 			'[opts] transfer [xmr_keyaddrfile] TRANSFER_SPEC',
 			'[opts] transfer [xmr_keyaddrfile] TRANSFER_SPEC',
@@ -133,7 +133,7 @@ match op:
 			cfg._usage()
 			cfg._usage()
 	case 'txview' | 'txlist':
 	case 'txview' | 'txlist':
 		infile = [infile] + cmd_args
 		infile = [infile] + cmd_args
-	case 'create' | 'sync' | 'list' | 'view' | 'listview' | 'dump' | 'restore': # kafile_arg_ops
+	case 'create' | 'sync' | 'list' | 'view' | 'listview' | 'dump_json' | 'dump' | 'restore':
 		if len(cmd_args) > 1:
 		if len(cmd_args) > 1:
 			cfg._usage()
 			cfg._usage()
 		wallets = cmd_args.pop(0) if cmd_args else None
 		wallets = cmd_args.pop(0) if cmd_args else None

+ 4 - 0
mmgen/xmrwallet/__init__.py

@@ -64,6 +64,8 @@ op_names = {
 	'submit':              'submit',
 	'submit':              'submit',
 	'resubmit':            'submit',
 	'resubmit':            'submit',
 	'abort':               'submit',
 	'abort':               'submit',
+	'dump_data':           'dump',
+	'dump_json':           'dump',
 	'dump':                'dump',
 	'dump':                'dump',
 	'restore':             'restore',
 	'restore':             'restore',
 	'export_outputs':      'export',
 	'export_outputs':      'export',
@@ -84,6 +86,8 @@ kafile_arg_ops = (
 	'transfer',
 	'transfer',
 	'sweep',
 	'sweep',
 	'sweep_all',
 	'sweep_all',
+	'dump_data',
+	'dump_json',
 	'dump',
 	'dump',
 	'restore')
 	'restore')
 
 

+ 28 - 1
mmgen/xmrwallet/ops/dump.py

@@ -12,7 +12,7 @@
 xmrwallet.ops.dump: Monero wallet ops for the MMGen Suite
 xmrwallet.ops.dump: Monero wallet ops for the MMGen Suite
 """
 """
 
 
-from ...util import msg
+from ...util import msg, Msg
 
 
 from ..file.outputs import MoneroWalletDumpFile
 from ..file.outputs import MoneroWalletDumpFile
 from ..rpc import MoneroWalletRPC
 from ..rpc import MoneroWalletRPC
@@ -33,3 +33,30 @@ class OpDump(OpWallet):
 			data      = {'wallet_metadata': wallet_data.addrs_data}
 			data      = {'wallet_metadata': wallet_data.addrs_data}
 		).write()
 		).write()
 		return True
 		return True
+
+class OpDumpDataBase(OpWallet):
+	wallet_offline = True
+	stem = 'dump'
+	return_data = True
+
+	async def process_wallet(self, d, fn, last):
+		h = MoneroWalletRPC(self, d)
+		h.open_wallet('source')
+		return {
+			'seed_id': self.kal.al_id.sid,
+			'wallet_num': d.idx,
+			'data': h.get_wallet_data(print=False)}
+
+	def post_main_success(self):
+		pass
+
+class OpDumpData(OpDumpDataBase):
+	start_daemon = False
+
+class OpDumpJson(OpDumpDataBase):
+
+	async def main(self):
+		import json
+		data = await super().main()
+		Msg(json.dumps(data))
+		return sum(map(bool, data))

+ 14 - 6
test/cmdtest_d/xmr_autosign.py

@@ -17,8 +17,8 @@ import re, asyncio
 
 
 from mmgen.color import blue, cyan, brown
 from mmgen.color import blue, cyan, brown
 
 
-from ..include.common import imsg, silence, end_silence
-from .include.common import get_file_with_ext
+from ..include.common import imsg, silence, end_silence, strip_ansi_escapes
+from .include.common import get_file_with_ext, cleanup_env
 
 
 from .xmrwallet import CmdTestXMRWallet
 from .xmrwallet import CmdTestXMRWallet
 from .autosign import CmdTestAutosignThreaded
 from .autosign import CmdTestAutosignThreaded
@@ -55,6 +55,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
 		('new_address_alice',        'adding an address to Alice’s tmp wallet'),
 		('new_address_alice',        'adding an address to Alice’s tmp wallet'),
 		('new_address_alice_label',  'adding an address to Alice’s tmp wallet (with label)'),
 		('new_address_alice_label',  'adding an address to Alice’s tmp wallet (with label)'),
 		('dump_tmp_wallets',         'dumping Alice’s tmp wallets'),
 		('dump_tmp_wallets',         'dumping Alice’s tmp wallets'),
+		('dump_tmp_wallets_json',    'dumping Alice’s tmp wallets to JSON format'),
 		('delete_tmp_wallets',       'deleting Alice’s tmp wallets'),
 		('delete_tmp_wallets',       'deleting Alice’s tmp wallets'),
 		('gen_kafile_miner',         'generating key-address file for Miner'),
 		('gen_kafile_miner',         'generating key-address file for Miner'),
 		('create_wallet_miner',      'creating Monero wallet for Miner'),
 		('create_wallet_miner',      'creating Monero wallet for Miner'),
@@ -174,10 +175,13 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
 	def dump_tmp_wallets(self):
 	def dump_tmp_wallets(self):
 		return self._dump_wallets(autosign=False)
 		return self._dump_wallets(autosign=False)
 
 
+	def dump_tmp_wallets_json(self):
+		return self._dump_wallets(autosign=False, op='dump_json')
+
 	def dump_wallets(self):
 	def dump_wallets(self):
 		return self._dump_wallets(autosign=True)
 		return self._dump_wallets(autosign=True)
 
 
-	def _dump_wallets(self, autosign):
+	def _dump_wallets(self, autosign, op='dump'):
 		data = self.users['alice']
 		data = self.users['alice']
 		self.insert_device_online()
 		self.insert_device_online()
 		t = self.spawn(
 		t = self.spawn(
@@ -186,10 +190,14 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
 			+ (['--alice', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
 			+ (['--alice', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
 			+ [f'--daemon=localhost:{data.md.rpc_port}']
 			+ [f'--daemon=localhost:{data.md.rpc_port}']
 			+ (self.autosign_opts if autosign else [])
 			+ (self.autosign_opts if autosign else [])
-			+ ['dump']
-			+ ([] if autosign else [get_file_with_ext(data.udir, 'akeys')]))
+			+ [op]
+			+ ([] if autosign else [get_file_with_ext(data.udir, 'akeys')]),
+			env = cleanup_env(self.cfg))
 		t.expect('2 wallets dumped')
 		t.expect('2 wallets dumped')
-		t.read()
+		res = t.read()
+		if op == 'dump_json':
+			import json
+			data = json.loads(re.sub('Stopping.*', '', strip_ansi_escapes(res)).strip())
 		self.remove_device_online()
 		self.remove_device_online()
 		return t
 		return t