Skip to content

Commit

Permalink
add reply for transient test esqueleton
Browse files Browse the repository at this point in the history
  • Loading branch information
jbernal87 committed Apr 29, 2024
1 parent 0d5fe3d commit 333cb2a
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 26 deletions.
36 changes: 28 additions & 8 deletions contracts/injective-cosmwasm-stargate-example/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use crate::{
error::ContractError,
handle::{handle_test_transient_derivative_order, handle_test_transient_spot_order},
msg::{ExecuteMsg, InstantiateMsg, QueryMsg},
query::handle_query_stargate,
reply::{handle_create_derivative_order_reply, handle_create_order_reply},
};
use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult};
use cw2::set_contract_version;
use injective_cosmwasm::{create_deposit_msg, InjectiveMsgWrapper, InjectiveQueryWrapper};
use injective_cosmwasm::{InjectiveMsgWrapper, InjectiveQueryWrapper};

const CONTRACT_NAME: &str = "crates.io:injective:dummy-stargate-contract";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const CREATE_SPOT_ORDER_REPLY_ID: u64 = 0u64;
pub const CREATE_DERIVATIVE_ORDER_REPLY_ID: u64 = 1u64;
pub const MSG_EXEC: &str = "/cosmos.authz.v1beta1.MsgExec";

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(deps: DepsMut, _env: Env, _info: MessageInfo, _msg: InstantiateMsg) -> Result<Response, ContractError> {
Expand All @@ -21,15 +22,25 @@ pub fn instantiate(deps: DepsMut, _env: Env, _info: MessageInfo, _msg: Instantia

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
_deps: DepsMut<InjectiveQueryWrapper>,
deps: DepsMut<InjectiveQueryWrapper>,
env: Env,
_info: MessageInfo,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
match msg {
ExecuteMsg::TestDepositMsg { subaccount_id, amount } => {
Ok(Response::new().add_message(create_deposit_msg(env.contract.address, subaccount_id, amount)))
}
ExecuteMsg::TestTraderTransientSpotOrders {
market_id,
subaccount_id,
price,
quantity,
} => handle_test_transient_spot_order(deps, env, &info, market_id, subaccount_id, price, quantity),
ExecuteMsg::TestTraderTransientDerivativeOrders {
market_id,
subaccount_id,
price,
quantity,
margin,
} => handle_test_transient_derivative_order(deps, env, &info, market_id, subaccount_id, price, quantity, margin),
}
}

Expand All @@ -39,3 +50,12 @@ pub fn query(deps: Deps<InjectiveQueryWrapper>, _env: Env, msg: QueryMsg) -> Std
QueryMsg::QueryStargate { path, query_request } => handle_query_stargate(&deps.querier, path, query_request),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(deps: DepsMut<InjectiveQueryWrapper>, _env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
CREATE_SPOT_ORDER_REPLY_ID => handle_create_order_reply(deps, &msg),
CREATE_DERIVATIVE_ORDER_REPLY_ID => handle_create_derivative_order_reply(deps, &msg),
_ => Err(ContractError::UnrecognizedReply(msg.id)),
}
}
113 changes: 113 additions & 0 deletions contracts/injective-cosmwasm-stargate-example/src/handle.rs
Original file line number Diff line number Diff line change
@@ -1 +1,114 @@
use crate::{
contract::{CREATE_DERIVATIVE_ORDER_REPLY_ID, CREATE_SPOT_ORDER_REPLY_ID},
msg::{MSG_CREATE_DERIVATIVE_LIMIT_ORDER_ENDPOINT, MSG_CREATE_SPOT_LIMIT_ORDER_ENDPOINT},
order_management::{create_derivative_limit_order, create_spot_limit_order, create_stargate_msg, encode_bytes_message},
state::{CacheOrderInfo, ORDER_CALL_CACHE},
ContractError,
};
use cosmos_sdk_proto::{cosmos::authz::v1beta1::MsgExec, Any};
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response, SubMsg};
use injective_cosmwasm::{InjectiveMsgWrapper, InjectiveQuerier, InjectiveQueryWrapper, MarketId, OrderType, SubaccountId};
use injective_math::{scale::Scaled, FPDecimal};

pub const MSG_EXEC: &str = "/cosmos.authz.v1beta1.MsgExec";

