Skip to content

Commit

Permalink
Organize python SDK methods to rust conventions
Browse files Browse the repository at this point in the history
  • Loading branch information
iamalwaysuncomfortable committed Oct 27, 2023
1 parent 9dd13dd commit 704c783
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 134 deletions.
34 changes: 20 additions & 14 deletions sdk/src/account/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,6 @@ use std::{
#[derive(Clone)]
pub struct Address(AddressNative);

impl Address {
pub fn from_native(address: AddressNative) -> Self {
Self(address)
}
}

impl Deref for Address {
type Target = AddressNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

#[pymethods]
impl Address {
/// Reads in an account address string.
Expand All @@ -52,6 +38,12 @@ impl Address {
Ok(Self(address))
}

/// Returns the address as a base58 string.
#[allow(clippy::inherent_to_string)]
fn to_string(&self) -> String {
self.0.to_string()
}

fn __str__(&self) -> String {
self.0.to_string()
}
Expand All @@ -66,3 +58,17 @@ impl Address {
hasher.finish()
}
}

impl Deref for Address {
type Target = AddressNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<AddressNative> for Address {
fn from(address: AddressNative) -> Self {
Self(address)
}
}
33 changes: 19 additions & 14 deletions sdk/src/account/compute_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.

use crate::types::ComputeKeyNative;
use crate::{types::ComputeKeyNative, Address};

use pyo3::prelude::*;

Expand All @@ -23,22 +23,13 @@ use std::ops::Deref;
#[pyclass(frozen)]
pub struct ComputeKey(ComputeKeyNative);

#[pymethods]
impl ComputeKey {
pub fn from_native(compute_key: ComputeKeyNative) -> Self {
Self(compute_key)
/// Returns the address from the compute key.
fn address(&self) -> Address {
Address::from(self.0.to_address())

This comment has been minimized.

Copy link
@kpp

kpp Oct 28, 2023

Contributor

.into()

}
}

impl Deref for ComputeKey {
type Target = ComputeKeyNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

#[pymethods]
impl ComputeKey {
/// Returns the signature public key.
fn pk_sig(&self) -> String {
self.0.pk_sig().to_string()
Expand All @@ -54,3 +45,17 @@ impl ComputeKey {
self.0.sk_prf().to_string()
}
}

impl Deref for ComputeKey {
type Target = ComputeKeyNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<ComputeKeyNative> for ComputeKey {
fn from(compute_key: ComputeKeyNative) -> Self {
Self(compute_key)
}
}
17 changes: 11 additions & 6 deletions sdk/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,14 @@ impl Account {
/// Generates a new account using a cryptographically secure random number generator
#[new]
fn new() -> Self {
let private_key = PrivateKey::random();
Self::from_private_key(private_key)
Self::from(PrivateKey::new())
}

/// Creates a new account from the given private key.
#[staticmethod]
fn from_private_key(private_key: PrivateKey) -> Self {
let view_key = private_key.view_key();
let address = private_key.address();
let address = private_key.address().unwrap();
Self {
private_key,
view_key,
Expand All @@ -69,7 +68,7 @@ impl Account {

/// Returns an account private key.
fn private_key(&self) -> PrivateKey {
self.private_key.clone()
self.private_key
}

/// Returns an account view key.
Expand All @@ -93,8 +92,8 @@ impl Account {
}

/// Decrypts a record ciphertext with a view key
fn decrypt(&self, cipherrecord: &RecordCiphertext) -> anyhow::Result<RecordPlaintext> {
cipherrecord.decrypt(&self.view_key)
fn decrypt(&self, record_ciphertext: &RecordCiphertext) -> anyhow::Result<RecordPlaintext> {
record_ciphertext.decrypt(&self.view_key)
}

/// Determines whether the record belongs to the account.
Expand All @@ -119,3 +118,9 @@ impl Account {
hasher.finish()
}
}

impl From<PrivateKey> for Account {
fn from(private_key: PrivateKey) -> Self {
Self::from_private_key(private_key)
}
}
79 changes: 48 additions & 31 deletions sdk/src/account/private_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,43 +30,45 @@ use std::{
};

#[pyclass(frozen)]
#[derive(Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct PrivateKey(PrivateKeyNative);

impl Deref for PrivateKey {
type Target = PrivateKeyNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

#[pymethods]
impl PrivateKey {
/// Generates a new private key using a cryptographically secure random number generator
#[allow(clippy::new_without_default)]
#[new]
pub fn random() -> Self {
let key = PrivateKeyNative::new(&mut StdRng::from_entropy()).unwrap();
Self(key)
pub fn new() -> Self {

This comment has been minimized.

Copy link
@kpp

kpp Oct 28, 2023

Contributor

Not matter how it’s named, from python it can be called only by PrivateKey(). So why need to rename this method and suppress clippy?

Self(PrivateKeyNative::new(&mut StdRng::from_entropy()).unwrap())
}

/// Reads in an account private key from a base58 string.
#[staticmethod]
fn from_string(s: &str) -> anyhow::Result<Self> {
let private_key = FromStr::from_str(s)?;
Ok(Self(private_key))
/// Derives the account address from an account private key.
pub fn address(&self) -> anyhow::Result<Address> {
Ok(Address::from(AddressNative::try_from(&self.0)?))
}

/// Returns a signature for the given message (as bytes) using the private key.
pub fn sign(&self, message: &[u8]) -> anyhow::Result<Signature> {
Signature::sign(self, message)
/// Derives the account compute key from an account private key.
fn compute_key(&self) -> ComputeKey {
let compute_key = ComputeKeyNative::try_from(&self.0).unwrap();
ComputeKey::from(compute_key)
}

/// Reads in an account private key from a base58 string.
#[staticmethod]
fn from_string(private_key: &str) -> anyhow::Result<Self> {
Ok(Self(PrivateKeyNative::from_str(private_key)?))
}

/// Returns the account seed.
fn seed(&self) -> String {
self.0.seed().to_string()
}

/// Returns a signature for the given message (as bytes) using the private key.
pub fn sign(&self, message: &[u8]) -> anyhow::Result<Signature> {
Signature::sign(self, message)
}

/// Returns the signature secret key.
fn sk_sig(&self) -> String {
self.0.sk_sig().to_string()
Expand All @@ -77,22 +79,17 @@ impl PrivateKey {
self.0.r_sig().to_string()
}

/// Derives the account address from an account private key.
pub fn address(&self) -> Address {
let address = AddressNative::try_from(&self.0).unwrap();
Address::from_native(address)
}

/// Derives the account compute key from an account private key.
fn compute_key(&self) -> ComputeKey {
let compute_key = ComputeKeyNative::try_from(&self.0).unwrap();
ComputeKey::from_native(compute_key)
/// Returns the private key as a base58 string.
#[allow(clippy::inherent_to_string)]
#[allow(clippy::wrong_self_convention)]
fn to_string(&self) -> String {
self.0.to_string()
}

/// Initializes a new account view key from an account private key.
pub fn view_key(&self) -> ViewKey {
let view_key = ViewKeyNative::try_from(&self.0).unwrap();
ViewKey::from_native(view_key)
ViewKey::from(view_key)
}

fn __str__(&self) -> String {
Expand All @@ -109,3 +106,23 @@ impl PrivateKey {
hasher.finish()
}
}

impl Deref for PrivateKey {
type Target = PrivateKeyNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<PrivateKey> for PrivateKeyNative {
fn from(private_key: PrivateKey) -> Self {
private_key.0
}
}

impl From<PrivateKeyNative> for PrivateKey {
fn from(private_key: PrivateKeyNative) -> Self {
Self(private_key)
}
}
89 changes: 83 additions & 6 deletions sdk/src/account/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.

use crate::{
account::ViewKey,
types::{RecordCiphertextNative, RecordPlaintextNative},
account::{PrivateKey, ViewKey},
types::{
IdentifierNative, ProgramIDNative, RecordCiphertextNative,
RecordPlaintextNative,
},
};
use std::ops::Deref;

use pyo3::prelude::*;

Expand All @@ -28,11 +32,16 @@ pub struct RecordCiphertext(RecordCiphertextNative);

#[pymethods]
impl RecordCiphertext {
/// Reads in the ciphertext string.
/// Creates a record ciphertext from string
#[staticmethod]
fn from_string(s: &str) -> anyhow::Result<Self> {
let view_key = FromStr::from_str(s)?;
Ok(Self(view_key))
Ok(Self::from(RecordCiphertextNative::from_str(s)?))
}

/// Returns the record ciphertext as a string.
#[allow(clippy::inherent_to_string)]
fn to_string(&self) -> String {
self.0.to_string()
}

/// Decrypts self into plaintext using the given view key and checks that the owner matches the view key.
Expand All @@ -41,7 +50,7 @@ impl RecordCiphertext {
Ok(RecordPlaintext(plaintext))
}

/// Determines whether the record belongs to the account.
/// Determines whether the record belongs to the view key associated with an account.
pub fn is_owner(&self, view_key: &ViewKey) -> bool {
self.0.is_owner(view_key)
}
Expand All @@ -51,12 +60,80 @@ impl RecordCiphertext {
}
}

impl Deref for RecordCiphertext {
type Target = RecordCiphertextNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<RecordCiphertextNative> for RecordCiphertext {
fn from(record_ciphertext: RecordCiphertextNative) -> Self {
Self(record_ciphertext)
}
}

#[pyclass(frozen)]
pub struct RecordPlaintext(RecordPlaintextNative);

#[pymethods]
impl RecordPlaintext {
/// Reads in the plaintext string.
#[staticmethod]
fn from_string(s: &str) -> anyhow::Result<Self> {
Ok(Self::from(RecordPlaintextNative::from_str(s)?))
}

/// Returns the owner of the record as a string
fn owner(&self) -> String {
self.0.owner().to_string()
}

/// Returns the nonce of the record as a string
fn nonce(&self) -> String {
self.0.nonce().to_string()
}

/// Attempt to get the serial number of a record to determine whether or not is has been spent
pub fn serial_number_string(
&self,
private_key: &PrivateKey,
program_id: &str,
record_name: &str,
) -> anyhow::Result<String> {
let parsed_program_id = ProgramIDNative::from_str(program_id)?;
let record_identifier = IdentifierNative::from_str(record_name)?;
let commitment = self.to_commitment(&parsed_program_id, &record_identifier)?;
let serial_number = RecordPlaintextNative::serial_number(**private_key, commitment)?;
Ok(serial_number.to_string())
}

/// Returns the plaintext as a string.
#[allow(clippy::inherent_to_string)]
fn to_string(&self) -> String {
self.0.to_string()
}

fn __eq__(&self, other: &Self) -> bool {
self.0 == other.0
}

fn __str__(&self) -> String {
self.0.to_string()
}
}

impl Deref for RecordPlaintext {
type Target = RecordPlaintextNative;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<RecordPlaintextNative> for RecordPlaintext {
fn from(record_plaintext: RecordPlaintextNative) -> Self {
Self(record_plaintext)
}
}
Loading

0 comments on commit 704c783

Please sign in to comment.