diff --git a/examples/heartbeat_demo/alicia.py b/examples/heartbeat_demo/alicia.py index 6d18dc433..cf8061d74 100644 --- a/examples/heartbeat_demo/alicia.py +++ b/examples/heartbeat_demo/alicia.py @@ -16,78 +16,84 @@ """ import base64 import datetime -import sys import json import os import shutil +from getpass import getpass from pathlib import Path import maya -from nucypher.characters.lawful import Bob, Ursula -from nucypher.config.characters import AliceConfiguration -from nucypher.config.constants import TEMPORARY_DOMAIN +from nucypher.blockchain.eth.signers import Signer +from nucypher.characters.lawful import Bob, Alice +from nucypher.policy.payment import SubscriptionManagerPayment +from nucypher.utilities.ethereum import connect_web3_provider from nucypher.utilities.logging import GlobalLoggerSettings - ###################### # Boring setup stuff # ###################### - -# Twisted Logger - +LOG_LEVEL = 'info' +GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL) GlobalLoggerSettings.start_console_logging() TEMP_ALICE_DIR = Path('/', 'tmp', 'heartbeat-demo-alice') - - -# if your ursulas are NOT running on your current host, -# run like this: python alicia.py 172.28.1.3:11500 -# otherwise the default will be fine. +POLICY_FILENAME = "policy-metadata.json" +shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) try: - SEEDNODE_URI = sys.argv[1] -except IndexError: - SEEDNODE_URI = "localhost:11500" -POLICY_FILENAME = "policy-metadata.json" + # Replace with ethereum RPC endpoint + L1_PROVIDER = os.environ['DEMO_L1_PROVIDER_URI'] + L2_PROVIDER = os.environ['DEMO_L2_PROVIDER_URI'] + + # Replace with wallet filepath. + WALLET_FILEPATH = os.environ['DEMO_L2_WALLET_FILEPATH'] + SIGNER_URI = f'keystore://{WALLET_FILEPATH}' + + # Replace with alice's ethereum address + ALICE_ADDRESS = os.environ['DEMO_ALICE_ADDRESS'] + +except KeyError: + raise RuntimeError('Missing environment variables to run demo.') + +L1_NETWORK = 'mainnet' # 'ibex' +L2_NETWORK = 'polygon' # 'mumbai' ####################################### # Alicia, the Authority of the Policy # ####################################### +connect_web3_provider(eth_provider_uri=L1_PROVIDER) # Connect to the ethereum provider. +connect_web3_provider(eth_provider_uri=L2_PROVIDER) # Connect to the layer 2 provider. -# We get a persistent Alice. -# If we had an existing Alicia in disk, let's get it from there -passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD" -# If anything fails, let's create Alicia from scratch -# Remove previous demo files and create new ones +# Setup and unlock alice's ethereum wallet. +# WARNING: Never give your mainnet password or mnemonic phrase to anyone. +# Do not use mainnet keys, create a dedicated software wallet to use for this demo. +wallet = Signer.from_signer_uri(SIGNER_URI) +password = os.environ.get('DEMO_ALICE_PASSWORD') or getpass(f"Enter password to unlock Alice's wallet ({ALICE_ADDRESS[:8]}): ") +wallet.unlock_account(account=ALICE_ADDRESS, password=password) -shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) - -ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, - federated_only=True, - minimum_stake=0) - -alice_config = AliceConfiguration( - config_root=TEMP_ALICE_DIR, - domain=TEMPORARY_DOMAIN, - known_nodes={ursula}, - start_learning_now=False, - federated_only=True, - learn_on_same_thread=True, +# This is Alice's payment method. +payment_method = SubscriptionManagerPayment( + network=L2_NETWORK, + eth_provider=L2_PROVIDER ) -alice_config.initialize(password=passphrase) +# This is Alicia. +alicia = Alice( + checksum_address=ALICE_ADDRESS, + signer=wallet, + domain=L1_NETWORK, + eth_provider_uri=L1_PROVIDER, + payment_method=payment_method +) -alice_config.keystore.unlock(password=passphrase) -alicia = alice_config.produce() - -# We will save Alicia's config to a file for later use -alice_config_file = alice_config.to_configuration_file() +# Alice puts her public key somewhere for Bob to find later... +alice_verifying_key = alicia.stamp.as_umbral_pubkey() # Let's get to learn about the NuCypher network alicia.start_learning_loop(now=True) diff --git a/examples/heartbeat_demo/doctor.py b/examples/heartbeat_demo/doctor.py index e7eb2cd3c..7b66066b8 100644 --- a/examples/heartbeat_demo/doctor.py +++ b/examples/heartbeat_demo/doctor.py @@ -14,46 +14,31 @@ You should have received a copy of the GNU Affero General Public License along with nucypher. If not, see . """ + + import base64 import json -from pathlib import Path +import shutil from timeit import default_timer as timer import maya import msgpack -import shutil -import sys - from nucypher_core import MessageKit, EncryptedTreasureMap from nucypher_core.umbral import PublicKey -from nucypher.characters.lawful import Bob, Enrico, Ursula -from nucypher.config.constants import TEMPORARY_DOMAIN +from nucypher.characters.lawful import Bob from nucypher.crypto.keypairs import DecryptingKeypair, SigningKeypair from nucypher.crypto.powers import DecryptingPower, SigningPower from nucypher.network.middleware import RestMiddleware from nucypher.utilities.logging import GlobalLoggerSettings -GlobalLoggerSettings.start_console_logging() - ###################### # Boring setup stuff # ###################### -try: - SEEDNODE_URI = sys.argv[1] -except IndexError: - SEEDNODE_URI = "localhost:11500" +GlobalLoggerSettings.start_console_logging() - -TEMP_DOCTOR_DIR = Path(__file__).parent.absolute() / "doctor-files" - -# Remove previous demo files and create new ones -shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True) - -ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, - federated_only=True, - minimum_stake=0) +L1_NETWORK = 'mainnet' # 'ibex' # To create a Bob, we need the doctor's private keys previously generated. from doctor_keys import get_doctor_privkeys @@ -69,13 +54,8 @@ power_ups = [enc_power, sig_power] print("Creating the Doctor ...") doctor = Bob( - domain=TEMPORARY_DOMAIN, - federated_only=True, + domain=L1_NETWORK, crypto_power_ups=power_ups, - start_learning_now=True, - abort_on_learning_error=True, - known_nodes=[ursula], - save_metadata=False, network_middleware=RestMiddleware(), ) diff --git a/examples/heartbeat_demo/heartbeat_demo.md b/examples/heartbeat_demo/heartbeat_demo.md index bde87ca22..ec24081c5 100644 --- a/examples/heartbeat_demo/heartbeat_demo.md +++ b/examples/heartbeat_demo/heartbeat_demo.md @@ -26,15 +26,31 @@ This simple use case showcases many interesting and distinctive aspects of NuCyp - The Doctor never interacts with Alicia or the Heart Monitor: he only needs the encrypted data and some policy metadata. -### How to run the demo +### Decentralized Network Demo + Ensure that you already have `nucypher` installed. -Run a fleet of federated Ursulas in a separate terminal: +First, configure the demo by making exporting environment variables +with your provider and wallet details for ethereum and polygon. -```sh -(nucypher)$ python ../run_demo_ursula_fleet.py +```bash +export DEMO_L1_PROVIDER_URI= +export DEMO_L2_PROVIDER_URI= +export DEMO_L2_WALLET_FILEPATH= +export DEMO_ALICE_ADDRESS= ``` -This will create a local network of federated Ursulas that will be used by the demo for re-encryption of data. + +Alternatively you can use the provided .env.template file by making a copy named .env +and adding your provider and wallet details. To set the variables in your current session run: +`export $(cat .env | xargs)` + +Optionally, you can change the network the demo is running on by changing the value of `L1_NETWORK` and `L2_NETWORK`. +If you change these values be sure to also change `L1_PROVIDER_URI` and `L2_PROVIDER_URI` accordingly. + +Available options for `L1_NETOWRK` are `ibex` or `mainnet`. +Available options for `L2_NETWORK` are `mumbai` or `mainnet` + +Ensure Alice's account has a bit of MATIC on polygon to pay for the policy. Subsequently, running the demo only involves running the `alicia.py` and `doctor.py` scripts. You should run `alicia.py` first: