abstract_core/
adapter.rs

1//! # Abstract Api Base
2//!
3//! `abstract_core::adapter` implements shared functionality that's useful for creating new Abstract adapters.
4//!
5//! ## Description
6//! An Abstract adapter contract is a contract that is allowed to perform actions on a [proxy](crate::proxy) contract.
7//! It is not migratable and its functionality is shared between users, meaning that all users call the same contract address to perform operations on the Account.
8//! The adapter structure is well-suited for implementing standard interfaces to external services like dexes, lending platforms, etc.
9
10use cosmwasm_schema::QueryResponses;
11use cosmwasm_std::{Addr, Empty};
12use serde::Serialize;
13
14use crate::{
15    base::{
16        ExecuteMsg as MiddlewareExecMsg, InstantiateMsg as MiddlewareInstantiateMsg,
17        QueryMsg as MiddlewareQueryMsg,
18    },
19    objects::module_version::ModuleDataResponse,
20};
21
22pub type ExecuteMsg<Request = Empty, ReceiveMsg = Empty> =
23    MiddlewareExecMsg<BaseExecuteMsg, AdapterRequestMsg<Request>, ReceiveMsg>;
24pub type QueryMsg<ModuleMsg = Empty> = MiddlewareQueryMsg<BaseQueryMsg, ModuleMsg>;
25pub type InstantiateMsg<ModuleMsg = Empty> =
26    MiddlewareInstantiateMsg<BaseInstantiateMsg, ModuleMsg>;
27
28/// Trait indicates that the type is used as an app message
29/// in the [`ExecuteMsg`] enum.
30/// Enables [`Into<ExecuteMsg>`] for BOOT fn-generation support.
31pub trait AdapterExecuteMsg: Serialize {}
32
33impl<T: AdapterExecuteMsg, R: Serialize> From<T> for ExecuteMsg<T, R> {
34    fn from(adapter_msg: T) -> Self {
35        Self::Module(AdapterRequestMsg {
36            proxy_address: None,
37            request: adapter_msg,
38        })
39    }
40}
41
42impl AdapterExecuteMsg for Empty {}
43
44/// Trait indicates that the type is used as an api message
45/// in the [`QueryMsg`] enum.
46/// Enables [`Into<QueryMsg>`] for BOOT fn-generation support.
47pub trait AdapterQueryMsg: Serialize {}
48
49impl<T: AdapterQueryMsg> From<T> for QueryMsg<T> {
50    fn from(app: T) -> Self {
51        Self::Module(app)
52    }
53}
54
55impl AdapterQueryMsg for Empty {}
56
57/// Used by Abstract to instantiate the contract
58/// The contract is then registered on the version control contract using [`crate::version_control::ExecuteMsg::ProposeModules`].
59#[cosmwasm_schema::cw_serde]
60pub struct BaseInstantiateMsg {
61    /// Used to easily perform address translation
62    pub ans_host_address: String,
63    /// Used to verify senders
64    pub version_control_address: String,
65}
66
67impl<RequestMsg, ReceiveMsg> From<BaseExecuteMsg>
68    for MiddlewareExecMsg<BaseExecuteMsg, RequestMsg, ReceiveMsg>
69{
70    fn from(adapter_msg: BaseExecuteMsg) -> Self {
71        Self::Base(adapter_msg)
72    }
73}
74
75impl<RequestMsg, Request, BaseExecMsg> From<AdapterRequestMsg<RequestMsg>>
76    for MiddlewareExecMsg<BaseExecMsg, AdapterRequestMsg<RequestMsg>, Request>
77{
78    fn from(request_msg: AdapterRequestMsg<RequestMsg>) -> Self {
79        Self::Module(request_msg)
80    }
81}
82
83/// An adapter request.
84/// If proxy is None, then the sender must be an Account manager and the proxy address is extrapolated from the Account id.
85#[cosmwasm_schema::cw_serde]
86pub struct AdapterRequestMsg<Request> {
87    pub proxy_address: Option<String>,
88    /// The actual request
89    pub request: Request,
90}
91
92impl<Request: Serialize> AdapterRequestMsg<Request> {
93    pub fn new(proxy_address: Option<String>, request: Request) -> Self {
94        Self {
95            proxy_address,
96            request,
97        }
98    }
99}
100
101// serde attributes remain it compatible with previous versions in cases where proxy_address is omitted
102#[cosmwasm_schema::cw_serde]
103pub struct BaseExecuteMsg {
104    /// The Proxy address for which to apply the configuration
105    /// If None, the sender must be an Account manager and the configuration is applied to its associated proxy.
106    /// If Some, the sender must be a direct or indirect owner (through sub-accounts) of the specified proxy.
107    pub proxy_address: Option<String>,
108    // The actual base message
109    pub msg: AdapterBaseMsg,
110}
111
112/// Configuration message for the adapter
113#[cosmwasm_schema::cw_serde]
114pub enum AdapterBaseMsg {
115    /// Add or remove authorized addresses
116    /// If an authorized address is both in to_add and to_remove, it will be removed.
117    UpdateAuthorizedAddresses {
118        to_add: Vec<String>,
119        to_remove: Vec<String>,
120    },
121}
122
123/// Query adapter message
124#[cosmwasm_schema::cw_serde]
125#[derive(QueryResponses)]
126#[cfg_attr(feature = "interface", derive(cw_orch::QueryFns))]
127#[cfg_attr(feature = "interface", impl_into(QueryMsg<ModuleMsg>))]
128pub enum BaseQueryMsg {
129    /// Returns [`AdapterConfigResponse`].
130    #[returns(AdapterConfigResponse)]
131    BaseConfig {},
132    /// Returns [`AuthorizedAddressesResponse`].
133    #[returns(AuthorizedAddressesResponse)]
134    AuthorizedAddresses { proxy_address: String },
135    /// Returns module data
136    /// Returns [`ModuleDataResponse`].
137    #[returns(ModuleDataResponse)]
138    ModuleData {},
139}
140
141impl<T> From<BaseQueryMsg> for QueryMsg<T> {
142    fn from(base: BaseQueryMsg) -> Self {
143        Self::Base(base)
144    }
145}
146
147#[cosmwasm_schema::cw_serde]
148pub struct AdapterConfigResponse {
149    pub version_control_address: Addr,
150    pub ans_host_address: Addr,
151    pub dependencies: Vec<String>,
152}
153
154#[cosmwasm_schema::cw_serde]
155pub struct AuthorizedAddressesResponse {
156    /// Contains all authorized addresses
157    pub addresses: Vec<Addr>,
158}