Example #1
0
def confirm_deployment(emitter: StdoutEmitter, deployer_interface: BlockchainDeployerInterface) -> bool:
    """
    Interactively confirm deployment by asking the user to type the ALL CAPS name of
    the network they are deploying to or 'DEPLOY' if the network if not a known public chain.

    Aborts if the confirmation word is incorrect.
    """
    if deployer_interface.client.chain_name == UNKNOWN_DEVELOPMENT_CHAIN_ID or deployer_interface.client.is_local:
        expected_chain_name = 'DEPLOY'
    else:
        expected_chain_name = deployer_interface.client.chain_name
    if click.prompt(f"Type '{expected_chain_name.upper()}' to continue") != expected_chain_name.upper():
        emitter.echo(ABORT_DEPLOYMENT, color='red', bold=True)
        raise click.Abort(ABORT_DEPLOYMENT)
    return True
Example #2
0
def transfer_ownership(  # Admin Actor Options
        provider_uri,
        contract_name,
        config_root,
        poa,
        force,
        etherscan,
        hw_wallet,
        deployer_address,
        registry_infile,
        registry_outfile,
        dev,
        se_test_mode,

        # Other
        target_address,
        gas):
    """
    Transfer ownership of contracts to another address.
    """
    # Init
    emitter = StdoutEmitter()
    _ensure_config_root(config_root)
    deployer_interface = _initialize_blockchain(poa, provider_uri)

    # Warnings
    _pre_launch_warnings(emitter, etherscan, hw_wallet)

    #
    # Make Authenticated Deployment Actor
    #
    ADMINISTRATOR, deployer_address, local_registry = _make_authenticated_deployment_actor(
        emitter, provider_uri, deployer_address, deployer_interface,
        contract_name, registry_infile, registry_outfile, hw_wallet, dev,
        force, se_test_mode)

    if not target_address:
        target_address = click.prompt("Enter new owner's checksum address",
                                      type=EIP55_CHECKSUM_ADDRESS)

    if contract_name:
        try:
            contract_deployer_class = ADMINISTRATOR.deployers[contract_name]
        except KeyError:
            message = f"No such contract {contract_name}. Available contracts are {ADMINISTRATOR.deployers.keys()}"
            emitter.echo(message, color='red', bold=True)
            raise click.Abort()
        else:
            contract_deployer = contract_deployer_class(
                registry=ADMINISTRATOR.registry,
                deployer_address=ADMINISTRATOR.deployer_address)
            receipt = contract_deployer.transfer_ownership(
                new_owner=target_address, transaction_gas_limit=gas)
            emitter.ipc(receipt, request_id=0, duration=0)  # TODO: #1216
    else:
        receipts = ADMINISTRATOR.relinquish_ownership(
            new_owner=target_address, transaction_gas_limit=gas)
        emitter.ipc(receipts, request_id=0, duration=0)  # TODO: #1216
Example #3
0
def nucypher_cli(click_config, verbose, mock_networking, json_ipc, no_logs,
                 quiet, debug, no_registry, log_level):

    # Session Emitter for pre and post character control engagement.
    if json_ipc:
        emitter = JSONRPCStdoutEmitter(
            quiet=quiet, capture_stdout=NucypherClickConfig.capture_stdout)
    else:
        emitter = StdoutEmitter(
            quiet=quiet, capture_stdout=NucypherClickConfig.capture_stdout)

    click_config.attach_emitter(emitter)
    if not json_ipc:
        click_config.emit(message=NUCYPHER_BANNER)

    if log_level:
        GlobalConsoleLogger.set_log_level(log_level_name=log_level)
        globalLogPublisher.addObserver(SimpleObserver())

    if debug and quiet:
        raise click.BadOptionUsage(
            option_name="quiet",
            message="--debug and --quiet cannot be used at the same time.")

    if debug:
        click_config.log_to_sentry = False
        click_config.log_to_file = True  # File Logging
        globalLogPublisher.addObserver(SimpleObserver())  # Console Logging
        globalLogPublisher.removeObserver(logToSentry)  # No Sentry
        GlobalConsoleLogger.set_log_level(log_level_name='debug')

    elif quiet:  # Disable Logging
        globalLogPublisher.removeObserver(logToSentry)
        globalLogPublisher.removeObserver(SimpleObserver)
        globalLogPublisher.removeObserver(getJsonFileObserver())

    # Logging
    if not no_logs:
        GlobalConsoleLogger.start_if_not_started()

    # CLI Session Configuration
    click_config.verbose = verbose
    click_config.mock_networking = mock_networking
    click_config.json_ipc = json_ipc
    click_config.no_logs = no_logs
    click_config.quiet = quiet
    click_config.no_registry = no_registry
    click_config.debug = debug

    # Only used for testing outputs;
    # Redirects outputs to in-memory python containers.
    if mock_networking:
        click_config.emit(message="WARNING: Mock networking is enabled")
        click_config.middleware = MockRestMiddleware()
    else:
        click_config.middleware = RestMiddleware()

    # Global Warnings
    if click_config.verbose:
        click_config.emit(message="Verbose mode is enabled", color='blue')
Example #4
0
def rollback(  # Admin Actor Options
        provider_uri, contract_name, config_root, poa, force, etherscan,
        hw_wallet, deployer_address, registry_infile, registry_outfile, dev,
        se_test_mode):
    """
    Rollback a proxy contract's target.
    """
    # Init
    emitter = StdoutEmitter()
    _ensure_config_root(config_root)
    deployer_interface = _initialize_blockchain(poa, provider_uri)

    # Warnings
    _pre_launch_warnings(emitter, etherscan, hw_wallet)

    #
    # Make Authenticated Deployment Actor
    #
    ADMINISTRATOR, deployer_address, local_registry = _make_authenticated_deployment_actor(
        emitter, provider_uri, deployer_address, deployer_interface,
        contract_name, registry_infile, registry_outfile, hw_wallet, dev,
        force, se_test_mode)

    if not contract_name:
        raise click.BadArgumentUsage(
            message="--contract-name is required when using --rollback")
    existing_secret = click.prompt('Enter existing contract upgrade secret',
                                   hide_input=True)
    new_secret = click.prompt('Enter new contract upgrade secret',
                              hide_input=True,
                              confirmation_prompt=True)
    ADMINISTRATOR.rollback_contract(contract_name=contract_name,
                                    existing_plaintext_secret=existing_secret,
                                    new_plaintext_secret=new_secret)
Example #5
0
def download_registry(config_root, registry_outfile, force):
    """
    Download the latest registry.
    """
    # Init
    emitter = StdoutEmitter()
    _ensure_config_root(config_root)

    if not force:
        prompt = f"Fetch and download latest registry from {BaseContractRegistry.get_publication_endpoint()}?"
        click.confirm(prompt, abort=True)
    registry = InMemoryContractRegistry.from_latest_publication()
    output_filepath = registry.commit(filepath=registry_outfile,
                                      overwrite=force)
    emitter.message(
        f"Successfully downloaded latest registry to {output_filepath}")
Example #6
0
def test_ursula_command_protocol_creation(ursula):

    emitter = StdoutEmitter()
    protocol = UrsulaCommandProtocol(ursula=ursula, emitter=emitter)

    assert protocol.ursula == ursula
    assert b'Ursula' in protocol.prompt
Example #7
0
def unlock_nucypher_keyring(emitter: StdoutEmitter, password: str, character_configuration: CharacterConfiguration) -> bool:
    """Unlocks a nucypher keyring and attaches it to the supplied configuration if successful."""
    emitter.message(DECRYPTING_CHARACTER_KEYRING.format(name=character_configuration.NAME.capitalize()), color='yellow')

    # precondition
    if character_configuration.dev_mode:
        return True  # Dev accounts are always unlocked

    # unlock
    try:
        character_configuration.attach_keyring()
        character_configuration.keyring.unlock(password=password)  # Takes ~3 seconds, ~1GB Ram
    except CryptoError:
        raise NucypherKeyring.AuthenticationFailed
    else:
        return True
Example #8
0
def _list():
    """Show all character cards"""
    emitter = StdoutEmitter()
    card_directory = Card.CARD_DIR
    try:
        card_filepaths = os.listdir(card_directory)
    except FileNotFoundError:
        os.mkdir(Card.CARD_DIR)
        card_filepaths = os.listdir(card_directory)
    if not card_filepaths:
        emitter.error(
            f'No cards found at {card_directory}.  '
            f"To create one run 'nucypher {contacts.name} {create.name}'.")
    cards = list()
    for filename in card_filepaths:
        card = Card.load(filepath=Card.CARD_DIR / filename)
        cards.append(card)
    paint_cards(emitter=emitter, cards=cards, as_table=True)
def test_get_nucypher_password(mock_stdin, mock_account, confirm, capsys):
    mock_stdin.password(INSECURE_DEVELOPMENT_PASSWORD, confirm=confirm)
    result = get_nucypher_password(emitter=StdoutEmitter(), confirm=confirm)
    assert result == INSECURE_DEVELOPMENT_PASSWORD
    assert mock_stdin.empty()
    captured = capsys.readouterr()
    assert COLLECT_NUCYPHER_PASSWORD in captured.out
    if confirm:
        prompt = COLLECT_NUCYPHER_PASSWORD + f" ({NucypherKeyring.MINIMUM_PASSWORD_LENGTH} character minimum)"
        assert prompt in captured.out
Example #10
0
def connect_to_blockchain(emitter: StdoutEmitter,
                          provider_uri: str,
                          debug: bool = False,
                          light: bool = False) -> BlockchainInterface:
    try:
        # Note: Conditional for test compatibility.
        if not BlockchainInterfaceFactory.is_interface_initialized(
                provider_uri=provider_uri):
            BlockchainInterfaceFactory.initialize_interface(
                provider_uri=provider_uri, light=light, emitter=emitter)
        emitter.echo(message=CONNECTING_TO_BLOCKCHAIN)
        blockchain = BlockchainInterfaceFactory.get_interface(
            provider_uri=provider_uri)
        return blockchain
    except Exception as e:
        if debug:
            raise
        emitter.echo(str(e), bold=True, color='red')
        raise click.Abort
Example #11
0
def collect_keys_from_card(emitter: StdoutEmitter, card_identifier: str,
                           force: bool):
    emitter.message(f"Searching contacts for {card_identifier}\n",
                    color='yellow')
    card = Card.load(identifier=card_identifier)

    if card.character is not Bob:
        emitter.error('Grantee card is not a Bob.')
        raise click.Abort
    paint_single_card(emitter=emitter, card=card)

    if not force:
        click.confirm('Is this the correct grantee (Bob)?', abort=True)

    bob_encrypting_key = card.encrypting_key.hex()
    bob_verifying_key = card.verifying_key.hex()
    public_keys = PublicKeys(encrypting_key=bob_encrypting_key,
                             verifying_key=bob_verifying_key)
    return public_keys
Example #12
0
def collect_worker_ip_address(emitter: StdoutEmitter, network: str, force: bool = False) -> str:

    # From node swarm
    try:
        message = f'Detecting external IP address automatically'
        emitter.message(message, verbosity=2)
        ip = determine_external_ip_address(network=network)
    except UnknownIPAddress:
        if force:
            raise
        emitter.message('Cannot automatically determine external IP address - input required')
        ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP)

    # Confirmation
    if not force:
        if not click.confirm(CONFIRM_URSULA_IPV4_ADDRESS.format(rest_host=ip)):
            ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP)

    validate_worker_ip(worker_ip=ip)
    return ip
Example #13
0
def paint_all_stakes(emitter: StdoutEmitter,
                     stakeholder: 'StakeHolder',
                     paint_unlocked: bool = False) -> None:

    stakers = stakeholder.get_stakers()
    if not stakers:
        emitter.echo("No staking accounts found.")

    total_stakers = 0
    for staker in stakers:
        if not staker.stakes:
            # This staker has no active stakes.
            # TODO: Something with non-staking accounts?
            continue

        paint_stakes(emitter=emitter, staker=staker, paint_unlocked=paint_unlocked, stakeholder=stakeholder)
        total_stakers += 1

    if not total_stakers:
        emitter.echo("No Stakes found", color='red')
Example #14
0
def select_stake(staker: Staker,
                 emitter: StdoutEmitter,
                 stakes_status: Stake.Status = Stake.Status.EDITABLE) -> Stake:
    """Interactively select a stake or abort if there are no eligible stakes."""

    if stakes_status.is_child(Stake.Status.DIVISIBLE):
        emitter.echo(ONLY_DISPLAYING_DIVISIBLE_STAKES_NOTE, color='yellow')

    # Filter stakes by status
    stakes = staker.sorted_stakes(parent_status=stakes_status)
    if not stakes:
        emitter.echo(NO_STAKES_FOUND, color='red')
        raise click.Abort

    # Interactive Selection
    paint_stakes(staker=staker, emitter=emitter, stakes=stakes)
    indexed_stakes = {stake.index: stake for stake in stakes}
    indices = [str(index) for index in indexed_stakes.keys()]
    choice = click.prompt(SELECT_STAKE, type=click.Choice(indices))
    chosen_stake = indexed_stakes[int(choice)]
    return chosen_stake
Example #15
0
def test_rapid_deployment(token_economics, test_registry):
    compiler = SolidityCompiler()
    allocation_registry = InMemoryAllocationRegistry()

    blockchain = _TesterBlockchain(eth_airdrop=False,
                                   test_accounts=4,
                                   compiler=compiler)

    # TODO: #1092 - TransactingPower
    blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                                    account=blockchain.etherbase_account)
    blockchain.transacting_power.activate()
    deployer_address = blockchain.etherbase_account

    deployer = ContractAdministrator(deployer_address=deployer_address,
                                     registry=test_registry)

    secrets = dict()
    for deployer_class in deployer.upgradeable_deployer_classes:
        secrets[deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD

    deployer.deploy_network_contracts(secrets=secrets, emitter=StdoutEmitter())

    all_yall = blockchain.unassigned_accounts

    # Start with some hard-coded cases...
    allocation_data = [{'beneficiary_address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'duration_seconds': ONE_YEAR_IN_SECONDS},

                       {'beneficiary_address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'duration_seconds': ONE_YEAR_IN_SECONDS*2},

                       {'beneficiary_address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'duration_seconds': ONE_YEAR_IN_SECONDS*3}
                       ]

    # Pile on the rest
    for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
        random_password = ''.join(random.SystemRandom().choice(string.ascii_uppercase+string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods*ONE_YEAR_IN_SECONDS,
                                  (token_economics.maximum_rewarded_periods*ONE_YEAR_IN_SECONDS)*3)
        random_allocation = {'beneficiary_address': beneficiary_address, 'amount': amount, 'duration_seconds': duration}
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(allocations=allocation_data,
                                          allocation_registry=allocation_registry,
                                          interactive=False)
Example #16
0
def get_or_update_configuration(emitter: StdoutEmitter,
                                filepath: str,
                                config_class: Type[CharacterConfiguration],
                                updates: Optional[dict] = None) -> None:
    """
    Utility for writing updates to an existing configuration file then displaying the result.
    If the config file is invalid, try very hard to display the problem.  If there are no updates,
    the config file will be displayed without changes.
    """
    try:
        config = config_class.from_configuration_file(filepath=filepath)
    except FileNotFoundError:
        return handle_missing_configuration_file(
            character_config_class=config_class, config_file=filepath)
    except config_class.ConfigurationError:
        return handle_invalid_configuration_file(emitter=emitter,
                                                 config_class=config_class,
                                                 filepath=filepath)

    emitter.echo(
        f"{config_class.NAME.capitalize()} Configuration {filepath} \n {'='*55}"
    )
    if updates:
        pretty_fields = ', '.join(updates)
        emitter.message(SUCCESSFUL_UPDATE_CONFIGURATION_VALUES.format(
            fields=pretty_fields),
                        color='yellow')
        config.update(**updates)
    emitter.echo(config.serialize())
Example #17
0
def select_stake(stakeholder: StakeHolder,
                 emitter: StdoutEmitter,
                 divisible: bool = False,
                 staker_address: str = None
                 ) -> Stake:
    """Interactively select a stake or abort if there are no eligible stakes."""

    # Precondition: Active Stakes
    if staker_address:
        staker = stakeholder.get_staker(checksum_address=staker_address)
        stakes = staker.stakes
    else:
        stakes = stakeholder.all_stakes
    if not stakes:
        emitter.echo(NO_STAKES_FOUND, color='red')
        raise click.Abort

    # Precondition: Divisible Stakes
    stakes = stakeholder.sorted_stakes
    if divisible:
        emitter.echo(ONLY_DISPLAYING_DIVISIBLE_STAKES_NOTE, color='yellow')
        stakes = stakeholder.divisible_stakes
        if not stakes:
            emitter.echo(NO_DIVISIBLE_STAKES, color='red')
            raise click.Abort

    # Interactive Selection
    enumerated_stakes = dict(enumerate(stakes))
    paint_stakes(stakeholder=stakeholder, emitter=emitter, staker_address=staker_address)
    choice = click.prompt(SELECT_STAKE, type=click.IntRange(min=0, max=len(enumerated_stakes)-1))
    chosen_stake = enumerated_stakes[choice]
    return chosen_stake
Example #18
0
def deployer_pre_launch_warnings(emitter: StdoutEmitter, etherscan: bool, hw_wallet: bool) -> None:
    if not hw_wallet:
        emitter.echo(NO_HARDWARE_WALLET_WARNING, color='yellow')
    if etherscan:
        emitter.echo(ETHERSCAN_FLAG_ENABLED_WARNING, color='yellow')
    else:
        emitter.echo(ETHERSCAN_FLAG_DISABLED_WARNING, color='yellow')
Example #19
0
def collect_worker_ip_address(emitter: StdoutEmitter,
                              network: str,
                              force: bool = False) -> str:

    # From environment variable  # TODO: remove this environment variable?
    ip = os.environ.get(NUCYPHER_ENVVAR_WORKER_IP_ADDRESS)
    if ip:
        message = f'Using IP address ({ip}) from {NUCYPHER_ENVVAR_WORKER_IP_ADDRESS} environment variable'
        emitter.message(message, verbosity=2)
        return ip

    # From node swarm
    try:
        message = f'Detecting external IP address automatically'
        emitter.message(message, verbosity=2)
        ip = determine_external_ip_address(network=network)
    except UnknownIPAddress:
        if force:
            raise
        emitter.message(
            'Cannot automatically determine external IP address - input required'
        )

    # Confirmation
    if not force:
        if not click.confirm(CONFIRM_URSULA_IPV4_ADDRESS.format(rest_host=ip)):
            ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP)

    validate_worker_ip(worker_ip=ip)
    return ip
Example #20
0
 def generate_config(self, config_root, discovery_port):
     return FelixConfiguration.generate(
         password=get_nucypher_password(emitter=StdoutEmitter(), confirm=True),
         config_root=config_root,
         rest_host=self.host,
         rest_port=discovery_port,
         db_filepath=self.db_filepath,
         domain=self.domain,
         checksum_address=self.checksum_address,
         registry_filepath=self.registry_filepath,
         provider_uri=self.provider_uri,
         signer_uri=self.signer_uri,
         poa=self.poa)
Example #21
0
def select_client_account_for_staking(
    emitter: StdoutEmitter,
    stakeholder: StakeHolder,
    staking_address: Optional[str],
    individual_allocation: Optional[IndividualAllocationRegistry],
    force: bool,
) -> Tuple[str, str]:
    """
    Manages client account selection for stake-related operations.
    It always returns a tuple of addresses: the first is the local client account and the second is the staking address.

    When this is not a preallocation staker (which is the normal use case), both addresses are the same.
    Otherwise, when the staker is a contract managed by a beneficiary account,
    then the local client account is the beneficiary, and the staking address is the address of the staking contract.
    """

    if individual_allocation:
        client_account = individual_allocation.beneficiary_address
        staking_address = individual_allocation.contract_address
        message = PREALLOCATION_STAKE_ADVISORY.format(
            client_account=client_account, staking_address=staking_address)
        emitter.echo(message, color='yellow', verbosity=1)
        if not force:
            click.confirm(IS_THIS_CORRECT, abort=True)
    else:
        if staking_address:
            client_account = staking_address
        else:
            client_account = select_client_account(
                prompt=SELECT_STAKING_ACCOUNT_INDEX,
                emitter=emitter,
                registry=stakeholder.registry,
                network=stakeholder.network,
                wallet=stakeholder.wallet)
            staking_address = client_account
    stakeholder.set_staker(client_account)

    return client_account, staking_address
Example #22
0
def test_rapid_deployment(token_economics, test_registry, tmpdir, get_random_checksum_address):
    compiler = SolidityCompiler()

    blockchain = _TesterBlockchain(eth_airdrop=False,
                                   test_accounts=4,
                                   compiler=compiler)

    # TODO: #1092 - TransactingPower
    blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                                    account=blockchain.etherbase_account)
    blockchain.transacting_power.activate()
    deployer_address = blockchain.etherbase_account

    administrator = ContractAdministrator(deployer_address=deployer_address,
                                          registry=test_registry)

    administrator.deploy_network_contracts(emitter=StdoutEmitter(), interactive=False)

    all_yall = blockchain.unassigned_accounts

    # Start with some hard-coded cases...
    allocation_data = [{'checksum_address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'lock_periods': token_economics.minimum_locked_periods},

                       {'checksum_address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'lock_periods': token_economics.minimum_locked_periods},

                       {'checksum_address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'lock_periods': token_economics.minimum_locked_periods},
                       ]

    # Pile on the rest
    for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
        checksum_address = get_random_checksum_address()
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods, token_economics.maximum_rewarded_periods)
        random_allocation = {'checksum_address': checksum_address, 'amount': amount, 'lock_periods': duration}
        allocation_data.append(random_allocation)

    filepath = tmpdir / "allocations.json"
    with open(filepath, 'w') as f:
        json.dump(allocation_data, f)

    administrator.batch_deposits(allocation_data_filepath=str(filepath), interactive=False)

    minimum, default, maximum = 10, 20, 30
    administrator.set_fee_rate_range(minimum, default, maximum)
Example #23
0
def inspect(provider_uri, config_root, registry_infile, deployer_address, poa):
    """
    Echo owner information and bare contract metadata.
    """
    # Init
    emitter = StdoutEmitter()
    _ensure_config_root(config_root)
    _initialize_blockchain(poa, provider_uri)

    local_registry = establish_deployer_registry(
        emitter=emitter, registry_infile=registry_infile)
    paint_deployer_contract_inspection(emitter=emitter,
                                       registry=local_registry,
                                       deployer_address=deployer_address)
Example #24
0
    def relinquish_ownership(self,
                             new_owner: str,
                             emitter: StdoutEmitter = None,
                             interactive: bool = True,
                             transaction_gas_limit: int = None) -> dict:

        if not is_checksum_address(new_owner):
            raise ValueError(f"{new_owner} is an invalid EIP-55 checksum address.")

        receipts = dict()

        for contract_deployer in self.ownable_deployer_classes:
            deployer = contract_deployer(registry=self.registry, deployer_address=self.deployer_address)
            deployer.transfer_ownership(new_owner=new_owner, transaction_gas_limit=transaction_gas_limit)

            if emitter:
                emitter.echo(f"Transferred ownership of {deployer.contract_name} to {new_owner}")

            if interactive:
                click.pause(info="Press any key to continue")

            receipts[contract_deployer.contract_name] = receipts

        return receipts
Example #25
0
def create(character_flag, verifying_key, encrypting_key, nickname, force):
    """Store a new character card"""
    emitter = StdoutEmitter()

    # Validate
    if not all((character_flag, verifying_key, encrypting_key)) and force:
        emitter.error(
            f'--verifying-key, --encrypting-key, and --type are required with --force enabled.'
        )

    # Card type
    from constant_sorrow.constants import ALICE, BOB
    flags = {'a': ALICE, 'b': BOB}
    if not character_flag:
        choice = click.prompt('Enter Card Type - (A)lice or (B)ob',
                              type=click.Choice(['a', 'b'],
                                                case_sensitive=False))
        character_flag = flags[choice]
    else:
        character_flag = flags[character_flag]

    # Verifying Key
    if not verifying_key:
        verifying_key = click.prompt('Enter Verifying Key',
                                     type=UMBRAL_PUBLIC_KEY_HEX)
    verifying_key = bytes.fromhex(verifying_key)  # TODO: Move / Validate

    # Encrypting Key
    if character_flag is BOB:
        if not encrypting_key:
            encrypting_key = click.prompt('Enter Encrypting Key',
                                          type=UMBRAL_PUBLIC_KEY_HEX)
        encrypting_key = bytes.fromhex(encrypting_key)  # TODO: Move / Validate

    # Init
    new_card = Card(character_flag=character_flag,
                    verifying_key=verifying_key,
                    encrypting_key=encrypting_key,
                    nickname=nickname)

    # Nickname
    if not force and not nickname:
        card_id_hex = new_card.id.hex()
        nickname = click.prompt('Enter nickname for card', default=card_id_hex)
        if nickname != card_id_hex:  # not the default
            nickname = nickname.strip()
            new_card.nickname = nickname

    # Save
    new_card.save()
    emitter.message(f'Saved new card {new_card}', color='green')
    paint_single_card(emitter=emitter, card=new_card)
Example #26
0
def allocations(  # Admin Actor Options
        provider_uri,
        contract_name,
        config_root,
        poa,
        force,
        etherscan,
        hw_wallet,
        deployer_address,
        registry_infile,
        registry_outfile,
        dev,
        se_test_mode,

        # Other
        allocation_infile,
        allocation_outfile):
    """
    Deploy pre-allocation contracts.
    """
    # Init
    emitter = StdoutEmitter()
    _ensure_config_root(config_root)
    deployer_interface = _initialize_blockchain(poa, provider_uri)

    # Warnings
    _pre_launch_warnings(emitter, etherscan, hw_wallet)

    #
    # Make Authenticated Deployment Actor
    #
    ADMINISTRATOR, deployer_address, local_registry = _make_authenticated_deployment_actor(
        emitter, provider_uri, deployer_address, deployer_interface,
        contract_name, registry_infile, registry_outfile, hw_wallet, dev,
        force, se_test_mode)

    if not allocation_infile:
        allocation_infile = click.prompt("Enter allocation data filepath")
    ADMINISTRATOR.deploy_beneficiaries_from_file(
        allocation_data_filepath=allocation_infile,
        allocation_outfile=allocation_outfile,
        emitter=emitter,
        interactive=not force)
Example #27
0
def nucypher_cli(click_config,
                 verbose,
                 mock_networking,
                 json_ipc,
                 no_logs,
                 quiet,
                 debug,
                 no_registry):

    # Session Emitter for pre and post character control engagement.
    if json_ipc:
        emitter = IPCStdoutEmitter(quiet=quiet, capture_stdout=NucypherClickConfig.capture_stdout)
    else:
        emitter = StdoutEmitter(quiet=quiet, capture_stdout=NucypherClickConfig.capture_stdout)

    NucypherClickConfig.emitter = emitter
    click_config.emitter(message=NUCYPHER_BANNER)

    # Logging
    if not no_logs:
        GlobalConsoleLogger.start_if_not_started()

    # CLI Session Configuration
    click_config.verbose = verbose
    click_config.mock_networking = mock_networking
    click_config.json_ipc = json_ipc
    click_config.no_logs = no_logs
    click_config.quiet = quiet
    click_config.no_registry = no_registry
    click_config.debug = debug

    # only used for testing outputs;
    # Redirects outputs to in-memory python containers.
    if mock_networking:
        click_config.emitter(message="WARNING: Mock networking is enabled")
        click_config.middleware = MockRestMiddleware()
    else:
        click_config.middleware = RestMiddleware()

    # Global Warnings
    if click_config.verbose:
        click_config.emitter("Verbose mode is enabled", color='blue')
Example #28
0
def validate_grant_command(emitter: StdoutEmitter, alice: Alice, force: bool,
                           bob: str, bob_verifying_key: str,
                           bob_encrypting_key: str, label: str,
                           expiration: maya.MayaDT, rate: int, value: int):

    # Force mode validation
    if force:
        required = (Precondition(
            options='--bob or --bob-encrypting-key and --bob-verifying-key.',
            condition=bob or all((bob_verifying_key, bob_encrypting_key))),
                    Precondition(options='--label', condition=bool(label)),
                    Precondition(options='--expiration',
                                 condition=bool(expiration)))
        triggered = False
        for condition in required:
            # see what condition my condition was in.
            if not condition.condition:
                triggered = True
                emitter.error(
                    f'Missing options in force mode: {condition.options}')
        if triggered:
            raise click.Abort()

    # Handle federated
    if alice.federated_only:
        if any((value, rate)):
            message = "Can't use --value or --rate with a federated Alice."
            raise click.BadOptionUsage(option_name="--value, --rate",
                                       message=message)
    elif bool(value) and bool(rate):
        raise click.BadOptionUsage(option_name="--rate",
                                   message="Can't use --value if using --rate")

    # From Bob card
    if bob:
        if any((bob_encrypting_key, bob_verifying_key)):
            message = '--bob cannot be used with --bob-encrypting-key or --bob-verifying key'
            raise click.BadOptionUsage(option_name='--bob', message=message)

    # From hex public keys
    else:
        if not all((bob_encrypting_key, bob_verifying_key)):
            if force:
                emitter.message(
                    'Missing options in force mode: --bob or --bob-encrypting-key and --bob-verifying-key.'
                )
                click.Abort()
            emitter.message("*Caution: Only enter public keys*")
Example #29
0
def retrieve_events(emitter: StdoutEmitter,
                    agent: EthereumContractAgent,
                    event_name: str,
                    from_block: BlockIdentifier,
                    to_block: BlockIdentifier,
                    argument_filters: Dict,
                    csv_output_file: Optional[str] = None) -> None:
    if csv_output_file:
        if Path(csv_output_file).exists():
            click.confirm(CONFIRM_OVERWRITE_EVENTS_CSV_FILE.format(
                csv_file=csv_output_file),
                          abort=True)
        available_events = write_events_to_csv_file(
            csv_file=csv_output_file,
            agent=agent,
            event_name=event_name,
            from_block=from_block,
            to_block=to_block,
            argument_filters=argument_filters)
        if available_events:
            emitter.echo(
                f"{agent.contract_name}::{event_name} events written to {csv_output_file}",
                bold=True,
                color='green')
        else:
            emitter.echo(
                f'No {agent.contract_name}::{event_name} events found',
                color='yellow')
    else:
        event = agent.contract.events[event_name]
        emitter.echo(f"{event_name}:", bold=True, color='yellow')
        entries = event.getLogs(fromBlock=from_block,
                                toBlock=to_block,
                                argument_filters=argument_filters)
        for event_record in entries:
            emitter.echo(f"  - {EventRecord(event_record)}")
Example #30
0
def handle_invalid_configuration_file(emitter: StdoutEmitter,
                                      config_class: Type[CharacterConfiguration],
                                      filepath: str) -> None:
    """
    Attempt to deserialize a config file that is not a valid nucypher character configuration
    as a means of user-friendly debugging. :-)  I hope this helps!
    """
    # Issue warning for invalid configuration...
    emitter.message(INVALID_CONFIGURATION_FILE_WARNING.format(filepath=filepath))
    try:
        # ... but try to display it anyways
        response = config_class._read_configuration_file(filepath=filepath)
        emitter.echo(json.dumps(response, indent=4))
        raise config_class.ConfigurationError
    except (TypeError, JSONDecodeError):
        emitter.message(INVALID_JSON_IN_CONFIGURATION_WARNING.format(filepath=filepath))
        # ... sorry.. we tried as hard as we could
        raise  # crash :-(