1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
pub mod multisig;
pub mod routing;

use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, CustomQuery, HexBinary, QuerierWrapper, StdResult};

#[cw_serde]
#[repr(u32)]
pub enum ISMType {
    Unused = 0,
    Routing = 1,
    Aggregation = 2,
    LegacyMultisig = 3,
    MerkleRootMultisig = 4,
    MessageIdMultisig = 5,
    Null = 6, // used with relayer carrying no metadata
    CcipRead = 7,
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum ISMQueryMsg {
    #[returns(ModuleTypeResponse)]
    ModuleType {},

    #[returns(VerifyResponse)]
    Verify {
        metadata: HexBinary,
        message: HexBinary,
    },

    #[returns(VerifyInfoResponse)]
    VerifyInfo { message: HexBinary },
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum ISMSpecifierQueryMsg {
    #[returns(InterchainSecurityModuleResponse)]
    InterchainSecurityModule(),
}

#[cw_serde]
pub struct ModuleTypeResponse {
    #[serde(rename = "type")]
    pub typ: ISMType,
}

#[cw_serde]
pub struct VerifyResponse {
    pub verified: bool,
}

#[cw_serde]
pub struct VerifyInfoResponse {
    pub threshold: u8,
    pub validators: Vec<String>,
}

#[cw_serde]
pub struct InterchainSecurityModuleResponse {
    pub ism: Option<Addr>,
}

pub fn recipient<C: CustomQuery>(
    querier: &QuerierWrapper<C>,
    recipient: impl Into<String>,
) -> StdResult<Option<Addr>> {
    let res = querier.query_wasm_smart::<InterchainSecurityModuleResponse>(
        recipient,
        &ISMSpecifierQueryMsg::InterchainSecurityModule(),
    )?;

    Ok(res.ism)
}

pub fn verify<C: CustomQuery>(
    querier: &QuerierWrapper<C>,
    ism: impl Into<String>,
    metadata: HexBinary,
    message: HexBinary,
) -> StdResult<bool> {
    let verify_resp = querier
        .query_wasm_smart::<VerifyResponse>(ism, &ISMQueryMsg::Verify { metadata, message })?;

    Ok(verify_resp.verified)
}