From b0e77b24cf52013ebf0a2dd8020df91dfc6f6e9a Mon Sep 17 00:00:00 2001 From: psofiterol Date: Wed, 20 Nov 2024 13:05:39 +0200 Subject: [PATCH] chore: update example and reqs for 0.7.0 --- .../client_code/secret_addition_complete.py | 182 +++++++----------- requirements.txt | 4 +- 2 files changed, 75 insertions(+), 111 deletions(-) diff --git a/quickstart_complete/client_code/secret_addition_complete.py b/quickstart_complete/client_code/secret_addition_complete.py index 2ca50740..972b110b 100644 --- a/quickstart_complete/client_code/secret_addition_complete.py +++ b/quickstart_complete/client_code/secret_addition_complete.py @@ -1,141 +1,107 @@ """ In this example, we: -1. connect to the local nillion-devnet -2. store the secret addition program -3. store a secret to be used in the computation -4. compute the secret addition program with the stored secret and another computation time secret +1. import packages we'll be using +2. connect to the local nillion-devnet +3. store the secret addition program +4. store a secret to be used in the computation +5. compute the secret addition program with the stored secret and another computation time secret +6. return the computation result """ import asyncio -import py_nillion_client as nillion import os -from py_nillion_client import NodeKey, UserKey +from nillion_client import ( + InputPartyBinding, + Network, + NilChainPayer, + NilChainPrivateKey, + OutputPartyBinding, + Permissions, + SecretInteger, + VmClient, + PrivateKey, +) from dotenv import load_dotenv -from nillion_python_helpers import get_quote_and_pay, create_nillion_client, create_payments_config - -from cosmpy.aerial.client import LedgerClient -from cosmpy.aerial.wallet import LocalWallet -from cosmpy.crypto.keypairs import PrivateKey home = os.getenv("HOME") load_dotenv(f"{home}/.config/nillion/nillion-devnet.env") async def main(): - # 1. Initial setup - # 1.1. Get cluster_id, grpc_endpoint, & chain_id from the .env file - cluster_id = os.getenv("NILLION_CLUSTER_ID") - grpc_endpoint = os.getenv("NILLION_NILCHAIN_GRPC") - chain_id = os.getenv("NILLION_NILCHAIN_CHAIN_ID") - # 1.2 pick a seed and generate user and node keys - seed = "my_seed" - userkey = UserKey.from_seed(seed) - nodekey = NodeKey.from_seed(seed) - - # 2. Initialize NillionClient against nillion-devnet - # Create Nillion Client for user - client = create_nillion_client(userkey, nodekey) - - party_id = client.party_id - user_id = client.user_id + # 2. Initial setup, Initialize NillionClient against nillion-devnet + # Use the devnet configuration generated by `nillion-devnet` + network = Network.from_config("devnet") + + # Create payments config and set up Nillion wallet with a private key to pay for operations + nilchain_key: str = os.getenv("NILLION_NILCHAIN_PRIVATE_KEY_0") # type: ignore + payer = NilChainPayer( + network, + wallet_private_key=NilChainPrivateKey(bytes.fromhex(nilchain_key)), + gas_limit=10000000, + ) - # 3. Pay for and store the program - # Set the program name and path to the compiled program + # Use a random key to identify ourselves + signing_key = PrivateKey() + client = await VmClient.create(signing_key, network, payer) + party_name = "Party1" program_name = "secret_addition_complete" program_mir_path = f"../nada_quickstart_programs/target/{program_name}.nada.bin" - # Create payments config, client and wallet - payments_config = create_payments_config(chain_id, grpc_endpoint) - payments_client = LedgerClient(payments_config) - payments_wallet = LocalWallet( - PrivateKey(bytes.fromhex(os.getenv("NILLION_NILCHAIN_PRIVATE_KEY_0"))), - prefix="nillion", - ) - # Pay to store the program and obtain a receipt of the payment - receipt_store_program = await get_quote_and_pay( - client, - nillion.Operation.store_program(program_mir_path), - payments_wallet, - payments_client, - cluster_id, - ) + # 3. Pay for and store the program + print("-----STORE PROGRAM") - # Store the program - action_id = await client.store_program( - cluster_id, program_name, program_mir_path, receipt_store_program - ) + # Store program + program_mir = open(program_mir_path, "rb").read() + program_id = await client.store_program(program_name, program_mir).invoke() - # Create a variable for the program_id, which is the {user_id}/{program_name}. We will need this later - program_id = f"{user_id}/{program_name}" - print("Stored program. action_id:", action_id) - print("Stored program_id:", program_id) + # Print details about stored program + print(f"Stored program_id: {program_id}") # 4. Create the 1st secret, add permissions, pay for and store it in the network - # Create a secret named "my_int1" with any value, ex: 500 - new_secret = nillion.NadaValues( - { - "my_int1": nillion.SecretInteger(500), - } - ) + print("-----STORE SECRETS") - # Set the input party for the secret - # The party name needs to match the party name that is storing "my_int1" in the program - party_name = "Party1" + # Create a secret + values = { + "my_int1": SecretInteger(500), + } - # Set permissions for the client to compute on the program - permissions = nillion.Permissions.default_for_user(client.user_id) - permissions.add_compute_permissions({client.user_id: {program_id}}) - - # Pay for and store the secret in the network and print the returned store_id - receipt_store = await get_quote_and_pay( - client, - nillion.Operation.store_values(new_secret, ttl_days=5), - payments_wallet, - payments_client, - cluster_id, - ) - # Store a secret - store_id = await client.store_values( - cluster_id, new_secret, permissions, receipt_store + # Create a permissions object to attach to the stored secret + permissions = Permissions.defaults_for_user(client.user_id).allow_compute( + client.user_id, program_id ) - print(f"Computing using program {program_id}") - print(f"Use secret store_id: {store_id}") + + # Store a secret, passing in the receipt that shows proof of payment + values_id = await client.store_values( + values, ttl_days=5, permissions=permissions + ).invoke() # 5. Create compute bindings to set input and output parties, add a computation time secret and pay for & run the computation - compute_bindings = nillion.ProgramBindings(program_id) - compute_bindings.add_input_party(party_name, party_id) - compute_bindings.add_output_party(party_name, party_id) - - # Add my_int2, the 2nd secret at computation time - computation_time_secrets = nillion.NadaValues({"my_int2": nillion.SecretInteger(10)}) - - # Pay for the compute - receipt_compute = await get_quote_and_pay( - client, - nillion.Operation.compute(program_id, computation_time_secrets), - payments_wallet, - payments_client, - cluster_id, - ) + print("-----COMPUTE") - # Compute on the secret - compute_id = await client.compute( - cluster_id, - compute_bindings, - [store_id], - computation_time_secrets, - receipt_compute, - ) + # Bind the parties in the computation to the client to set input and output parties + input_bindings = [InputPartyBinding(party_name, client.user_id)] + output_bindings = [OutputPartyBinding(party_name, [client.user_id])] - # 8. Return the computation result + # Create a computation time secret to use + compute_time_values = {"my_int2": SecretInteger(10)} + + # Compute, passing in the compute time values as well as the previously uploaded value. + print(f"Invoking computation using program {program_id} and values id {values_id}") + compute_id = await client.compute( + program_id, + input_bindings, + output_bindings, + values=compute_time_values, + value_ids=[values_id], + ).invoke() + + # 6. Return the computation result print(f"The computation was sent to the network. compute_id: {compute_id}") - while True: - compute_event = await client.next_compute_event() - if isinstance(compute_event, nillion.ComputeFinishedEvent): - print(f"✅ Compute complete for compute_id {compute_event.uuid}") - print(f"🖥️ The result is {compute_event.result.value}") - return compute_event.result.value + result = await client.retrieve_compute_results(compute_id).invoke() + print(f"✅ Compute complete for compute_id {compute_id}") + print(f"🖥️ The result is {result}") + return result if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index ae1f4379..fa7d01d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,3 @@ -py-nillion-client +nillion-client nada-dsl -nillion-python-helpers python-dotenv==1.0.0 -cosmpy>=0.9.2