During Ursula interactive configuration, don't show NU balance since is/will be no longer applicable to Threshold Network. Show MATIC balance instead of ETH.

pull/3262/head
derekpierre 2023-10-02 13:06:58 -04:00
parent fa4051d504
commit 8fcf422728
4 changed files with 49 additions and 64 deletions

View File

@ -6,21 +6,19 @@ import click
from tabulate import tabulate from tabulate import tabulate
from web3.main import Web3 from web3.main import Web3
from nucypher.blockchain.eth.agents import ContractAgency, NucypherTokenAgent
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.networks import NetworksInventory from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.registry import ( from nucypher.blockchain.eth.registry import (
ContractRegistry, ContractRegistry,
) )
from nucypher.blockchain.eth.signers.base import Signer from nucypher.blockchain.eth.signers.base import Signer
from nucypher.blockchain.eth.token import NU
from nucypher.cli.actions.configure import get_config_filepaths from nucypher.cli.actions.configure import get_config_filepaths
from nucypher.cli.literature import ( from nucypher.cli.literature import (
DEFAULT_TO_LONE_CONFIG_FILE, DEFAULT_TO_LONE_CONFIG_FILE,
GENERIC_SELECT_ACCOUNT, GENERIC_SELECT_ACCOUNT,
IGNORE_OLD_CONFIGURATION, IGNORE_OLD_CONFIGURATION,
NO_ACCOUNTS,
NO_CONFIGURATIONS_ON_DISK, NO_CONFIGURATIONS_ON_DISK,
NO_ETH_ACCOUNTS,
SELECT_NETWORK, SELECT_NETWORK,
SELECTED_ACCOUNT, SELECTED_ACCOUNT,
) )
@ -34,49 +32,50 @@ from nucypher.utilities.emitters import StdoutEmitter
def select_client_account( def select_client_account(
emitter, emitter,
eth_endpoint: str = None, polygon_endpoint: str = None,
signer: Signer = None, signer: Signer = None,
signer_uri: str = None, signer_uri: str = None,
prompt: str = None, prompt: str = None,
default: int = 0, default: int = 0,
registry: ContractRegistry = None, registry: ContractRegistry = None,
show_eth_balance: bool = False, show_matic_balance: bool = False,
show_nu_balance: bool = False,
show_staking: bool = False, show_staking: bool = False,
network: str = None, network: str = None,
poa: bool = None, poa: bool = None,
) -> str: ) -> str:
""" """
Interactively select an ethereum wallet account from a table of nucypher account metadata. Interactively select an ethereum wallet account from a table of account metadata.
Note: Showing ETH and/or NU balances, causes an eager blockchain connection. Note: Showing MATIC balance causes an eager blockchain connection.
""" """
if signer and signer_uri: if signer and signer_uri:
raise ValueError('Pass either signer or signer_uri but not both.') raise ValueError('Pass either signer or signer_uri but not both.')
if not any((eth_endpoint, signer_uri, signer)): if not any((polygon_endpoint, signer_uri, signer)):
raise ValueError("At least a provider URI, signer URI or signer must be provided to select an account") raise ValueError("At least a provider URI, signer URI or signer must be provided to select an account")
if eth_endpoint: if polygon_endpoint:
# Connect to the blockchain in order to select an account # Connect to the blockchain in order to select an account
if not BlockchainInterfaceFactory.is_interface_initialized( if not BlockchainInterfaceFactory.is_interface_initialized(
eth_provider_uri=eth_endpoint eth_provider_uri=polygon_endpoint
): ):
BlockchainInterfaceFactory.initialize_interface( BlockchainInterfaceFactory.initialize_interface(
eth_provider_uri=eth_endpoint, poa=poa, emitter=emitter eth_provider_uri=polygon_endpoint, poa=poa, emitter=emitter
) )
if not signer_uri: if not signer_uri:
signer_uri = eth_endpoint signer_uri = polygon_endpoint
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_endpoint) blockchain = BlockchainInterfaceFactory.get_interface(
eth_provider_uri=polygon_endpoint
)
if signer_uri and not signer: if signer_uri and not signer:
testnet = network != NetworksInventory.MAINNET.name testnet = network != NetworksInventory.MAINNET.name
signer = Signer.from_signer_uri(signer_uri, testnet=testnet) signer = Signer.from_signer_uri(signer_uri, testnet=testnet)
# Display accounts info # Display accounts info
if show_nu_balance or show_staking: # Lazy registry fetching if show_staking: # Lazy registry fetching
if not registry: if not registry:
if not network: if not network:
raise ValueError("Pass network name or registry; Got neither.") raise ValueError("Pass network name or registry; Got neither.")
@ -84,7 +83,7 @@ def select_client_account(
enumerated_accounts = dict(enumerate(signer.accounts)) enumerated_accounts = dict(enumerate(signer.accounts))
if len(enumerated_accounts) < 1: if len(enumerated_accounts) < 1:
emitter.echo(NO_ETH_ACCOUNTS, color='red', bold=True) emitter.echo(NO_ACCOUNTS, color="red", bold=True)
raise click.Abort() raise click.Abort()
elif len(enumerated_accounts) == 1: elif len(enumerated_accounts) == 1:
# There are no choices if there is only one available address. # There are no choices if there is only one available address.
@ -92,23 +91,17 @@ def select_client_account(
# Display account info # Display account info
headers = ['Account'] headers = ['Account']
if show_eth_balance: if show_matic_balance:
headers.append('ETH') headers.append("MATIC")
if show_nu_balance:
headers.append('NU')
rows = list() rows = list()
for index, account in enumerated_accounts.items(): for index, account in enumerated_accounts.items():
row = [account] row = [account]
if show_eth_balance: if show_matic_balance:
ether_balance = Web3.from_wei(blockchain.client.get_balance(account), 'ether') matic_balance = Web3.from_wei(
row.append(f'{ether_balance} ETH') blockchain.client.get_balance(account), "ether"
if show_nu_balance:
token_agent = ContractAgency.get_agent(
NucypherTokenAgent, registry=registry, provider_uri=eth_endpoint
) )
token_balance = NU.from_units(token_agent.get_balance(account, registry)) row.append(f"{matic_balance} MATIC")
row.append(token_balance)
rows.append(row) rows.append(row)
emitter.echo(tabulate(rows, headers=headers, showindex='always')) emitter.echo(tabulate(rows, headers=headers, showindex='always'))

View File

@ -170,7 +170,7 @@ class UrsulaConfigOptions:
self.operator_address = select_client_account( self.operator_address = select_client_account(
emitter=emitter, emitter=emitter,
prompt=prompt, prompt=prompt,
eth_endpoint=self.eth_endpoint, polygon_endpoint=self.polygon_endpoint,
signer_uri=self.signer_uri, signer_uri=self.signer_uri,
) )

View File

@ -53,7 +53,7 @@ INVALID_JSON_IN_CONFIGURATION_WARNING = "Invalid JSON in Configuration File at {
INVALID_CONFIGURATION_FILE_WARNING = "Invalid Configuration at {filepath}." INVALID_CONFIGURATION_FILE_WARNING = "Invalid Configuration at {filepath}."
NO_ETH_ACCOUNTS = "No ETH accounts were found." NO_ACCOUNTS = "No accounts were found."
GENERIC_SELECT_ACCOUNT = "Select index of account" GENERIC_SELECT_ACCOUNT = "Select index of account"

View File

@ -12,9 +12,8 @@ from nucypher.blockchain.eth.clients import EthereumClient
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.signers import KeystoreSigner from nucypher.blockchain.eth.signers import KeystoreSigner
from nucypher.blockchain.eth.signers.software import Web3Signer from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.blockchain.eth.token import NU
from nucypher.cli.actions.select import select_client_account from nucypher.cli.actions.select import select_client_account
from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ETH_ACCOUNTS from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ACCOUNTS
from nucypher.config.constants import TEMPORARY_DOMAIN from nucypher.config.constants import TEMPORARY_DOMAIN
from tests.constants import ( from tests.constants import (
MOCK_ETH_PROVIDER_URI, MOCK_ETH_PROVIDER_URI,
@ -33,7 +32,7 @@ def test_select_client_account(
selected_account = select_client_account( selected_account = select_client_account(
emitter=test_emitter, emitter=test_emitter,
signer=Web3Signer(testerchain.client), signer=Web3Signer(testerchain.client),
eth_endpoint=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
) )
assert selected_account, "Account selection returned Falsy instead of an address" assert selected_account, "Account selection returned Falsy instead of an address"
assert isinstance(selected_account, str), "Selection is not a str" assert isinstance(selected_account, str), "Selection is not a str"
@ -56,10 +55,10 @@ def test_select_client_account_with_no_accounts(
select_client_account( select_client_account(
emitter=test_emitter, emitter=test_emitter,
signer=Web3Signer(testerchain.client), signer=Web3Signer(testerchain.client),
eth_endpoint=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
) )
captured = capsys.readouterr() captured = capsys.readouterr()
assert NO_ETH_ACCOUNTS in captured.out assert NO_ACCOUNTS in captured.out
def test_select_client_account_ambiguous_source( def test_select_client_account_ambiguous_source(
@ -121,7 +120,7 @@ def test_select_client_account_valid_sources(
mock_stdin.line(str(selection)) mock_stdin.line(str(selection))
expected_account = testerchain.client.accounts[selection] expected_account = testerchain.client.accounts[selection]
selected_account = select_client_account( selected_account = select_client_account(
emitter=test_emitter, eth_endpoint=MOCK_ETH_PROVIDER_URI emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
) )
assert selected_account == expected_account assert selected_account == expected_account
assert mock_stdin.empty() assert mock_stdin.empty()
@ -138,7 +137,7 @@ def test_select_client_account_valid_sources(
BlockchainInterfaceFactory, "get_interface", return_value=testerchain BlockchainInterfaceFactory, "get_interface", return_value=testerchain
) )
selected_account = select_client_account( selected_account = select_client_account(
emitter=test_emitter, eth_endpoint=MOCK_ETH_PROVIDER_URI emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
) )
assert selected_account == expected_account assert selected_account == expected_account
assert mock_stdin.empty() assert mock_stdin.empty()
@ -146,15 +145,17 @@ def test_select_client_account_valid_sources(
assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out
@pytest.mark.skip('fix me') @pytest.mark.skip("fix me")
@pytest.mark.parametrize('selection,show_staking,show_eth,show_tokens,stake_info', ( @pytest.mark.parametrize(
(0, True, True, True, []), "selection,show_staking,show_matic,stake_info",
(1, True, True, True, []), (
(5, True, True, True, []), (0, True, True, []),
(NUMBER_OF_ETH_TEST_ACCOUNTS-1, True, True, True, []), (1, True, True, []),
(0, False, True, True, []), (5, True, True, []),
(0, False, False, True, []), (NUMBER_OF_ETH_TEST_ACCOUNTS - 1, True, True, []),
(0, False, False, False, []), (0, False, True, []),
(0, False, False, []),
(0, False, False, []),
), ),
) )
def test_select_client_account_with_balance_display( def test_select_client_account_with_balance_display(
@ -166,8 +167,7 @@ def test_select_client_account_with_balance_display(
mock_token_agent, mock_token_agent,
selection, selection,
show_staking, show_staking,
show_eth, show_matic,
show_tokens,
stake_info, stake_info,
): ):
@ -175,17 +175,16 @@ def test_select_client_account_with_balance_display(
mock_staking_agent.get_all_stakes.return_value = stake_info mock_staking_agent.get_all_stakes.return_value = stake_info
# Missing network kwarg with balance display active # Missing network kwarg with balance display active
blockchain_read_required = any((show_staking, show_eth, show_tokens)) blockchain_read_required = any((show_staking, show_matic))
if blockchain_read_required: if blockchain_read_required:
with pytest.raises( with pytest.raises(
ValueError, match="Pass network name or registry; Got neither." ValueError, match="Pass network name or registry; Got neither."
): ):
select_client_account( select_client_account(
emitter=test_emitter, emitter=test_emitter,
show_eth_balance=show_eth, show_matic_balance=show_matic,
show_nu_balance=show_tokens,
show_staking=show_staking, show_staking=show_staking,
eth_endpoint=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
) )
# Good selection # Good selection
@ -193,10 +192,9 @@ def test_select_client_account_with_balance_display(
selected_account = select_client_account( selected_account = select_client_account(
emitter=test_emitter, emitter=test_emitter,
network=TEMPORARY_DOMAIN, network=TEMPORARY_DOMAIN,
show_eth_balance=show_eth, show_matic_balance=show_matic,
show_nu_balance=show_tokens,
show_staking=show_staking, show_staking=show_staking,
eth_endpoint=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
) )
# check for accurate selection consistency with client index # check for accurate selection consistency with client index
@ -207,10 +205,8 @@ def test_select_client_account_with_balance_display(
headers = ['Account'] headers = ['Account']
if show_staking: if show_staking:
headers.append('Staking') headers.append('Staking')
if show_eth: if show_matic:
headers.append('ETH') headers.append("MATIC")
if show_tokens:
headers.append('NU')
captured = capsys.readouterr() captured = capsys.readouterr()
for column_name in headers: for column_name in headers:
@ -219,11 +215,7 @@ def test_select_client_account_with_balance_display(
for account in testerchain.client.accounts: for account in testerchain.client.accounts:
assert account in captured.out assert account in captured.out
if show_tokens: if show_matic:
balance = mock_token_agent.get_balance(address=account)
assert str(NU.from_units(balance)) in captured.out
if show_eth:
balance = testerchain.client.get_balance(account=account) balance = testerchain.client.get_balance(account=account)
assert str(Web3.from_wei(balance, 'ether')) in captured.out assert str(Web3.from_wei(balance, 'ether')) in captured.out