Implements signer URI for remaining CLI and configuration entrypoints: Alice, Bob, Ursula, Worklock, etc.

pull/1664/head
Kieran Prasch 2020-03-23 13:09:01 -07:00
parent 878a243246
commit fe1c4703aa
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
10 changed files with 82 additions and 42 deletions

View File

@ -72,7 +72,7 @@ from nucypher.blockchain.eth.registry import (
BaseContractRegistry, BaseContractRegistry,
IndividualAllocationRegistry IndividualAllocationRegistry
) )
from nucypher.blockchain.eth.signers import ClefSigner, Web3Signer from nucypher.blockchain.eth.signers import ClefSigner, Web3Signer, Signer
from nucypher.blockchain.eth.token import NU, Stake, StakeList, WorkTracker from nucypher.blockchain.eth.token import NU, Stake, StakeList, WorkTracker
from nucypher.blockchain.eth.utils import datetime_to_period, calculate_period_duration, datetime_at_period, \ from nucypher.blockchain.eth.utils import datetime_to_period, calculate_period_duration, datetime_at_period, \
prettify_eth_amount prettify_eth_amount
@ -194,27 +194,30 @@ class ContractAdministrator(NucypherTokenActor):
registry: BaseContractRegistry, registry: BaseContractRegistry,
deployer_address: str = None, deployer_address: str = None,
client_password: str = None, client_password: str = None,
signer: Signer = None,
staking_escrow_test_mode: bool = False, staking_escrow_test_mode: bool = False,
economics: BaseEconomics = None): economics: BaseEconomics = None):
""" """
Note: super() is not called here to avoid setting the token agent. Note: super() is not called here to avoid setting the token agent. TODO: call super but use "bare mode" without token agent. #1510
TODO: Review this logic ^^ "bare mode". #1510
""" """
self.log = Logger("Deployment-Actor") self.log = Logger("Deployment-Actor")
self.deployer_address = deployer_address self.deployer_address = deployer_address
self.checksum_address = self.deployer_address self.checksum_address = self.deployer_address
self.economics = economics or StandardTokenEconomics() self.economics = economics or StandardTokenEconomics()
self.staking_escrow_test_mode = staking_escrow_test_mode
self.registry = registry self.registry = registry
self.preallocation_escrow_deployers = dict() self.preallocation_escrow_deployers = dict()
self.deployers = {d.contract_name: d for d in self.all_deployer_classes} self.deployers = {d.contract_name: d for d in self.all_deployer_classes}
self.deployer_power = TransactingPower(password=client_password, # Powers
account=deployer_address, cache=True) self.deployer_power = TransactingPower(signer=signer,
password=client_password,
account=deployer_address,
cache=True)
self.transacting_power = self.deployer_power self.transacting_power = self.deployer_power
self.transacting_power.activate() self.transacting_power.activate()
self.staking_escrow_test_mode = staking_escrow_test_mode
self.sidekick_power = None self.sidekick_power = None
self.sidekick_address = None self.sidekick_address = None
@ -1526,7 +1529,9 @@ class StakeHolder(Staker):
try: try:
transacting_power = self.__transacting_powers[checksum_address] transacting_power = self.__transacting_powers[checksum_address]
except KeyError: except KeyError:
transacting_power = TransactingPower(password=password, account=checksum_address) transacting_power = TransactingPower(signer=self.__signer,
password=password,
account=checksum_address)
self.__transacting_powers[checksum_address] = transacting_power self.__transacting_powers[checksum_address] = transacting_power
transacting_power.activate(password=password) transacting_power.activate(password=password)
@ -1664,17 +1669,20 @@ class Bidder(NucypherTokenActor):
@validate_checksum_address @validate_checksum_address
def __init__(self, def __init__(self,
checksum_address: str, checksum_address: str,
is_transacting: bool = True, signer: Signer = None,
client_password: str = None, client_password: str = None,
*args, **kwargs): *args, **kwargs):
super().__init__(checksum_address=checksum_address, *args, **kwargs) super().__init__(checksum_address=checksum_address, *args, **kwargs)
self.log = Logger(f"WorkLockBidder") self.log = Logger(f"WorkLockBidder")
self.worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=self.registry) # type: WorkLockAgent self.worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=self.registry) # type: WorkLockAgent
self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry) self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry)
self.economics = EconomicsFactory.get_economics(registry=self.registry) self.economics = EconomicsFactory.get_economics(registry=self.registry)
if is_transacting: if signer:
self.transacting_power = TransactingPower(password=client_password, account=checksum_address) self.transacting_power = TransactingPower(signer=signer,
password=client_password,
account=checksum_address)
self.transacting_power.activate() self.transacting_power.activate()
self._all_bonus_bidders = None self._all_bonus_bidders = None

