#!/usr/bin/python import argparse import logging import operator import re from monero import exceptions from monero.backends.jsonrpc import JSONRPCWallet, RPCError from monero.wallet import Wallet def url_data(url): gs = re.compile( r'^(?:(?P[a-z0-9_-]+)?(?::(?P[^@]+))?@)?(?P[^:\s]+)(?::(?P[0-9]+))?$' ).match(url).groupdict() return dict(filter(operator.itemgetter(1), gs.items())) def get_wallet(): argsparser = argparse.ArgumentParser(description="Display wallet contents") argsparser.add_argument('wallet_rpc_url', nargs='?', type=url_data, default='127.0.0.1:34562', help="Wallet RPC URL [user[:password]@]host[:port]") argsparser.add_argument('-v', dest='verbosity', action='count', default=0, help="Verbosity (repeat to increase; -v for INFO, -vv for DEBUG") argsparser.add_argument('-t', dest='timeout', type=int, default=30, help="Request timeout") args = argsparser.parse_args() level = logging.WARNING if args.verbosity == 1: level = logging.INFO elif args.verbosity > 1: level = logging.DEBUG logging.basicConfig(level=level, format="%(asctime)-15s %(message)s") return Wallet(JSONRPCWallet(timeout=args.timeout, **args.wallet_rpc_url)) _TXHDR = "timestamp height id/hash " \ " amount fee {dir:95s} payment_id" def pmt2str(pmt): res = ["{time} {height:7d} {hash} {amount:17.12f} {fee:13.12f} {addr} {payment_id}".format( time=pmt.timestamp.strftime("%d-%m-%y %H:%M:%S") if getattr(pmt, 'timestamp', None) else None, height=pmt.transaction.height or 0, hash=pmt.transaction.hash, amount=pmt.amount, fee=pmt.transaction.fee or 0, payment_id=pmt.payment_id, addr=getattr(pmt, 'local_address', None) or '')] try: for dest in pmt.destinations: res.append(" {amount:17.12f} to {address}".format(address=dest[0], amount=dest[1])) except AttributeError: pass return "\n".join(res) def a2str(a): return "{addr} {label}".format( addr=a, label=a.label or "") w = get_wallet() masteraddr = w.address() print( "Master address: {addr}\n" \ "Balance: {total:16.12f} ({unlocked:16.12f} unlocked)".format( addr=a2str(masteraddr), total=w.balance(), unlocked=w.balance(unlocked=True))) try: seed = w.seed() except (exceptions.WalletIsNotDeterministic, RPCError): # FIXME: Remove RPCError once PR#4563 is merged in monero seed = '[--- wallet is not deterministic and has no seed ---]' print( "Keys:\n" \ " private spend: {ssk}\n" \ " private view: {svk}\n" \ " public spend: {psk}\n" \ " public view: {pvk}\n\n" \ "Seed:\n{seed}".format( ssk=w.spend_key(), svk=w.view_key(), psk=masteraddr.spend_key(), pvk=masteraddr.view_key(), seed=seed )) if len(w.accounts) > 1: print("\nWallet has {num} account(s):".format(num=len(w.accounts))) for acc in w.accounts: print("\nAccount {idx:02d}:".format(idx=acc.index)) print("Balance: {total:16.12f} ({unlocked:16.12f} unlocked)".format( total=acc.balance(), unlocked=acc.balance(unlocked=True))) addresses = acc.addresses() print("{num:2d} address(es):".format(num=len(addresses))) print("\n".join(map(a2str, addresses))) ins = acc.incoming(unconfirmed=True) if ins: print("\nIncoming transactions:") print(_TXHDR.format(dir='received by')) for tx in ins: print(pmt2str(tx)) outs = acc.outgoing(unconfirmed=True) if outs: print("\nOutgoing transactions:") print(_TXHDR.format(dir='sent from')) for tx in outs: print(pmt2str(tx)) else: addresses = w.accounts[0].addresses() print("{num:2d} address(es):".format(num=len(addresses))) print("\n".join(map(a2str, addresses))) ins = w.incoming(unconfirmed=True) if ins: print("\nIncoming transactions:") print(_TXHDR.format(dir='received by')) for tx in ins: print(pmt2str(tx)) outs = w.outgoing(unconfirmed=True) if outs: print("\nOutgoing transactions:") print(_TXHDR.format(dir='sent from')) for tx in outs: print(pmt2str(tx))