pub fn handle_test_transient_spot_order(
deps: DepsMut<InjectiveQueryWrapper>,
env: Env,
info: &MessageInfo,
market_id: MarketId,
subaccount_id: SubaccountId,
price: String,
quantity: String,
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
let querier = InjectiveQuerier::new(&deps.querier);
let spot_market = querier.query_spot_market(&market_id).unwrap().market.unwrap();

let order_msg = create_spot_limit_order(
FPDecimal::must_from_str(price.as_str()).scaled(18i32),
FPDecimal::must_from_str(quantity.as_str()).scaled(18i32),
OrderType::Sell,
info.sender.as_str(),
subaccount_id.as_str(),
&spot_market,
);

let order_bytes = encode_bytes_message(&order_msg).unwrap();

let msg_exec = MsgExec {
grantee: env.contract.address.to_string(),
msgs: vec![Any {
type_url: MSG_CREATE_SPOT_LIMIT_ORDER_ENDPOINT.to_string(),
value: order_bytes,
}],
};

let order_submessage = SubMsg::reply_on_success(
create_stargate_msg(MSG_EXEC, msg_exec.encode_to_vec()).unwrap(),
CREATE_SPOT_ORDER_REPLY_ID,
);

save_cache_info(deps, market_id, subaccount_id)?;

Ok(Response::new().add_submessage(order_submessage))
}

pub fn handle_test_transient_derivative_order(
deps: DepsMut<InjectiveQueryWrapper>,
env: Env,
info: &MessageInfo,
market_id: MarketId,
subaccount_id: SubaccountId,
price: String,
quantity: String,
margin: String,
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
let querier: InjectiveQuerier = InjectiveQuerier::new(&deps.querier);
let market = querier.query_derivative_market(&market_id).unwrap().market.unwrap();

let order_msg = create_derivative_limit_order(
FPDecimal::must_from_str(price.as_str()).scaled(18i32),
FPDecimal::must_from_str(quantity.as_str()).scaled(18i32),
FPDecimal::must_from_str(margin.as_str()).scaled(18i32),
OrderType::Buy,
info.sender.as_str(),
subaccount_id.as_str(),
&market,
);

let order_bytes = encode_bytes_message(&order_msg).unwrap();

let msg_exec = MsgExec {
grantee: env.contract.address.to_string(),
msgs: vec![Any {
type_url: MSG_CREATE_DERIVATIVE_LIMIT_ORDER_ENDPOINT.to_string(),
value: order_bytes,
}],
};

let order_submessage = SubMsg::reply_on_success(
create_stargate_msg(MSG_EXEC, msg_exec.encode_to_vec()).unwrap(),
CREATE_DERIVATIVE_ORDER_REPLY_ID,
);

save_cache_info(deps, market_id, subaccount_id)?;

Ok(Response::new().add_submessage(order_submessage))
}

fn save_cache_info(deps: DepsMut<InjectiveQueryWrapper>, market_id: MarketId, subaccount_id: SubaccountId) -> Result<(), ContractError> {
let cache_order_info = CacheOrderInfo {
subaccount: subaccount_id,
market_id,
};

let mut order_cache = match ORDER_CALL_CACHE.may_load(deps.storage)? {
Some(order_cache) => order_cache,
None => vec![],
};

order_cache.push(cache_order_info);

ORDER_CALL_CACHE.save(deps.storage, &order_cache)?;
Ok(())
}
2 changes: 2 additions & 0 deletions contracts/injective-cosmwasm-stargate-example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ mod handle;
pub mod msg;
mod order_management;
mod query;
mod reply;
mod state;
#[cfg(test)]
mod testing;
mod types;
#[cfg(test)]
pub mod utils;

pub use crate::error::ContractError;
17 changes: 14 additions & 3 deletions contracts/injective-cosmwasm-stargate-example/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use cosmwasm_std::Coin;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use injective_cosmwasm::SubaccountId;
use injective_cosmwasm::{MarketId, SubaccountId};

pub const MSG_CREATE_SPOT_LIMIT_ORDER_ENDPOINT: &str = "/injective.exchange.v1beta1.MsgCreateSpotLimitOrder";
pub const MSG_CREATE_DERIVATIVE_LIMIT_ORDER_ENDPOINT: &str = "/injective.exchange.v1beta1.MsgCreateDerivativeLimitOrder";
Expand All @@ -13,7 +12,19 @@ pub struct InstantiateMsg {}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
TestDepositMsg { subaccount_id: SubaccountId, amount: Coin },
TestTraderTransientSpotOrders {
market_id: MarketId,
subaccount_id: SubaccountId,
price: String,
quantity: String,
},
TestTraderTransientDerivativeOrders {
market_id: MarketId,
subaccount_id: SubaccountId,
price: String,
quantity: String,
margin: String,
},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
Expand Down
39 changes: 39 additions & 0 deletions contracts/injective-cosmwasm-stargate-example/src/reply.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::state::ORDER_CALL_CACHE;
use crate::ContractError;
use cosmwasm_std::{DepsMut, Event, Reply, Response};
use injective_cosmwasm::{InjectiveQuerier, InjectiveQueryWrapper};

pub fn handle_create_order_reply(deps: DepsMut<InjectiveQueryWrapper>, _msg: &Reply) -> Result<Response, ContractError> {
let mut response_str = "Something went wrong".to_string();

let querier: InjectiveQuerier = InjectiveQuerier::new(&deps.querier);

if let Some(mut cache) = ORDER_CALL_CACHE.may_load(deps.storage)? {
if !cache.is_empty() {
let order_info = &cache[0];
let response = querier.query_trader_transient_spot_orders(&order_info.market_id, &order_info.subaccount);
response_str = format!("{:?}", &response);
cache.clear();
ORDER_CALL_CACHE.save(deps.storage, &cache)?;
}
};

Ok(Response::new().add_event(Event::new("transient_order").add_attributes([("query_str", response_str)])))
}

