layer_climb_signer/
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            async fn address(&self, chain_config: &layer_climb_config::ChainConfig) -> Result<layer_climb_address::Address> {
20                let public_key = self.public_key().await?;
21                chain_config.address_from_pub_key(&public_key)
22            }
23        }
24    } else {
25        #[async_trait]
26        pub trait TxSigner: Send + Sync {
27            async fn sign(&self, doc: &layer_climb_proto::tx::SignDoc) -> Result<Vec<u8>>;
28            async fn public_key(&self) -> Result<PublicKey>;
29            async fn public_key_as_proto(&self) -> Result<layer_climb_proto::Any> {
30                public_key_to_proto(&self.public_key().await?)
31            }
32            async fn signer_info(&self, sequence: u64, sign_mode: layer_climb_proto::tx::SignMode) -> Result<layer_climb_proto::tx::SignerInfo> {
33                Ok(signer_info(self.public_key_as_proto().await?, sequence, sign_mode))
34            }
35            async fn address(&self, chain_config: &layer_climb_config::ChainConfig) -> Result<layer_climb_address::Address> {
36                let public_key = self.public_key().await?;
37                chain_config.address_from_pub_key(&public_key)
38            }
39        }
40    }
41}
42
43fn public_key_to_proto(public_key: &PublicKey) -> Result<layer_climb_proto::Any> {
44    let value = match public_key {
45        tendermint::PublicKey::Ed25519(_) => layer_climb_proto::crypto::ed25519::PubKey {
46            key: public_key.to_bytes(),
47        }
48        .to_bytes()?,
49        tendermint::PublicKey::Secp256k1(_) => layer_climb_proto::crypto::secp256k1::PubKey {
50            key: public_key.to_bytes(),
51        }
52        .to_bytes()?,
53        _ => {
54            bail!("Invalid public key type!")
55        }
56    };
57
58    let type_url = match public_key {
59        tendermint::PublicKey::Ed25519(_) => "/cosmos.crypto.ed25519.PubKey",
60        tendermint::PublicKey::Secp256k1(_) => "/cosmos.crypto.secp256k1.PubKey",
61        _ => {
62            bail!("Invalid public key type!")
63        }
64    };
65
66    Ok(layer_climb_proto::Any {
67        type_url: type_url.to_string(),
68        value,
69    })
70}
71
72fn signer_info(
73    public_key: layer_climb_proto::Any,
74    sequence: u64,
75    sign_mode: layer_climb_proto::tx::SignMode,
76) -> layer_climb_proto::tx::SignerInfo {
77    layer_climb_proto::tx::SignerInfo {
78        public_key: Some(public_key),
79        mode_info: Some(layer_climb_proto::tx::ModeInfo {
80            sum: Some(layer_climb_proto::tx::mode_info::Sum::Single(
81                layer_climb_proto::tx::mode_info::Single {
82                    mode: sign_mode.into(),
83                },
84            )),
85        }),
86        sequence,
87    }
88}