Skip to content

Commit

Permalink
Add MarketPrice query in example smart contract (#987)
Browse files Browse the repository at this point in the history
* Example query in Smart contract

* merge conflict
  • Loading branch information
teddyding authored Jan 18, 2024
1 parent d08d29a commit 574f275
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 23 deletions.
2 changes: 1 addition & 1 deletion protocol/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ func New(

// AllCapabilities returns all capabilities available with the current wasmvm
// See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md
supportedFeatures := "iterator,staking,stargate,osmosis,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_4,dydx"
supportedFeatures := "iterator,staking,stargate,osmosis,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_4,dydxprotocol"

wasmbinding.RegisterCustomPlugins(&app.PricesKeeper, &app.SendingKeeper)

Expand Down
37 changes: 37 additions & 0 deletions protocol/contracts/dydx-messages-example/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 15 additions & 4 deletions protocol/contracts/dydx-messages-example/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::{
entry_point, to_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response,
StdResult
StdResult,
QueryResponse,
};

use crate::error::ContractError;
use crate::msg::{ArbiterResponse, ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::{Config, CONFIG};
use cw2::set_contract_version;
use dydx_cosmwasm::{SendingMsg, SubaccountId};
use dydx_cosmwasm::{SendingMsg, SubaccountId, DydxQuerier, MarketPrice, DydxQueryWrapper};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:dydx-messages-example";
Expand Down Expand Up @@ -120,13 +121,23 @@ fn send_tokens(from_address: Addr, to_address: Addr, amount: u64, action: &str)
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps<DydxQueryWrapper>, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::MarketPrice { id } => to_binary(&query_price(deps, id)?),
QueryMsg::Arbiter {} => to_binary(&query_arbiter(deps)?),
}
}

fn query_arbiter(deps: Deps) -> StdResult<ArbiterResponse> {
fn query_price(
deps: Deps<DydxQueryWrapper>,
id: u32,
) -> StdResult<MarketPrice> {
let querier = DydxQuerier::new(&deps.querier);
let res = querier.query_market_price(id);
Ok(res?)
}

fn query_arbiter(deps: Deps<DydxQueryWrapper>) -> StdResult<ArbiterResponse> {
let config = CONFIG.load(deps.storage)?;
let addr = config.arbiter;
Ok(ArbiterResponse { arbiter: addr })
Expand Down
5 changes: 5 additions & 0 deletions protocol/contracts/dydx-messages-example/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Coin};
use cw_utils::Expiration;
use dydx_cosmwasm::MarketPrice;

#[cw_serde]
pub struct InstantiateMsg {
Expand Down Expand Up @@ -31,6 +32,10 @@ pub enum QueryMsg {
/// Returns a human-readable representation of the arbiter.
#[returns(ArbiterResponse)]
Arbiter {},
#[returns(MarketPrice)]
MarketPrice {
id: u32,
}
}

#[cw_serde]
Expand Down
5 changes: 3 additions & 2 deletions protocol/dydx-cosmwasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ mod response_helper;
pub use msg::{SendingMsg, SubaccountId, Transfer};
pub use querier::DydxQuerier;
pub use query::{
MarketPriceResponse, DydxQuery, DydxQueryWrapper,
DydxQuery, DydxQueryWrapper,
};
// TODO: Export MarketPriceResponse instead for style consistency.
pub use proto_structs::MarketPrice;
pub use route::DydxRoute;

// This export is added to all contracts that import this package, signifying that they require
// "dydx" support on the chain they run on.
#[no_mangle]
extern "C" fn requires_dydx() {}
extern "C" fn requires_dydxprotocol() {}
1 change: 1 addition & 0 deletions protocol/dydx-cosmwasm/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use cosmwasm_std::{
to_json_binary,
CosmosMsg,
CustomMsg,
CustomQuery,
};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
Expand Down
8 changes: 6 additions & 2 deletions protocol/dydx-cosmwasm/src/proto_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct MarketPrice {
pub id: u32,
// TODO: Missing "Id" field compared to pricestypes.MarketPrice
// Adding `Id` field leads to this error when querying the contract:
// `Error parsing into type dydx_cosmwasm::proto_structs::MarketPrice: missing field `id`: query wasm contract failed: unknown request`
// Suspect it's failing due to parse the query since `Id` being tested is `0`.
// We don't need `Id` in the response, so leaving it out for now.
pub exponent: i32,
pub price: Uint64,
pub price: i64,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
Expand Down
7 changes: 4 additions & 3 deletions protocol/dydx-cosmwasm/src/querier.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cosmwasm_std::{QuerierWrapper, StdResult};

use crate::query::{MarketPriceResponse, SubaccountResponse, DydxQuery, DydxQueryWrapper};
use crate::proto_structs::MarketPrice;
use crate::query::{DydxQuery, DydxQueryWrapper, SubaccountResponse};
use crate::route::DydxRoute;

/// This is a helper wrapper to easily use our custom queries
Expand All @@ -13,9 +14,9 @@ impl<'a> DydxQuerier<'a> {
DydxQuerier { querier }
}

pub fn query_market_price(&self, market_id: u32) -> StdResult<MarketPriceResponse> {
pub fn query_market_price(&self, market_id: u32) -> StdResult<MarketPrice> {
let request = DydxQueryWrapper {
route: DydxRoute::Oracle,
route: DydxRoute::Prices,
query_data: DydxQuery::MarketPrice { id: market_id },
}
.into();
Expand Down
5 changes: 0 additions & 5 deletions protocol/dydx-cosmwasm/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ pub enum DydxQuery {
}
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct MarketPriceResponse {
pub market_price: MarketPrice,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SubaccountResponse {
pub subaccount: Subaccount,
Expand Down
2 changes: 1 addition & 1 deletion protocol/dydx-cosmwasm/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum DydxRoute {
Oracle,
Subaccount,
Prices,
}
6 changes: 1 addition & 5 deletions protocol/wasmbinding/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ func (qp QueryPlugin) HandleMarketPriceQuery(ctx sdk.Context, queryData json.Raw
return nil, errorsmod.Wrap(err, fmt.Sprintf("Error getting price for market %d", parsedQuery.Id))
}

res := pricestypes.QueryMarketPriceResponse{
MarketPrice: marketPrice,
}

bz, err := json.Marshal(res)
bz, err := json.Marshal(marketPrice)
if err != nil {
return nil, errorsmod.Wrap(err, "Error encoding MarketPrice as JSON")
}
Expand Down

0 comments on commit 574f275

Please sign in to comment.