View File

@ -23,6 +23,7 @@ from geth.process import BaseGethProcess
from twisted.logger import Logger from twisted.logger import Logger
from web3 import Web3 from web3 import Web3
from nucypher.blockchain.eth.signers import ClefSigner
from nucypher.config.constants import DEFAULT_CONFIG_ROOT, DEPLOY_DIR, USER_LOG_DIR from nucypher.config.constants import DEFAULT_CONFIG_ROOT, DEPLOY_DIR, USER_LOG_DIR
UNKNOWN_DEVELOPMENT_CHAIN_ID.bool_value(True) UNKNOWN_DEVELOPMENT_CHAIN_ID.bool_value(True)

View File

@ -7,9 +7,7 @@ from hexbytes import HexBytes
from twisted.logger import Logger from twisted.logger import Logger
from web3 import Web3, IPCProvider from web3 import Web3, IPCProvider
from nucypher.blockchain.eth.clients import EthereumClient
from nucypher.blockchain.eth.decorators import validate_checksum_address from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.interfaces import BlockchainInterface, BlockchainInterfaceFactory
class Signer(ABC): class Signer(ABC):
@ -57,12 +55,14 @@ class Signer(ABC):
class Web3Signer(Signer): class Web3Signer(Signer):
def __init__(self, client: EthereumClient): def __init__(self, client):
super().__init__() super().__init__()
self.__client = client self.__client = client
@classmethod @classmethod
def from_signer_uri(cls, uri: str) -> 'Web3Signer': def from_signer_uri(cls, uri: str) -> 'Web3Signer':
from nucypher.blockchain.eth.interfaces import BlockchainInterface, BlockchainInterfaceFactory
try: try:
blockchain = BlockchainInterfaceFactory.get_or_create_interface(provider_uri=uri) blockchain = BlockchainInterfaceFactory.get_or_create_interface(provider_uri=uri)
except BlockchainInterface.UnsupportedProvider: except BlockchainInterface.UnsupportedProvider:
@ -150,14 +150,14 @@ class ClefSigner(Signer):
return checksum_addresses return checksum_addresses
@validate_checksum_address @validate_checksum_address
def sign_transaction(self, account: str, transaction_dict: dict) -> HexBytes: def sign_transaction(self, transaction_dict: dict) -> HexBytes:
formatters = { formatters = {
'nonce': Web3.toHex, 'nonce': Web3.toHex,
'gasPrice': Web3.toHex, 'gasPrice': Web3.toHex,
'gas': Web3.toHex, 'gas': Web3.toHex,
'value': Web3.toHex, 'value': Web3.toHex,
'chainId': Web3.toHex, 'chainId': Web3.toHex,
'from': to_normalized_address 'from': to_checksum_address
} }
transaction_dict = apply_formatters_to_dict(formatters, transaction_dict) transaction_dict = apply_formatters_to_dict(formatters, transaction_dict)
signed = self.w3.manager.request_blocking("account_signTransaction", [transaction_dict]) signed = self.w3.manager.request_blocking("account_signTransaction", [transaction_dict])

View File

