layer_climb_address/
signer.rs

1use super::key::PublicKey;
2use anyhow::{bail, Result};
3use async_trait::async_trait;
4use layer_climb_proto::MessageExt;
5
6cfg_if::cfg_if! {
7    if #[cfg(target_arch = "wasm32")] {
8        // we assume that any signer we use in wasm32 is purely single-threaded
9        #[async_trait(?Send)]
10        pub trait TxSigner: Send + Sync {
11            async fn sign(&self, doc: &layer_climb_proto::tx::SignDoc) -> Result<Vec<u8>>;
12            async fn public_key(&self) -> Result<PublicKey>;
13            async fn public_key_as_proto(&self) -> Result<layer_climb_proto::Any> {
14                public_key_to_proto(&self.public_key().await?)
15            }
16            async fn signer_info(&self, sequence: u64, sign_mode: layer_climb_proto::tx::SignMode) -> Result<layer_climb_proto::tx::SignerInfo> {
17                Ok(signer_info(self.public_key_as_proto().await?, sequence, sign_mode))
18            }
19        }
20    } else {
21        #[async_trait]
22        pub trait TxSigner: Send + Sync {
23            async fn sign(&self, doc: &layer_climb_proto::tx::SignDoc) -> Result<Vec<u8>>;
24            async fn public_key(&self) -> Result<PublicKey>;
25            async fn public_key_as_proto(&self) -> Result<layer_climb_proto::Any> {
26                public_key_to_proto(&self.public_key().await?)
27            }
28            async fn signer_info(&self, sequence: u64, sign_mode: layer_climb_proto::tx::SignMode) -> Result<layer_climb_proto::tx::SignerInfo> {
29                Ok(signer_info(self.public_key_as_proto().await?, sequence, sign_mode))
30            }
31        }
32    }
33}
34
35fn public_key_to_proto(public_key: &PublicKey) -> Result<layer_climb_proto::Any> {
36    let value = match public_key {
37        tendermint::PublicKey::Ed25519(_) => layer_climb_proto::crypto::ed25519::PubKey {
38            key: public_key.to_bytes(),
39        }
40        .to_bytes()?,
41        tendermint::PublicKey::Secp256k1(_) => layer_climb_proto::crypto::secp256k1::PubKey {
42            key: public_key.to_bytes(),
43        }
44        .to_bytes()?,
45        _ => {
46            bail!("Invalid public key type!")
47        }
48    };
49
50    let type_url = match public_key {
51        tendermint::PublicKey::Ed25519(_) => "/cosmos.crypto.ed25519.PubKey",
52        tendermint::PublicKey::Secp256k1(_) => "/cosmos.crypto.secp256k1.PubKey",
53        _ => {
54            bail!("Invalid public key type!")
55        }
56    };
57
58    Ok(layer_climb_proto::Any {
59        type_url: type_url.to_string(),
60        value,
61    })
62}
63
64fn signer_info(
65    public_key: layer_climb_proto::Any,
66    sequence: u64,
67    sign_mode: layer_climb_proto::tx::SignMode,
68) -> layer_climb_proto::tx::SignerInfo {
69    layer_climb_proto::tx::SignerInfo {
70        public_key: Some(public_key),
71        mode_info: Some(layer_climb_proto::tx::ModeInfo {
72            sum: Some(layer_climb_proto::tx::mode_info::Sum::Single(
73                layer_climb_proto::tx::mode_info::Single {
74                    mode: sign_mode.into(),
75                },
76            )),
77        }),
78        sequence,
79    }
80}