abstract_os/native/
ibc_client.rs

1use self::state::AccountData;
2use crate::{abstract_ica::StdAck, ibc_host::HostAction, objects::core::OsId};
3use abstract_ica::IbcResponseMsg;
4use cosmwasm_schema::QueryResponses;
5use cosmwasm_std::{from_slice, Binary, Coin, CosmosMsg, StdResult, Timestamp};
6
7pub mod state {
8
9    use super::LatestQueryResponse;
10    use crate::{
11        objects::{ans_host::AnsHost, common_namespace::ADMIN_NAMESPACE, core::OsId},
12        ANS_HOST as ANS_HOST_KEY,
13    };
14    use cosmwasm_std::{Addr, Coin, Timestamp};
15    use cw_controllers::Admin;
16    use cw_storage_plus::{Item, Map};
17
18    #[cosmwasm_schema::cw_serde]
19    pub struct Config {
20        pub version_control_address: Addr,
21        pub chain: String,
22    }
23
24    #[cosmwasm_schema::cw_serde]
25    #[derive(Default)]
26    pub struct AccountData {
27        /// last block balance was updated (0 is never)
28        pub last_update_time: Timestamp,
29        /// In normal cases, it should be set, but there is a delay between binding
30        /// the channel and making a query and in that time it is empty.
31        ///
32        /// Since we do not have a way to validate the remote address format, this
33        /// must not be of type `Addr`.
34        pub remote_addr: Option<String>,
35        pub remote_balance: Vec<Coin>,
36    }
37
38    pub const ADMIN: Admin = Admin::new(ADMIN_NAMESPACE);
39    /// host_chain -> channel-id
40    pub const CHANNELS: Map<&str, String> = Map::new("channels");
41    pub const CONFIG: Item<Config> = Item::new("config");
42    /// (channel-id,os_id) -> remote_addr
43    pub const ACCOUNTS: Map<(&str, OsId), AccountData> = Map::new("accounts");
44    /// Todo: see if we can remove this
45    pub const LATEST_QUERIES: Map<(&str, OsId), LatestQueryResponse> = Map::new("queries");
46    pub const ANS_HOST: Item<AnsHost> = Item::new(ANS_HOST_KEY);
47}
48
49/// This needs no info. Owner of the contract is whoever signed the InstantiateMsg.
50#[cosmwasm_schema::cw_serde]
51pub struct InstantiateMsg {
52    pub ans_host_address: String,
53    pub version_control_address: String,
54    pub chain: String,
55}
56
57#[cosmwasm_schema::cw_serde]
58pub struct MigrateMsg {}
59
60#[cosmwasm_schema::cw_serde]
61pub struct CallbackInfo {
62    pub id: String,
63    pub receiver: String,
64}
65
66impl CallbackInfo {
67    pub fn to_callback_msg(self, ack_data: &Binary) -> StdResult<CosmosMsg> {
68        let msg: StdAck = from_slice(ack_data)?;
69        IbcResponseMsg { id: self.id, msg }.into_cosmos_msg(self.receiver)
70    }
71}
72
73#[cosmwasm_schema::cw_serde]
74#[cfg_attr(feature = "boot", derive(boot_core::ExecuteFns))]
75pub enum ExecuteMsg {
76    /// Update the Admin
77    UpdateAdmin {
78        admin: String,
79    },
80    /// Changes the config
81    UpdateConfig {
82        ans_host: Option<String>,
83        version_control: Option<String>,
84    },
85    /// Only callable by OS proxy
86    /// Will attempt to forward the specified funds to the corresponding
87    /// address on the remote chain.
88    SendFunds {
89        host_chain: String,
90        funds: Vec<Coin>,
91    },
92    /// Register an OS on a remote chain over IBC
93    /// This action creates a proxy for them on the remote chain.
94    Register {
95        host_chain: String,
96    },
97    SendPacket {
98        // host chain to be executed on
99        // Example: "osmosis"
100        host_chain: String,
101        // execute the custom host function
102        action: HostAction,
103        // optional callback info
104        callback_info: Option<CallbackInfo>,
105        // Number of retries if packet errors
106        retries: u8,
107    },
108    RemoveHost {
109        host_chain: String,
110    },
111}
112
113#[cosmwasm_schema::cw_serde]
114#[cfg_attr(feature = "boot", derive(boot_core::QueryFns))]
115#[derive(QueryResponses)]
116pub enum QueryMsg {
117    // Returns config
118    #[returns(ConfigResponse)]
119    Config {},
120    // Shows all open channels (incl. remote info)
121    #[returns(ListAccountsResponse)]
122    ListAccounts {},
123    // Get channel info for one chain
124    #[returns(AccountResponse)]
125    Account { chain: String, os_id: OsId },
126    // Get remote account info for a chain + OS
127    #[returns(LatestQueryResponse)]
128    LatestQueryResult { chain: String, os_id: OsId },
129    // get the channels
130    #[returns(ListChannelsResponse)]
131    ListChannels {},
132}
133
134#[cosmwasm_schema::cw_serde]
135pub struct ConfigResponse {
136    pub admin: String,
137    pub version_control_address: String,
138    pub chain: String,
139}
140
141#[cosmwasm_schema::cw_serde]
142pub struct ListAccountsResponse {
143    pub accounts: Vec<AccountInfo>,
144}
145#[cosmwasm_schema::cw_serde]
146pub struct ListChannelsResponse {
147    pub channels: Vec<(String, String)>,
148}
149
150#[cosmwasm_schema::cw_serde]
151pub struct LatestQueryResponse {
152    /// last block balance was updated (0 is never)
153    pub last_update_time: Timestamp,
154    pub response: StdAck,
155}
156
157#[cosmwasm_schema::cw_serde]
158pub struct RemoteProxyResponse {
159    /// last block balance was updated (0 is never)
160    pub channel_id: String,
161    /// address of the remote proxy
162    pub proxy_address: String,
163}
164
165#[cosmwasm_schema::cw_serde]
166pub struct AccountInfo {
167    pub channel_id: String,
168    pub os_id: OsId,
169    /// last block balance was updated (0 is never)
170    pub last_update_time: Timestamp,
171    /// in normal cases, it should be set, but there is a delay between binding
172    /// the channel and making a query and in that time it is empty
173    pub remote_addr: Option<String>,
174    pub remote_balance: Vec<Coin>,
175}
176
177impl AccountInfo {
178    pub fn convert(channel_id: String, os_id: OsId, input: AccountData) -> Self {
179        AccountInfo {
180            channel_id,
181            os_id,
182            last_update_time: input.last_update_time,
183            remote_addr: input.remote_addr,
184            remote_balance: input.remote_balance,
185        }
186    }
187}
188
189#[cosmwasm_schema::cw_serde]
190pub struct AccountResponse {
191    /// last block balance was updated (0 is never)
192    pub last_update_time: Timestamp,
193    /// in normal cases, it should be set, but there is a delay between binding
194    /// the channel and making a query and in that time it is empty
195    pub remote_addr: Option<String>,
196    pub remote_balance: Vec<Coin>,
197}
198
199impl From<AccountData> for AccountResponse {
200    fn from(input: AccountData) -> Self {
201        AccountResponse {
202            last_update_time: input.last_update_time,
203            remote_addr: input.remote_addr,
204            remote_balance: input.remote_balance,
205        }
206    }
207}