@ -49,7 +49,7 @@ from nucypher.cli.options import (
option_provider_uri, option_provider_uri,
option_registry_filepath, option_registry_filepath,
option_teacher_uri, option_teacher_uri,
option_rate) option_rate, option_signer_uri)
from nucypher.cli.types import EIP55_CHECKSUM_ADDRESS from nucypher.cli.types import EIP55_CHECKSUM_ADDRESS
from nucypher.config.characters import AliceConfiguration from nucypher.config.characters import AliceConfiguration
from nucypher.config.constants import NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD from nucypher.config.constants import NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD
@ -72,7 +72,7 @@ class AliceConfigOptions:
__option_name__ = 'config_options' __option_name__ = 'config_options'
def __init__(self, dev, network, provider_uri, geth, federated_only, discovery_port, def __init__(self, dev, network, provider_uri, geth, federated_only, discovery_port,
pay_with, registry_filepath, middleware, gas_strategy): pay_with, registry_filepath, middleware, gas_strategy, signer_uri):
if federated_only and geth: if federated_only and geth:
raise click.BadOptionUsage( raise click.BadOptionUsage(
@ -88,6 +88,7 @@ class AliceConfigOptions:
self.dev = dev self.dev = dev
self.domains = {network} if network else None self.domains = {network} if network else None
self.provider_uri = provider_uri self.provider_uri = provider_uri
self.signer_uri = signer_uri
self.gas_strategy = gas_strategy self.gas_strategy = gas_strategy
self.geth = geth self.geth = geth
self.federated_only = federated_only self.federated_only = federated_only
@ -114,6 +115,7 @@ class AliceConfigOptions:
domains={TEMPORARY_DOMAIN}, domains={TEMPORARY_DOMAIN},
provider_process=self.eth_node, provider_process=self.eth_node,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
federated_only=True) federated_only=True)
@ -126,6 +128,7 @@ class AliceConfigOptions:
domains=self.domains, domains=self.domains,
provider_process=self.eth_node, provider_process=self.eth_node,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
filepath=config_file, filepath=config_file,
rest_port=self.discovery_port, rest_port=self.discovery_port,
@ -143,6 +146,7 @@ group_config_options = group_options(
dev=option_dev, dev=option_dev,
network=option_network, network=option_network,
provider_uri=option_provider_uri(), provider_uri=option_provider_uri(),
signer_uri=option_signer_uri,
gas_strategy=option_gas_strategy, gas_strategy=option_gas_strategy,
geth=option_geth, geth=option_geth,
federated_only=option_federated_only, federated_only=option_federated_only,
@ -188,6 +192,7 @@ class AliceFullConfigOptions:
domains=opts.domains, domains=opts.domains,
federated_only=opts.federated_only, federated_only=opts.federated_only,
provider_uri=opts.provider_uri, provider_uri=opts.provider_uri,
signer_uri=opts.signer_uri,
provider_process=opts.eth_node, provider_process=opts.eth_node,
registry_filepath=opts.registry_filepath, registry_filepath=opts.registry_filepath,
poa=self.poa, poa=self.poa,
@ -202,6 +207,7 @@ class AliceFullConfigOptions:
domains=opts.domains, domains=opts.domains,
federated_only=opts.federated_only, federated_only=opts.federated_only,
provider_uri=opts.provider_uri, provider_uri=opts.provider_uri,
signer_uri=opts.signer_uri,
registry_filepath=opts.registry_filepath, registry_filepath=opts.registry_filepath,
poa=self.poa, poa=self.poa,
light=self.light, light=self.light,

View File

@ -23,7 +23,7 @@ from nucypher.cli.options import (
option_provider_uri, option_provider_uri,
option_registry_filepath, option_registry_filepath,
option_teacher_uri, option_teacher_uri,
) option_signer_uri)
from nucypher.config.characters import BobConfiguration from nucypher.config.characters import BobConfiguration
from nucypher.crypto.powers import DecryptingPower from nucypher.crypto.powers import DecryptingPower
from nucypher.utilities.sandbox.constants import TEMPORARY_DOMAIN from nucypher.utilities.sandbox.constants import TEMPORARY_DOMAIN
@ -33,10 +33,11 @@ class BobConfigOptions:
__option_name__ = 'config_options' __option_name__ = 'config_options'
def __init__(self, provider_uri, network, registry_filepath, def __init__(self, provider_uri, network, registry_filepath, checksum_address, discovery_port,
checksum_address, discovery_port, dev, middleware, federated_only, gas_strategy): dev, middleware, federated_only, gas_strategy, signer_uri):
self.provider_uri = provider_uri self.provider_uri = provider_uri
self.signer_uri = signer_uri
self.gas_strategy = gas_strategy, self.gas_strategy = gas_strategy,
self.domains = {network} if network else None self.domains = {network} if network else None
self.registry_filepath = registry_filepath self.registry_filepath = registry_filepath
@ -54,6 +55,7 @@ class BobConfigOptions:
domains={TEMPORARY_DOMAIN}, domains={TEMPORARY_DOMAIN},
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
signer_uri=self.signer_uri,
federated_only=True, federated_only=True,
checksum_address=self.checksum_address, checksum_address=self.checksum_address,
network_middleware=self.middleware) network_middleware=self.middleware)
@ -66,6 +68,7 @@ class BobConfigOptions:
checksum_address=self.checksum_address, checksum_address=self.checksum_address,
rest_port=self.discovery_port, rest_port=self.discovery_port,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
network_middleware=self.middleware) network_middleware=self.middleware)
@ -90,6 +93,7 @@ class BobConfigOptions:
federated_only=self.federated_only, federated_only=self.federated_only,
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
) )
@ -99,6 +103,7 @@ class BobConfigOptions:
federated_only=self.federated_only, federated_only=self.federated_only,
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy gas_strategy=self.gas_strategy
) )
# Depends on defaults being set on Configuration classes, filtrates None values # Depends on defaults being set on Configuration classes, filtrates None values
@ -110,6 +115,7 @@ group_config_options = group_options(
BobConfigOptions, BobConfigOptions,
provider_uri=option_provider_uri(), provider_uri=option_provider_uri(),
gas_strategy=option_gas_strategy, gas_strategy=option_gas_strategy,
signer_uri=option_signer_uri,
network=option_network, network=option_network,
registry_filepath=option_registry_filepath, registry_filepath=option_registry_filepath,
checksum_address=option_checksum_address, checksum_address=option_checksum_address,

View File

@ -52,8 +52,8 @@ from nucypher.cli.options import (
option_hw_wallet, option_hw_wallet,
option_poa, option_poa,
option_provider_uri, option_provider_uri,
option_contract_name option_contract_name,
) option_signer_uri)
from nucypher.cli.painting import ( from nucypher.cli.painting import (
echo_solidity_version, echo_solidity_version,
paint_staged_deployment, paint_staged_deployment,
@ -123,8 +123,9 @@ class ActorOptions:
def __init__(self, provider_uri, deployer_address, contract_name, def __init__(self, provider_uri, deployer_address, contract_name,
registry_infile, registry_outfile, hw_wallet, dev, force, poa, config_root, etherscan, registry_infile, registry_outfile, hw_wallet, dev, force, poa, config_root, etherscan,
se_test_mode, ignore_solidity_check, gas_strategy): se_test_mode, ignore_solidity_check, gas_strategy, signer_uri):
self.provider_uri = provider_uri self.provider_uri = provider_uri
self.signer_uri = signer_uri
self.gas_strategy = gas_strategy self.gas_strategy = gas_strategy
self.deployer_address = deployer_address self.deployer_address = deployer_address
self.contract_name = contract_name self.contract_name = contract_name
@ -194,6 +195,7 @@ group_actor_options = group_options(
ActorOptions, ActorOptions,
provider_uri=option_provider_uri(), provider_uri=option_provider_uri(),
gas_strategy=option_gas_strategy, gas_strategy=option_gas_strategy,
signer_uri=option_signer_uri,
contract_name=option_contract_name, contract_name=option_contract_name,
poa=option_poa, poa=option_poa,
force=option_force, force=option_force,

View File

@ -49,18 +49,18 @@ from nucypher.cli.options import (
option_provider_uri, option_provider_uri,
option_registry_filepath, option_registry_filepath,
option_staking_address, option_staking_address,
) option_signer_uri)
from nucypher.cli.painting import paint_receipt_summary from nucypher.cli.painting import paint_receipt_summary
from nucypher.cli.types import ( from nucypher.cli.types import (
EIP55_CHECKSUM_ADDRESS, EIP55_CHECKSUM_ADDRESS,
EXISTING_READABLE_FILE, EXISTING_READABLE_FILE,
WEI) WEI
)
from nucypher.config.characters import StakeHolderConfiguration from nucypher.config.characters import StakeHolderConfiguration
option_value = click.option('--value', help="Token value of stake", type=click.INT) option_value = click.option('--value', help="Token value of stake", type=click.INT)
option_lock_periods = click.option('--lock-periods', help="Duration of stake in periods.", type=click.INT) option_lock_periods = click.option('--lock-periods', help="Duration of stake in periods.", type=click.INT)
option_worker_address = click.option('--worker-address', help="Address to assign as an Ursula-Worker", type=EIP55_CHECKSUM_ADDRESS) option_worker_address = click.option('--worker-address', help="Address to assign as an Ursula-Worker", type=EIP55_CHECKSUM_ADDRESS)
option_signer_uri = click.option('--signer', 'signer_uri', '-S', default=None, type=str)
def _setup_emitter(general_config): def _setup_emitter(general_config):
@ -175,7 +175,7 @@ group_staker_options = group_options(
StakerOptions, StakerOptions,
config_options=group_config_options, config_options=group_config_options,
staking_address=option_staking_address, staking_address=option_staking_address,
) )
class TransactingStakerOptions: class TransactingStakerOptions:

View File

@ -51,7 +51,7 @@ from nucypher.cli.options import (
option_provider_uri, option_provider_uri,
option_registry_filepath, option_registry_filepath,
option_teacher_uri, option_teacher_uri,
) option_signer_uri)
from nucypher.cli.processes import UrsulaCommandProtocol from nucypher.cli.processes import UrsulaCommandProtocol
from nucypher.cli.types import EIP55_CHECKSUM_ADDRESS, NETWORK_PORT from nucypher.cli.types import EIP55_CHECKSUM_ADDRESS, NETWORK_PORT
from nucypher.config.characters import UrsulaConfiguration from nucypher.config.characters import UrsulaConfiguration
@ -65,7 +65,7 @@ class UrsulaConfigOptions:
__option_name__ = 'config_options' __option_name__ = 'config_options'
def __init__(self, geth, provider_uri, worker_address, federated_only, rest_host, def __init__(self, geth, provider_uri, worker_address, federated_only, rest_host,
rest_port, db_filepath, network, registry_filepath, dev, poa, light, gas_strategy): rest_port, db_filepath, network, registry_filepath, dev, poa, light, gas_strategy, signer_uri):
if federated_only: if federated_only:
# TODO: consider rephrasing in a more universal voice. # TODO: consider rephrasing in a more universal voice.
@ -85,6 +85,7 @@ class UrsulaConfigOptions:
self.eth_node = eth_node self.eth_node = eth_node
self.provider_uri = provider_uri self.provider_uri = provider_uri
self.signer_uri = signer_uri
self.worker_address = worker_address self.worker_address = worker_address
self.federated_only = federated_only self.federated_only = federated_only
self.rest_host = rest_host self.rest_host = rest_host
@ -108,6 +109,7 @@ class UrsulaConfigOptions:
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_process=self.eth_node, provider_process=self.eth_node,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
checksum_address=self.worker_address, checksum_address=self.worker_address,
federated_only=self.federated_only, federated_only=self.federated_only,
@ -123,6 +125,7 @@ class UrsulaConfigOptions:
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_process=self.eth_node, provider_process=self.eth_node,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
rest_host=self.rest_host, rest_host=self.rest_host,
rest_port=self.rest_port, rest_port=self.rest_port,
@ -170,6 +173,7 @@ class UrsulaConfigOptions:
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_process=self.eth_node, provider_process=self.eth_node,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
poa=self.poa, poa=self.poa,
light=self.light) light=self.light)
@ -183,6 +187,7 @@ class UrsulaConfigOptions:
checksum_address=self.worker_address, checksum_address=self.worker_address,
registry_filepath=self.registry_filepath, registry_filepath=self.registry_filepath,
provider_uri=self.provider_uri, provider_uri=self.provider_uri,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy, gas_strategy=self.gas_strategy,
poa=self.poa, poa=self.poa,
light=self.light) light=self.light)
@ -195,6 +200,7 @@ group_config_options = group_options(
UrsulaConfigOptions, UrsulaConfigOptions,
geth=option_geth, geth=option_geth,
provider_uri=option_provider_uri(), provider_uri=option_provider_uri(),
signer_uri=option_signer_uri,
gas_strategy=option_gas_strategy, gas_strategy=option_gas_strategy,
worker_address=click.option('--worker-address', help="Run the worker-ursula with a specified address", type=EIP55_CHECKSUM_ADDRESS), worker_address=click.option('--worker-address', help="Run the worker-ursula with a specified address", type=EIP55_CHECKSUM_ADDRESS),
federated_only=option_federated_only, federated_only=option_federated_only,
@ -205,7 +211,8 @@ group_config_options = group_options(
registry_filepath=option_registry_filepath, registry_filepath=option_registry_filepath,
poa=option_poa, poa=option_poa,
light=option_light, light=option_light,
dev=option_dev) dev=option_dev
)
class UrsulaCharacterOptions: class UrsulaCharacterOptions:

