abstract_std/
adapter.rs

1//! # Abstract Api Base
2//!
3//! `abstract_std::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 [account](crate::account) 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> =
23    MiddlewareExecMsg<BaseExecuteMsg, AdapterRequestMsg<Request>>;
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 {}
32impl<T: AdapterExecuteMsg> From<T> for ExecuteMsg<T> {
33    fn from(request: T) -> Self {
34        Self::Module(AdapterRequestMsg {
35            account_address: None,
36            request,
37        })
38    }
39}
40
41impl AdapterExecuteMsg for Empty {}
42
43/// Trait indicates that the type is used as an api message
44/// in the [`QueryMsg`] enum.
45/// Enables [`Into<QueryMsg>`] for BOOT fn-generation support.
46pub trait AdapterQueryMsg: Serialize {}
47
48impl<T: AdapterQueryMsg> From<T> for QueryMsg<T> {
49    fn from(module: T) -> Self {
50        Self::Module(module)
51    }
52}
53
54impl AdapterQueryMsg for Empty {}
55
56/// Used by Abstract to instantiate the contract
57/// The contract is then registered on the registry contract using [`crate::registry::ExecuteMsg::ProposeModules`].
58#[cosmwasm_schema::cw_serde]
59pub struct BaseInstantiateMsg {
60    pub registry_address: String,
61}
62
63impl<RequestMsg> From<BaseExecuteMsg> for MiddlewareExecMsg<BaseExecuteMsg, RequestMsg> {
64    fn from(adapter_msg: BaseExecuteMsg) -> Self {
65        Self::Base(adapter_msg)
66    }
67}
68
69impl<RequestMsg, BaseExecMsg> From<AdapterRequestMsg<RequestMsg>>
70    for MiddlewareExecMsg<BaseExecMsg, AdapterRequestMsg<RequestMsg>>
71{
72    fn from(request_msg: AdapterRequestMsg<RequestMsg>) -> Self {
73        Self::Module(request_msg)
74    }
75}
76
77/// An adapter request.
78/// If account is None, then the sender must be an Account.
79#[cosmwasm_schema::cw_serde]
80pub struct AdapterRequestMsg<Request> {
81    pub account_address: Option<String>,
82    /// The actual request
83    pub request: Request,
84}
85
86impl<Request: Serialize> AdapterRequestMsg<Request> {
87    pub fn new(account_address: Option<String>, request: Request) -> Self {
88        Self {
89            account_address,
90            request,
91        }
92    }
93}
94
95// serde attributes remain it compatible with previous versions in cases where account_address is omitted
96#[cosmwasm_schema::cw_serde]
97pub struct BaseExecuteMsg {
98    /// The account address for which to apply the configuration
99    /// If None, the sender must be an Account
100    /// If Some, the sender must be a direct or indirect owner (through sub-accounts) of the specified account.
101    pub account_address: Option<String>,
102    // The actual base message
103    pub msg: AdapterBaseMsg,
104}
105
106/// Configuration message for the adapter
107#[cosmwasm_schema::cw_serde]
108pub enum AdapterBaseMsg {
109    /// Add or remove authorized addresses
110    /// If an authorized address is both in to_add and to_remove, it will be removed.
111    UpdateAuthorizedAddresses {
112        to_add: Vec<String>,
113        to_remove: Vec<String>,
114    },
115}
116
117/// Query adapter message
118#[cosmwasm_schema::cw_serde]
119#[derive(QueryResponses, cw_orch::QueryFns)]
120pub enum BaseQueryMsg {
121    /// Returns [`AdapterConfigResponse`].
122    #[returns(AdapterConfigResponse)]
123    BaseConfig {},
124    /// Returns [`AuthorizedAddressesResponse`].
125    #[returns(AuthorizedAddressesResponse)]
126    AuthorizedAddresses { account_address: String },
127    /// Returns module data
128    /// Returns [`ModuleDataResponse`].
129    #[returns(ModuleDataResponse)]
130    ModuleData {},
131}
132
133impl<T> From<BaseQueryMsg> for QueryMsg<T> {
134    fn from(base: BaseQueryMsg) -> Self {
135        Self::Base(base)
136    }
137}
138
139#[cosmwasm_schema::cw_serde]
140pub struct AdapterConfigResponse {
141    pub registry_address: Addr,
142    pub ans_host_address: Addr,
143    pub dependencies: Vec<String>,
144}
145
146#[cosmwasm_schema::cw_serde]
147pub struct AuthorizedAddressesResponse {
148    /// Contains all authorized addresses
149    pub addresses: Vec<Addr>,
150}
151
152/// The BaseState contains the main addresses needed for sending and verifying messages
153/// Every DApp should use the provided **ans_host** contract for token/contract address resolution.
154#[cosmwasm_schema::cw_serde]
155pub struct AdapterState {
156    /// Code id of abstract contract
157    pub code_id: u64,
158}