2020-02-28 12:02:29 +00:00
|
|
|
import os
|
2020-03-10 18:40:19 +00:00
|
|
|
import sys
|
2020-02-28 12:02:29 +00:00
|
|
|
import click
|
|
|
|
|
2020-05-08 13:34:09 +00:00
|
|
|
from eth2deposit.credentials import (
|
2020-05-21 12:43:02 +00:00
|
|
|
CredentialList,
|
2020-02-28 12:02:29 +00:00
|
|
|
)
|
2020-05-08 13:34:09 +00:00
|
|
|
from eth2deposit.key_handling.key_derivation.mnemonic import (
|
|
|
|
get_languages,
|
|
|
|
get_mnemonic,
|
|
|
|
)
|
2020-05-21 12:43:02 +00:00
|
|
|
from eth2deposit.utils.validation import verify_deposit_data_json
|
2020-05-08 13:34:09 +00:00
|
|
|
from eth2deposit.utils.constants import (
|
2020-02-28 15:35:52 +00:00
|
|
|
WORD_LISTS_PATH,
|
|
|
|
MAX_DEPOSIT_AMOUNT,
|
2020-05-08 20:11:02 +00:00
|
|
|
DEFAULT_VALIDATOR_KEYS_FOLDER_NAME,
|
2020-02-28 15:35:52 +00:00
|
|
|
)
|
2020-05-08 13:34:09 +00:00
|
|
|
from eth2deposit.utils.ascii_art import RHINO_0
|
2020-05-23 16:19:41 +00:00
|
|
|
from eth2deposit.settings import (
|
|
|
|
ALL_CHAINS,
|
|
|
|
MAINNET,
|
|
|
|
get_setting,
|
|
|
|
)
|
2020-02-28 12:02:29 +00:00
|
|
|
|
2020-07-24 10:24:23 +00:00
|
|
|
languages = get_languages(WORD_LISTS_PATH)
|
2020-02-28 12:02:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
def generate_mnemonic(language: str, words_path: str) -> str:
|
|
|
|
mnemonic = get_mnemonic(language=language, words_path=words_path)
|
|
|
|
test_mnemonic = ''
|
|
|
|
while mnemonic != test_mnemonic:
|
|
|
|
click.clear()
|
|
|
|
click.echo('This is your seed phrase. Write it down and store it safely, it is the ONLY way to retrieve your deposit.') # noqa: E501
|
|
|
|
click.echo('\n\n%s\n\n' % mnemonic)
|
|
|
|
click.pause('Press any key when you have written down your mnemonic.')
|
|
|
|
|
|
|
|
click.clear()
|
|
|
|
test_mnemonic = click.prompt('Please type your mnemonic (separated by spaces) to confirm you have written it down\n\n') # noqa: E501
|
|
|
|
test_mnemonic = test_mnemonic.lower()
|
|
|
|
click.clear()
|
|
|
|
return mnemonic
|
|
|
|
|
|
|
|
|
2020-05-19 13:34:16 +00:00
|
|
|
def check_python_version() -> None:
|
2020-03-10 18:40:19 +00:00
|
|
|
'''
|
|
|
|
Checks that the python version running is sufficient and exits if not.
|
|
|
|
'''
|
|
|
|
if sys.version_info < (3, 7):
|
|
|
|
click.pause('Your python version is insufficient, please install version 3.7 or greater.')
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
|
2020-02-28 12:02:29 +00:00
|
|
|
@click.command()
|
|
|
|
@click.option(
|
|
|
|
'--num_validators',
|
|
|
|
prompt='Please choose how many validators you wish to run',
|
|
|
|
required=True,
|
2020-05-23 16:19:41 +00:00
|
|
|
type=int,
|
2020-02-28 12:02:29 +00:00
|
|
|
)
|
|
|
|
@click.option(
|
|
|
|
'--mnemonic_language',
|
|
|
|
prompt='Please choose your mnemonic language',
|
2020-05-19 13:34:16 +00:00
|
|
|
type=click.Choice(languages, case_sensitive=False),
|
2020-02-28 12:02:29 +00:00
|
|
|
default='english',
|
|
|
|
)
|
|
|
|
@click.option(
|
|
|
|
'--folder',
|
|
|
|
type=click.Path(exists=True, file_okay=False, dir_okay=True),
|
|
|
|
default=os.getcwd()
|
|
|
|
)
|
2020-05-23 16:19:41 +00:00
|
|
|
@click.option(
|
|
|
|
'--chain',
|
2020-07-27 15:52:00 +00:00
|
|
|
prompt='Please choose the (mainnet or testnet) network/chain name',
|
2020-05-23 16:19:41 +00:00
|
|
|
type=click.Choice(ALL_CHAINS.keys(), case_sensitive=False),
|
|
|
|
default=MAINNET,
|
|
|
|
)
|
2020-05-08 20:11:02 +00:00
|
|
|
@click.password_option(prompt='Type the password that secures your validator keystore(s)')
|
2020-05-23 16:19:41 +00:00
|
|
|
def main(num_validators: int, mnemonic_language: str, folder: str, chain: str, password: str) -> None:
|
2020-03-10 18:40:19 +00:00
|
|
|
check_python_version()
|
2020-07-24 10:24:23 +00:00
|
|
|
mnemonic = generate_mnemonic(mnemonic_language, WORD_LISTS_PATH)
|
2020-02-28 15:35:52 +00:00
|
|
|
amounts = [MAX_DEPOSIT_AMOUNT] * num_validators
|
2020-05-08 20:11:02 +00:00
|
|
|
folder = os.path.join(folder, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME)
|
2020-05-23 16:19:41 +00:00
|
|
|
setting = get_setting(chain)
|
2020-02-28 12:02:29 +00:00
|
|
|
if not os.path.exists(folder):
|
|
|
|
os.mkdir(folder)
|
|
|
|
click.clear()
|
2020-03-09 17:38:45 +00:00
|
|
|
click.echo(RHINO_0)
|
2020-02-28 12:02:29 +00:00
|
|
|
click.echo('Creating your keys.')
|
2020-05-27 06:58:01 +00:00
|
|
|
credentials = CredentialList.from_mnemonic(
|
2020-05-23 16:19:41 +00:00
|
|
|
mnemonic=mnemonic,
|
|
|
|
num_keys=num_validators,
|
|
|
|
amounts=amounts,
|
|
|
|
fork_version=setting.GENESIS_FORK_VERSION,
|
|
|
|
)
|
2020-02-28 15:35:52 +00:00
|
|
|
click.echo('Saving your keystore(s).')
|
2020-05-21 12:43:02 +00:00
|
|
|
keystore_filefolders = credentials.export_keystores(password=password, folder=folder)
|
2020-02-28 15:35:52 +00:00
|
|
|
click.echo('Creating your deposit(s).')
|
2020-05-21 12:43:02 +00:00
|
|
|
deposits_file = credentials.export_deposit_data_json(folder=folder)
|
2020-02-28 21:07:04 +00:00
|
|
|
click.echo('Verifying your keystore(s).')
|
2020-05-21 12:43:02 +00:00
|
|
|
assert credentials.verify_keystores(keystore_filefolders=keystore_filefolders, password=password)
|
2020-02-28 15:35:52 +00:00
|
|
|
click.echo('Verifying your deposit(s).')
|
|
|
|
assert verify_deposit_data_json(deposits_file)
|
2020-02-28 12:02:29 +00:00
|
|
|
click.echo('\nSuccess!\nYour keys can be found at: %s' % folder)
|
|
|
|
click.pause('\n\nPress any key.')
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|