saa_custom/cosmos/
arbitrary.rs

1
2#[cfg(any(feature = "wasm", feature = "native"))]
3use {
4    saa_common::{hashes::sha256, utils::pubkey_to_address, ensure},
5    super::utils::preamble_msg_arb_036
6};
7use saa_common::{AuthError, Binary, CredentialId, String, ToString, Verifiable};
8use saa_schema::wasm_serde;
9
10
11#[wasm_serde]
12pub struct CosmosArbitrary {
13    pub pubkey:    Binary,
14    pub signature: Binary,
15    pub message:   Binary,
16    pub hrp:       Option<String>
17}
18
19#[cfg(any(feature = "wasm", feature = "native"))]
20impl CosmosArbitrary {
21    fn message_digest(&self) -> Result<Vec<u8>, AuthError> {
22        ensure!(self.hrp.is_some(), AuthError::Generic("Must provide prefix for the public key".to_string()));
23        Ok(sha256(&preamble_msg_arb_036(
24            pubkey_to_address(&self.pubkey, self.hrp.as_ref().unwrap())?.as_str(),
25            &self.message.to_string()
26        ).as_bytes()))
27    }
28}
29
30
31impl Verifiable for CosmosArbitrary {
32
33    fn id(&self) -> CredentialId {
34        self.pubkey.to_vec()
35    }
36
37    fn hrp(&self) -> Option<String> {
38        self.hrp.clone()
39    }
40
41    fn validate(&self) -> Result<(), AuthError> {
42        if !(self.signature.len() > 0 &&
43            self.message.to_string().len() > 0 && 
44            self.pubkey.len() > 0) {
45            return Err(AuthError::MissingData("Empty credential data".to_string()));
46        }
47        Ok(())
48    }
49
50    #[cfg(feature = "native")]
51    fn verify(&self) -> Result<(), AuthError> {
52        let success = saa_common::crypto::secp256k1_verify(
53            &self.message_digest()?,
54            &self.signature,
55            &self.pubkey
56        )?;
57        ensure!(success, AuthError::Signature("Signature verification failed".to_string()));
58        Ok(())
59    }
60
61
62    #[cfg(feature = "wasm")]
63    fn verify_cosmwasm(
64        &self, 
65        api:  &dyn saa_common::cosmwasm::Api
66    ) -> Result<(), AuthError> {
67        let success = api.secp256k1_verify(
68            &self.message_digest()?,
69            &self.signature,
70            &self.pubkey
71        )?;
72        ensure!(success, AuthError::Signature("Signature verification failed".to_string()));
73        Ok(())
74    }
75
76}