From 701e7a77e5cb02a30fc00a8a15da165f34203100 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Thu, 9 Apr 2020 19:32:23 +0000 Subject: [PATCH] use relative imports throughout --- mmgen/addr.py | 52 +++++++++++++++---------------- mmgen/baseconv.py | 14 ++++----- mmgen/bip39.py | 6 ++-- mmgen/cfg.py | 4 +-- mmgen/color.py | 4 +-- mmgen/common.py | 12 ++++---- mmgen/crypto.py | 4 +-- mmgen/daemon.py | 10 +++--- mmgen/devtools.py | 4 +-- mmgen/filename.py | 10 +++--- mmgen/globalvars.py | 2 +- mmgen/license.py | 2 +- mmgen/main.py | 4 +-- mmgen/main_addrgen.py | 6 ++-- mmgen/main_addrimport.py | 10 +++--- mmgen/main_autosign.py | 10 +++--- mmgen/main_passgen.py | 8 ++--- mmgen/main_regtest.py | 4 +-- mmgen/main_seedjoin.py | 4 +-- mmgen/main_split.py | 8 ++--- mmgen/main_tool.py | 2 +- mmgen/main_txbump.py | 8 ++--- mmgen/main_txcreate.py | 4 +-- mmgen/main_txdo.py | 8 ++--- mmgen/main_txsend.py | 4 +-- mmgen/main_txsign.py | 6 ++-- mmgen/main_wallet.py | 10 +++--- mmgen/mn_entry.py | 8 ++--- mmgen/obj.py | 34 ++++++++++----------- mmgen/opts.py | 26 ++++++++-------- mmgen/protocol.py | 18 +++++------ mmgen/regtest.py | 6 ++-- mmgen/rpc.py | 12 ++++---- mmgen/seed.py | 4 +-- mmgen/term.py | 2 +- mmgen/tool.py | 66 ++++++++++++++++++++-------------------- mmgen/tw.py | 20 ++++++------ mmgen/tx.py | 22 +++++++------- mmgen/txsign.py | 10 +++--- mmgen/util.py | 24 +++++++-------- 40 files changed, 236 insertions(+), 236 deletions(-) diff --git a/mmgen/addr.py b/mmgen/addr.py index e4b25e26..e140f211 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -21,9 +21,9 @@ addr.py: Address generation/display routines for the MMGen suite """ from hashlib import sha256,sha512 -from mmgen.common import * -from mmgen.obj import * -from mmgen.baseconv import * +from .common import * +from .obj import * +from .baseconv import * pnm = g.proj_name @@ -53,7 +53,7 @@ class AddrGenerator(MMGenObject): class AddrGeneratorP2PKH(AddrGenerator): def to_addr(self,pubhex): - from mmgen.protocol import hash160 + from .protocol import hash160 assert type(pubhex) == PubKey return CoinAddr(g.proto.pubhash2addr(hash160(pubhex),p2sh=False)) @@ -72,7 +72,7 @@ class AddrGeneratorSegwit(AddrGenerator): class AddrGeneratorBech32(AddrGenerator): def to_addr(self,pubhex): assert pubhex.compressed,'Uncompressed public keys incompatible with Segwit' - from mmgen.protocol import hash160 + from .protocol import hash160 return CoinAddr(g.proto.pubhash2bech32addr(hash160(pubhex))) def to_segwit_redeem_script(self,pubhex): @@ -86,10 +86,10 @@ class AddrGeneratorEthereum(AddrGenerator): assert not g.use_internal_keccak_module from sha3 import keccak_256 except: - from mmgen.keccak import keccak_256 + from .keccak import keccak_256 self.keccak_256 = keccak_256 - from mmgen.protocol import hash256 + from .protocol import hash256 self.hash256 = hash256 return AddrGenerator.__init__(addr_type) @@ -111,7 +111,7 @@ class AddrGeneratorZcashZ(AddrGenerator): s = bytearray(s + bytes(32)) s[0] |= 0xc0 s[32] = t - from mmgen.sha2 import Sha256 + from .sha2 import Sha256 return Sha256(s,preprocess=False).digest() def to_addr(self,pubhex): # pubhex is really privhex @@ -119,7 +119,7 @@ class AddrGeneratorZcashZ(AddrGenerator): assert len(key) == 32,'{}: incorrect privkey length'.format(len(key)) from nacl.bindings import crypto_scalarmult_base p2 = crypto_scalarmult_base(self.zhash256(key,1)) - from mmgen.protocol import _b58chk_encode + from .protocol import _b58chk_encode ver_bytes = g.proto.addr_fmt_to_ver_bytes('zcash_z') ret = _b58chk_encode(ver_bytes + self.zhash256(key,0) + p2) return CoinAddr(ret) @@ -131,7 +131,7 @@ class AddrGeneratorZcashZ(AddrGenerator): vk[32] &= 0xf8 vk[63] &= 0x7f vk[63] |= 0x40 - from mmgen.protocol import _b58chk_encode + from .protocol import _b58chk_encode ver_bytes = g.proto.addr_fmt_to_ver_bytes('viewkey') ret = _b58chk_encode(ver_bytes + vk) return ZcashViewKey(ret) @@ -147,17 +147,17 @@ class AddrGeneratorMonero(AddrGenerator): assert not g.use_internal_keccak_module from sha3 import keccak_256 except: - from mmgen.keccak import keccak_256 + from .keccak import keccak_256 self.keccak_256 = keccak_256 - from mmgen.protocol import hash256 + from .protocol import hash256 self.hash256 = hash256 if opt.use_old_ed25519: - from mmgen.ed25519 import edwards,encodepoint,B,scalarmult + from .ed25519 import edwards,encodepoint,B,scalarmult else: - from mmgen.ed25519ll_djbec import scalarmult - from mmgen.ed25519 import edwards,encodepoint,B + from .ed25519ll_djbec import scalarmult + from .ed25519 import edwards,encodepoint,B self.edwards = edwards self.encodepoint = encodepoint @@ -233,7 +233,7 @@ class KeyGenerator(MMGenObject): @classmethod def test_for_secp256k1(self,silent=False): try: - from mmgen.secp256k1 import priv2pub + from .secp256k1 import priv2pub m = 'Unable to execute priv2pub() from secp256k1 extension module' assert priv2pub(bytes.fromhex('deadbeef'*8),1),m return True @@ -280,7 +280,7 @@ class KeyGeneratorSecp256k1(KeyGenerator): desc = 'mmgen-secp256k1' def to_pubhex(self,privhex): assert type(privhex) == PrivKey - from mmgen.secp256k1 import priv2pub + from .secp256k1 import priv2pub return PubKey(priv2pub(bytes.fromhex(privhex),int(privhex.compressed)).hex(),compressed=privhex.compressed) class KeyGeneratorDummy(KeyGenerator): @@ -494,14 +494,14 @@ Removed {{}} duplicate WIF key{{}} from keylist (also in {pnm} key-address file scramble_key = g.coin.lower() else: scramble_key = (g.coin.lower()+':','')[is_btcfork] + self.al_id.mmtype.name - from mmgen.crypto import scramble_seed + from .crypto import scramble_seed if g.proto.is_testnet(): scramble_key += ':testnet' dmsg_sc('str',scramble_key) return scramble_seed(seed,scramble_key.encode()) def encrypt(self,desc='new key list'): - from mmgen.crypto import mmgen_encrypt + from .crypto import mmgen_encrypt self.fmt_data = mmgen_encrypt(self.fmt_data.encode(),desc,'') self.ext += '.'+g.mmenc_ext @@ -697,7 +697,7 @@ Removed {{}} duplicate WIF key{{}} from keylist (also in {pnm} key-address file else: mmtype = MMGenAddrType(al_mmtype,on_fail='raise') - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol base_coin = CoinProtocol(al_coin or 'BTC',testnet=False).base_coin return base_coin,mmtype,tn @@ -780,7 +780,7 @@ class KeyList(AddrList): chksum_rec_f = lambda foo,e: (str(e.idx), e.addr, e.sec.wif) def is_bip39_str(s): - from mmgen.bip39 import bip39 + from .bip39 import bip39 return bool(bip39.tohex(s.split(),wl_id='bip39')) def is_xmrseed(s): @@ -918,7 +918,7 @@ Record this checksum: it will be used to verify the password file in the future pw_bytes = self.pw_len // 2 good_pw_len = seed.byte_len * 2 elif pf == 'bip39': - from mmgen.bip39 import bip39 + from .bip39 import bip39 pw_bytes = bip39.nwords2seedlen(self.pw_len,in_bytes=True) good_pw_len = bip39.seedlen2nwords(seed.byte_len,in_bytes=True) elif pf == 'xmrseed': @@ -952,7 +952,7 @@ Record this checksum: it will be used to verify the password file in the future # take most significant part return hex_sec[:self.pw_len] elif self.pw_fmt == 'bip39': - from mmgen.bip39 import bip39 + from .bip39 import bip39 pw_len_hex = bip39.nwords2seedlen(self.pw_len,in_hex=True) # take most significant part return ' '.join(bip39.fromhex(hex_sec[:pw_len_hex],wl_id='bip39')) @@ -960,7 +960,7 @@ Record this checksum: it will be used to verify the password file in the future pw_len_hex = baseconv.seedlen_map_rev['xmrseed'][self.pw_len] * 2 # take most significant part bytes_trunc = bytes.fromhex(hex_sec[:pw_len_hex]) - from mmgen.protocol import MoneroProtocol + from .protocol import MoneroProtocol bytes_preproc = MoneroProtocol.preprocess_key(bytes_trunc,None) return ' '.join(baseconv.frombytes(bytes_preproc,wl_id='xmrseed')) else: @@ -982,11 +982,11 @@ Record this checksum: it will be used to verify the password file in the future scramble_key = '{}:{}:{}'.format(self.pw_fmt,self.pw_len,self.pw_id_str) if self.hex2bip39: - from mmgen.bip39 import bip39 + from .bip39 import bip39 pwlen = bip39.nwords2seedlen(self.pw_len,in_hex=True) scramble_key = '{}:{}:{}'.format('hex',pwlen,self.pw_id_str) - from mmgen.crypto import scramble_seed + from .crypto import scramble_seed dmsg_sc('str',scramble_key) return scramble_seed(seed,scramble_key.encode()) diff --git a/mmgen/baseconv.py b/mmgen/baseconv.py index 561b3d9e..52d794f7 100755 --- a/mmgen/baseconv.py +++ b/mmgen/baseconv.py @@ -21,8 +21,8 @@ baseconv.py: base conversion class for the MMGen suite """ from hashlib import sha256 -from mmgen.exception import * -from mmgen.util import die +from .exception import * +from .util import die def is_b58_str(s): return set(list(s)) <= set(baseconv.digits['b58']) def is_b32_str(s): return set(list(s)) <= set(baseconv.digits['b32']) @@ -76,13 +76,13 @@ class baseconv(object): if mn_id in cls.digits: return if mn_id == 'mmgen': - from mmgen.mn_electrum import words + from .mn_electrum import words cls.digits[mn_id] = words elif mn_id == 'xmrseed': - from mmgen.mn_monero import words + from .mn_monero import words cls.digits[mn_id] = words elif mn_id == 'tirosh': - from mmgen.mn_tirosh import words + from .mn_tirosh import words cls.digits[mn_id] = words[:cls.mn_base] else: raise ValueError('{}: unrecognized mnemonic ID'.format(mn_id)) @@ -109,7 +109,7 @@ class baseconv(object): cls.init_mn(wl_id) wl = cls.digits[wl_id] - from mmgen.util import qmsg,compare_chksums + from .util import qmsg,compare_chksums ret = 'Wordlist: {}\nLength: {} words'.format(wl_id,len(wl)) new_chksum = cls.get_wordlist_chksum(wl_id) @@ -202,7 +202,7 @@ class baseconv(object): def fromhex(cls,hexstr,wl_id,pad=None,tostr=False): "convert hex string to list or string data of base 'wl_id'" - from mmgen.util import is_hex_str + from .util import is_hex_str if not is_hex_str(hexstr): m = ('{h!r}:','seed data')[pad=='seed'] + ' not a hexadecimal string' raise HexadecimalStringError(m.format(h=hexstr)) diff --git a/mmgen/bip39.py b/mmgen/bip39.py index 0a26ae83..56a5918e 100755 --- a/mmgen/bip39.py +++ b/mmgen/bip39.py @@ -22,9 +22,9 @@ bip39.py - Data and routines for BIP39 mnemonic seed phrases from hashlib import sha256 -from mmgen.exception import * -from mmgen.baseconv import * -from mmgen.util import is_hex_str +from .exception import * +from .baseconv import * +from .util import is_hex_str # implements a subset of the baseconv API class bip39(baseconv): diff --git a/mmgen/cfg.py b/mmgen/cfg.py index baa95e3a..2c3c72b2 100755 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -27,8 +27,8 @@ cfg.py: API for the MMGen runtime configuration file and related files import sys,os,re,hashlib from collections import namedtuple -from mmgen.globalvars import * -from mmgen.util import * +from .globalvars import * +from .util import * def cfg_file(id_str): return CfgFile.get_cls_by_id(id_str)() diff --git a/mmgen/color.py b/mmgen/color.py index 12c907c8..8fb2a171 100755 --- a/mmgen/color.py +++ b/mmgen/color.py @@ -93,12 +93,12 @@ def init_color(num_colors='auto'): def start_mscolor(): import sys - from mmgen.globalvars import g + from .globalvars import g try: import colorama colorama.init(strip=True,convert=True) except: - from mmgen.util import msg + from .util import msg msg('Import of colorama module failed') else: g.stdout = sys.stdout diff --git a/mmgen/common.py b/mmgen/common.py index e576e0e7..d75518c4 100755 --- a/mmgen/common.py +++ b/mmgen/common.py @@ -21,16 +21,16 @@ common.py: Common imports for all MMGen scripts """ import sys,os -from mmgen.exception import * -from mmgen.globalvars import * +from .exception import * +from .globalvars import * import mmgen.opts as opts -from mmgen.opts import opt -from mmgen.util import * +from .opts import opt +from .util import * def help_notes(k): - from mmgen.obj import SubSeedIdxRange,SeedShareIdx,SeedShareCount,MasterShareIdx + from .obj import SubSeedIdxRange,SeedShareIdx,SeedShareCount,MasterShareIdx from .wallet import Wallet - from mmgen.tx import MMGenTX + from .tx import MMGenTX def fee_spec_letters(use_quotes=False): cu = g.proto.coin_amt.units sep,conj = ((',',' or '),("','","' or '"))[use_quotes] diff --git a/mmgen/crypto.py b/mmgen/crypto.py index 36939b92..60d5ebe8 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -23,7 +23,7 @@ crypto.py: Cryptographic and related routines for the MMGen suite from cryptography.hazmat.primitives.ciphers import Cipher,algorithms,modes from cryptography.hazmat.backends import default_backend from hashlib import sha256 -from mmgen.common import * +from .common import * crmsg = { 'usr_rand_notice': """ @@ -158,7 +158,7 @@ def _get_random_data_from_user(uchars,desc,test_suite=False): prompt = 'You may begin typing. {} symbols left: ' import time - from mmgen.term import get_char_raw + from .term import get_char_raw key_data,time_data = '',[] for i in range(uchars): diff --git a/mmgen/daemon.py b/mmgen/daemon.py index dbe8e758..565f42e8 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -23,8 +23,8 @@ daemon.py: Daemon control interface for the MMGen suite import shutil from subprocess import run,PIPE from collections import namedtuple -from mmgen.exception import * -from mmgen.common import * +from .exception import * +from .common import * class Daemon(MMGenObject): @@ -253,7 +253,7 @@ class MoneroWalletDaemon(Daemon): def state(self): if not self.test_socket(g.monero_wallet_rpc_host,self.rpc_port): return 'stopped' - from mmgen.rpc import MoneroWalletRPCConnection + from .rpc import MoneroWalletRPCConnection try: MoneroWalletRPCConnection( g.monero_wallet_rpc_host, @@ -337,7 +337,7 @@ class CoinDaemon(Daemon): me.desc = 'test suite daemon' rel_datadir = os.path.join('test','daemons',daemon_id) else: - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol me.datadir = CoinProtocol(daemon_id,False).daemon_data_dir if test_suite: @@ -523,7 +523,7 @@ class EthereumDaemon(CoinDaemon): @property def state(self): - from mmgen.rpc import EthereumRPCConnection + from .rpc import EthereumRPCConnection try: conn = EthereumRPCConnection('localhost',self.rpc_port,socket_timeout=0.2) except: diff --git a/mmgen/devtools.py b/mmgen/devtools.py index 43f597ae..47ce8747 100755 --- a/mmgen/devtools.py +++ b/mmgen/devtools.py @@ -102,9 +102,9 @@ if os.getenv('MMGEN_DEBUG') or os.getenv('MMGEN_TEST_SUITE') or os.getenv('MMGEN # Check that all immutables have been initialized. Expensive, so do only when testing. def immutable_attr_init_check(self): - from mmgen.globalvars import g + from .globalvars import g if g.test_suite: - from mmgen.util import rdie + from .util import rdie cls = type(self) for attrname in sorted({a for a in self.valid_attrs if a[0] != '_'}): for o in (cls,cls.__bases__[0]): # assume there's only one base class diff --git a/mmgen/filename.py b/mmgen/filename.py index 220fb445..957a86c1 100755 --- a/mmgen/filename.py +++ b/mmgen/filename.py @@ -22,10 +22,10 @@ filename.py: Filename class and methods for the MMGen suite import sys,os -from mmgen.exception import BadFileExtension,FileNotFound -from mmgen.obj import * -from mmgen.util import die,get_extension -from mmgen.seed import * +from .exception import BadFileExtension,FileNotFound +from .obj import * +from .util import die,get_extension +from .seed import * class Filename(MMGenObject): @@ -40,7 +40,7 @@ class Filename(MMGenObject): self.atime = None from .wallet import Wallet - from mmgen.tx import MMGenTX + from .tx import MMGenTX if ftype: if isinstance(ftype,type): if issubclass(ftype,(Wallet,MMGenTX)): diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index 634d572a..e5400629 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -23,7 +23,7 @@ globalvars.py: Constants and configuration options for the MMGen suite import sys,os from decimal import Decimal from collections import namedtuple -from mmgen.devtools import * +from .devtools import * # Global vars are set to dfl values in class g. # They're overridden in this order: diff --git a/mmgen/license.py b/mmgen/license.py index 22f97512..d9af1b6b 100755 --- a/mmgen/license.py +++ b/mmgen/license.py @@ -20,7 +20,7 @@ license.py: Copyright notice and text of GPLv3 """ -from mmgen.globalvars import g +from .globalvars import g warning = """ {pnm} Copyright (C) {g.Cdates} by {g.author} {g.email}. This diff --git a/mmgen/main.py b/mmgen/main.py index cad2bc32..e3bf8c94 100755 --- a/mmgen/main.py +++ b/mmgen/main.py @@ -27,7 +27,7 @@ def launch(mod): if mod == 'keygen': mod = 'addrgen' import sys,os - from mmgen.globalvars import g + from .globalvars import g if g.platform == 'linux' and sys.stdin.isatty(): import termios,atexit @@ -49,7 +49,7 @@ def launch(mod): try: m = '{}'.format(e.args[0]) except: m = repr(e.args[0]) - from mmgen.util import die,ydie,rdie + from .util import die,ydie,rdie d = [ (ydie,2,'\nMMGen Unhandled Exception ({n}): {m}'), (die, 1,'{m}'), (ydie,2,'{m}'), diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 93facc71..bf683666 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -21,9 +21,9 @@ mmgen-addrgen: Generate a series or range of addresses from an MMGen deterministic wallet """ -from mmgen.common import * -from mmgen.crypto import * -from mmgen.addr import * +from .common import * +from .crypto import * +from .addr import * from .wallet import Wallet if g.prog_name == 'mmgen-keygen': diff --git a/mmgen/main_addrimport.py b/mmgen/main_addrimport.py index 0d37846e..f740ce2f 100755 --- a/mmgen/main_addrimport.py +++ b/mmgen/main_addrimport.py @@ -22,9 +22,9 @@ mmgen-addrimport: Import addresses into a MMGen coin daemon tracking wallet import time -from mmgen.common import * -from mmgen.addr import AddrList,KeyAddrList -from mmgen.obj import TwLabel,is_coin_addr +from .common import * +from .addr import AddrList,KeyAddrList +from .obj import TwLabel,is_coin_addr ai_msgs = lambda k: { 'rescan': """ @@ -76,7 +76,7 @@ cmd_args = opts.init(opts_data) def import_mmgen_list(infile): al = (AddrList,KeyAddrList)[bool(opt.keyaddr_file)](infile) if al.al_id.mmtype in ('S','B'): - from mmgen.tx import segwit_is_active + from .tx import segwit_is_active if not segwit_is_active(): rdie(2,'Segwit is not active on this chain. Cannot import Segwit addresses') return al @@ -102,7 +102,7 @@ qmsg('OK. {} addresses{}'.format(al.num_addrs,m)) err_msg = None -from mmgen.tw import TrackingWallet +from .tw import TrackingWallet tw = TrackingWallet(mode='w') if g.token: diff --git a/mmgen/main_autosign.py b/mmgen/main_autosign.py index 55db26fd..a99ff7dc 100755 --- a/mmgen/main_autosign.py +++ b/mmgen/main_autosign.py @@ -30,7 +30,7 @@ part_label = 'MMGEN_TX' wallet_dir = '/dev/shm/autosign' key_fn = 'autosign.key' -from mmgen.common import * +from .common import * prog_name = os.path.basename(sys.argv[0]) opts_data = { 'text': { @@ -111,10 +111,10 @@ exit_if_mswin('autosigning') import mmgen.tx import mmgen.altcoins.eth.tx -from mmgen.txsign import txsign -from mmgen.protocol import CoinProtocol,init_coin +from .txsign import txsign +from .protocol import CoinProtocol,init_coin if g.test_suite: - from mmgen.daemon import CoinDaemon + from .daemon import CoinDaemon if opt.stealth_led: opt.led = True @@ -362,7 +362,7 @@ def setup(): opt.hash_preset = '1' opt.set_by_user = ['hash_preset'] opt.passwd_file = os.path.join(tx_dir,key_fn) - from mmgen.obj import MMGenWalletLabel + from .obj import MMGenWalletLabel opt.label = MMGenWalletLabel('Autosign Wallet') ss_out = Wallet(ss=ss_in) ss_out.write_to_file(desc='autosign wallet',outdir=wallet_dir) diff --git a/mmgen/main_passgen.py b/mmgen/main_passgen.py index a0f351e1..794fe8fb 100755 --- a/mmgen/main_passgen.py +++ b/mmgen/main_passgen.py @@ -21,11 +21,11 @@ mmgen-passgen: Generate a series or range of passwords from an MMGen deterministic wallet """ -from mmgen.common import * -from mmgen.crypto import * -from mmgen.addr import PasswordList,AddrIdxList +from .common import * +from .crypto import * +from .addr import PasswordList,AddrIdxList from .wallet import Wallet -from mmgen.obj import MMGenPWIDString +from .obj import MMGenPWIDString pwi = PasswordList.pw_info pwi_fs = '{:8} {:1} {:26} {:<7} {:<7} {}' diff --git a/mmgen/main_regtest.py b/mmgen/main_regtest.py index 7dbe1053..04c623ea 100755 --- a/mmgen/main_regtest.py +++ b/mmgen/main_regtest.py @@ -21,7 +21,7 @@ mmgen-regtest: Coin daemon regression test mode setup and operations for the MMG suite """ -from mmgen.common import * +from .common import * opts_data = { 'sets': [('yes', True, 'quiet', True)], @@ -58,7 +58,7 @@ opts_data = { cmd_args = opts.init(opts_data) -from mmgen.regtest import MMGenRegtest +from .regtest import MMGenRegtest def check_num_args(): m = getattr(MMGenRegtest,cmd_args[0]) diff --git a/mmgen/main_seedjoin.py b/mmgen/main_seedjoin.py index 352e68a9..7a606ac6 100755 --- a/mmgen/main_seedjoin.py +++ b/mmgen/main_seedjoin.py @@ -21,8 +21,8 @@ mmgen/main_seedjoin: Regenerate an MMGen deterministic wallet from seed shares created by 'mmgen-seedsplit' """ -from mmgen.common import * -from mmgen.obj import MasterShareIdx,SeedSplitIDString,MMGenWalletLabel +from .common import * +from .obj import MasterShareIdx,SeedSplitIDString,MMGenWalletLabel from .seed import Seed,SeedShareMasterJoining from .wallet import Wallet diff --git a/mmgen/main_split.py b/mmgen/main_split.py index 80edac95..d405b7dd 100755 --- a/mmgen/main_split.py +++ b/mmgen/main_split.py @@ -24,7 +24,7 @@ mmgen-split: Split funds after a replayable chain fork using a timelocked transa import time -from mmgen.common import * +from .common import * opts_data = { 'text': { @@ -97,7 +97,7 @@ if len(cmd_args) != 2: fs = 'This command requires exactly two {} addresses as arguments' die(1,fs.format(g.proj_name)) -from mmgen.obj import MMGenID +from .obj import MMGenID try: mmids = [MMGenID(a,on_fail='die') for a in cmd_args] except: @@ -106,8 +106,8 @@ except: if mmids[0] == mmids[1]: die(2,'Both transactions have the same output! ({})'.format(mmids[0])) -from mmgen.tx import MMGenSplitTX -from mmgen.protocol import init_coin +from .tx import MMGenSplitTX +from .protocol import init_coin if opt.tx_fees: for idx,g_coin in ((1,opt.other_coin),(0,g.coin)): diff --git a/mmgen/main_tool.py b/mmgen/main_tool.py index 344622f8..f7ea9f49 100755 --- a/mmgen/main_tool.py +++ b/mmgen/main_tool.py @@ -21,7 +21,7 @@ mmgen-tool: Perform various MMGen- and cryptocoin-related operations. Part of the MMGen suite """ -from mmgen.common import * +from .common import * def make_cmd_help(): import mmgen.tool diff --git a/mmgen/main_txbump.py b/mmgen/main_txbump.py index 10baf013..8061a56a 100755 --- a/mmgen/main_txbump.py +++ b/mmgen/main_txbump.py @@ -21,7 +21,7 @@ mmgen-txbump: Increase the fee on a replaceable (replace-by-fee) MMGen transaction, and optionally sign and send it """ -from mmgen.common import * +from .common import * from .wallet import Wallet opts_data = { @@ -101,8 +101,8 @@ rpc_init() tx_file = cmd_args.pop(0) check_infile(tx_file) -from mmgen.tx import * -from mmgen.txsign import * +from .tx import * +from .txsign import * seed_files = get_seed_files(opt,cmd_args) if (cmd_args or opt.send) else None @@ -143,7 +143,7 @@ if g.proto.base_proto == 'Bitcoin': if not opt.yes: tx.add_comment() # edits an existing comment -from mmgen.tw import TwUnspentOutputs +from .tw import TwUnspentOutputs tx.twuo = TwUnspentOutputs(minconf=opt.minconf) tx.create_raw() # creates tx.hex, tx.txid diff --git a/mmgen/main_txcreate.py b/mmgen/main_txcreate.py index ea3d0c70..014e25d1 100755 --- a/mmgen/main_txcreate.py +++ b/mmgen/main_txcreate.py @@ -21,7 +21,7 @@ mmgen-txcreate: Create a cryptocoin transaction with MMGen- and/or non-MMGen inputs and outputs """ -from mmgen.common import * +from .common import * opts_data = { 'sets': [('yes', True, 'quiet', True)], @@ -79,7 +79,7 @@ g.use_cached_balances = opt.cached_balances rpc_init() -from mmgen.tx import MMGenTX +from .tx import MMGenTX tx = MMGenTX() tx.create(cmd_args,int(opt.locktime or 0),do_info=opt.info) tx.write_to_file(ask_write=not opt.yes,ask_overwrite=not opt.yes,ask_write_default_yes=False) diff --git a/mmgen/main_txdo.py b/mmgen/main_txdo.py index 52688632..71843259 100755 --- a/mmgen/main_txdo.py +++ b/mmgen/main_txdo.py @@ -20,9 +20,9 @@ mmgen-txdo: Create, sign and broadcast an online MMGen transaction """ -from mmgen.common import * +from .common import * from .wallet import Wallet -from mmgen.obj import SubSeedIdxRange +from .obj import SubSeedIdxRange opts_data = { 'sets': [('yes', True, 'quiet', True)], @@ -116,8 +116,8 @@ g.use_cached_balances = opt.cached_balances rpc_init() -from mmgen.tx import * -from mmgen.txsign import * +from .tx import * +from .txsign import * seed_files = get_seed_files(opt,cmd_args) diff --git a/mmgen/main_txsend.py b/mmgen/main_txsend.py index 89340ff4..d372115b 100755 --- a/mmgen/main_txsend.py +++ b/mmgen/main_txsend.py @@ -20,7 +20,7 @@ mmgen-txsend: Broadcast a transaction signed by 'mmgen-txsign' to the network """ -from mmgen.common import * +from .common import * opts_data = { 'sets': [('yes', True, 'quiet', True)], @@ -48,7 +48,7 @@ else: opts.usage() if not opt.status: do_license_msg() -from mmgen.tx import * +from .tx import * tx = MMGenTX(infile,quiet_open=True) # sig check performed here vmsg("Signed transaction file '{}' is valid".format(infile)) diff --git a/mmgen/main_txsign.py b/mmgen/main_txsign.py index 4825b633..4062c0fa 100755 --- a/mmgen/main_txsign.py +++ b/mmgen/main_txsign.py @@ -20,8 +20,8 @@ mmgen-txsign: Sign a transaction generated by 'mmgen-txcreate' """ -from mmgen.common import * -from mmgen.obj import SubSeedIdxRange +from .common import * +from .obj import SubSeedIdxRange from .wallet import Wallet # -w, --use-wallet-dat (keys from running coin daemon) removed: use walletdump rpc instead @@ -100,7 +100,7 @@ if g.proto.sign_mode == 'daemon': if not opt.info and not opt.terse_info: do_license_msg(immed=True) -from mmgen.txsign import * +from .txsign import * tx_files = get_tx_files(opt,infiles) seed_files = get_seed_files(opt,infiles) diff --git a/mmgen/main_wallet.py b/mmgen/main_wallet.py index 17def138..cd56675d 100755 --- a/mmgen/main_wallet.py +++ b/mmgen/main_wallet.py @@ -21,10 +21,10 @@ mmgen/main_wallet: Entry point for MMGen wallet-related scripts """ import os -from mmgen.common import * +from .common import * from .wallet import Wallet,MMGenWallet -from mmgen.filename import find_file_in_dir -from mmgen.obj import MMGenWalletLabel,MasterShareIdx +from .filename import find_file_in_dir +from .obj import MMGenWalletLabel,MasterShareIdx usage = '[opts] [infile]' nargs = 1 @@ -148,10 +148,10 @@ if opt.label: opt.label = MMGenWalletLabel(opt.label,msg="Error in option '--label'") if invoked_as == 'subgen': - from mmgen.obj import SubSeedIdx + from .obj import SubSeedIdx ss_idx = SubSeedIdx(cmd_args.pop()) elif invoked_as == 'seedsplit': - from mmgen.obj import SeedSplitSpecifier + from .obj import SeedSplitSpecifier master_share = MasterShareIdx(opt.master_share) if opt.master_share else None if cmd_args: sss = SeedSplitSpecifier(cmd_args.pop(),on_fail='silent') diff --git a/mmgen/mn_entry.py b/mmgen/mn_entry.py index f95722f2..4d581878 100755 --- a/mmgen/mn_entry.py +++ b/mmgen/mn_entry.py @@ -22,10 +22,10 @@ mn_entry.py - Mnemonic user entry methods for the MMGen suite import time -from mmgen.globalvars import * -from mmgen.util import msg,msg_r,qmsg,fmt,fmt_list,capfirst,die -from mmgen.term import get_char,get_char_raw -from mmgen.color import cyan +from .globalvars import * +from .util import msg,msg_r,qmsg,fmt,fmt_list,capfirst,die +from .term import get_char,get_char_raw +from .color import cyan from string import ascii_lowercase as _word_chars _return_chars = '\n\r ' diff --git a/mmgen/obj.py b/mmgen/obj.py index 3282aa9a..eb5a4031 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -24,9 +24,9 @@ import sys,os,unicodedata from decimal import * from string import hexdigits,ascii_letters,digits -from mmgen.exception import * -from mmgen.color import * -from mmgen.devtools import * +from .exception import * +from .color import * +from .devtools import * def is_mmgen_seed_id(s): return SeedID(sid=s,on_fail='silent') def is_mmgen_idx(s): return AddrIdx(s,on_fail='silent') @@ -105,8 +105,8 @@ class InitErrors(object): if m2: errmsg = '{!r}\n{}'.format(m2,errmsg) - from mmgen.globalvars import g - from mmgen.util import die,msg + from .globalvars import g + from .util import die,msg if cls.on_fail == 'silent': return None # TODO: return False instead? elif cls.on_fail == 'return': @@ -495,7 +495,7 @@ class XMRAmt(BTCAmt): min_coin_unit = Decimal('0.000000000001') units = ('min_coin_unit',) -from mmgen.altcoins.eth.obj import ETHAmt,ETHNonce +from .altcoins.eth.obj import ETHAmt,ETHNonce class CoinAddr(str,Hilite,InitErrors,MMGenObject): color = 'cyan' @@ -505,7 +505,7 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject): def __new__(cls,s,on_fail='die'): if type(s) == cls: return s cls.arg_chk(on_fail) - from mmgen.globalvars import g + from .globalvars import g try: assert set(s) <= set(ascii_letters+digits),'contains non-alphanumeric characters' me = str.__new__(cls,s) @@ -529,7 +529,7 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject): def is_for_chain(self,chain): - from mmgen.globalvars import g + from .globalvars import g if g.proto.__name__[:8] == 'Ethereum': return True @@ -545,7 +545,7 @@ class TokenAddr(CoinAddr): class ViewKey(object): def __new__(cls,s,on_fail='die'): - from mmgen.globalvars import g + from .globalvars import g if g.proto.name == 'zcash': return ZcashViewKey.__new__(ZcashViewKey,s,on_fail) elif g.proto.name == 'monero': @@ -564,9 +564,9 @@ class SeedID(str,Hilite,InitErrors): cls.arg_chk(on_fail) try: if seed: - from mmgen.seed import SeedBase + from .seed import SeedBase assert isinstance(seed,SeedBase),'not a subclass of SeedBase' - from mmgen.util import make_chksum_8 + from .util import make_chksum_8 return str.__new__(cls,make_chksum_8(seed.data)) elif sid: assert set(sid) <= set(hexdigits.upper()),'not uppercase hex digits' @@ -585,7 +585,7 @@ class SubSeedIdx(str,Hilite,InitErrors): try: assert isinstance(s,str),'not a string or string subclass' idx = s[:-1] if s[-1] in 'SsLl' else s - from mmgen.util import is_int + from .util import is_int assert is_int(idx),"valid format: an integer, plus optional letter 'S','s','L' or 'l'" idx = int(idx) assert idx >= SubSeedIdxRange.min_idx, 'subseed index < {:,}'.format(SubSeedIdxRange.min_idx) @@ -605,7 +605,7 @@ class MMGenID(str,Hilite,InitErrors,MMGenObject): trunc_ok = False def __new__(cls,s,on_fail='die'): cls.arg_chk(on_fail) - from mmgen.globalvars import g + from .globalvars import g try: ss = str(s).split(':') assert len(ss) in (2,3),'not 2 or 3 colon-separated items' @@ -634,7 +634,7 @@ class TwMMGenID(str,Hilite,InitErrors,MMGenObject): sort_key,idtype = ret.sort_key,'mmgen' except Exception as e: try: - from mmgen.globalvars import g + from .globalvars import g assert s.split(':',1)[0] == g.proto.base_coin.lower(),( "not a string beginning with the prefix '{}:'".format(g.proto.base_coin.lower())) assert set(s[4:]) <= set(ascii_letters+digits),'contains non-alphanumeric characters' @@ -703,7 +703,7 @@ class WifKey(str,Hilite,InitErrors): cls.arg_chk(on_fail) try: assert set(s) <= set(ascii_letters+digits),'not an ascii alphanumeric string' - from mmgen.globalvars import g + from .globalvars import g g.proto.parse_wif(s) # raises exception on error return str.__new__(cls,s) except Exception as e: @@ -736,7 +736,7 @@ class PrivKey(str,Hilite,InitErrors,MMGenObject): # initialize with (priv_bin,compressed), WIF or self def __new__(cls,s=None,compressed=None,wif=None,pubkey_type=None,on_fail='die'): - from mmgen.globalvars import g + from .globalvars import g if type(s) == cls: return s cls.arg_chk(on_fail) @@ -904,7 +904,7 @@ class MMGenAddrType(str,Hilite,InitErrors,MMGenObject): def __new__(cls,s,on_fail='die',errmsg=None): if type(s) == cls: return s cls.arg_chk(on_fail) - from mmgen.globalvars import g + from .globalvars import g try: for k,v in list(cls.mmtypes.items()): if s in (k,v.name): diff --git a/mmgen/opts.py b/mmgen/opts.py index 0bcbc908..50332c73 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -25,10 +25,10 @@ class opt_cls(object): pass opt = opt_cls() -from mmgen.exception import UserOptError -from mmgen.globalvars import g +from .exception import UserOptError +from .globalvars import g import mmgen.share.Opts -from mmgen.util import * +from .util import * def usage(): Die(1,'USAGE: {} {}'.format(g.prog_name,usage_txt)) @@ -78,17 +78,17 @@ def opt_postproc_debug(): Msg('\n=== end opts.py debug ===\n') def init_term_and_color(): - from mmgen.term import init_term + from .term import init_term init_term() if g.color: # MMGEN_DISABLE_COLOR sets this to False - from mmgen.color import start_mscolor,init_color + from .color import start_mscolor,init_color if g.platform == 'win': start_mscolor() init_color(num_colors=('auto',256)[bool(g.force_256_color)]) def override_globals_from_cfg_file(ucfg): - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol for d in ucfg.parse(): val = d.value if d.name in g.cfg_file_opts: @@ -121,7 +121,7 @@ def override_globals_from_env(): setattr(g,gname,set_for_type(val,getattr(g,gname),name,disable)) def common_opts_code(s): - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol return s.format( pnm=g.proj_name,pn=g.proto.name,dn=g.proto.daemon_name, cu_dfl=g.coin, @@ -228,7 +228,7 @@ def init(opts_data,add_opts=[],opt_filter=None,parse_only=False): init_term_and_color() if not opt.skip_cfg_file: - from mmgen.cfg import cfg_file + from .cfg import cfg_file cfg_file('sample') # check for changes in system template file override_globals_from_cfg_file(cfg_file('usr')) @@ -251,7 +251,7 @@ def init(opts_data,add_opts=[],opt_filter=None,parse_only=False): g.network = 'testnet' if g.testnet else 'mainnet' - from mmgen.protocol import init_genonly_altcoins,CoinProtocol + from .protocol import init_genonly_altcoins,CoinProtocol altcoin_trust_level = init_genonly_altcoins(g.coin) # g.testnet is finalized, so we can set g.proto @@ -288,7 +288,7 @@ def init(opts_data,add_opts=[],opt_filter=None,parse_only=False): g.proto = CoinProtocol(g.coin,g.testnet) g.rpc_host = 'localhost' g.data_dir = os.path.join(g.data_dir_root,'regtest',g.coin.lower(),('alice','bob')[g.bob]) - from mmgen.regtest import MMGenRegtest + from .regtest import MMGenRegtest g.rpc_user = MMGenRegtest.rpc_user g.rpc_password = MMGenRegtest.rpc_password g.rpc_port = MMGenRegtest(g.coin).d.rpc_port @@ -335,7 +335,7 @@ def opt_is_tx_fee(key,val,desc): # 'key' must remain a placeholder if hasattr(opt,'tx_gas') and opt.tx_gas: return - from mmgen.tx import MMGenTX + from .tx import MMGenTX tx = MMGenTX(offline=True) # Size of 224 is just a ball-park figure to eliminate the most extreme cases at startup # This check will be performed again once we know the true size @@ -480,7 +480,7 @@ def check_usr_opts(usr_opts): # Raises an exception if any check fails opt_compares(val,'>',0,desc) def chk_coin(key,val,desc): - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol opt_is_in_list(val.lower(),list(CoinProtocol.coins.keys()),'coin') def chk_rbf(key,val,desc): @@ -490,7 +490,7 @@ def check_usr_opts(usr_opts): # Raises an exception if any check fails def chk_bob(key,val,desc): m = "Regtest (Bob and Alice) mode not set up yet. Run '{}-regtest setup' to initialize." - from mmgen.regtest import MMGenRegtest + from .regtest import MMGenRegtest try: os.stat(os.path.join(MMGenRegtest(g.coin).d.datadir,'regtest','debug.log')) except: diff --git a/mmgen/protocol.py b/mmgen/protocol.py index bd8003e3..d0e159f4 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -23,10 +23,10 @@ protocol.py: Coin protocol functions, classes and methods import sys,os,hashlib from collections import namedtuple,OrderedDict -from mmgen.util import msg,ymsg,Msg,ydie -from mmgen.devtools import * -from mmgen.obj import BTCAmt,LTCAmt,BCHAmt,B2XAmt,ETHAmt -from mmgen.globalvars import g +from .util import msg,ymsg,Msg,ydie +from .devtools import * +from .obj import BTCAmt,LTCAmt,BCHAmt,B2XAmt,ETHAmt +from .globalvars import g import mmgen.bech32 as bech32 parsed_wif = namedtuple('parsed_wif',['sec','pubkey_type','compressed']) @@ -343,7 +343,7 @@ class EthereumProtocol(DummyWIF,BitcoinProtocol): @classmethod def parse_addr(cls,addr): - from mmgen.util import is_hex_str_lc + from .util import is_hex_str_lc if is_hex_str_lc(addr) and len(addr) == cls.addr_len * 2: return parsed_addr( bytes.fromhex(addr), 'ethereum' ) if g.debug: Msg("Invalid address '{}'".format(addr)) @@ -416,14 +416,14 @@ class MoneroProtocol(DummyWIF,BitcoinProtocolAddrgen): @classmethod def preprocess_key(cls,sec,pubkey_type): # reduce key - from mmgen.ed25519 import l + from .ed25519 import l n = int.from_bytes(sec[::-1],'big') % l return int.to_bytes(n,cls.privkey_len,'big')[::-1] @classmethod def parse_addr(cls,addr): - from mmgen.baseconv import baseconv,is_b58_str + from .baseconv import baseconv,is_b58_str def b58dec(addr_str): l = len(addr_str) @@ -437,7 +437,7 @@ class MoneroProtocol(DummyWIF,BitcoinProtocolAddrgen): assert not g.use_internal_keccak_module from sha3 import keccak_256 except: - from mmgen.keccak import keccak_256 + from .keccak import keccak_256 chk = keccak_256(ret[:-4]).digest()[:4] assert ret[-4:] == chk,'{}: incorrect checksum. Correct value: {}'.format(ret[-4:].hex(),chk.hex()) @@ -489,7 +489,7 @@ def init_genonly_altcoins(usr_coin=None): If usr_coin is None, initializes all coins for current network with trust level >-1. Returns trust_level of usr_coin, or 0 (untrusted) if usr_coin is None. """ - from mmgen.altcoin import CoinInfo as ci + from .altcoin import CoinInfo as ci data = { 'mainnet': (), 'testnet': () } networks = ['mainnet'] + (['testnet'] if g.testnet else []) diff --git a/mmgen/regtest.py b/mmgen/regtest.py index d749404f..3d3fdc72 100755 --- a/mmgen/regtest.py +++ b/mmgen/regtest.py @@ -22,8 +22,8 @@ regtest: Coin daemon regression test mode setup and operations for the MMGen sui import os,time,shutil,re,json from subprocess import run,PIPE -from mmgen.common import * -from mmgen.daemon import CoinDaemon +from .common import * +from .daemon import CoinDaemon def create_data_dir(data_dir): try: os.stat(os.path.join(data_dir,'regtest')) @@ -269,7 +269,7 @@ class MMGenRegtest(MMGenObject): def fork(self,coin): # currently disabled - from mmgen.protocol import CoinProtocol + from .protocol import CoinProtocol forks = CoinProtocol(coin,False).forks if not [f for f in forks if f[2] == g.coin.lower() and f[3] == True]: die(1,"Coin {} is not a replayable fork of coin {}".format(g.coin,coin)) diff --git a/mmgen/rpc.py b/mmgen/rpc.py index 536833c4..50a68330 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -23,7 +23,7 @@ rpc.py: Cryptocoin RPC library for the MMGen suite import http.client,base64,json from decimal import Decimal -from mmgen.common import * +from .common import * def dmsg_rpc(fs,data=None,is_json=False): if g.debug_rpc: @@ -113,7 +113,7 @@ class RPCConnection(MMGenObject): dmsg_rpc(' RPC POST data ==>\n{}\n',p) ca_type = self.coin_amt_type if hasattr(self,'coin_amt_type') else str - from mmgen.obj import HexStr + from .obj import HexStr class MyJSONEncoder(json.JSONEncoder): def default(self,obj): if isinstance(obj,g.proto.coin_amt): @@ -385,9 +385,9 @@ def rpc_errmsg(ret): def init_daemon_parity(): def resolve_token_arg(token_arg): - from mmgen.obj import CoinAddr - from mmgen.altcoins.eth.tw import EthereumTrackingWallet - from mmgen.altcoins.eth.contract import Token + from .obj import CoinAddr + from .altcoins.eth.tw import EthereumTrackingWallet + from .altcoins.eth.contract import Token tw = EthereumTrackingWallet(no_rpc=True) @@ -458,7 +458,7 @@ def init_daemon_bitcoind(): auth_cookie=get_coin_daemon_auth_cookie()) if g.bob or g.alice: - from mmgen.regtest import MMGenRegtest + from .regtest import MMGenRegtest MMGenRegtest(g.coin).switch_user(('alice','bob')[g.bob],quiet=True) conn.daemon_version = int(conn.getnetworkinfo()['version']) conn.blockcount = conn.getblockcount() diff --git a/mmgen/seed.py b/mmgen/seed.py index 37e413d6..c20f661c 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -20,8 +20,8 @@ seed.py: Seed-related classes and methods for the MMGen suite """ -from mmgen.common import * -from mmgen.obj import * +from .common import * +from .obj import * from .crypto import get_random,scramble_seed class SeedBase(MMGenObject): diff --git a/mmgen/term.py b/mmgen/term.py index c73969d9..d6999f15 100755 --- a/mmgen/term.py +++ b/mmgen/term.py @@ -22,7 +22,7 @@ term.py: Terminal classes for the MMGen suite import sys,os,time from collections import namedtuple -from mmgen.common import * +from .common import * try: import tty,termios diff --git a/mmgen/tool.py b/mmgen/tool.py index 2f425076..096703b1 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -20,10 +20,10 @@ tool.py: Routines for the 'mmgen-tool' utility """ -from mmgen.protocol import hash160 -from mmgen.common import * -from mmgen.crypto import * -from mmgen.addr import * +from .protocol import hash160 +from .common import * +from .crypto import * +from .addr import * NL = ('\n','\r\n')[g.platform=='win'] @@ -215,7 +215,7 @@ def _process_result(ret,pager=False,print_result=False): else: ydie(1,"tool.py: can't handle return value of type '{}'".format(type(ret).__name__)) -from mmgen.obj import MMGenAddrType +from .obj import MMGenAddrType def init_generators(arg=None): global at,kg,ag @@ -225,7 +225,7 @@ def init_generators(arg=None): ag = AddrGenerator(at) def conv_cls_bip39(): - from mmgen.bip39 import bip39 + from .bip39 import bip39 return bip39 dfl_mnemonic_fmt = 'mmgen' @@ -369,12 +369,12 @@ class MMGenToolCmdUtil(MMGenToolCmds): def hextob58chk(self,hexstr:'sstr'): "convert a hexadecimal number to base58-check encoding" - from mmgen.protocol import _b58chk_encode + from .protocol import _b58chk_encode return _b58chk_encode(bytes.fromhex(hexstr)) def b58chktohex(self,b58chk_num:'sstr'): "convert a base58-check encoded number to hexadecimal" - from mmgen.protocol import _b58chk_decode + from .protocol import _b58chk_decode return _b58chk_decode(b58chk_num).hex() def hextob32(self,hexstr:'sstr',pad=0): @@ -488,17 +488,17 @@ class MMGenToolCmdCoin(MMGenToolCmds): def addr2pubhash(self,addr:'sstr'): "convert coin address to public key hash" - from mmgen.tx import addr2pubhash + from .tx import addr2pubhash return addr2pubhash(CoinAddr(addr)) def addr2scriptpubkey(self,addr:'sstr'): "convert coin address to scriptPubKey" - from mmgen.tx import addr2scriptPubKey + from .tx import addr2scriptPubKey return addr2scriptPubKey(CoinAddr(addr)) def scriptpubkey2addr(self,hexstr:'sstr'): "convert scriptPubKey to coin address" - from mmgen.tx import scriptPubKey2addr + from .tx import scriptPubKey2addr return scriptPubKey2addr(hexstr)[0] class MMGenToolCmdMnemonic(MMGenToolCmds): @@ -524,7 +524,7 @@ class MMGenToolCmdMnemonic(MMGenToolCmds): @staticmethod def _xmr_reduce(bytestr): - from mmgen.protocol import MoneroProtocol as mp + from .protocol import MoneroProtocol as mp if len(bytestr) != mp.privkey_len: m = '{!r}: invalid bit length for Monero private key (must be {})' die(1,m.format(len(bytestr*8),mp.privkey_len*8)) @@ -560,7 +560,7 @@ class MMGenToolCmdMnemonic(MMGenToolCmds): def hex2mn( self, hexstr:'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt ): "convert a 16, 24 or 32-byte hexadecimal number to a mnemonic seed phrase" if fmt == 'bip39': - from mmgen.bip39 import bip39 + from .bip39 import bip39 return ' '.join(bip39.fromhex(hexstr,fmt)) else: bytestr = bytes.fromhex(hexstr) @@ -571,14 +571,14 @@ class MMGenToolCmdMnemonic(MMGenToolCmds): def mn2hex( self, seed_mnemonic:'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt ): "convert a mnemonic seed phrase to a hexadecimal number" if fmt == 'bip39': - from mmgen.bip39 import bip39 + from .bip39 import bip39 return bip39.tohex(seed_mnemonic.split(),fmt) else: return baseconv.tohex(seed_mnemonic.split(),fmt,'seed') def mn2hex_interactive( self, fmt:mn_opts_disp=dfl_mnemonic_fmt, mn_len=24, print_mn=False ): "convert an interactively supplied mnemonic seed phrase to a hexadecimal number" - from mmgen.mn_entry import mn_entry + from .mn_entry import mn_entry mn = mn_entry(fmt).get_mnemonic_from_user(25 if fmt == 'xmrseed' else mn_len,validate=False) if print_mn: msg(mn) @@ -603,7 +603,7 @@ class MMGenToolCmdFile(MMGenToolCmds): def _file_chksum(self,mmgen_addrfile,objname): opt.yes = True opt.quiet = True - from mmgen.addr import AddrList,KeyAddrList,PasswordList + from .addr import AddrList,KeyAddrList,PasswordList ret = locals()[objname](mmgen_addrfile) if opt.verbose: if ret.al_id.mmtype.name == 'password': @@ -647,8 +647,8 @@ class MMGenToolCmdFile(MMGenToolCmds): tx_sort = kwargs.get('sort') or 'addr' file_sort = kwargs.get('filesort') or 'mtime' - from mmgen.filename import MMGenFileList - from mmgen.tx import MMGenTX + from .filename import MMGenFileList + from .tx import MMGenTX flist = MMGenFileList(infiles,ftype=MMGenTX) flist.sort_by_age(key=file_sort) # in-place sort @@ -834,14 +834,14 @@ class MMGenToolCmdWallet(MMGenToolCmds): ret = d.sec.wif if target=='wif' else d.addr return ret -from mmgen.tw import TwAddrList,TwUnspentOutputs +from .tw import TwAddrList,TwUnspentOutputs class MMGenToolCmdRPC(MMGenToolCmds): "tracking wallet commands using the JSON-RPC interface" def getbalance(self,minconf=1,quiet=False,pager=False): "list confirmed/unconfirmed, spendable/unspendable balances in tracking wallet" - from mmgen.tw import TwGetBalance + from .tw import TwGetBalance return TwGetBalance(minconf,quiet).format() def listaddress(self, @@ -921,7 +921,7 @@ class MMGenToolCmdRPC(MMGenToolCmds): def add_label(self,mmgen_or_coin_addr:str,label:str): "add descriptive label for address in tracking wallet" rpc_init() - from mmgen.tw import TrackingWallet + from .tw import TrackingWallet TrackingWallet(mode='w').add_label(mmgen_or_coin_addr,label,on_fail='raise') return True @@ -932,7 +932,7 @@ class MMGenToolCmdRPC(MMGenToolCmds): def remove_address(self,mmgen_or_coin_addr:str): "remove an address from tracking wallet" - from mmgen.tw import TrackingWallet + from .tw import TrackingWallet tw = TrackingWallet(mode='w') ret = tw.remove_address(mmgen_or_coin_addr) # returns None on failure if ret: @@ -954,7 +954,7 @@ class MMGenToolCmdMonero(MMGenToolCmds): @property def monero_chain_height(self): if self._monero_chain_height == None: - from mmgen.daemon import CoinDaemon + from .daemon import CoinDaemon port = CoinDaemon('xmr',test_suite=g.test_suite).rpc_port cmd = ['monerod','--rpc-bind-port={}'.format(port)] + self.monerod_args + ['status'] @@ -996,7 +996,7 @@ class MMGenToolCmdMonero(MMGenToolCmds): return False gmsg(m) - from mmgen.baseconv import baseconv + from .baseconv import baseconv ret = c.restore_deterministic_wallet( filename = os.path.basename(fn), password = d.wallet_passwd, @@ -1045,7 +1045,7 @@ class MMGenToolCmdMonero(MMGenToolCmds): ret = c.get_balance() # account_index=0, address_indices=[0,1] - from mmgen.obj import XMRAmt + from .obj import XMRAmt bals[fn] = tuple([XMRAmt(ret[k],from_unit='min_coin_unit') for k in ('balance','unlocked_balance')]) if opt.verbose: @@ -1063,20 +1063,20 @@ class MMGenToolCmdMonero(MMGenToolCmds): m = { 'create': ('Creat','Generat',create,False), 'sync': ('Sync', 'Sync', sync, True) } opt.accept_defaults = opt.accept_defaults or m[op][3] - from mmgen.protocol import init_coin + from .protocol import init_coin init_coin('xmr') - from mmgen.addr import AddrList + from .addr import AddrList al = KeyAddrList(infile) data = [d for d in al.data if addrs == '' or d.idx in AddrIdxList(addrs)] dl = len(data) assert dl,"No addresses in addrfile within range '{}'".format(addrs) gmsg('\n{}ing {} wallet{}'.format(m[op][0],dl,suf(dl))) - from mmgen.daemon import MoneroWalletDaemon + from .daemon import MoneroWalletDaemon wd = MoneroWalletDaemon(opt.outdir or '.',test_suite=g.test_suite) wd.restart() - from mmgen.rpc import MoneroWalletRPCConnection + from .rpc import MoneroWalletRPCConnection c = MoneroWalletRPCConnection( g.monero_wallet_rpc_host, wd.rpc_port, @@ -1101,7 +1101,7 @@ class MMGenToolCmdMonero(MMGenToolCmds): col1_w = max(map(len,bals)) + 1 fs = '{:%s} {} {}' % col1_w msg('\n'+fs.format('Wallet','Balance ','Unlocked Balance ')) - from mmgen.obj import XMRAmt + from .obj import XMRAmt tbals = [XMRAmt('0'),XMRAmt('0')] for bal in bals: for i in (0,1): tbals[i] += bals[bal][i] @@ -1179,7 +1179,7 @@ class tool_api( Valid choices for coins: one of the symbols returned by the 'coins' attribute Valid choices for network: 'mainnet','testnet','regtest' """ - from mmgen.protocol import init_coin,init_genonly_altcoins + from .protocol import init_coin,init_genonly_altcoins altcoin_trust_level = init_genonly_altcoins(coinsym) warn_altcoins(coinsym,altcoin_trust_level) if network == 'regtest': @@ -1189,8 +1189,8 @@ class tool_api( @property def coins(self): """The available coins""" - from mmgen.protocol import CoinProtocol - from mmgen.altcoin import CoinInfo + from .protocol import CoinProtocol + from .altcoin import CoinInfo return sorted(set(CoinProtocol.list_coins() + [c.symbol for c in CoinInfo.get_supported_coins(g.network)])) @property diff --git a/mmgen/tw.py b/mmgen/tw.py index 08981987..94fc8016 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -21,10 +21,10 @@ tw: Tracking wallet methods for the MMGen suite """ import json -from mmgen.exception import * -from mmgen.common import * -from mmgen.obj import * -from mmgen.tx import is_mmgen_id +from .exception import * +from .common import * +from .obj import * +from .tx import is_mmgen_id CUR_HOME,ERASE_ALL = '\033[H','\033[0J' def CUR_RIGHT(n): return '\033[{}C'.format(n) @@ -217,7 +217,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. return ret def set_term_columns(self): - from mmgen.term import get_terminal_size + from .term import get_terminal_size while True: self.cols = g.terminal_width or get_terminal_size().width if self.cols >= g.min_screen_width: break @@ -383,7 +383,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. return n def view_and_sort(self,tx): - from mmgen.term import get_char + from .term import get_char prompt = self.prompt.strip() + '\b' no_output,oneshot_msg = False,None while True: @@ -819,7 +819,7 @@ class TrackingWallet(MMGenObject): # returns on failure @write_mode def add_label(self,arg1,label='',addr=None,silent=False,on_fail='return'): - from mmgen.tx import is_mmgen_id,is_coin_addr + from .tx import is_mmgen_id,is_coin_addr mmaddr,coinaddr = None,None if is_coin_addr(addr or arg1): coinaddr = CoinAddr(addr or arg1,on_fail='return') @@ -827,7 +827,7 @@ class TrackingWallet(MMGenObject): mmaddr = TwMMGenID(arg1) if mmaddr and not coinaddr: - from mmgen.addr import AddrData + from .addr import AddrData coinaddr = AddrData(source='tw').mmaddr2coinaddr(mmaddr) try: @@ -842,7 +842,7 @@ class TrackingWallet(MMGenObject): # Allow for the possibility that BTC addr of MMGen addr was entered. # Do reverse lookup, so that MMGen addr will not be marked as non-MMGen. if not mmaddr: - from mmgen.addr import AddrData + from .addr import AddrData mmaddr = AddrData(source='tw').coinaddr2mmaddr(coinaddr) if not mmaddr: mmaddr = '{}:{}'.format(g.proto.base_coin.lower(),coinaddr) @@ -856,7 +856,7 @@ class TrackingWallet(MMGenObject): ret = self.set_label(coinaddr,lbl) - from mmgen.rpc import rpc_error,rpc_errmsg + from .rpc import rpc_error,rpc_errmsg if rpc_error(ret): msg('From {}: {}'.format(g.proto.daemon_name,rpc_errmsg(ret))) if not silent: diff --git a/mmgen/tx.py b/mmgen/tx.py index 532d3bc0..67301292 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -22,8 +22,8 @@ tx.py: Transaction routines for the MMGen suite import sys,os,json from stat import * -from mmgen.common import * -from mmgen.obj import * +from .common import * +from .obj import * wmsg = lambda k: { 'addr_in_addrfile_only': """ @@ -700,7 +700,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam repr([amt_to_str(e.__dict__) for e in self.outputs]) ] if self.label: - from mmgen.baseconv import baseconv + from .baseconv import baseconv lines.append(baseconv.frombytes(self.label.encode(),'b58',tostr=True)) if self.coin_txid: if not self.label: lines.append('-') # keep old tx files backwards compatible @@ -732,7 +732,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam qmsg('Passing {} key{} to {}'.format(len(keys),suf(keys),g.proto.daemon_name)) if self.has_segwit_inputs(): - from mmgen.addr import KeyGenerator,AddrGenerator + from .addr import KeyGenerator,AddrGenerator kg = KeyGenerator('std') ag = AddrGenerator('segwit') keydict = MMGenDict([(d.addr,d.sec) for d in keys]) @@ -963,7 +963,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam ret = None if g.bogus_send else g.rpch.sendrawtransaction(self.hex,on_fail='return') - from mmgen.rpc import rpc_error,rpc_errmsg + from .rpc import rpc_error,rpc_errmsg if rpc_error(ret): errmsg = rpc_errmsg(ret) if 'Signature must use SIGHASH_FORKID' in errmsg: @@ -1032,7 +1032,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam def view_with_prompt(self,prompt='',pause=True): prompt += ' (y)es, (N)o, pager (v)iew, (t)erse view: ' - from mmgen.term import get_char + from .term import get_char ok_chars = 'YyNnVvTt' while True: reply = get_char(prompt,immed_chars=ok_chars).strip('\n\r') @@ -1050,7 +1050,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam if pager: do_pager(o) else: msg_r(o) - from mmgen.term import get_char + from .term import get_char if pause: get_char('Press any key to continue: ') msg('') @@ -1226,7 +1226,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam c = tx_data.pop(-1) if c != '-': desc = 'encoded comment (not base58)' - from mmgen.baseconv import baseconv + from .baseconv import baseconv comment = baseconv.tobytes(c,'b58').decode() assert comment != False,'invalid comment' desc = 'comment' @@ -1316,7 +1316,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam die(2,'At least one output must be specified on the command line') def get_outputs_from_cmdline(self,cmd_args): - from mmgen.addr import AddrList,AddrData + from .addr import AddrList,AddrData addrfiles = [a for a in cmd_args if get_extension(a) == AddrList.ext] cmd_args = set(cmd_args) - set(addrfiles) @@ -1441,7 +1441,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam twuo_addrs = self.get_cmdline_input_addrs() - from mmgen.tw import TwUnspentOutputs + from .tw import TwUnspentOutputs self.twuo = TwUnspentOutputs(minconf=opt.minconf,addrs=twuo_addrs) if not do_info: @@ -1593,7 +1593,7 @@ class MMGenSplitTX(MMGenTX): def get_outputs_from_cmdline(self,mmid): # TODO: check that addr is empty - from mmgen.addr import AddrData + from .addr import AddrData ad_w = AddrData(source='tw') if is_mmgen_id(mmid): diff --git a/mmgen/txsign.py b/mmgen/txsign.py index bee9f97b..78af581f 100755 --- a/mmgen/txsign.py +++ b/mmgen/txsign.py @@ -20,10 +20,10 @@ txsign: Sign a transaction generated by 'mmgen-txcreate' """ -from mmgen.common import * +from .common import * from .wallet import * -from mmgen.tx import * -from mmgen.addr import * +from .tx import * +from .addr import * pnm = g.proj_name @@ -72,7 +72,7 @@ def generate_kals_for_mmgen_addrs(need_keys,infiles,saved_seeds): sids = {i.sid for i in mmids} vmsg('Need seed{}: {}'.format(suf(sids),' '.join(sids))) d = MMGenList() - from mmgen.addr import KeyAddrList + from .addr import KeyAddrList for sid in sids: # Returns only if seed is found seed = get_seed_for_seed_id(sid,infiles,saved_seeds) @@ -119,7 +119,7 @@ def get_seed_files(opt,args): # favor unencrypted seed sources first, as they don't require passwords u,e = WalletUnenc,WalletEnc ret = _pop_and_return(args,u.get_extensions()) - from mmgen.filename import find_file_in_dir + from .filename import find_file_in_dir wf = find_file_in_dir(MMGenWallet,g.data_dir) # Make this the first encrypted ss in the list if wf: ret.append(wf) ret += _pop_and_return(args,e.get_extensions()) diff --git a/mmgen/util.py b/mmgen/util.py index 51936672..cbc58be1 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -23,9 +23,9 @@ util.py: Low-level routines imported by other modules in the MMGen suite import sys,os,time,stat,re from hashlib import sha256 from string import hexdigits,digits -from mmgen.color import * -from mmgen.exception import * -from mmgen.globalvars import * +from .color import * +from .exception import * +from .globalvars import * if g.platform == 'win': def msg_r(s): @@ -201,7 +201,7 @@ def check_or_create_dir(path): except: die(2,"ERROR: unable to read or create path '{}'".format(path)) -from mmgen.opts import opt +from .opts import opt def qmsg(s,alt=None): if opt.quiet: @@ -264,11 +264,11 @@ def make_chksum_N(s,nchars,sep=False): return sep.join([s[i*4:i*4+4] for i in range(nchars//4)]) def make_chksum_8(s,sep=False): - from mmgen.obj import HexStr + from .obj import HexStr s = HexStr(sha256(sha256(s).digest()).hexdigest()[:8].upper(),case='upper') return '{} {}'.format(s[:4],s[4:]) if sep else s def make_chksum_6(s): - from mmgen.obj import HexStr + from .obj import HexStr if isinstance(s,str): s = s.encode() return HexStr(sha256(s).hexdigest()[:6]) def is_chksum_6(s): return len(s) == 6 and is_hex_str_lc(s) @@ -477,7 +477,7 @@ def make_full_path(outdir,outfile): return os.path.normpath(os.path.join(outdir, os.path.basename(outfile))) def get_seed_file(cmd_args,nargs,invoked_as=None): - from mmgen.filename import find_file_in_dir + from .filename import find_file_in_dir from .wallet import MMGenWallet wf = find_file_in_dir(MMGenWallet,g.data_dir) @@ -658,7 +658,7 @@ def mmgen_decrypt_file_maybe(fn,desc='',quiet=False,silent=False): if have_enc_ext or not is_utf8(d): m = ('Attempting to decrypt','Decrypting')[have_enc_ext] qmsg("{} {} '{}'".format(m,desc,fn)) - from mmgen.crypto import mmgen_decrypt_retry + from .crypto import mmgen_decrypt_retry d = mmgen_decrypt_retry(d,desc) return d @@ -720,7 +720,7 @@ def my_raw_input(prompt,echo=True,insert_txt='',use_readline=True): msg_r(prompt) prompt = '' - from mmgen.term import kb_hold_protect + from .term import kb_hold_protect kb_hold_protect() if g.test_suite_popen_spawn: @@ -756,7 +756,7 @@ def keypress_confirm(prompt,default_yes=False,verbose=False,no_nl=False,complete msg(p) return default_yes - from mmgen.term import get_char + from .term import get_char while True: reply = get_char(p,immed_chars='yYnN').strip('\n\r') if not reply: @@ -802,7 +802,7 @@ def do_license_msg(immed=False): msg(gpl.warning) prompt = '{} '.format(p.strip()) - from mmgen.term import get_char + from .term import get_char while True: reply = get_char(prompt, immed_chars=('','wc')[bool(immed)]) if reply == 'w': @@ -840,7 +840,7 @@ def rpc_init(reinit=False): if not 'rpc' in g.proto.mmcaps: die(1,'Coin daemon operations not supported for coin {}!'.format(g.coin)) if g.rpch != None and not reinit: return g.rpch - from mmgen.rpc import init_daemon + from .rpc import init_daemon g.rpch = init_daemon(g.proto.daemon_family) return g.rpch