Osmosis's proto-generated types and helpers for interacting with the appchain. Compatible with CosmWasm contract.
You can find all types and querier generated from osmosis's protobuf in their respective module in osmosis_std
. To understand how each module works, please look at the osmosis documentation.
Full working example contract can be found here.
```rust use cosmwasmstd::{CosmosMsg, Response, Env}; use osmosisstd::types::osmosis::tokenfactory::v1beta1::MsgCreateDenom;
// ..
pub fn trycreatedenom(env: Env, subdenom: String) -> Result
// construct message and convert them into cosmos message
// (notice `CosmosMsg` type and `.into()`)
let msg_create_denom: CosmosMsg = MsgCreateDenom { sender, subdenom }.into();
Ok(Response::new()
.add_message(msg_create_denom)
.add_attribute("method", "try_create_denom"))
}
```
Each module has its own querier that derived from protobuf service definition that can be found here.
To avoid non-determinism in stargate queries, only some of them are whitelisted, you can find the list here.
```rust use cosmwasmstd::{Deps, Env, StdResult}; use osmosisstd::types::osmosis::tokenfactory::v1beta1::{TokenfactoryQuerier, QueryDenomsFromCreatorResponse};
// ..
fn querycreatordenoms(deps: Deps, env: Env) -> StdResultTokenfactoryQuerier
let tokenfactory = TokenfactoryQuerier::new(&deps.querier);
// `TokenfactoryQuerier` has all the fns for querying the module
let res = tokenfactory.denoms_from_creator(env.contract.address.into())?;
Ok(QueryDenomsFromCreatorResponse { denoms: res.denoms })
} ```
When querying pool related values, eg. Gamm::pool
, you might find that return type contains Any
. It's a cosmos' way to implement polymorphism in protobuf.
https://github.com/osmosis-labs/osmosis/blob/f024498f1e8e0d2a1fe259cd9cc4223803fea0cd/proto/osmosis/gamm/v1beta1/query.proto#L82-L84
proto
message QueryPoolResponse {
google.protobuf.Any pool = 1 [ (cosmos_proto.accepts_interface) = "PoolI" ];
}
This is needed due to osmosis supporting multiple pool types which will be added in the future.
For that matter, osmosis-std
provides TryFrom
trait for all possible Any
used in all query responses in this crate.
That means the following code works:
```rust use prost::DecodeError; use cosmwasmstd::{Deps, StdResult, StdError}; use osmosisstd::types::osmosis::gamm::v1beta1::GammQuerier;
fn querypool(
deps: &Deps,
poolid: u64,
) -> StdResultAny
to osmosis_std::types::osmosis::gamm::v1beta1::Pool
.maperr(|e: DecodeError| StdError::ParseErr {
targettype: "osmosisstd::types::osmosis::gamm::v1beta1::Pool".tostring(),
msg: e.tostring(),
})
}
```
Or if later you want to support multiple pool type
```rust use prost::{DecodeError, Message}; use cosmwasmstd::{Deps, StdResult, StdError}; use osmosisstd::types::osmosis::gamm::v1beta1::GammQuerier;
enum Pool { Balancer(osmosisstd::types::osmosis::gamm::v1beta1::Pool), StableSwap(osmosisstd::types::osmosis::gamm::poolmodels::stableswap::v1beta1::Pool), }
impl TryFrom
fn try_from(value: osmosis_std::shim::Any) -> Result<Self, Self::Error> {
if let Ok(pool) = osmosis_std::types::osmosis::gamm::v1beta1::Pool::decode(value.value.as_slice()) {
return Ok(Pool::Balancer(pool));
}
if let Ok(pool) = osmosis_std::types::osmosis::gamm::poolmodels::stableswap::v1beta1::Pool::decode(value.value.as_slice()) {
return Ok(Pool::StableSwap(pool));
}
Err(StdError::ParseErr {
target_type: "Pool".to_string(),
msg: "Unmatched pool: must be either `Balancer` or `StableSwap`.".to_string(),
})
}
}
fn querypool(
deps: &Deps,
poolid: u64,
) -> StdResultAny
to Pool
}
```
When translate to rust, especially with CosmWasm, it can get tricky if we want to also support json (de)serialization. It could erase type url information from serialized json as for current implementation..
(WIP)