diff --git a/build.rs b/build.rs index 1f866b6..9fc2367 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,5 @@ extern crate napi_build; fn main() { - napi_build::setup(); + napi_build::setup(); } diff --git a/src/lib.rs b/src/lib.rs index 53ca26f..27bbad3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,9 @@ extern crate napi_derive; use std::ops::Deref; +use holochain_zome_types::{Signature, ZomeCallUnsigned}; +use lair_keystore_api::{dependencies::url::Url, ipc_keystore::ipc_keystore_connect, LairClient}; use napi::Result; -use lair_keystore_api::{ipc_keystore::ipc_keystore_connect, dependencies::url::Url, LairClient}; -use holochain_zome_types::{ZomeCallUnsigned, Signature}; use sodoken::BufRead; mod types; @@ -15,82 +15,90 @@ use types::*; pub mod utils; struct ZomeCallSigner { - lair_client: LairClient, + lair_client: LairClient, } impl ZomeCallSigner { - /// Connect to lair keystore - pub async fn new(connection_url: String, passphrase: String) -> Self { - let connection_url_parsed = Url::parse(connection_url.deref()).unwrap(); - let passphrase_bufread: BufRead = passphrase.as_bytes().into(); - - let lair_client = ipc_keystore_connect(connection_url_parsed, passphrase_bufread) - .await - .unwrap(); - - Self { - lair_client + /// Connect to lair keystore + pub async fn new(connection_url: String, passphrase: String) -> Self { + let connection_url_parsed = Url::parse(connection_url.deref()).unwrap(); + let passphrase_bufread: BufRead = passphrase.as_bytes().into(); + + let lair_client = ipc_keystore_connect(connection_url_parsed, passphrase_bufread) + .await + .unwrap(); + + Self { lair_client } } - } - - /// Sign a zome call - pub async fn sign_zome_call(&self, zome_call_unsigned_js: ZomeCallUnsignedNapi) -> Result { - let zome_call_unsigned: ZomeCallUnsigned = zome_call_unsigned_js.clone().into(); - let pub_key = zome_call_unsigned.provenance.clone(); - let mut pub_key_2 = [0; 32]; - pub_key_2.copy_from_slice(pub_key.get_raw_32()); - - let data_to_sign = zome_call_unsigned.data_to_sign().unwrap(); - - let sig = self.lair_client.sign_by_pub_key( - pub_key_2.into(), - None, - data_to_sign) - .await - .unwrap(); - - let signature = Signature(*sig.0); - - let signed_zome_call = ZomeCallNapi { - cell_id: zome_call_unsigned_js.cell_id, - zome_name: zome_call_unsigned.zome_name.to_string(), - fn_name: zome_call_unsigned.fn_name.0, - payload: zome_call_unsigned_js.payload, - cap_secret: zome_call_unsigned_js.cap_secret, - provenance: zome_call_unsigned_js.provenance, - nonce: zome_call_unsigned_js.nonce, - expires_at: zome_call_unsigned_js.expires_at, - signature: signature.0.to_vec() - }; - - Ok(signed_zome_call) - } -} + /// Sign a zome call + pub async fn sign_zome_call( + &self, + zome_call_unsigned_js: ZomeCallUnsignedNapi, + ) -> Result { + let zome_call_unsigned: ZomeCallUnsigned = zome_call_unsigned_js.clone().into(); + let pub_key = zome_call_unsigned.provenance.clone(); + let mut pub_key_2 = [0; 32]; + pub_key_2.copy_from_slice(pub_key.get_raw_32()); + + let data_to_sign = zome_call_unsigned.data_to_sign().unwrap(); + + let sig = self + .lair_client + .sign_by_pub_key(pub_key_2.into(), None, data_to_sign) + .await + .unwrap(); + + let signature = Signature(*sig.0); + + let signed_zome_call = ZomeCallNapi { + cell_id: zome_call_unsigned_js.cell_id, + zome_name: zome_call_unsigned.zome_name.to_string(), + fn_name: zome_call_unsigned.fn_name.0, + payload: zome_call_unsigned_js.payload, + cap_secret: zome_call_unsigned_js.cap_secret, + provenance: zome_call_unsigned_js.provenance, + nonce: zome_call_unsigned_js.nonce, + expires_at: zome_call_unsigned_js.expires_at, + signature: signature.0.to_vec(), + }; + + Ok(signed_zome_call) + } +} #[napi(js_name = "ZomeCallSigner")] pub struct JsZomeCallSigner { - zome_call_signer: Option, + zome_call_signer: Option, } #[napi] impl JsZomeCallSigner { - #[napi(constructor)] - pub fn new() -> Self { - Self { - zome_call_signer: None + #[napi(constructor)] + pub fn new() -> Self { + Self { + zome_call_signer: None, + } } - } - - #[napi] - pub async fn connect(connection_url: String, passphrase: String) -> Self { - let zome_call_signer = ZomeCallSigner::new(connection_url, passphrase).await; - - JsZomeCallSigner { zome_call_signer: Some(zome_call_signer) } - } - - #[napi] - pub async fn sign_zome_call(&self, zome_call_unsigned_js: ZomeCallUnsignedNapi) -> Result { - self.zome_call_signer.as_ref().unwrap().sign_zome_call(zome_call_unsigned_js).await - } -} \ No newline at end of file + + #[napi] + pub async fn connect(connection_url: String, passphrase: String) -> Self { + let zome_call_signer = ZomeCallSigner::new(connection_url, passphrase).await; + + JsZomeCallSigner { + zome_call_signer: Some(zome_call_signer), + } + } + + #[napi] + pub async fn sign_zome_call( + &self, + zome_call_unsigned_js: ZomeCallUnsignedNapi, + ) -> Result { + self.zome_call_signer + .as_ref() + .unwrap() + .sign_zome_call(zome_call_unsigned_js) + .await + } +} diff --git a/src/types.rs b/src/types.rs index 4fa2976..0048090 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,51 +1,52 @@ -use kitsune_p2p_timestamp::Timestamp; -use holochain_zome_types::CellId; -use holochain_integrity_types::{ZomeName, FunctionName}; -use holo_hash::{DnaHash, AgentPubKey}; -use holochain_zome_types::{ExternIO, CapSecret, ZomeCallUnsigned}; use crate::utils::*; +use holo_hash::{AgentPubKey, DnaHash}; +use holochain_integrity_types::{FunctionName, ZomeName}; +use holochain_zome_types::CellId; +use holochain_zome_types::{CapSecret, ExternIO, ZomeCallUnsigned}; +use kitsune_p2p_timestamp::Timestamp; #[derive(Clone)] #[napi(object)] pub struct ZomeCallUnsignedNapi { - pub cell_id: Vec>, - pub zome_name: String, - pub fn_name: String, - pub payload: Vec, - pub cap_secret: Option>, - pub provenance: Vec, - pub nonce: Vec, - pub expires_at: i64, + pub cell_id: Vec>, + pub zome_name: String, + pub fn_name: String, + pub payload: Vec, + pub cap_secret: Option>, + pub provenance: Vec, + pub nonce: Vec, + pub expires_at: i64, } - impl Into for ZomeCallUnsignedNapi { - fn into(self: Self) -> ZomeCallUnsigned { - ZomeCallUnsigned { - cell_id: CellId::new( - DnaHash::from_raw_39(self.cell_id.get(0).unwrap().clone()).unwrap(), - AgentPubKey::from_raw_39(self.cell_id.get(1).unwrap().clone()).unwrap() - ), - zome_name: ZomeName::from(self.zome_name), - fn_name: FunctionName::from(self.fn_name), - payload: ExternIO::from(self.payload), - cap_secret: self.cap_secret.map_or(None, |c| Some(CapSecret::from(vec_to_arr(c)))), - provenance: AgentPubKey::from_raw_39(self.provenance).unwrap(), - nonce: vec_to_arr(self.nonce).into(), - expires_at: Timestamp(self.expires_at) + fn into(self: Self) -> ZomeCallUnsigned { + ZomeCallUnsigned { + cell_id: CellId::new( + DnaHash::from_raw_39(self.cell_id.get(0).unwrap().clone()).unwrap(), + AgentPubKey::from_raw_39(self.cell_id.get(1).unwrap().clone()).unwrap(), + ), + zome_name: ZomeName::from(self.zome_name), + fn_name: FunctionName::from(self.fn_name), + payload: ExternIO::from(self.payload), + cap_secret: self + .cap_secret + .map_or(None, |c| Some(CapSecret::from(vec_to_arr(c)))), + provenance: AgentPubKey::from_raw_39(self.provenance).unwrap(), + nonce: vec_to_arr(self.nonce).into(), + expires_at: Timestamp(self.expires_at), + } } - } } #[napi(object)] pub struct ZomeCallNapi { - pub cell_id: Vec>, - pub zome_name: String, - pub fn_name: String, - pub payload: Vec, - pub cap_secret: Option>, - pub provenance: Vec, - pub nonce: Vec, - pub expires_at: i64, - pub signature: Vec + pub cell_id: Vec>, + pub zome_name: String, + pub fn_name: String, + pub payload: Vec, + pub cap_secret: Option>, + pub provenance: Vec, + pub nonce: Vec, + pub expires_at: i64, + pub signature: Vec, } diff --git a/src/utils.rs b/src/utils.rs index 519edee..ae85d6c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ pub fn vec_to_arr(v: Vec) -> [T; N] { - v.try_into() - .unwrap_or_else(|v: Vec| panic!("Expected a Vec of length {} but it was {}", N, v.len())) -} \ No newline at end of file + v.try_into() + .unwrap_or_else(|v: Vec| panic!("Expected a Vec of length {} but it was {}", N, v.len())) +}