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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
pub mod aggregate;
pub mod merkle;
pub mod pausable;
pub mod routing;
pub mod routing_custom;
pub mod routing_fallback;
pub mod fee;

use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{
    wasm_execute, Coin, CustomQuery, HexBinary, QuerierWrapper, StdResult, WasmMsg,
};

#[cw_serde]
pub struct PostDispatchMsg {
    pub metadata: HexBinary,
    pub message: HexBinary,
}

impl PostDispatchMsg {
    pub fn wrap(self) -> ExpectedHookMsg {
        ExpectedHookMsg::PostDispatch(self)
    }
}

#[cw_serde]
#[derive(Default)]
pub struct QuoteDispatchMsg {
    pub metadata: HexBinary,
    pub message: HexBinary,
}

impl QuoteDispatchMsg {
    pub fn wrap(self) -> HookQueryMsg {
        HookQueryMsg::QuoteDispatch(self)
    }

    pub fn request(self) -> ExpectedHookQueryMsg {
        ExpectedHookQueryMsg::Hook(self.wrap())
    }
}

/// This is the basic message to demonstrate the required interface
#[cw_serde]
pub enum ExpectedHookMsg {
    PostDispatch(PostDispatchMsg),
}

#[cw_serde]
#[derive(QueryResponses)]
pub enum HookQueryMsg {
    #[returns(QuoteDispatchResponse)]
    QuoteDispatch(QuoteDispatchMsg),

    #[returns(MailboxResponse)]
    Mailbox {},
}

#[cw_serde]
#[derive(QueryResponses)]
#[query_responses(nested)]
pub enum ExpectedHookQueryMsg {
    Hook(HookQueryMsg),
}

#[cw_serde]
pub struct MailboxResponse {
    pub mailbox: String,
}

#[cw_serde]
pub struct QuoteDispatchResponse {
    pub fees: Vec<Coin>,
}

pub fn post_dispatch(
    hook: impl Into<String>,
    metadata: impl Into<HexBinary>,
    message: impl Into<HexBinary>,
    funds: Option<Vec<Coin>>,
) -> StdResult<WasmMsg> {
    wasm_execute(
        hook,
        &PostDispatchMsg {
            metadata: metadata.into(),
            message: message.into(),
        }
        .wrap(),
        funds.unwrap_or_default(),
    )
}

pub fn quote_dispatch<C: CustomQuery>(
    querier: &QuerierWrapper<C>,
    hook: impl Into<String>,
    metadata: impl Into<HexBinary>,
    message: impl Into<HexBinary>,
) -> StdResult<QuoteDispatchResponse> {
    querier.query_wasm_smart(
        hook,
        &QuoteDispatchMsg {
            metadata: metadata.into(),
            message: message.into(),
        }
        .request(),
    )
}