abstract_sdk/apis/ibc_memo/
hooks.rs

1use std::collections::BTreeMap;
2
3use cosmwasm_std::{from_json, to_json_binary, Addr, Binary, Env};
4use serde_cw_value::Value;
5
6/// Builder for [IbcHooks](https://github.com/cosmos/ibc-apps/tree/main/modules/ibc-hooks) memo field.
7pub struct HookMemoBuilder {
8    contract_addr: String,
9    msg: Binary,
10    ibc_callback: Option<Addr>,
11}
12
13impl HookMemoBuilder {
14    /// New Wasm Contract Memo IBC Hook
15    /// Note: contract_addr should be the same as "receiver"
16    pub fn new(contract_addr: impl Into<String>, msg: &impl serde::Serialize) -> Self {
17        let msg = to_json_binary(&msg).unwrap();
18        Self {
19            contract_addr: contract_addr.into(),
20            msg,
21            ibc_callback: None,
22        }
23    }
24
25    /// Contract that will receive callback, see:
26    /// https://github.com/cosmos/ibc-apps/blob/main/modules/ibc-hooks/README.md#interface-for-receiving-the-acks-and-timeouts
27    pub fn callback_contract(mut self, callback_contract: Addr) -> Self {
28        self.ibc_callback = Some(callback_contract);
29        self
30    }
31
32    /// The current contract will receive a callback
33    /// https://github.com/cosmos/ibc-apps/blob/main/modules/ibc-hooks/README.md#interface-for-receiving-the-acks-and-timeouts
34    pub fn callback(self, env: &Env) -> Self {
35        self.callback_contract(env.contract.address.clone())
36    }
37
38    /// Build memo json string
39    pub fn build(self) -> cosmwasm_std::StdResult<String> {
40        let execute_wasm_value = BTreeMap::from([
41            (
42                Value::String("contract".to_owned()),
43                Value::String(self.contract_addr),
44            ),
45            (
46                Value::String("msg".to_owned()),
47                from_json(&self.msg).expect("expected valid json message"),
48            ),
49        ]);
50
51        let mut memo = BTreeMap::from([(
52            Value::String("wasm".to_owned()),
53            Value::Map(execute_wasm_value.into_iter().collect()),
54        )]);
55        if let Some(contract_addr) = self.ibc_callback {
56            memo.insert(
57                Value::String("ibc_callback".to_owned()),
58                Value::String(contract_addr.into_string()),
59            );
60        }
61        cosmwasm_std::to_json_string(&memo)
62    }
63}