Skip to content

Commit

Permalink
fancy trait stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
kent-3 committed Aug 20, 2024
1 parent 11e0ac1 commit 596e420
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 129 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
214 changes: 89 additions & 125 deletions src/keplr/keplr.rs
Original file line number Diff line number Diff line change
@@ -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<u8>,
}

/// 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<AminoMsg>,
pub memo: String,
}

/// Standard fee.
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct StdFee {
pub amount: Vec<Coin>,
pub gas: String,
pub granter: Option<String>,
}
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")]
Expand Down Expand Up @@ -128,7 +80,7 @@ impl Keplr {
.map_err(Into::into)
}

pub async fn get_account(chain_id: &str) -> Result<Account, Error> {
pub async fn get_account(chain_id: &str) -> Result<AccountData, Error> {
let signer = get_offline_signer_only_amino(chain_id);
let accounts = signer
.get_accounts()
Expand All @@ -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)
}
Expand Down Expand Up @@ -185,113 +137,125 @@ impl Keplr {

#[derive(Clone)]
pub struct KeplrOfflineSigner {
inner: Rc<keplr_sys::KeplrOfflineSigner>,
inner: SendWrapper<Rc<keplr_sys::KeplrOfflineSigner>>,
}

impl From<keplr_sys::KeplrOfflineSigner> 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<Vec<AccountData>, 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::<Result<Vec<AccountData>, Error>>()
})
})
.await
}

pub async fn get_accounts(&self) -> Result<Account, Error> {
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<AminoSignResponse, Self::Error> {
todo!()
}

pub async fn sign_amino(
async fn sign_permit(
&self,
signer_address: impl ToString,
signer_address: &str,
sign_doc: StdSignDoc,
) -> Result<AminoSignResponse, Error> {
) -> Result<AminoSignResponse, Self::Error> {
todo!()
}

// pub async fn sign_direct(
// &self,
// signer_address: impl ToString,
// sign_doc: SignDoc,
// ) -> Result<DirectSignResponse, Error> {
// todo!()
// }
async fn sign_direct(
&self,
signer_address: &str,
sign_doc: SignDocVariant,
) -> Result<DirectSignResponse, Self::Error> {
todo!()
}
}

#[derive(Clone)]
pub struct KeplrOfflineSignerOnlyAmino {
inner: Rc<keplr_sys::KeplrOfflineSignerOnlyAmino>,
inner: SendWrapper<Rc<keplr_sys::KeplrOfflineSignerOnlyAmino>>,
}

impl From<keplr_sys::KeplrOfflineSignerOnlyAmino> 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<Account, Error> {
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<Vec<AccountData>, 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::<Result<Vec<AccountData>, Error>>()
})
})
.await
}

pub async fn sign_amino(
async fn sign_amino(
&self,
signer_address: impl ToString,
signer_address: &str,
sign_doc: StdSignDoc,
) -> Result<AminoSignResponse, Error> {
) -> Result<AminoSignResponse, Self::Error> {
todo!()
}

// pub async fn sign_direct(
// &self,
// signer_address: impl ToString,
// sign_doc: SignDoc,
// ) -> Result<DirectSignResponse, Error> {
// todo!()
// }
}
#[derive(Deserialize, Clone)]
pub struct Account {
pub address: String,
pub algo: String,
pub pubkey: Vec<u8>,
}

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<AminoSignResponse, Self::Error> {
todo!()
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/keplr/tests.rs
Original file line number Diff line number Diff line change
@@ -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::*;
Expand All @@ -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
Expand Down Expand Up @@ -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));
Expand Down

0 comments on commit 596e420

Please sign in to comment.