1use cosmwasm_schema::{
2 cw_serde,
3 serde::{de::DeserializeOwned, Serialize},
4};
5use cosmwasm_std::{
6 from_json, to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, StdResult, WasmMsg,
7};
8
9#[cw_serde]
10pub struct CallbackMsg {
11 pub data: Binary,
12 pub callback: CallbackData,
13}
14#[cw_serde]
15pub struct CallbackData(pub Binary);
16
17#[cw_serde]
18enum ReceiverExecuteMsg {
20 Callback(CallbackMsg),
21}
22
23impl CallbackData {
24 pub fn to_message<T>(
25 &self,
26 cb_addr: &Addr,
27 data: impl Serialize,
28 funds: impl Into<Vec<Coin>>,
29 ) -> StdResult<CosmosMsg<T>> {
30 let msg = CallbackMsg {
31 data: to_json_binary(&data)?,
32 callback: self.clone(),
33 };
34 Ok(CosmosMsg::Wasm(WasmMsg::Execute {
35 contract_addr: cb_addr.to_string(),
36 msg: to_json_binary(&ReceiverExecuteMsg::Callback(msg))?,
37 funds: funds.into(),
38 }))
39 }
40
41 pub fn into_json_binary(self) -> Binary {
42 self.0
43 }
44}
45
46impl CallbackMsg {
47 pub fn new<D: Serialize>(data: D, callback: CallbackData) -> StdResult<Self> {
48 let data = to_json_binary(&data)?;
49 Ok(Self { data, callback })
50 }
51
52 pub fn new_without_data(callback: CallbackData) -> Self {
53 Self {
54 data: to_json_binary(&Empty {}).unwrap(),
55 callback,
56 }
57 }
58
59 pub fn deserialize<D: DeserializeOwned, CB: DeserializeOwned>(self) -> StdResult<(D, CB)> {
60 let data = from_json(&self.data)?;
61 let callback = from_json(self.callback.into_json_binary())?;
62 Ok((data, callback))
63 }
64
65 pub fn deserialize_data<D: DeserializeOwned>(&self) -> StdResult<D> {
66 let data = from_json(&self.data)?;
67 Ok(data)
68 }
69
70 pub fn deserialize_callback<CB: DeserializeOwned>(&self) -> StdResult<CB> {
71 let callback = from_json(self.callback.clone().into_json_binary())?;
72 Ok(callback)
73 }
74}
75
76impl From<Binary> for CallbackData {
77 fn from(b: Binary) -> Self {
78 Self(b)
79 }
80}