abstract_os/
api.rs

1//! # Abstract Api Base
2//!
3//! `abstract_os::api` implements shared functionality that's useful for creating new Abstract apis.
4//!
5//! ## Description
6//! An Abstract api 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 OS.
8//! The api structure is well-suited for implementing standard interfaces to external services like dexes, lending platforms, etc.
9
10use crate::base::{
11    ExecuteMsg as MiddlewareExecMsg, InstantiateMsg as MiddlewareInstantiateMsg,
12    QueryMsg as MiddlewareQueryMsg,
13};
14use cosmwasm_schema::QueryResponses;
15use cosmwasm_std::{Addr, Empty};
16use serde::Serialize;
17
18pub type ExecuteMsg<Request = Empty, ReceiveMsg = Empty> =
19    MiddlewareExecMsg<BaseExecuteMsg, ApiRequestMsg<Request>, ReceiveMsg>;
20pub type QueryMsg<AppMsg = Empty> = MiddlewareQueryMsg<BaseQueryMsg, AppMsg>;
21pub type InstantiateMsg<AppMsg = Empty> = MiddlewareInstantiateMsg<BaseInstantiateMsg, AppMsg>;
22
23/// Trait indicates that the type is used as an app message
24/// in the [`ExecuteMsg`] enum.
25/// Enables [`Into<ExecuteMsg>`] for BOOT fn-generation support.
26pub trait ApiExecuteMsg: Serialize {}
27
28impl<T: ApiExecuteMsg, R: Serialize> From<T> for ExecuteMsg<T, R> {
29    fn from(api_msg: T) -> Self {
30        Self::App(ApiRequestMsg {
31            proxy_address: None,
32            request: api_msg,
33        })
34    }
35}
36
37impl ApiExecuteMsg for Empty {}
38
39/// Trait indicates that the type is used as an api message
40/// in the [`QueryMsg`] enum.
41/// Enables [`Into<QueryMsg>`] for BOOT fn-generation support.
42pub trait ApiQueryMsg: Serialize {}
43
44impl<T: ApiQueryMsg> From<T> for QueryMsg<T> {
45    fn from(app: T) -> Self {
46        Self::App(app)
47    }
48}
49
50impl ApiQueryMsg for Empty {}
51
52/// Used by Abstract to instantiate the contract
53/// The contract is then registered on the version control contract using [`crate::version_control::ExecuteMsg::AddModules`].
54#[cosmwasm_schema::cw_serde]
55pub struct BaseInstantiateMsg {
56    /// Used to easily perform address translation
57    pub ans_host_address: String,
58    /// Used to verify senders
59    pub version_control_address: String,
60}
61
62impl<RequestMsg, ReceiveMsg> From<BaseExecuteMsg>
63    for MiddlewareExecMsg<BaseExecuteMsg, RequestMsg, ReceiveMsg>
64{
65    fn from(api_msg: BaseExecuteMsg) -> Self {
66        Self::Base(api_msg)
67    }
68}
69
70impl<RequestMsg, Request, BaseExecMsg> From<ApiRequestMsg<RequestMsg>>
71    for MiddlewareExecMsg<BaseExecMsg, ApiRequestMsg<RequestMsg>, Request>
72{
73    fn from(request_msg: ApiRequestMsg<RequestMsg>) -> Self {
74        Self::App(request_msg)
75    }
76}
77
78/// An api request.
79/// If proxy is None, then the sender must be an OS manager and the proxy address is extrapolated from the OS id.
80#[cosmwasm_schema::cw_serde]
81pub struct ApiRequestMsg<Request> {
82    pub proxy_address: Option<String>,
83    /// The actual request
84    pub request: Request,
85}
86
87impl<Request: Serialize> ApiRequestMsg<Request> {
88    pub fn new(proxy_address: Option<String>, request: Request) -> Self {
89        Self {
90            proxy_address,
91            request,
92        }
93    }
94}
95
96/// Configuration message for the api
97#[cosmwasm_schema::cw_serde]
98#[cfg_attr(feature = "boot", derive(boot_core::ExecuteFns))]
99#[cfg_attr(feature = "boot", impl_into(ExecuteMsg<T>))]
100pub enum BaseExecuteMsg {
101    /// Add or remove traders
102    /// If a trader is both in to_add and to_remove, it will be removed.
103    UpdateTraders {
104        to_add: Vec<String>,
105        to_remove: Vec<String>,
106    },
107    /// Remove the api
108    Remove {},
109}
110
111/// Query api message
112#[cosmwasm_schema::cw_serde]
113#[derive(QueryResponses)]
114#[cfg_attr(feature = "boot", derive(boot_core::QueryFns))]
115#[cfg_attr(feature = "boot", impl_into(QueryMsg<AppMsg>))]
116pub enum BaseQueryMsg {
117    /// Returns [`ApiConfigResponse`].
118    #[returns(ApiConfigResponse)]
119    Config {},
120    /// Returns [`TradersResponse`].
121    /// TODO: enable pagination
122    #[returns(TradersResponse)]
123    Traders { proxy_address: String },
124}
125
126impl<T> From<BaseQueryMsg> for QueryMsg<T> {
127    fn from(base: BaseQueryMsg) -> Self {
128        Self::Base(base)
129    }
130}
131#[cosmwasm_schema::cw_serde]
132pub struct ApiConfigResponse {
133    pub version_control_address: Addr,
134    pub ans_host_address: Addr,
135    pub dependencies: Vec<String>,
136}
137
138#[cosmwasm_schema::cw_serde]
139pub struct TradersResponse {
140    /// Contains all traders
141    pub traders: Vec<Addr>,
142}