Skip to content

Commit

Permalink
[Documentation] Update aleo-wasm documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
iamalwaysuncomfortable authored Jul 28, 2023
2 parents 2457570 + 3d16e4d commit dc7c638
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 31 deletions.
21 changes: 21 additions & 0 deletions wasm/src/account/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,50 @@ use crate::{
use core::{convert::TryFrom, fmt, ops::Deref, str::FromStr};
use wasm_bindgen::prelude::*;

/// Public address of an Aleo account
#[wasm_bindgen]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Address(AddressNative);

#[wasm_bindgen]
impl Address {
/// Derive an Aleo address from a private key
///
/// @param {PrivateKey} private_key The private key to derive the address from
/// @returns {Address} Address corresponding to the private key
pub fn from_private_key(private_key: &PrivateKey) -> Self {
Self(AddressNative::try_from(**private_key).unwrap())
}

/// Derive an Aleo address from a view key
///
/// @param {ViewKey} view_key The view key to derive the address from
/// @returns {Address} Address corresponding to the view key
pub fn from_view_key(view_key: &ViewKey) -> Self {
Self(AddressNative::try_from(**view_key).unwrap())
}

/// Create an aleo address object from a string representation of an address
///
/// @param {string} address String representation of an addressm
/// @returns {Address} Address
pub fn from_string(address: &str) -> Self {
Self::from_str(address).unwrap()
}

/// Get a string representation of an Aleo address object
///
/// @param {Address} Address
/// @returns {string} String representation of the address
#[allow(clippy::inherent_to_string_shadow_display)]
pub fn to_string(&self) -> String {
self.0.to_string()
}

/// Verify a signature for a message signed by the address
///
/// @param {Uint8Array} Byte array representing a message signed by the address
/// @returns {boolean} Boolean representing whether or not the signature is valid
pub fn verify(&self, message: &[u8], signature: &Signature) -> bool {
signature.verify(self, message)
}
Expand Down
43 changes: 33 additions & 10 deletions wasm/src/account/private_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ use core::{convert::TryInto, fmt, ops::Deref, str::FromStr};
use rand::{rngs::StdRng, SeedableRng};
use wasm_bindgen::prelude::*;

/// Private key of an Aleo account
#[wasm_bindgen]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PrivateKey(PrivateKeyNative);

#[wasm_bindgen]
impl PrivateKey {
/// Generate a new private key
/// Generate a new private key using a cryptographically secure random number generator
///
/// @returns {PrivateKey}
#[wasm_bindgen(constructor)]
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Expand All @@ -38,6 +41,9 @@ impl PrivateKey {
}

/// Get a private key from a series of unchecked bytes
///
/// @param {Uint8Array} seed Unchecked 32 byte long Uint8Array acting as the seed for the private key
/// @returns {PrivateKey}
pub fn from_seed_unchecked(seed: &[u8]) -> PrivateKey {
console_error_panic_hook::set_once();
// Cast into a fixed-size byte array. Note: This is a **hard** requirement for security.
Expand All @@ -48,39 +54,50 @@ impl PrivateKey {
Self(PrivateKeyNative::try_from(FromBytes::read_le(&*field.to_bytes_le().unwrap()).unwrap()).unwrap())
}

/// Create a private key from a string representation
/// Get a private key from a string representation of a private key
///
/// This function will fail if the text is not a valid private key
/// @param {string} seed String representation of a private key
/// @returns {PrivateKey}
pub fn from_string(private_key: &str) -> Result<PrivateKey, String> {
Self::from_str(private_key).map_err(|_| "Invalid private key".to_string())
}

/// Get a string representation of the private key
/// Get a string representation of the private key. This function should be used very carefully
/// as it exposes the private key plaintext
///
/// This function should be used very carefully as it exposes the private key plaintext
/// @returns {string} String representation of a private key
#[allow(clippy::inherent_to_string_shadow_display)]
pub fn to_string(&self) -> String {
self.0.to_string()
}

/// Get the view key corresponding to the private key
///
/// @returns {ViewKey}
pub fn to_view_key(&self) -> ViewKey {
ViewKey::from_private_key(self)
}

/// Get the address corresponding to the private key
///
/// @returns {Address}
pub fn to_address(&self) -> Address {
Address::from_private_key(self)
}

/// Sign a message with the private key
///
/// @param {Uint8Array} Byte array representing a message signed by the address
/// @returns {Signature} Signature generated by signing the message with the address
pub fn sign(&self, message: &[u8]) -> Signature {
Signature::sign(self, message)
}

/// Get a private key ciphertext using a secret.
/// Get a new randomly generated private key ciphertext using a secret. The secret is sensitive
/// and will be needed to decrypt the private key later, so it should be stored securely
///
/// The secret is sensitive and will be needed to decrypt the private key later, so it should be stored securely
/// @param {string} secret Secret used to encrypt the private key
/// @returns {PrivateKeyCiphertext | Error} Ciphertext representation of the private key
#[wasm_bindgen(js_name = newEncrypted)]
pub fn new_encrypted(secret: &str) -> Result<PrivateKeyCiphertext, String> {
let key = Self::new();
Expand All @@ -89,17 +106,23 @@ impl PrivateKey {
Ok(PrivateKeyCiphertext::from(ciphertext))
}

/// Encrypt the private key with a secret.
/// Encrypt an existing private key with a secret. The secret is sensitive and will be needed to
/// decrypt the private key later, so it should be stored securely
///
/// The secret is sensitive and will be needed to decrypt the private key later, so it should be stored securely
/// @param {string} secret Secret used to encrypt the private key
/// @returns {PrivateKeyCiphertext | Error} Ciphertext representation of the private key
#[wasm_bindgen(js_name = toCiphertext)]
pub fn to_ciphertext(&self, secret: &str) -> Result<PrivateKeyCiphertext, String> {
let ciphertext =
Encryptor::encrypt_private_key_with_secret(self, secret).map_err(|_| "Encryption failed".to_string())?;
Ok(PrivateKeyCiphertext::from(ciphertext))
}

/// Get private key from a private key ciphertext using a secret.
/// Get private key from a private key ciphertext and secret originally used to encrypt it
///
/// @param {PrivateKeyCiphertext} ciphertext Ciphertext representation of the private key
/// @param {string} secret Secret originally used to encrypt the private key
/// @returns {PrivateKey | Error} Private key
#[wasm_bindgen(js_name = fromPrivateKeyCiphertext)]
pub fn from_private_key_ciphertext(ciphertext: &PrivateKeyCiphertext, secret: &str) -> Result<PrivateKey, String> {
let private_key = Encryptor::decrypt_private_key_with_secret(ciphertext, secret)
Expand Down
18 changes: 14 additions & 4 deletions wasm/src/account/private_key_ciphertext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@ pub struct PrivateKeyCiphertext(CiphertextNative);

#[wasm_bindgen]
impl PrivateKeyCiphertext {
/// Encrypt a private key using a secret string.
/// Encrypt a private key using a secret string. The secret is sensitive and will be needed to
/// decrypt the private key later, so it should be stored securely
///
/// The secret is sensitive and will be needed to decrypt the private key later, so it should be stored securely.
/// @param {PrivateKey} private_key Private key to encrypt
/// @param {string} secret Secret to encrypt the private key with
/// @returns {PrivateKeyCiphertext | Error} Private key ciphertext
#[wasm_bindgen(js_name = encryptPrivateKey)]
pub fn encrypt_private_key(private_key: &PrivateKey, secret: &str) -> Result<PrivateKeyCiphertext, String> {
let ciphertext = Encryptor::encrypt_private_key_with_secret(private_key, secret)
.map_err(|_| "Encryption failed".to_string())?;
Ok(Self::from(ciphertext))
}

/// Decrypts a private ciphertext using a secret string.
/// Decrypts a private ciphertext using a secret string. This must be the same secret used to
/// encrypt the private key
///
/// This must be the same secret used to encrypt the private key
/// @param {string} secret Secret used to encrypt the private key
/// @returns {PrivateKey | Error} Private key
#[wasm_bindgen(js_name = decryptToPrivateKey)]
pub fn decrypt_to_private_key(&self, secret: &str) -> Result<PrivateKey, String> {
let private_key = Encryptor::decrypt_private_key_with_secret(&self.0, secret)
Expand All @@ -50,13 +55,18 @@ impl PrivateKeyCiphertext {
}

/// Returns the ciphertext string
///
/// @returns {string} Ciphertext string
#[allow(clippy::inherent_to_string)]
#[wasm_bindgen(js_name = toString)]
pub fn to_string(&self) -> String {
self.0.to_string()
}

/// Creates a PrivateKeyCiphertext from a string
///
/// @param {string} ciphertext Ciphertext string
/// @returns {PrivateKeyCiphertext | Error} Private key ciphertext
#[wasm_bindgen(js_name = fromString)]
pub fn from_string(ciphertext: String) -> Result<PrivateKeyCiphertext, String> {
Self::try_from(ciphertext).map_err(|_| "Invalid ciphertext".to_string())
Expand Down
18 changes: 18 additions & 0 deletions wasm/src/account/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,41 @@ use core::{fmt, ops::Deref, str::FromStr};
use rand::{rngs::StdRng, SeedableRng};
use wasm_bindgen::prelude::*;

/// Cryptographic signature of a message signed by an Aleo account
#[wasm_bindgen]
pub struct Signature(SignatureNative);

#[wasm_bindgen]
impl Signature {
/// Sign a message with a private key
///
/// @param {PrivateKey} private_key The private key to sign the message with
/// @param {Uint8Array} message Byte representation of the message to sign
/// @returns {Signature} Signature of the message
pub fn sign(private_key: &PrivateKey, message: &[u8]) -> Self {
Self(SignatureNative::sign_bytes(private_key, message, &mut StdRng::from_entropy()).unwrap())
}

/// Verify a signature of a message with an address
///
/// @param {Address} address The address to verify the signature with
/// @param {Uint8Array} message Byte representation of the message to verify
/// @returns {boolean} True if the signature is valid, false otherwise
pub fn verify(&self, address: &Address, message: &[u8]) -> bool {
self.0.verify_bytes(address, message)
}

/// Get a signature from a string representation of a signature
///
/// @param {string} signature String representation of a signature
/// @returns {Signature} Signature
pub fn from_string(signature: &str) -> Self {
Self::from_str(signature).unwrap()
}

/// Get a string representation of a signature
///
/// @returns {string} String representation of a signature
#[allow(clippy::inherent_to_string_shadow_display)]
pub fn to_string(&self) -> String {
self.0.to_string()
Expand Down
18 changes: 18 additions & 0 deletions wasm/src/account/view_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,41 @@ pub struct ViewKey(ViewKeyNative);

#[wasm_bindgen]
impl ViewKey {
/// Create a new view key from a private key
///
/// @param {PrivateKey} private_key Private key
/// @returns {ViewKey} View key
pub fn from_private_key(private_key: &PrivateKey) -> Self {
Self(ViewKeyNative::try_from(**private_key).unwrap())
}

/// Create a new view key from a string representation of a view key
///
/// @param {string} view_key String representation of a view key
/// @returns {ViewKey} View key
pub fn from_string(view_key: &str) -> Self {
Self::from_str(view_key).unwrap()
}

/// Get a string representation of a view key
///
/// @returns {string} String representation of a view key
#[allow(clippy::inherent_to_string_shadow_display)]
pub fn to_string(&self) -> String {
self.0.to_string()
}

/// Get the address corresponding to a view key
///
/// @returns {Address} Address
pub fn to_address(&self) -> Address {
Address::from_view_key(self)
}

/// Decrypt a record ciphertext with a view key
///
/// @param {string} ciphertext String representation of a record ciphertext
/// @returns {string} String representation of a record plaintext
pub fn decrypt(&self, ciphertext: &str) -> Result<String, String> {
let ciphertext = RecordCiphertext::from_str(ciphertext).map_err(|error| error.to_string())?;
match ciphertext.decrypt(self) {
Expand Down
12 changes: 10 additions & 2 deletions wasm/src/programs/key_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,26 @@ pub struct KeyPair {
#[wasm_bindgen]
impl KeyPair {
/// Create new key pair from proving and verifying keys
///
/// @param {ProvingKey} proving_key Proving key corresponding to a function in an Aleo program
/// @param {VerifyingKey} verifying_key Verifying key corresponding to a function in an Aleo program
/// @returns {KeyPair} Key pair object containing both the function proving and verifying keys
#[wasm_bindgen(constructor)]
pub fn new(proving_key: ProvingKey, verifying_key: VerifyingKey) -> KeyPair {
KeyPair { proving_key: Some(proving_key), verifying_key: Some(verifying_key) }
}

/// Get the proving key
/// Get the proving key. This method will remove the proving key from the key pair
///
/// @returns {ProvingKey | Error}
#[wasm_bindgen(js_name = "provingKey")]
pub fn proving_key(&mut self) -> Result<ProvingKey, String> {
self.proving_key.take().ok_or("Proving key has already been removed".to_string())
}

/// Get the verifying key
/// Get the verifying key. This method will remove the verifying key from the key pair
///
/// @returns {VerifyingKey | Error}
#[wasm_bindgen(js_name = "verifyingKey")]
pub fn verifying_key(&mut self) -> Result<VerifyingKey, String> {
self.verifying_key.take().ok_or("Proving key has already been removed".to_string())
Expand Down
9 changes: 6 additions & 3 deletions wasm/src/programs/manager/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl ProgramManager {
/// @param private_key The private key of the sender
/// @param program The source code of the program being deployed
/// @param imports A javascript object holding the source code of any imported programs in the
/// form {"program_name1": "program_source_code", "program_name2": "program_source_code", ..}.
/// form \{"program_name1": "program_source_code", "program_name2": "program_source_code", ..\}.
/// Note that all imported programs must be deployed on chain before the main program in order
/// for the deployment to succeed
/// @param fee_credits The amount of credits to pay as a fee
Expand All @@ -55,9 +55,10 @@ impl ProgramManager {
/// @param cache Cache the synthesized keys for future use
/// @param imports (optional) Provide a list of imports to use for the program deployment in the
/// form of a javascript object where the keys are a string of the program name and the values
/// are a string representing the program source code { "hello.aleo": "hello.aleo source code" }
/// are a string representing the program source code \{ "hello.aleo": "hello.aleo source code" \}
/// @param fee_proving_key (optional) Provide a proving key to use for the fee execution
/// @param fee_verifying_key (optional) Provide a verifying key to use for the fee execution
/// @returns {Transaction | Error}
#[wasm_bindgen]
#[allow(clippy::too_many_arguments)]
pub async fn deploy(
Expand Down Expand Up @@ -141,7 +142,8 @@ impl ProgramManager {
/// @param cache Cache the synthesized keys for future use
/// @param imports (optional) Provide a list of imports to use for the deployment fee estimation
/// in the form of a javascript object where the keys are a string of the program name and the values
/// are a string representing the program source code { "hello.aleo": "hello.aleo source code" }
/// are a string representing the program source code \{ "hello.aleo": "hello.aleo source code" \}
/// @returns {u64 | Error}
#[wasm_bindgen(js_name = estimateDeploymentFee)]
pub async fn estimate_deployment_fee(
&mut self,
Expand Down Expand Up @@ -182,6 +184,7 @@ impl ProgramManager {
/// Disclaimer: Fee estimation is experimental and may not represent a correct estimate on any current or future network
///
/// @param name The name of the program to be deployed
/// @returns {u64 | Error}
#[wasm_bindgen(js_name = estimateProgramNameCost)]
pub fn program_name_cost(&self, name: &str) -> Result<u64, String> {
log(
Expand Down
Loading

0 comments on commit dc7c638

Please sign in to comment.