View File

@ -15,27 +15,30 @@ You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>. along with nucypher. If not, see <https://www.gnu.org/licenses/>.
""" """
from decimal import Decimal
from typing import Optional
import click import click
import maya import maya
import tabulate import tabulate
from decimal import Decimal
from web3 import Web3 from web3 import Web3
from nucypher.blockchain.eth.actors import Bidder from nucypher.blockchain.eth.actors import Bidder
from nucypher.blockchain.eth.agents import WorkLockAgent, ContractAgency from nucypher.blockchain.eth.agents import ContractAgency, WorkLockAgent
from nucypher.blockchain.eth.signers import Signer
from nucypher.blockchain.eth.token import NU from nucypher.blockchain.eth.token import NU
from nucypher.blockchain.eth.utils import prettify_eth_amount from nucypher.blockchain.eth.utils import prettify_eth_amount
from nucypher.characters.banners import WORKLOCK_BANNER from nucypher.characters.banners import WORKLOCK_BANNER
from nucypher.cli.actions import get_client_password
from nucypher.cli.actions import select_client_account from nucypher.cli.actions import select_client_account
from nucypher.cli.commands.status import group_registry_options from nucypher.cli.commands.status import group_registry_options
from nucypher.cli.config import group_general_config from nucypher.cli.config import group_general_config
from nucypher.cli.options import ( from nucypher.cli.options import (
option_force, option_force,
group_options, group_options,
option_hw_wallet option_hw_wallet,
option_signer_uri
) )
from nucypher.cli.actions import get_client_password
from nucypher.cli.painting import ( from nucypher.cli.painting import (
paint_receipt_summary, paint_receipt_summary,
paint_worklock_status, paint_worklock_status,
@ -60,29 +63,35 @@ class WorkLockOptions:
__option_name__ = 'worklock_options' __option_name__ = 'worklock_options'
def __init__(self, bidder_address: str): def __init__(self, bidder_address: str, signer_uri):
self.bidder_address = bidder_address self.bidder_address = bidder_address
self.signer_uri = signer_uri
def __create_bidder(self, registry, transacting: bool = False, hw_wallet: bool = False): def __create_bidder(self, registry, signer: Optional[Signer] = None, hw_wallet: bool = False):
client_password = None client_password = None
if transacting and not hw_wallet: if signer:
client_password = get_client_password(checksum_address=self.bidder_address) # and not hw_wallet: # TODO: ...mabye?
client_password = None
if signer.is_device(self.bidder_address):
client_password = get_client_password(checksum_address=self.bidder_address)
bidder = Bidder(checksum_address=self.bidder_address, bidder = Bidder(checksum_address=self.bidder_address,
registry=registry, registry=registry,
client_password=client_password, client_password=client_password,
is_transacting=transacting) signer=signer)
return bidder return bidder
def create_bidder(self, registry, hw_wallet: bool = False): def create_bidder(self, registry, hw_wallet: bool = False):
return self.__create_bidder(registry, transacting=True, hw_wallet=hw_wallet) signer = Signer.from_signer_uri(self.signer_uri) if self.signer_uri else None
return self.__create_bidder(registry=registry, signer=signer, hw_wallet=hw_wallet)
def create_transactionless_bidder(self, registry): def create_transactionless_bidder(self, registry):
return self.__create_bidder(registry, transacting=False) return self.__create_bidder(registry)
group_worklock_options = group_options( group_worklock_options = group_options(
WorkLockOptions, WorkLockOptions,
bidder_address=option_bidder_address bidder_address=option_bidder_address,
signer_uri=option_signer_uri
) )

View File

@ -190,3 +190,4 @@ option_middleware = wrap_option(
process_middleware, process_middleware,
mock_networking=click.option('-Z', '--mock-networking', help="Use in-memory transport instead of networking", count=True), mock_networking=click.option('-Z', '--mock-networking', help="Use in-memory transport instead of networking", count=True),
) )
option_signer_uri = click.option('--signer', 'signer_uri', '-S', default=None, type=str)