Python Client Reference
Nillion Client Python module.
class py_nillion_client.Amount
ByteSize()
Returns the size of the message in bytes.
Clear()
Clears the message.
ClearExtension()
Clears a message field.
ClearField()
Clears a message field.
CopyFrom()
Copies a protocol message into the current message.
DESCRIPTOR *= *
DiscardUnknownFields()
Discards the unknown fields.
Extensions
Extension dict
FindInitializationErrors()
Finds unset required fields.
FromString()
Creates new method instance from given serialized data.
HasExtension()
Checks if a message field is set.
HasField()
Checks if a message field is set.
IsInitialized()
Checks if all required fields of a protocol message are set.
ListFields()
Lists all set fields of a message.
MergeFrom()
Merges a protocol message into the current message.
MergeFromString()
Merges a serialized message into the current message.
ParseFromString()
Parses a serialized message into the current message.
static RegisterExtension(field_descriptor)
SerializePartialToString()
Serializes the message to a string, even if it isn’t initialized.
SerializeToString()
Serializes the message to a string, only for initialized messages.
SetInParent()
Sets the has bit of the given field in its parent message.
UnknownFields()
Parse unknown field set
WhichOneof()
Returns the name of the field set inside a oneof, or None if no field is set.
class py_nillion_client.Array(value)
This is a Array
class used to
encode a secret array of elements.
Note: __len__ method is implemented to allow getting the length of the array.
- Parameters: value (list) – List of secret encoded elements.
- Returns:
Instance of the
Array
class. - Return type: Array
- Raises: ValueError – invalid secret type: Raises an error when a public encoded element is included inside a secret array.
Example
import py_nillion_client as nillion
secret_array = nillion.Array([
nillion.SecretInteger(1),
nillion.SecretInteger(2),
])
print("The length of the array is: ", len(secret_array))
>>> The length of the array is: 2
value
Getter method for the value inside a
Array
instance.
- Returns: List of secret encoded elements.
- Return type: list
Example
print("My secret array: \n", secret_array.value)
>>> My secret array:
>>> [, ]
exception py_nillion_client.AuthenticationError
Error related to authentication: invalid password, public key, or other internal errors
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.ClusterDescriptor
The ClusterDescriptor
contains attributes
that describe the cluster configuration. It includes information
about:
- Cluster id;
- Security parameters (statistical security and security threshold);
- Parties (nodes) in the cluster;
- Preprocessing configuration.
This object is returned when invoking NillionClient
cluster_information method.
Example
cinfo = await client.cluster_information(args.cluster_id)
id
The Cluster identifier.
- Return type: A string containing the Nillion Cluster identifier.
Example
cinfo = await client.cluster_information(args.cluster_id)
print("Cluster id:", cinfo.id)
>>> Cluster id: 147f8d45-2126-4a54-9a64-8141ee55f51a
kappa
The statistical security parameter kappa for this cluster.
- Return type: The value of the statistical security parameter kappa used in this cluster.
Example
cinfo = await client.cluster_information(args.cluster_id)
print("Statistical sec parameter kappa:", cinfo.kappa)
>>> Statistical sec parameter kappa: 40
parties
Cluster’s parties ids.
- Return type: A list of strings containing the party identifiers in the cluster.
Example
cinfo = await client.cluster_information(args.cluster_id)
print("Cluster parties' ids:", cinfo.parties)
>>> Parties: {'12D3KooWJtRXjmV1HctQgvLUcrdxJ7cXwCHiL6PCheikN2rTJ2ZH',
'12D3KooWHSveXS4DdXpCQyDDsp9D1x7fiTRnm1fsH9yJRpR6y4FM',
'12D3KooWLV6HzUXpt6Tt5HUM5Fo3mpjvwsv9n4ADkJ962ArAZCvX'}
polynomial_degree
The polynomial degree used by this cluster. The polynomial degree is directly related with the security threshold of the Nillion network.
- Returns:
- An integer corresponding to the degree of the polynomial used
- in the cluster for linear secret sharing.
Example
cinfo = await client.cluster_information(args.cluster_id)
print("Polynomial degree:", cinfo.polynomial_degree)
>>> Polynomial degree: 1
prime
The prime number used in this cluster.
- Return type: The identifier of the prime used in the cluster.
Example
cinfo = await client.cluster_information(args.cluster_id)
print("Prime type:", cinfo.prime)
>>> Prime: U256SafePrime
exception py_nillion_client.ComputeError
Error related to the computation: initialization, scheduling, or other internal errors
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.ComputeFinishedEvent
The ComputeFinishedEvent
class is
returned by an async computation when the computation
has just finished.
This class has no public constructor and is received from
method NillionClient.next_compute_event()
.
result
The computation’s result, as a FinalResult
class.
Use the FinalResult.value()
method to
obtain the wrapped value.
- Returns:
The
FinalResult
class containing the final result of the computation. Use theFinalResult.value()
method to obtain the wrapped value. - Return type: FinalResult
Example
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.compute_secrets,
args.compute_public_variables,
payment_receipt
)
while True:
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
pass
if isinstance(event, nillion.ComputeFinishedEvent) and event.uuid == uuid:
print(
f"Received computation result for {event.uuid}, result = {event.result}"
)
print(
f"Received computation result value for {event.uuid}, value = {event.result.value}"
)
break
uuid
The computation’s UUID.
- Returns: Uuid
- Return type: str
Example
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.compute_secrets,
args.compute_public_variables,
payment_receipt
)
while True:
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
pass
if isinstance(event, nillion.ComputeFinishedEvent) and event.uuid == uuid:
print(
f"Result for computation with UUID {event.uuid} is ready!"
)
break
class py_nillion_client.ComputeScheduledEvent
The ComputeScheduledEvent
class is
returned by an async computation when the computation is not finished yet.
This class has no public constructor and is received from
method NillionClient.next_compute_event()
.
uuid
The computation’s UUID. This outputs the same UUID
provided by the NillionClient.compute()
method.
- Returns: Computation UUID.
- Return type: str
Example
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.compute_secrets,
args.compute_public_variables,
payment_receipt
)
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
computation_uuid = event.uuid
class py_nillion_client.ConnectionMode
This is a ConnectionMode
class. It designates the
connection mode to use in a client constructor. We support three
different modes:
- Dialer (
dialer()
); - Direct (
direct()
); - Relay (
relay()
).
dialer()
Specifies the client should connect in dialer mode.
In this mode the client only allows outgoing connections, so no need to listen or open a port. This mode prohibits this client from recieving results, as an output party, from the network.
- Return type: ConnectionMode
Example
connection_mode = ConnectionMode.dialer()
direct()
Specifies a socket address structure for a listening client connection.
This mode is suited for clients that are backend services.
You allow incoming and outgoing connections, they are done directly so you have to listen and have the port open to receive incoming connections. This option is faster than relay as it avoids the extra hop, but requires to have the port open / have port forwarding in NATs and firewalls. This mode requires that the client’s IPv4 address is addressible on the internet.
- Parameters: str – Socket address structure.
- Return type: ConnectionMode
Example
connection_mode = ConnectionMode.direct('0.0.0.0:11337')
relay()
Specifies the client connects to the Nillion Network in relay mode. So, if others want to contact the client, they have to do so through a relay node that the client is connected to (all nodes in the network are relay nodes).
This mode is suited for clients that cannot open a port like phones behind a CGNAT, desktop apps behind a NAT or Firewall, and others.
You allow incoming and outgoing connection but the incoming are established via a node in the network (the relayer) so that you don’t need to listen and open a port. This is slower than direct because it adds another hop in the connection but allows to bypass NATs and Firewalls. Also this option adds more load to the p2p network of the nodes becasue they have to do the relay increasing the incoming and outgoing traffic
- processing of secure connections.
- Return type: ConnectionMode
Example
connection_mode = ConnectionMode.relay()
exception py_nillion_client.DealerError
Error related to the dealer: initialization, scheduling, unexpected errors
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.FinalResult
This is a FinalResult
class that is returned
from a finished computation.
This class has no public constructor and is received from
method ComputeFinishedEvent.result()
.
value
The resulting value of a computation.
- Returns: Result value from a computation.
- Return type: Dict
Example
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.compute_secrets,
args.compute_public_variables,
payment_receipt
)
while True:
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
pass
if isinstance(event, nillion.ComputeFinishedEvent) and event.uuid == uuid:
print(
f"Received computation result value for {event.uuid}, value = {event.result.value}"
)
break
class py_nillion_client.Integer(value)
This is a Integer
class used to
encode a public variable value as an integer.
Note: __eq__ method is implemented to allow to compare two integers.
- Parameters: value (int) – Value of the public encoded element.
- Returns:
Instance of the
Integer
class. - Return type: Integer
Example
import py_nillion_client as nillion
pub_integer_1 = nillion.Integer(1)
pub_integer_2 = nillion.Integer(2)
print("Are the public integers the same? ", pub_integer_1 == pub_integer_2)
>>> Are the public integers the same? False
value
Getter and setter for the value inside a
Integer
instance.
- Returns: The value of the public integer.
- Return type: int
Example
pub_integer = nillion.Integer(1)
print("Public integer is: ", pub_integer.value)
pub_integer.value = 2
print("Public integer is now: ", pub_integer.value)
>>> Public integer is: 1
>>> Public integer is now: 2
class py_nillion_client.MsgPayFor
ByteSize()
Returns the size of the message in bytes.
Clear()
Clears the message.
ClearExtension()
Clears a message field.
ClearField()
Clears a message field.
CopyFrom()
Copies a protocol message into the current message.
DESCRIPTOR *= *
DiscardUnknownFields()
Discards the unknown fields.
Extensions
Extension dict
FindInitializationErrors()
Finds unset required fields.
FromString()
Creates new method instance from given serialized data.
HasExtension()
Checks if a message field is set.
HasField()
Checks if a message field is set.
IsInitialized()
Checks if all required fields of a protocol message are set.
ListFields()
Lists all set fields of a message.
MergeFrom()
Merges a protocol message into the current message.
MergeFromString()
Merges a serialized message into the current message.
ParseFromString()
Parses a serialized message into the current message.
static RegisterExtension(field_descriptor)
SerializePartialToString()
Serializes the message to a string, even if it isn’t initialized.
SerializeToString()
Serializes the message to a string, only for initialized messages.
SetInParent()
Sets the has bit of the given field in its parent message.
UnknownFields()
Parse unknown field set
WhichOneof()
Returns the name of the field set inside a oneof, or None if no field is set.
class py_nillion_client.NadaValues(values)
This is a NadaValues
class used to
hold secrets and public values. It can contain:
- Secret integers (
SecretInteger
); - Secret unsigned integers (
SecretUnsignedInteger
); - Arrays (
Array
). - Public integers (
PublicInteger
) - Public unsigned integers (
PublicUnsignedInteger
)
This class is used by the NillionClient.compute()
method to pass the
secrets used by the corresponding Nada program that are not stored.
- Parameters: values (dict) – A map of named encoded secret and public values to store
- Returns:
Instance of the
NadaValues
class. - Return type: NadaValues
- Raises: ValueError – invalid public variable type: Raises an error when a public variabel element is included inside the secrets dictionary.
Example
import py_nillion_client as nillion
sec_uinteger = nillion.SecretUnsignedInteger(1)
sec_integer = nillion.SecretInteger(1)
sec_array = nillion.SecretArray([
nillion.SecretInteger(1),
nillion.SecretInteger(2),
])
secrets = nillion.NadaValues({
"sec_uinteger": sec_uinteger,
"sec_integer": sec_integer,
"sec_array": sec_array
})
dict()
Returns the stored values as a dictionary.
- Returns: Native python dictionary with mapped encoded values
- Return type: dict
Example
values = nillion.NadaValues({
"sec_uinteger": sec_uinteger,
"sec_integer": sec_integer,
"sec_array": sec_array
})
print("Values:\n", values.dict())
>>> Values:
>>> {'sec_array': , 'sec_uinteger': , 'sec_integer': }
class py_nillion_client.NillionClient(node_key, bootnodes, connection_mode, user_key, whitelist=None)
The NillionClient
class serves as
the primary tool for connecting to the Nillion
network and facilitating various operations.
It allows users to interact with the Nillion
network efficiently, including for the following actions:
- Store Nada programs (
store_program()
); - Store values (
store_values()
); - Update values (
update_values()
); - Retrieve values (
retrieve_value()
); - Delete values (
delete_values()
); - Compute a Nada program over some secrets (
compute()
); - Receive compute results (
next_compute_event()
).
An instance of NillionClient
can embody either
a dealer node, responsible for providing inputs, or a result
node, tasked with receiving computation outputs. Under the hood,
this spawns a set of actors and acts as a node in the network that
has both dealer and result node capabilities.
Note: multiple instances can be employed concurrently if required;
however, it is imperative that each instance possesses
a distinct NodeKey
when utilized within the
same interpreter.
- Parameters:
- node_key (NodeKey) – A private key to use for the Client node.
- bootnodes (list of str) – A list of nodes belonging to the network (other may be discovered later).
- connection_mode (ConnectionMode) – How to connect to the network, either directly (indicating a listen address), through a relay server or as a dialer client.
- user_key (UserKey) – User credentials to use.
- whitelist (list of str , optional) – A list of peer ids to connecto to/from.
- Returns: Instance of the NillionClient and an event receiver channel used to retrieve computation results.
- Return type: NillionClient
Example
For further information about the structure of the objects used by the constructor, we refer to the quickstart guide .
import py_nillion_client as nillion
node_key = nillion.NodeKey.from_file("/path/to/node/key")
bootnodes = [os.getenv("NILLION_BOOTNODE_MULTIADDRESS")]
# e.g. bootnodes = ["/ip4/127.0.0.1/tcp/45305/p2p/11E4UiiRgsJILZYeushYEOQyMCrJLeRTaonNxBMBq4oF6bJ6MfoF"]
connection_mode = nillion.ConnectionMode.dialer()
user_key = nillion.UserKey.from_file("/path/to/user/key")
client = nillion.NillionClient(
node_key,
bootnodes,
nillion.ConnectionMode.relay(),
user_key,
)
build_version = 'client/0.1.0 (commit: 2454586480c93ea9664ddc563cac902e0bb03278; ts: 1720014719; date: 2024-07-03T13:51:59+00:00)'
cluster_information(cluster_id)
Get information about a cluster by returning an instance of the ClusterDescriptor
class.
We can access various information about the cluster through its methods.
- Parameters: cluster_id (str) – UUID of the targeted preprocessing cluster.
- Return type:
An instance of
ClusterDescriptor
populated with the cluster information.
Example
await client.cluster_information(cluster_id)
compute(cluster_id, bindings, store_ids, values, receipt)
Requests a compute action in the Nillion Network for a specific Nada program under a set of secrets.
Note: This method does not directly output the result of the Nada program. Instead, it returns a computation UUID. To obtain the result, you’ll need to fetch it separately. The UUID, in conjunction with the event provided by the corresponding NillionClient instance channel, allows you to retrieve the computation results. Please refer to the e xample below for clarification.
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- bindings (ProgramBindings) – The prepared program specification and secret bindings
- secrets (Secrets) – Additional secrets to use for the computation
- store_ids (list of str) – List of the store IDs (uuids) of the secrets to use for the computation
- public_variables (PublicVariables) – Public variables to use for the computation
- receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: A computation UUID.
- Return type: str
Example
import py_nillion_client as nillion
store_payment_receipt = ... # quote + pay
compute_payment_receipt = ... # quote + pay
bindings = nillion.ProgramBindings(args.program_id)
bindings.add_input_party("Dealer", client.party_id)
store_id = await client.store_values(
args.cluster_id, bindings, args.store_values, None, store_payment_receipt
)
bindings = nillion.ProgramBindings(args.program_id)
bindings.add_input_party("Dealer", client.party_id)
bindings.add_output_party("Result", client.party_id)
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.values,
compute_payment_receipt
)
while True:
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
pass
if isinstance(event, nillion.ComputeFinishedEvent) and event.uuid == uuid:
print(
f"Received computation result for {event.uuid}, result = {event.result}"
)
print(
f"Received computation result value for {event.uuid}, value = {event.result.value}"
)
break
delete_values(cluster_id, store_id)
Delete existing values.
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- store_id (str) – The identifier of the stored secret to be deleted (returned when calling
store_values()
)
- Return type: None
Example
await client.delete_values(cluster_id, store_id)
next_compute_event()
Returns the state of the computation in the Nillion Network.
If the event is from an ongoing computation, it only includes
the corresponding UUID from the compute()
process.
Once the computation is complete, the event includes both the
UUID and the computation result (FinalResult
).
- Returns: Either event type will pull the next compute event from the internal result channel which can be inspected to determine if compute operation has completed
- Return type: ComputeScheduledEvent | ComputeFinishedEvent
Example
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
args.compute_secrets,
args.compute_public_variables,
payment_receipt
)
while True:
event = await client.next_compute_event()
if isinstance(event, nillion.ComputeScheduledEvent):
print(
f"Waiting for computation with UUID={event.uuid} to finish."
)
if isinstance(event, nillion.ComputeFinishedEvent) and event.uuid == uuid:
print(
f"Received computation result for {event.uuid}, result = {event.result}"
)
print(
f"Received computation result value for {event.uuid}, value = {event.result.value}"
)
break
party_id
Returns the SDK client’s instance party ID, which can be used
by the client to create program bindings (ProgramBindings
,
check examples).
Effectively, the party ID is equivalent to the Peer ID
used within libp2p for inter-node communication. It is a hash
generated from the public key of the node’s key-pair (NodeKey
). Not to
be confused with the user_id()
which is generated from the
public key of the user’s key-pair (UserKey
).
Read more about party ID and peer ID.
- Returns: UUID of libp2p party identifier.
- Return type: str
Example
print("Party ID:", client.party_id)
request_price_quote(cluster_id, operation)
Request a price quote for an operation. This method asks the network to calculate a price quote for the specified operation. Payment and submission of the operation is the client’s responsibility and must be done before the quote expires.
Note that the nodes of your target Nillion petnet cluster will be bound to a single payment network (eg. testnet).
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- operation (Operation) – The operation to get a price quote for.
- Returns: The price quoted for this operation.
- Return type: PriceQuote
Example
secrets = py_nillion_client.Secrets(
{
"foo": py_nillion_client.SecretInteger(42),
"bar": py_nillion_client.SecretBlob(bytearray(b"hello world")),
}
)
operation = py_nillion_client.Operation.store_values(secrets)
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
store_id = await client.store_values(
cluster_id, secrets, None, payment_receipt
)
updated_secrets = nillion.Secrets({"foo": nillion.SecretInteger(42)})
operation = py_nillion_client.Operation.update_values(updated_secrets)
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
await client.update_values(
args.cluster_id, store_id, update_values, payment_receipt
)
# compute quote is based on compute time secrets; stored secrets have already
# been paid
secrets = nillion.Secrets({"fortytwo": nillion.SecretInteger(42)})
quote = py_nillion_client.Operation.compute(program_id, secrets)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
uuid = await client.compute(
args.cluster_id,
bindings,
[store_id],
secrets,
py_nillion_client.PublicVariables({}),
compute_payment_receipt
)
value_name = "fortytwo"
operation = py_nillion_client.Operation.retrieve_value()
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
result = await client.retrieve_value(cluster_id, args.store_id, value_name, payment_receipt)
program_name = "myprogram"
program_mir_path = f"./your/compiled/programs/{program_name}.nada.bin"
operation = py_nillion_client.Operation.store_program(program_mir_path)
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
program_id = await client.store_program(
args.cluster_id, program_name, program_mir_path, payment_receipt
)
operation = py_nillion_client.Operation.retrieve_permissions()
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
permissions = await client.retrieve_permissions(cluster_id, store_id, payment_receipt)
operation = py_nillion_client.Operation.update_permissions()
quote = await client.request_price_quote(cluster_id, operation)
# this is where you activate your payment method
txn_hash = yourapp.your_payment_method_in_unil(quote.cost)
payment_receipt = nillion.PaymentReceipt(quote, txn_hash)
permissions = nillion.Permissions.default_for_user(client.user_id())
permissions.add_retrieve_permissions(set([args.retriever_user_id]))
updated_store_id = await client.update_permissions(args.cluster_id, store_id, permissions, payment_receipt)
retrieve_permissions(cluster_id, store_id, receipt)
Retrieve permissions for a group of secrets in the Nillion Network
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- store_id (str) – The secrets’ store ID (returned when calling
store_values()
) - receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: The permissions
- Return type: Permissions
Example
permissions = await client.retrieve_permissions(cluster_id, store_id, payment_receipt)
retrieve_value(cluster_id, store_id, value_id, receipt)
Retrieve a value stored in the Nillion Network.
To retrieve the value, you need to use the value attribute on the second element of the output tuple. Check the example below to read the value of a secret integer.
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster.
- store_id (str) – The value’s store ID (returned when calling
store_values()
). - value_id (str) – The value’s ID.
- receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: The value ID as a UUID as well as the value itself.
- Return type: tuple
Example
value_name = "fortytwo"
result = await client.retrieve_value(cluster_id, args.store_id, value_name, payment_receipt)
print("Value ID: ", result[0])
print("Value: ", result[1])
>>> Value ID: 2424a65c-d20c-4635-b864-06c064188dd4
>>> Value: 42
store_program(cluster_id, program_name, program_mir_path, receipt)
Store programs in the Nillion Network.
The program_id used by store_values()
and compute()
can be
built as follows:
client.user_id + "/" + program_name
where client is a NillionClient
instantiation and program_name
is the name of the program.
- Parameters:
- cluster. ( * cluster_id - UUID of the targeted preprocessing) –
- store. ( * program_name - Name of the program to) –
- stored. ( * program_mir_path - Path to the MIR program being) –
- made. ( * receipt - The receipt for the payment) –
- Returns: The program identifier associated with the program
- Return type: str
Example
program_name = "prog"
program_mir_path = "programs-compiled/prog.nada.bin"
# Store program in the Network
print(f"Storing program in the network: {program_name}")
program_id = await client.store_program(
args.cluster_id, program_name, program_mir_path, payment_receipt
)
print("program_id is: ", program_id)
store_values(cluster_id, values, permissions, receipt)
Store values in the Nillion Network.
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- secrets (Secrets) – The secrets to store; this is a hash map indexed by secret IDs
- permissions (Permissions , optional) – permissions to be set. By default the user has update and retrieve permissions on the secret as well as compute permissions for the program bound, should there be a program bound.
- receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: A store identifier that can be used to retrieve the secret.
- Return type: str
- Raises: TypeError – When using bindings, the input party name provided (e.g. “InputPartyName”) must match the input party name in the Nada program. Otherwise, we get a TypeError.
Example
Here are some examples of how to use this function. Note that to give permissions we use the User ID and to bind a secret to a program we use the Party ID.
###########################
# Example 1 - Simple #
###########################
# Notice that both bindings and permissions are set to None.
# Bindings need to be set to use secrets in programs
# Permissions need to be set to allow users other than the secret creator to use the secret
secrets = nillion.Secrets({"fortytwo": nillion.SecretInteger(42)})
store_id = await client.store_values(
cluster_id, secrets, None, payment_receipt
)
###########################
# Example 2 - Permissions #
###########################
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_retrieve_permissions(set([args.retriever_user_id]))
values = nillion.NadaValues({"fortytwo": nillion.SecretInteger(42)})
store_id = await client.store_values(
cluster_id, secrets, permissions, payment_receipt
)
update_permissions(cluster_id, store_id, permissions, receipt)
Update permissions for a group of secrets in the Nillion Network
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster
- store_id (str) – The secrets’ store ID (returned when calling
store_values()
) - permissions (Permissions , optional) – permissions to be set.
- receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: The unique identifier of this update operation ID that can be used to help troubleshoot issues with this operation.
- Return type: str
Example
# Store
store_payment_receipt = ... # quote + pay for action
secrets = nillion.Secrets({"fortytwo": nillion.SecretInteger(42)})
store_id = await client.store_values(
cluster_id, None, secrets, None, store_payment_receipt
)
update_payment_receipt = ... # quote + pay for action
# Update permissions
permissions = nillion.Permissions.default_for_user(client.user_id())
permissions.add_retrieve_permissions(set([args.retriever_user_id]))
updated_store_id = await client.update_permissions(args.cluster_id, store_id, permissions, update_payment_receipt)
print("Stored secret id: ", store_id)
print("Updated stored secret id: ", updated_store_id)
>>> Stored secret id: 3c504263-fd3f-40b8-8a1d-9056b7846637
>>> Updated stored secret id: ccdb8036-2635-40d9-9144-2cc89551fce9
update_values(cluster_id, store_id, values, receipt)
Update values already stored in the Nillion Network.
- Parameters:
- cluster_id (str) – UUID of the targeted preprocessing cluster.
- store_id (str) – The secret’s store ID (returned when calling
store_values()
). - values (Secrets) – The values to update; this is a hash map indexed by secret IDs.
- receipt (PaymentReceipt) – The receipt for the payment made.
- Returns: The unique identifier of this update operation.
- Return type: str
Example
updated_secrets = nillion.Secrets({"fortytwo": nillion.SecretInteger(42)})
payment_receipt = ... # quote + pay
await client.update_values(
args.cluster_id, store_id, update_values, payment_receipt
)
user_id
Returns SDK client’s user ID, which is the public user identifier.
The user ID is used to:
- Generate a program ID (identification of a program in the Nillion Network). Check example in
store_program()
; - Grant a user permission to use secrets. Check
Permissions
.
It is a hash generated from the public key of the user’s key-pair (UserKey
). Not to
be confused with the party_id()
which is the generated from the
public key of the node’s key-pair (NodeKey
).
Read more about user ID in the Nillion Docs.
- Returns: Client’s user identifier.
- Return type: str
Example
print("Party ID:", client.user_id)
class py_nillion_client.NodeKey
This is a NodeKey
class that
contains a private key used by the
underlying libp2p to form multiaddress and
identity secrets. This class is consumed by NillionClient
class to initialize a client.
This object’s constructors can be used via the following class methods:
- From string encoded in Base58 (
from_base58()
); - From a file (
from_file()
); - From a seed (
from_seed()
).
Example
from py_nillion_client import NodeKey
node_key = NodeKey.from_seed('my_seed')
from_base58()
Decodes a private key from a string encoded in Base58.
- Parameters: contents (str) – A base58 string.
- Return type: NodeKey
Example
from py_nillion_client import NodeKey
node_key = NodeKey.from_base58()
from_file()
Loads a file containing a private key.
- Parameters: path (str) – The filesystem path to the file containing a base58 string.
- Return type: NodeKey
Example
from py_nillion_client import NodeKey
node_key = NodeKey.from_file('/path/to/nodekey.base58')
from_seed()
Generates a private key using a seed.
- Parameters: path (str) – A seed string.
- Return type: NodeKey
Example
from py_nillion_client import NodeKey
node_key = NodeKey.from_seed('my_seed')
class py_nillion_client.Operation
An operation that we want to run on the network.
compute(values)
Construct a new update values operation.
- Parameters:
- program_id (str) – The identifier of the program to be invoked.
- values (NadaValues) – The values to be stored.
- Return type: Operation
retrieve_permissions()
Construct a new retrieve permissions operation.
- Return type: Operation
retrieve_value()
Construct a new retrieve value operation.
- Return type: Operation
store_program()
Construct a new store program operation.
- Return type: Operation
store_values(ttl_days)
Construct a new store values operation.
- Parameters:
- values (Secrets) – The values to be stored.
- ttl_days (int) – The time to live for the values in days
- Return type: Operation
update_permissions()
Construct a new update permissions operation.
- Return type: Operation
update_values(ttl_days)
Construct a new update values operation.
- Parameters:
- values (NadaValues) – The values to be stored.
- ttl_days (int) – The time to live for the values in days.
- Return type: Operation
exception py_nillion_client.PaymentError
Payment-related errors: missing funds or other errors
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.PaymentReceipt(quote, transaction_hash)
A payment receipt.
Payment receipt are used to indicate that you made the payment for a price quote.
exception py_nillion_client.PermissionError
Missing permission errors
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.Permissions
This is a Permissions
class used to
manage permissions of stored secrets and compute.
Permissions need to be set to allow users other
than the secret creator to use the secret. This
class is used either by NillionClient.store_values()
or by NillionClient.update_permissions()
.
The default instantiation of this class is given by
the method default_for_user()
.
Example
See examples
on method request_price_quote()
.
add_compute_permissions(compute)
Add compute permissions to the Permissions
instance for the
user IDs provided.
- Parameters: compute (dict of set of str) – Dict keyed by the user_id of the targets where the value is a set of str specifying which program IDs to permit compute for.
Example
import py_nillion_client as nillion
program_id = client.user_id() + "/" + "program_name"
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_compute_permissions({
args.compute_user_id: {program_id},
})
add_delete_permissions(delete)
Add delete permissions to the Permissions
instance for the
given set of user IDs
- Parameters:
delete (set of str) – Desired targets to permit delete
Secrets
.
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_delete_permissions(set([args.delete_user_id]))
add_retrieve_permissions(retrieve)
Add retrieve permissions to the Permissions
instance for the
given set of user IDs.
- Parameters:
retrieve (set of str) – Desired targets to permit read of stored programs or retrieve
Secrets
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_retrieve_permissions(set([args.retriever_user_id]))
add_update_permissions(update)
Add update permissions to the Permissions
instance for the
given set of user IDs.
- Parameters:
update (set of str) – Desired targets to permit update
Secrets
.
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_update_permissions(set([args.update_user_id]))
static default_for_user(user_id)
Returns the default permission set for the given user ID.
Note: this method can be used to clear/revoke permissions previously granted by the user.
- Parameters: user_id (str) – Desired target user ID.
- Return type: Permissions
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
is_compute_allowed(user_id, program)
Returns true if user has compute permissions for every single program.
- Return type: bool
Example
program_id = client.user_id() + "/" + "program_name"
compute_allowed = permissions.is_compute_allowed(user_client.user_id(), program_id)
is_delete_allowed(user_id)
Returns true if user has delete permissions.
- Return type: bool
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
delete_allowed = permissions.is_delete_allowed(user_client.user_id)
print("Default user is always allowed: ", delete_allowed)
>>> Default user is always allowed: True
is_retrieve_allowed(user_id)
Returns true if user has retrieve permissions.
- Return type: bool
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
retrieve_allowed = permissions.is_retrieve_allowed(user_client.user_id)
print("Default user is always allowed: ", retrieve_allowed)
>>> Default user is always allowed: True
is_retrieve_permissions_allowed(user_id)
Checks if user is allowed to retrieve the permissions.
- Return type: bool
Example
retrieve_permissions_allowed = permissions.is_retrieve_permissions_allowed(user_client.user_id())
is_update_allowed(user_id)
Returns true if user has update permissions.
- Return type: bool
Example
import py_nillion_client as nillion
permissions = nillion.Permissions.default_for_user(client.user_id)
update_allowed = permissions.is_update_allowed(user_client.user_id)
print("Default user is always allowed: ", update_allowed)
>>> Default user is always allowed: True
is_update_permissions_allowed(user_id)
Checks if user is allowed to update the permissions.
- Return type: bool
Example
update_permissions_allowed = permissions.is_update_permissions_allowed(user_client.user_id())
class py_nillion_client.PriceQuote
A price quote for an operation to be run in the network.
Quotes can be requested by using NillionClient.request_price_quote()
.
cost
Gets the cost for the quoted operation in unil units. The payment associated for the quoted operation must transfer the total amount for it to be considered a valid payment.
- Returns: The cost for this quote.
- Return type: OperationCost
Example
print("Total Cost:", quote.cost.total)
expires_at
Gets the expiration time for this quote in seconds since the unix epoch. The payment and the operation execution must be invoked before this deadline is hit, otherwise the network will reject the operation request.
- Returns: The expiration time for this quote.
- Return type: int
Example
print("Expiration time:", quote.expires_at)
nonce
Gets the nonce for this quote. This nonce must be used as part of the payment transaction.
- Return type: bytearray
Example
print("Nonce:", quote.nonce)
class py_nillion_client.ProgramBindings(program_id)
This is a ProgramBindings
class used to
bind compute parties to explicit peer IDs (provided
by the NillionClient.party_id()
). Bindings
need to be set to use secrets in programs
This class is used by the NillionClient.store_values()
and NillionClient.compute()
methods.
- Parameters: program_id (str) – The identifier of the program to bind to.
- Returns:
An instance of
ProgramBindings
. - Return type: ProgramBindings
Example
import py_nillion_client as nillion
# program_id looks like: "/"
bindings = nillion.ProgramBindings(args.program_id)
# Add bindings when storing a secret
bindings.add_input_party("InputPartyName", client.party_id)
secrets = nillion.Secrets({"fortytwo": nillion.SecretInteger(42)})
store_id = await client.store_values(
cluster_id, bindings, secrets, None
)
# Add bindings for compute action
bindings = nillion.ProgramBindings(args.program_id)
bindings.add_input_party("InputPartyName" client.party_id)
bindings.add_output_party("OutputPartyName", client.party_id)
add_input_party(name, id)
Bind an input party with a name to a specific program.
- Parameters:
- name (str) – The logical name of the input party in the Nada program.
- id (str) – The party identifier.
Example
bindings = nillion.ProgramBindings(args.program_id)
bindings.add_input_party("InputPartyName" client.party_id)
add_output_party(name, id)
Bind an output party with a name to a specific program.
- Parameters:
- name (str) – The name of the output party in the Nada program.
- id (str) – The party identifier.
Example
bindings = nillion.ProgramBindings(args.program_id)
bindings.add_output_party("OutputPartyName", client.party_id)
exception py_nillion_client.ProgramError
Program not found or invalid
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
exception py_nillion_client.ResultError
Errors related to fetching computation results
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.SecretBlob(value)
This is a SecretBlob
class used to
encode a secret as a blob.
Note: __eq__ method is implemented to allow comparing two blobs.
- Parameters: value (bytearray) – Value of the secret blob as a bytearray.
- Returns:
Instance of the
SecretBlob
class. - Return type: SecretBlob
- Raises: VTypeError – argument ‘value’: Raises an error when a non-bytearray object is provided.
Example
import py_nillion_client as nillion
gm_blob_ba = bytearray("gm, builder!", "utf-8")
gm_blob = py_nillion_client.SecretBlob(gm_blob_ba)
ready_blob_ba = bytearray("ready to build!", "utf-8")
ready_blob = py_nillion_client.SecretBlob(ready_blob_ba)
print("Are these blobs the same?", gm_blob == ready_blob)
>>> Are these blobs the same? False
value
Getter and setter for the value inside a
SecretBlob
instance.
- Returns: The value of the secret blob.
- Return type: int
Example
gm_blob_ba = bytearray("gm, builder!", "utf-8")
blob = nillion.SecretBlob(gm_blob_ba)
print("Blob is: ", blob.value)
ready_blob_ba = bytearray("ready to build!", "utf-8")
blob.value = ready_blob_ba
print("Blob is now: ", blob.value)
>>> Blob is: bytearray(b'gm, builder!')
>>> Blob is now: bytearray(b'ready to build!')
class py_nillion_client.SecretInteger(value)
This is a SecretInteger
class used to
encode a secret as a integer.
Note: __eq__ method is implemented to allow comparing two integers.
- Parameters: value (int) – Value of the secret encoded element.
- Returns:
Instance of the
SecretInteger
class. - Return type: SecretInteger
Example
import py_nillion_client as nillion
sec_integer_1 = nillion.SecretInteger(1)
sec_integer_2 = nillion.SecretInteger(2)
print("Are the secret integers the same? ", sec_integer_1 == sec_integer_2)
>>> Are the secret integers the same? False
Providing zero as SecretInteger
leaks information.
value
Getter and setter for the value inside a
SecretInteger
instance.
- Returns: The value of the secret integer.
- Return type: int
Example
sec_integer = nillion.SecretInteger(1)
print("Secret integer is: ", sec_integer.value)
sec_integer.value = 2
print("Secret integer is now: ", sec_integer.value)
>>> Secret integer is: 1
>>> Secret integer is now: 2
class py_nillion_client.SecretUnsignedInteger(value)
This is a SecretUnsignedInteger
class used to
encode a secret as an unsigned integer.
Note: __eq__ method is implemented to allow comparing two unsigned integers.
- Parameters: value (int) – Value of the secret encoded element.
- Returns:
Instance of the
SecretUnsignedInteger
class. - Return type: SecretUnsignedInteger
- Raises: OverflowError – can’t convert negative int to unsigned: Raises an error when a negative integer value is used.
Example
import py_nillion_client as nillion
sec_uinteger_1 = nillion.SecretUnsignedInteger(1)
sec_uinteger_2 = nillion.SecretUnsignedInteger(2)
print("Are the secret unsigned integers the same? ", sec_uinteger_1 == sec_uinteger_2)
>>> Are the secret unsigned integers the same? False
Providing zero as SecretUnsignedInteger
leaks information.
value
Getter and setter for the value inside a
SecretUnsignedInteger
instance.
- Returns: The value of the secret unsigned integer.
- Return type: int
Example
sec_uinteger = nillion.SecretUnsignedInteger(1)
print("Secret unsigned integer is: ", sec_uinteger.value)
sec_uinteger.value = 2
print("Secret unsigned integer is now: ", sec_uinteger.value)
>>> Secret unsigned integer is: 1
>>> Secret unsigned integer is now: 2
exception py_nillion_client.TimeoutError
Timed out
args
with_traceback()
Exception.with_traceback(tb) – set self._traceback_ to tb and return self.
class py_nillion_client.UnsignedInteger(value)
This is a UnsignedInteger
class used to
encode a public variable value as an unsigned integer.
Note: __eq__ method is implemented to allow to compare two unsigned integers.
- Parameters: value (int) – Value of the public encoded element.
- Returns:
Instance of the
UnsignedInteger
class. - Return type: UnsignedInteger
- Raises: OverflowError – can’t convert negative int to unsigned: Raises an error when a negative integer value is used.
Example
import py_nillion_client as nillion
pub_uinteger_1 = nillion.UnsignedInteger(1)
pub_uinteger_2 = nillion.UnsignedInteger(2)
print("Are the public unsigned integers the same? ", pub_uinteger_1 == pub_uinteger_2)
>>> Are the public unsigned integers the same? False
value
Getter and setter for the value inside a
UnsignedInteger
instance.
- Returns: The value of the public unsigned integer.
- Return type: int
Example
pub_uinteger = nillion.UnsignedInteger(1)
print("Public unsigned integer is: ", pub_uinteger.value)
pub_uinteger.value = 2
print("Public unsigned integer is now: ", pub_uinteger.value)
>>> Public unsigned integer is: 1
>>> Public unsigned integer is now: 2
class py_nillion_client.UserKey
This is a UserKey
class that
contains the public and private keys for the user.
This class is used by NillionClient
class to initialize a client.
This object’s constructors can be used via the following class methods:
- From string encoded in Base58 (
from_base58()
); - From a file (
from_file()
); - From scratch (
generate()
); - From seed (
seed()
).
from_base58()
Loads public and private key from base 58 encoded data.
- Parameters: contents (str) – A base58 string.
- Return type: UserKey
Example
from py_nillion_client import UserKey
user_key = UserKey.from_base58()
from_file()
Loads public and private key from a file.
- Parameters: path (str) – The filesystem path to the file containing a base58 string.
- Return type: UserKey
Example
from py_nillion_client import UserKey
user_key = UserKey.from_file('/path/to/userkey.base58')
from_seed()
Generates a public and private key from a seed.
- Parameters: seed (str) – A seed string.
- Return type: UserKey
Example
from py_nillion_client import UserKey
user_key = UserKey.from_seed('my_seed')
generate()
Generates a random public and private key.
- Return type: UserKey
Example
from py_nillion_client import UserKey
user_key = UserKey.generate()
py_nillion_client.create_payments_message(quote: PriceQuote, payer_address: str)
Create a payments message.
- Parameters:
- quote (PriceQuote) – The price quote for the operation being paid for.
- sender_address (str) – The nilchain address of the payer.
- Returns: A protobuf message to be used when building a payments transaction.
- Return type: MsgPayFor
py_nillion_client.version()
Return the version of this SDK client.
- Returns: The version of this build.
- Return type: str
Example
py_nillion_client.version()