1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::{Addr, Decimal256, Empty, QueryRequest};
3
4pub const BASE_PRECISION: u8 = 6;
8
9#[cw_serde]
10pub struct InstantiateMsg {
11 pub owner: String,
12 pub base_asset: String,
13}
14
15#[cw_serde]
16pub enum ExecuteMsg {
17 UpdateConfig {
18 owner: Option<String>,
19 },
20
21 FeedPrice {
22 prices: Vec<FeedPriceInfo>, },
24
25 UpdateSource {
26 asset: String,
27 source: UpdateSource,
28 },
29
30 RegisterAsset {
31 asset: String,
32 source: RegisterSource,
33 },
34}
35
36#[cw_serde]
37pub enum QueryMsg {
38 Config {},
39 SourceInfo {
40 asset: String,
41 },
42 Price {
43 base: String,
44 quote: String,
45 },
46 Prices {
47 start_after: Option<String>,
48 limit: Option<u32>,
49 },
50}
51
52#[cw_serde]
53pub struct MigrateMsg {}
54
55#[cw_serde]
56pub struct FeedPriceInfo {
57 pub asset_name: String,
58 pub price: Decimal256,
59}
60
61impl From<(String, Decimal256)> for FeedPriceInfo {
62 fn from(value: (String, Decimal256)) -> Self {
63 Self {
64 asset_name: value.0,
65 price: value.1,
66 }
67 }
68}
69
70#[cw_serde]
71pub enum Source {
72 Feeder {
73 feeder: Addr,
74 price: Option<Decimal256>,
75 last_updated_time: Option<u64>,
76 normalized_precision: u8,
77 },
78 OnChainQuery {
79 base_asset: Option<String>,
80 query: QueryRequest<Empty>,
81 path_key: Vec<PathKey>,
82 is_inverted: bool,
83 },
84 AstroportLpVault {
85 vault_contract: Addr,
86 generator_contract: Addr,
87 pool_contract: Addr,
88 lp_contract: Addr,
89 assets: Vec<String>,
90 },
91}
92
93#[cw_serde]
94pub enum RegisterSource {
95 Feeder {
96 feeder: String,
97
98 precision: u8,
99 },
100 OnChainRate {
101 base_asset: Option<String>,
102 query: QueryRequest<Empty>,
103 path_key: Vec<PathKey>,
104 is_inverted: bool,
105 },
106 AstroportLpVault {
107 vault_contract: Addr,
108 generator_contract: Addr,
109 pool_contract: Addr,
110 },
111}
112
113#[cw_serde]
114pub enum UpdateSource {
115 Feeder {
116 feeder: Addr,
117 precision: u8,
118 },
119 OnChainRate {
120 base_asset: Option<UpdateOption<String>>,
121 query: Option<QueryRequest<Empty>>,
122 path_key: Option<Vec<PathKey>>,
123 is_inverted: Option<bool>,
124 },
125 AstroportLpVault {
126 vault_contract: Option<Addr>,
127 generator_contract: Option<Addr>,
128 pool_contract: Option<Addr>,
129 },
130}
131
132#[cw_serde]
134pub struct ConfigResponse {
135 pub owner: String,
136 pub base_asset: String,
137}
138
139#[cw_serde]
141pub struct SourceInfoResponse {
142 pub source: Source,
143}
144
145#[cw_serde]
147pub struct PriceResponse {
148 pub rate: Decimal256,
149 pub last_updated_base: u64,
150 pub last_updated_quote: u64,
151}
152
153#[cw_serde]
155pub struct PricesResponseElem {
156 pub asset: String,
157 pub price: Decimal256,
158 pub last_updated_time: u64,
159}
160
161#[cw_serde]
163pub struct PricesResponse {
164 pub prices: Vec<PricesResponseElem>,
165}
166
167#[cw_serde]
168pub enum PathKey {
169 Index(u64),
170 String(String),
171}
172
173#[cw_serde]
174pub enum UpdateOption<T> {
175 ToNone,
176 Some(T),
177}
178
179impl<T: Clone> UpdateOption<T> {
180 pub fn into_option(&self) -> Option<T> {
181 match self {
182 UpdateOption::ToNone => None,
183 UpdateOption::Some(t) => Some(t.clone()),
184 }
185 }
186
187 pub fn unwrap(self) -> T {
188 match self {
189 UpdateOption::ToNone => panic!("Unwrap a None value"),
190 UpdateOption::Some(val) => val,
191 }
192 }
193}
194
195#[allow(clippy::from_over_into)]
196impl<T> Into<Option<T>> for UpdateOption<T> {
197 fn into(self) -> Option<T> {
198 match self {
199 UpdateOption::ToNone => None,
200 UpdateOption::Some(val) => Some(val),
201 }
202 }
203}