pub fn handle_create_derivative_order_reply(deps: DepsMut<InjectiveQueryWrapper>, _msg: &Reply) -> Result<Response, ContractError> {
let mut response_str = "Something went wrong".to_string();
let querier: InjectiveQuerier = InjectiveQuerier::new(&deps.querier);

if let Some(mut cache) = ORDER_CALL_CACHE.may_load(deps.storage)? {
if !cache.is_empty() {
let order_info = &cache[0];
let response = querier.query_trader_transient_derivative_orders(&order_info.market_id, &order_info.subaccount);
response_str = format!("{:?}", &response);
cache.clear();
ORDER_CALL_CACHE.save(deps.storage, &cache)?;
}
};

Ok(Response::new().add_event(Event::new("transient_derivative_order").add_attributes([("query_str", response_str)])))
}
11 changes: 11 additions & 0 deletions contracts/injective-cosmwasm-stargate-example/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use cosmwasm_schema::cw_serde;
use cw_storage_plus::Item;
use injective_cosmwasm::{MarketId, SubaccountId};

pub const ORDER_CALL_CACHE: Item<Vec<CacheOrderInfo>> = Item::new("order_call_cache");

#[cw_serde]
pub struct CacheOrderInfo {
pub subaccount: SubaccountId,
pub market_id: MarketId,
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod test_auction;
mod test_bank;
mod test_exchange;
mod test_exchange_derivative;
mod test_oracle;
mod type_helpers;
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::utils::encode_proto_message;
use crate::msg::ExecuteMsg;
use crate::utils::{add_spot_initial_liquidity, execute_all_authorizations, scale_price_quantity_for_spot_market_dec};
use crate::{
msg::{QueryMsg, QueryStargateResponse},
testing::type_helpers::{ExchangeParams, ParamResponse},
utils::{human_to_dec, human_to_proto, str_coin, ExchangeType, Setup, BASE_DECIMALS, BASE_DENOM, QUOTE_DECIMALS},
utils::{encode_proto_message, human_to_dec, human_to_proto, str_coin, ExchangeType, Setup, BASE_DECIMALS, BASE_DENOM, QUOTE_DECIMALS},
};
use cosmwasm_std::{from_json, Addr};
use injective_cosmwasm::{checked_address_to_subaccount_id, SubaccountDepositResponse};
use injective_cosmwasm::{checked_address_to_subaccount_id, MarketId, SubaccountDepositResponse};
use injective_std::types::injective::exchange::v1beta1::{Deposit, MsgDeposit, QuerySubaccountDepositRequest, QuerySubaccountDepositsRequest};
use injective_test_tube::{Account, Exchange, Module, Wasm};

Expand Down Expand Up @@ -93,3 +94,42 @@ fn test_query_subaccount_deposit() {
let deposit = contract_response.deposits;
assert_eq!(deposit.total_balance, human_to_dec("10.0", BASE_DECIMALS));
}

#[test]
#[cfg_attr(not(feature = "integration"), ignore)]
fn test_query_trader_transient_spot_orders() {
let env = Setup::new(ExchangeType::Spot);
let wasm = Wasm::new(&env.app);
let market_id = env.market_id.unwrap();

let subaccount_id = checked_address_to_subaccount_id(&Addr::unchecked(env.users[0].account.address()), 0u32);

execute_all_authorizations(&env.app, &env.users[0].account, env.contract_address.clone());
add_spot_initial_liquidity(&env.app, market_id.clone());

let (scale_price, scale_quantity) = scale_price_quantity_for_spot_market_dec("9.8", "1", &BASE_DECIMALS, &QUOTE_DECIMALS);

let res = wasm
.execute(
&env.contract_address,
&ExecuteMsg::TestTraderTransientSpotOrders {
market_id: MarketId::new(market_id).unwrap(),
subaccount_id: subaccount_id.clone(),
price: scale_price.to_string(),
quantity: scale_quantity.to_string(),
},
&[],
&env.users[0].account,
)
.unwrap();

let transient_query = res
.events
.iter()
.find(|e| e.ty == "wasm-transient_order")
.and_then(|event| event.attributes.iter().find(|a| a.key == "query_str"));

assert!(transient_query.is_some());
let expected_order_info = "TraderSpotOrdersResponse { orders: Some([TrimmedSpotLimitOrder { price: FPDecimal { num: 9800000, sign: 1 }, quantity: FPDecimal { num: 1000000000000000000000000000000000000, sign: 1 }";
assert!(transient_query.unwrap().value.contains(expected_order_info));
}
Loading

0 comments on commit 333cb2a

Please sign in to comment.