diff --git a/Cargo.lock b/Cargo.lock index 4dcef95..c39f014 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2859,6 +2859,7 @@ dependencies = [ name = "secret-leptos" version = "0.1.0" dependencies = [ + "async-trait", "base64 0.22.1", "codee", "console_error_panic_hook", diff --git a/Cargo.toml b/Cargo.toml index 68b3c73..8875f8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1" base64 = "0.22" futures = "0.3" +async-trait = "0.1.81" thiserror = "1.0" # Logging diff --git a/src/keplr/keplr.rs b/src/keplr/keplr.rs index 13ce33c..00f49a4 100644 --- a/src/keplr/keplr.rs +++ b/src/keplr/keplr.rs @@ -1,70 +1,22 @@ use crate::keplr::Error; +use async_trait::async_trait; use base64::prelude::{Engine as _, BASE64_STANDARD}; use futures::TryFutureExt; use js_sys::JsString; use keplr_sys::KeplrOfflineSigner as RawKeplrOfflineSigner; use keplr_sys::*; +use send_wrapper::SendWrapper; use serde::{Deserialize, Serialize}; use std::{rc::Rc, sync::Arc}; use tracing::debug; +use wasm_bindgen_futures::spawn_local; use web_sys::console; -/// An Amino encoded message. -#[derive(Debug, Serialize, Deserialize)] -pub struct AminoMsg { - pub r#type: String, - pub value: Vec, -} - -/// Response after signing with Amino. -#[derive(Debug, Serialize, Deserialize)] -pub struct AminoSignResponse { - /// The sign_doc that was signed. - /// - /// This may be different from the input sign_doc when the signer modifies it as part of the signing process. - pub signed: StdSignDoc, - pub signature: StdSignature, -} - -/// Standard signature. -#[derive(Debug, Serialize, Deserialize)] -pub struct StdSignature { - #[serde(alias = "pubKey")] - pub pub_key: Pubkey, - pub signature: String, -} - -/// Public key. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Pubkey { - /// Possible types include: - /// - "tendermint/PubKeySecp256k1" - /// - "tendermint/PubKeyEd25519" - /// - "tendermint/PubKeySr25519 - pub r#type: String, - /// Base64 encoded String - pub value: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct StdSignDoc { - pub chain_id: String, - pub account_number: String, - pub sequence: String, - pub fee: StdFee, - pub msgs: Vec, - pub memo: String, -} - -/// Standard fee. -#[derive(Default, Debug, Clone, Serialize, Deserialize)] -pub struct StdFee { - pub amount: Vec, - pub gas: String, - pub granter: Option, -} +use rsecret::wallet::wallet_amino::*; +use rsecret::wallet::wallet_proto::*; +use secretrs::tx::SignDoc; -pub type Coin = String; +pub use rsecret::wallet::wallet_amino::AccountData; #[derive(Serialize, Deserialize, Clone, Default, PartialEq)] #[serde(rename_all = "camelCase")] @@ -128,7 +80,7 @@ impl Keplr { .map_err(Into::into) } - pub async fn get_account(chain_id: &str) -> Result { + pub async fn get_account(chain_id: &str) -> Result { let signer = get_offline_signer_only_amino(chain_id); let accounts = signer .get_accounts() @@ -137,7 +89,7 @@ impl Keplr { let accounts = js_sys::Array::from(&accounts); let account = accounts.get(0); - let account: Account = serde_wasm_bindgen::from_value(account)?; + let account: AccountData = serde_wasm_bindgen::from_value(account)?; Ok(account) } @@ -185,113 +137,125 @@ impl Keplr { #[derive(Clone)] pub struct KeplrOfflineSigner { - inner: Rc, + inner: SendWrapper>, } impl From for KeplrOfflineSigner { fn from(value: keplr_sys::KeplrOfflineSigner) -> Self { Self { - inner: Rc::new(value), + inner: SendWrapper::new(Rc::new(value)), } } } -impl KeplrOfflineSigner { - pub fn chain_id(&self) -> String { - self.inner - .chain_id() - .as_string() - .expect("chain_id field is missing!") +#[async_trait] +impl DirectSigner for KeplrOfflineSigner { + type Error = super::Error; + + // pub fn chain_id(&self) -> String { + // self.inner + // .chain_id() + // .as_string() + // .expect("chain_id field is missing!") + // } + + async fn get_accounts(&self) -> Result, Self::Error> { + SendWrapper::new(async move { + self.inner + .get_accounts() + .await + .map_err(|_| Error::KeplrUnavailable) + .map(|val| js_sys::Array::from(&val)) + .and_then(|accounts| { + accounts + .iter() + .map(|account| serde_wasm_bindgen::from_value(account).map_err(Into::into)) + .collect::, Error>>() + }) + }) + .await } - pub async fn get_accounts(&self) -> Result { - self.inner - .get_accounts() - .await - .map_err(|_| Error::KeplrUnavailable) - .map(|val| js_sys::Array::from(&val)) - .map(|accounts| accounts.get(0)) - .and_then(|account| serde_wasm_bindgen::from_value(account).map_err(Into::into)) + async fn sign_amino( + &self, + signer_address: &str, + sign_doc: StdSignDoc, + ) -> Result { + todo!() } - pub async fn sign_amino( + async fn sign_permit( &self, - signer_address: impl ToString, + signer_address: &str, sign_doc: StdSignDoc, - ) -> Result { + ) -> Result { todo!() } - // pub async fn sign_direct( - // &self, - // signer_address: impl ToString, - // sign_doc: SignDoc, - // ) -> Result { - // todo!() - // } + async fn sign_direct( + &self, + signer_address: &str, + sign_doc: SignDocVariant, + ) -> Result { + todo!() + } } #[derive(Clone)] pub struct KeplrOfflineSignerOnlyAmino { - inner: Rc, + inner: SendWrapper>, } impl From for KeplrOfflineSignerOnlyAmino { fn from(value: keplr_sys::KeplrOfflineSignerOnlyAmino) -> Self { Self { - inner: Rc::new(value), + inner: SendWrapper::new(Rc::new(value)), } } } -impl KeplrOfflineSignerOnlyAmino { - pub fn chain_id(&self) -> String { - self.inner - .chain_id() - .as_string() - .expect("chain_id field is missing!") - } +#[async_trait] +impl AminoSigner for KeplrOfflineSignerOnlyAmino { + type Error = super::Error; - pub async fn get_accounts(&self) -> Result { - self.inner - .get_accounts() - .await - .map_err(|_| Error::KeplrUnavailable) - .map(|val| js_sys::Array::from(&val)) - .map(|accounts| accounts.get(0)) - .and_then(|account| serde_wasm_bindgen::from_value(account).map_err(Into::into)) + // pub fn chain_id(&self) -> String { + // self.inner + // .chain_id() + // .as_string() + // .expect("chain_id field is missing!") + // } + + async fn get_accounts(&self) -> Result, Self::Error> { + SendWrapper::new(async move { + self.inner + .get_accounts() + .await + .map_err(|_| Error::KeplrUnavailable) + .map(|val| js_sys::Array::from(&val)) + .and_then(|accounts| { + accounts + .iter() + .map(|account| serde_wasm_bindgen::from_value(account).map_err(Into::into)) + .collect::, Error>>() + }) + }) + .await } - pub async fn sign_amino( + async fn sign_amino( &self, - signer_address: impl ToString, + signer_address: &str, sign_doc: StdSignDoc, - ) -> Result { + ) -> Result { todo!() } - // pub async fn sign_direct( - // &self, - // signer_address: impl ToString, - // sign_doc: SignDoc, - // ) -> Result { - // todo!() - // } -} -#[derive(Deserialize, Clone)] -pub struct Account { - pub address: String, - pub algo: String, - pub pubkey: Vec, -} - -impl std::fmt::Debug for Account { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Account") - .field("address", &self.address) - .field("algo", &self.algo) - .field("pubkey", &BASE64_STANDARD.encode(&self.pubkey)) // Convert pubkey to base64 - .finish() + async fn sign_permit( + &self, + signer_address: &str, + sign_doc: StdSignDoc, + ) -> Result { + todo!() } } diff --git a/src/keplr/tests.rs b/src/keplr/tests.rs index b30f57f..1b0a57c 100644 --- a/src/keplr/tests.rs +++ b/src/keplr/tests.rs @@ -1,4 +1,4 @@ -use crate::keplr::{suggest_chain_types::*, Account, Keplr, Key}; +use crate::keplr::{suggest_chain_types::*, AccountData, Keplr, Key}; use crate::CHAIN_ID; use keplr_sys; // normally you wouldn't use keplr_sys directly use leptos::prelude::*; @@ -11,13 +11,13 @@ async fn enable_keplr(chain_id: impl ToString) -> bool { } // the "keplrOfflineSigner" object is used in the client constructor -async fn get_account(chain_id: &str) -> Account { +async fn get_account(chain_id: &str) -> AccountData { let signer = keplr_sys::get_offline_signer_only_amino(chain_id); let accounts = signer.get_accounts().await.unwrap(); let accounts = js_sys::Array::from(&accounts); let account = accounts.get(0); - let account: Account = serde_wasm_bindgen::from_value(account).unwrap(); + let account: AccountData = serde_wasm_bindgen::from_value(account).unwrap(); log!("{account:#?}"); account @@ -76,7 +76,7 @@ pub fn KeplrTests() -> impl IntoView { let enable_keplr_action: Action<(), bool, SyncStorage> = Action::new_unsync_with_value(Some(false), |_: &()| enable_keplr(CHAIN_ID)); - let get_account_action: Action<(), Account, SyncStorage> = + let get_account_action: Action<(), AccountData, SyncStorage> = Action::new_unsync(|_: &()| get_account(CHAIN_ID)); let get_key_action: Action<(), Key, SyncStorage> = Action::new_unsync(|_: &()| get_key(CHAIN_ID));