def generate_keys(ctx: click.Context, validator_start_index: int,
                  num_validators: int, folder: str, chain: str,
                  keystore_password: str, **kwargs: Any) -> None:
    mnemonic = ctx.obj['mnemonic']
    mnemonic_password = ctx.obj['mnemonic_password']
    amounts = [MAX_DEPOSIT_AMOUNT] * num_validators
    folder = os.path.join(folder, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME)
    setting = get_setting(chain)
    if not os.path.exists(folder):
        os.mkdir(folder)
    click.clear()
    click.echo(RHINO_0)
    click.echo('Creating your keys.')
    credentials = CredentialList.from_mnemonic(
        mnemonic=mnemonic,
        mnemonic_password=mnemonic_password,
        num_keys=num_validators,
        amounts=amounts,
        fork_version=setting.GENESIS_FORK_VERSION,
        start_index=validator_start_index,
    )
    keystore_filefolders = credentials.export_keystores(
        password=keystore_password, folder=folder)
    deposits_file = credentials.export_deposit_data_json(folder=folder)
    if not credentials.verify_keystores(
            keystore_filefolders=keystore_filefolders,
            password=keystore_password):
        raise ValidationError("Failed to verify the keystores.")
    if not verify_deposit_data_json(deposits_file):
        raise ValidationError("Failed to verify the deposit data JSON files.")
    click.echo('\nSuccess!\nYour keys can be found at: %s' % folder)
    click.pause('\n\nPress any key.')
def main(num_validators: int, mnemonic_language: str, folder: str, chain: str,
         password: str) -> None:
    check_python_version()
    mnemonic = generate_mnemonic(mnemonic_language, WORD_LISTS_PATH)
    amounts = [MAX_DEPOSIT_AMOUNT] * num_validators
    folder = os.path.join(folder, DEFAULT_VALIDATOR_KEYS_FOLDER_NAME)
    setting = get_setting(chain)
    if not os.path.exists(folder):
        os.mkdir(folder)
    click.clear()
    click.echo(RHINO_0)
    click.echo('Creating your keys.')
    credentials = CredentialList.from_mnemonic(
        mnemonic=mnemonic,
        num_keys=num_validators,
        amounts=amounts,
        fork_version=setting.GENESIS_FORK_VERSION,
    )
    click.echo('Saving your keystore(s).')
    keystore_filefolders = credentials.export_keystores(password=password,
                                                        folder=folder)
    click.echo('Creating your deposit(s).')
    deposits_file = credentials.export_deposit_data_json(folder=folder)

    click.echo('Verifying your keystore(s).')
    if not credentials.verify_keystores(
            keystore_filefolders=keystore_filefolders, password=password):
        raise ValidationError("Failed to verify the keystores.")

    click.echo('Verifying your deposit(s).')
    if not verify_deposit_data_json(deposits_file):
        raise ValidationError("Failed to verify the deposit data JSON files.")

    click.echo('\nSuccess!\nYour keys can be found at: %s' % folder)
    click.pause('\n\nPress any key.')
Exemple #3
0
def validate_withdrawal_credentials(withdrawal_credentials: str) -> bytes:
    try:
        decoded_withdrawal_credentials = bytes.fromhex(withdrawal_credentials)
    except Exception:
        raise ValueError(
            "Wrong withdrawal_credentials value. Is it HEX (not Base64) format?"
        )
    if len(decoded_withdrawal_credentials) != 32:
        raise ValidationError(
            "Wrong withdrawal_credentials length. Must be 32 bytes (64 hex symbols)."
        )
    if decoded_withdrawal_credentials[:1] != BLS_WITHDRAWAL_PREFIX:
        raise ValidationError("Wrong withdrawal_credentials format.")
    return decoded_withdrawal_credentials
Exemple #4
0
 def __init__(self, *, mnemonic: str, mnemonic_password: str, index: int,
              amount: int, chain_setting: BaseChainSetting,
              withdrawal_pk: str, withdrawal_credentials: str):
     # Set path as EIP-2334 format
     # https://eips.ethereum.org/EIPS/eip-2334
     purpose = '12381'
     coin_type = '3600'
     account = str(index)
     withdrawal_key_path = f'm/{purpose}/{coin_type}/{account}/0'
     self.signing_key_path = f'{withdrawal_key_path}/0'
     if withdrawal_pk and withdrawal_credentials:
         raise ValidationError(
             "Simultaneous use of withdrawal_credentials and withdrawal_pk is incompatible. Use only one of them."
         )
     if withdrawal_pk:
         self.custom_withdrawal_pk = validate_withdrawal_pk(
             withdrawal_pk=withdrawal_pk)
     else:
         self.custom_withdrawal_pk = None
     if withdrawal_credentials:
         self.custom_withdrawal_credentials = validate_withdrawal_credentials(
             withdrawal_credentials=withdrawal_credentials)
     else:
         self.custom_withdrawal_credentials = None
     self.withdrawal_sk = mnemonic_and_path_to_key(
         mnemonic=mnemonic,
         path=withdrawal_key_path,
         password=mnemonic_password)
     self.signing_sk = mnemonic_and_path_to_key(mnemonic=mnemonic,
                                                path=self.signing_key_path,
                                                password=mnemonic_password)
     self.amount = amount
     self.chain_setting = chain_setting
Exemple #5
0
 def deposit_message(self) -> DepositMessage:
     if not MIN_DEPOSIT_AMOUNT <= self.amount <= MAX_DEPOSIT_AMOUNT:
         raise ValidationError(
             f"{self.amount / ETH2GWEI} ETH deposits are not within the bounds of this cli."
         )
     return DepositMessage(
         pubkey=self.signing_pk,
         withdrawal_credentials=self.withdrawal_credentials,
         amount=self.amount,
     )
Exemple #6
0
def validate_withdrawal_pk(withdrawal_pk: str) -> bytes:
    try:
        decoded_withdrawal_pk = bytes.fromhex(withdrawal_pk)
    except Exception:
        raise ValueError(
            "Wrong withdrawal_pk value. Is it HEX (not Base64) format?")
    if len(decoded_withdrawal_pk) != 48:
        raise ValidationError(
            "Wrong withdrawal_pk length. Must be 48 bytes (96 hex symbols).")
    return decoded_withdrawal_pk
def validate_mnemonic(cts: click.Context, param: Any, mnemonic: str) -> str:
    if verify_mnemonic(mnemonic, WORD_LISTS_PATH):
        return mnemonic
    else:
        raise ValidationError(
            'That is not a valid mnemonic, please check for typos.')
def validate_password_strength(password: str) -> None:
    if len(password) < 8:
        raise ValidationError(
            f"The password length should be at least 8. Got {len(password)}.")