aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AppImageBuilder.yml2
-rw-r--r--README.rst14
-rwxr-xr-xkeytree.py19
3 files changed, 20 insertions, 15 deletions
diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml
index 63e7d28..4ad9d83 100644
--- a/AppImageBuilder.yml
+++ b/AppImageBuilder.yml
@@ -16,7 +16,7 @@ AppDir:
id: org.ted.keytree
name: keytree
icon: utilities-terminal
- version: 0.1.0
+ version: 0.1.1
exec: usr/bin/python3.9
exec_args: $APPDIR/usr/src/keytree.py $@
diff --git a/README.rst b/README.rst
index f438cb4..7a6670b 100644
--- a/README.rst
+++ b/README.rst
@@ -12,14 +12,14 @@ Examples
- To see all private keys and the mnemonic phrase, use ``--show-private`` (only
use it after you look around and ensure there is no one else looking at your
screen)
-- Use arbitrary UTF-8 string as your mnemonic ``./keytree.py --custom-words --save-keystore mykeystore.json``
+- Use arbitrary UTF-8 string as your mnemonic ``./keytree.py --custom --save-keystore mykeystore.json``
- Show Fuji testnet address format ``./keytree.py <your options> --hrp fuji``
- Use Metamask's deriving algorithm: ``./keytree.py <your options>
- --account-path "44'/60'/0'/0"``. By default, ETH addresses/keys use AVAX's
- deriving path (AVAX C-Chain keys/addresses) instead of Metamask's. To treat
- the mnemonic in Metamask's way, use ``--account-path``. Whatever deriving
- path is used, the generated individual key-address pair is always valid
- Ethereum format.
+ --path "44'/60'/0'/0"`` or ``./keytree.py <your options> --metamask``. By
+ default, ETH addresses/keys use AVAX's deriving path (AVAX C-Chain
+ keys/addresses) instead of Metamask's. To treat the mnemonic in Metamask's
+ way, use ``--path``. Whatever deriving path is used, the generated
+ individual key-address pair is always valid Ethereum format.
Caveat
------
@@ -32,4 +32,4 @@ pip.
Portable Binary
---------------
-Use ``./keytree-0.1.0-x86_64.AppImage`` in place of ``./keytree.py``.
+Use ``./keytree-0.1.1-x86_64.AppImage`` in place of ``./keytree.py``.
diff --git a/keytree.py b/keytree.py
index 3e9a319..1ad9955 100755
--- a/keytree.py
+++ b/keytree.py
@@ -270,24 +270,29 @@ def save_to_keystore(filename, words):
except FileNotFoundError:
raise KeytreeError("failed while saving")
+metamask_path = r"44'/60'/0'/0"
+avax_path = r"44'/9000'/0'/0"
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Derive BIP32 key pairs from BIP39 mnemonic')
parser.add_argument('--load-keystore', type=str, default=None, help='load mnemonic from a keystore file (AVAX Wallet compatible)')
parser.add_argument('--save-keystore', type=str, default=None, help='save mnemonic to a keystore file (AVAX Wallet compatible)')
parser.add_argument('--show-private', action='store_true', default=False, help='also show private keys and the mnemonic')
- parser.add_argument('--custom-words', action='store_true', default=False, help='use an arbitrary word combination as mnemonic')
- parser.add_argument('--account-path', default="44'/9000'/0'/0", help="path prefix for key deriving (e.g. \"0/1'/2\")")
+ parser.add_argument('--custom', action='store_true', default=False, help='use an arbitrary word combination as mnemonic')
+ parser.add_argument('--path', default=avax_path, help="path prefix for key deriving (e.g. \"{}\" for Metamask)".format(metamask_path))
+ parser.add_argument('--metamask', action='store_true', default=False, help="use metamask path for key deriving (synonym to `--path \"{}\"`)".format(metamask_path))
parser.add_argument('--gen-mnemonic', action='store_true', default=False, help='generate a mnemonic (instead of taking an input)')
parser.add_argument('--lang', type=str, default="english", help='language for mnemonic words')
parser.add_argument('--start-idx', type=int, default=0, help='the start index for keys')
parser.add_argument('--end-idx', type=int, default=1, help='the end index for keys (exclusive)')
parser.add_argument('--hrp', type=str, default="avax", help='HRP (Human Readable Prefix, defined by Bech32)')
- args, _ = parser.parse_known_args()
-
+ args, unknown = parser.parse_known_args()
try:
+ for arg in unknown:
+ if len(arg) > 0:
+ raise KeytreeError("invalid argument: `{}`".format(arg))
try:
if args.gen_mnemonic:
mgen = mnemonic.Mnemonic(args.lang)
@@ -297,7 +302,7 @@ if __name__ == '__main__':
words = load_from_keystore(args.load_keystore)
else:
words = getpass('Enter the mnemonic: ').strip()
- if not args.custom_words:
+ if not args.custom:
mchecker = mnemonic.Mnemonic(args.lang)
if not mchecker.check(words):
raise KeytreeError("invalid mnemonic")
@@ -310,14 +315,14 @@ if __name__ == '__main__':
if args.start_idx < 0 or args.end_idx < 0:
raise KeytreeError("invalid start/end index")
for i in range(args.start_idx, args.end_idx):
- path = "m/{}/{}".format(args.account_path, i)
+ path = "m/{}/{}".format(metamask_path if args.metamask else args.path, i)
priv = gen.derive(path)
pub = priv.get_verifying_key()
cpub = pub.to_string(encoding="compressed")
if args.show_private:
print("{}.priv(raw/ETH) 0x{}".format(i, priv.to_string().hex()))
print("{}.priv(BTC) {}".format(i, get_privkey_btc(priv)))
- print("{}.addr(AVAX) X-{}".format(i, bech32.bech32_encode(args.hrp, bech32.convertbits(ripemd160(sha256(cpub)), 8, 5))))
+ print("{}.addr(AVAX) (X/P)-{}".format(i, bech32.bech32_encode(args.hrp, bech32.convertbits(ripemd160(sha256(cpub)), 8, 5))))
print("{}.addr(BTC) {}".format(i, get_btc_addr(pub)))
print("{}.addr(ETH) {}".format(i, get_eth_addr(pub)))
if args.save_keystore: