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
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
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')
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)
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}")
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
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
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
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
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
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
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')
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
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)
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())
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
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')
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
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)
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
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)
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)
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
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)
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)
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')
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*")
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)}")
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 :-(