Skip to content
This repository has been archived by the owner on Dec 29, 2023. It is now read-only.

Commit

Permalink
feat/Query spot orders (#30)
Browse files Browse the repository at this point in the history
* feat: add query to multiple orders

* save change

* save change

* test: create test for get spot orders

* feat: bindings repository integration

* feat: get orders logic with binding pagination

* test: fix get orders tests

* ci: trigger GitHub Actions

* integrate the binding module to the smart contract (#29)

* save change

* save change

* feat: bindings repository integration

* feat: script to test the process order endpoint

* fix: fix the code to be usable with the changes from the bindings repository

* feat: add query to multiple orders

* test: create test for get spot orders

* save change

* feat: bindings repository integration

* feat: get orders logic with binding pagination

* test: fix get orders tests

* fix: remove unused import

* test: create test for get spot orders

* ci: trigger GitHub Actions
  • Loading branch information
politeWall authored Nov 16, 2023
1 parent a596ee9 commit 58eaabd
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod query {
mod asset_info;
mod get_all_price;
mod get_spot_order;
mod get_spot_orders;

use super::*;

Expand All @@ -16,6 +17,7 @@ pub mod query {
pub use asset_info::asset_info;
pub use get_all_price::get_all_prices;
pub use get_spot_order::get_spot_order;
pub use get_spot_orders::get_spot_orders;
}

pub mod execute {
Expand Down
51 changes: 51 additions & 0 deletions src/action/query/get_spot_orders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use super::*;

pub fn get_spot_orders(
deps: Deps<ElysQuery>,
pagination: PageRequest,
order_owner: Option<String>,
order_type: Option<SpotOrderType>,
) -> Result<GetSpotOrdersResp, ContractError> {
let orders = SPOT_ORDER.load(deps.storage)?;

let (orders, page_response) = pagination.filter(orders)?;

if orders.is_empty() {
return Ok(GetSpotOrdersResp {
page_response,
orders,
});
};

let orders = match (order_owner, order_type) {
(None, Some(order_type)) => orders
.iter()
.filter(|order| order.order_type == order_type)
.cloned()
.collect(),
(Some(owner), None) => orders
.iter()
.filter(|order| order.owner_address == owner)
.cloned()
.collect(),
(Some(owner), Some(order_type)) => orders
.iter()
.filter(|order| order.owner_address == owner && order.order_type == order_type)
.cloned()
.collect(),
(None, None) => orders,
};

let page_response = match page_response.total {
Some(_) => PageResponse {
next_key: page_response.next_key,
total: Some(orders.len() as u64),
},
None => page_response,
};

Ok(GetSpotOrdersResp {
page_response,
orders,
})
}
10 changes: 10 additions & 0 deletions src/entry_point/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,15 @@ pub fn query(deps: Deps<ElysQuery>, _env: Env, msg: QueryMsg) -> Result<Binary,
GetSpotOrder { order_id } => Ok(to_json_binary(&query::get_spot_order(deps, order_id)?)?),
GetAllPrices {} => Ok(to_json_binary(&query::get_all_prices(deps)?)?),
AssetInfo { denom } => Ok(to_json_binary(&query::asset_info(deps, denom)?)?),
GetSpotOrders {
pagination,
order_owner,
order_type,
} => Ok(to_json_binary(&query::get_spot_orders(
deps,
pagination,
order_owner,
order_type,
)?)?),
}
}
6 changes: 4 additions & 2 deletions src/msg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ pub use reply_type::ReplyType;

pub mod query_resp {
mod get_all_prices_resp;
mod get_order_resp;
mod get_spot_order_resp;
mod get_spot_orders_resp;
pub use get_all_prices_resp::GetAllPricesResponse;
pub use get_order_resp::GetSpotOrderResp;
pub use get_spot_order_resp::GetSpotOrderResp;
pub use get_spot_orders_resp::GetSpotOrdersResp;
}
7 changes: 7 additions & 0 deletions src/msg/query_msg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[allow(unused_imports)]
use super::query_resp::*;
use crate::types::{PageRequest, SpotOrderType};
use cosmwasm_schema::{cw_serde, QueryResponses};
#[allow(unused_imports)]
use elys_bindings::query_resp::*;
Expand All @@ -13,4 +14,10 @@ pub enum QueryMsg {
GetAllPrices {},
#[returns(OracleAssetInfoResponse)]
AssetInfo { denom: String },
#[returns(GetSpotOrdersResp)]
GetSpotOrders {
pagination: PageRequest,
order_owner: Option<String>,
order_type: Option<SpotOrderType>,
},
}
1 change: 0 additions & 1 deletion src/msg/query_resp/get_all_prices_resp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
use elys_bindings::types::Price;

#[cw_serde]
Expand Down
17 changes: 17 additions & 0 deletions src/msg/query_resp/get_spot_orders_resp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::types::{PageResponse, SpotOrder};
use cosmwasm_schema::cw_serde;

#[cw_serde]
pub struct GetSpotOrdersResp {
pub page_response: PageResponse,
pub orders: Vec<SpotOrder>,
}

impl GetSpotOrdersResp {
pub fn empty(have_total: bool) -> Self {
Self {
page_response: PageResponse::empty(have_total),
orders: vec![],
}
}
}
150 changes: 150 additions & 0 deletions src/tests/get_spot_orders/get_spot_orders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
use crate::msg::query_resp::GetSpotOrdersResp;

use super::*;

#[test]
fn get_spot_orders() {
let orders: Vec<SpotOrder> = create_orders();
let mut app = ElysApp::new();

let instantiate_msg = InstantiateMockMsg {
process_order_executor: "owner".to_string(),
orders: orders.clone(),
};

let code = ContractWrapper::new(execute, instantiate, query);
let code_id = app.store_code(Box::new(code));

let addr = app
.instantiate_contract(
code_id,
Addr::unchecked("owner"),
&instantiate_msg,
&[],
"Contract",
None,
)
.unwrap();

let mut page_req = PageRequest::new(2);

let resp: GetSpotOrdersResp = app
.wrap()
.query_wasm_smart(
&addr,
&QueryMsg::GetSpotOrders {
pagination: page_req.clone(),
order_owner: None,
order_type: None,
},
)
.unwrap();

let (first_third, the_rest) = orders.split_at(2);

assert_eq!(&resp.orders, first_third);

page_req.update(resp.page_response.next_key);

let resp: GetSpotOrdersResp = app
.wrap()
.query_wasm_smart(
&addr,
&QueryMsg::GetSpotOrders {
pagination: page_req.clone(),
order_owner: None,
order_type: None,
},
)
.unwrap();

let (second_third, last_order) = the_rest.split_at(2);

assert_eq!(&resp.orders, second_third);

page_req.update(resp.page_response.next_key);

let resp: GetSpotOrdersResp = app
.wrap()
.query_wasm_smart(
&addr,
&QueryMsg::GetSpotOrders {
pagination: page_req.clone(),
order_owner: None,
order_type: None,
},
)
.unwrap();

assert_eq!(&resp.orders, last_order);
}

fn create_orders() -> Vec<SpotOrder> {
vec![
SpotOrder {
order_type: SpotOrderType::LimitBuy,
order_id: 0,
order_price: SpotOrderPrice {
base_denom: "btc".to_owned(),
quote_denom: "usdc".to_owned(),
rate: Decimal::from_atomics(Uint128::new(25), 1).unwrap(),
},
order_amount: coin(255, "btc"),
owner_address: Addr::unchecked("userA"),
order_target_denom: "btc".to_owned(),
order_amm_routes: vec![],
},
SpotOrder {
order_type: SpotOrderType::LimitSell,
order_id: 1,
order_price: SpotOrderPrice {
base_denom: "eth".to_owned(),
quote_denom: "usdt".to_owned(),
rate: Decimal::from_atomics(Uint128::new(10), 1).unwrap(),
},
order_amount: coin(100, "eth"),
owner_address: Addr::unchecked("userB"),
order_target_denom: "eth".to_owned(),
order_amm_routes: vec![],
},
SpotOrder {
order_type: SpotOrderType::StopLoss,
order_id: 2,
order_price: SpotOrderPrice {
base_denom: "xrp".to_owned(),
quote_denom: "usdt".to_owned(),
rate: Decimal::from_atomics(Uint128::new(5), 1).unwrap(),
},
order_amount: coin(500, "xrp"),
owner_address: Addr::unchecked("userC"),
order_target_denom: "xrp".to_owned(),
order_amm_routes: vec![],
},
SpotOrder {
order_type: SpotOrderType::StopLoss,
order_id: 3,
order_price: SpotOrderPrice {
base_denom: "ltc".to_owned(),
quote_denom: "usdc".to_owned(),
rate: Decimal::from_atomics(Uint128::new(15), 1).unwrap(),
},
order_amount: coin(75, "ltc"),
owner_address: Addr::unchecked("userD"),
order_target_denom: "ltc".to_owned(),
order_amm_routes: vec![],
},
SpotOrder {
order_type: SpotOrderType::LimitBuy,
order_id: 4,
order_price: SpotOrderPrice {
base_denom: "ada".to_owned(),
quote_denom: "usdt".to_owned(),
rate: Decimal::from_atomics(Uint128::new(3), 1).unwrap(),
},
order_amount: coin(200, "ada"),
owner_address: Addr::unchecked("userE"),
order_target_denom: "ada".to_owned(),
order_amm_routes: vec![],
},
]
}
5 changes: 5 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ mod get_spot_order {
mod successful_query_message;
}

mod get_spot_orders {
use super::*;
mod get_spot_orders;
}

mod process_spot_order {
use super::*;
mod succesful_process_limit_buy_order;
Expand Down
27 changes: 27 additions & 0 deletions src/types/page_request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Binary;

#[cw_serde]
pub struct PageRequest {
pub key: Option<Binary>,
pub offset: Option<u64>,
pub limit: u64,
pub count_total: bool,
pub reverse: bool,
}

impl PageRequest {
pub fn new(limit: u64) -> Self {
Self {
key: None,
limit,
offset: None,
count_total: false,
reverse: false,
}
}

pub fn update(&mut self, key: Option<Binary>) -> () {
self.key = key;
}
}
21 changes: 21 additions & 0 deletions src/types/page_response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Binary;

#[cw_serde]
pub struct PageResponse {
pub next_key: Option<Binary>,
pub total: Option<u64>,
}

impl PageResponse {
pub fn new(next_key: Option<Binary>, total: Option<u64>) -> Self {
Self { next_key, total }
}

pub fn empty(have_total: bool) -> Self {
Self {
next_key: None,
total: if have_total { Some(0) } else { None },
}
}
}

0 comments on commit 58eaabd

Please sign in to comment.