diff --git a/README.md b/README.md index ef9d0cb1..00efbcc4 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ In Sylvia, we define our contracts as structures: ```rust use cw_storage_plus::Item; use cosmwasm_schema::cw_serde; -use sylvia::types::QueryCtx; +use sylvia::ctx::QueryCtx; use sylvia::cw_std::ensure; @@ -59,7 +59,7 @@ struct MyContract<'a> { /// Response type returned by the /// query method. -/// +/// #[cw_serde] pub struct CounterResp { pub counter: u64, @@ -165,7 +165,6 @@ result type has to implement `Into`, where `ContractError` is a c error type - it will all be commonized in the generated dispatching function (so entry points have to return `ContractError` as its error variant). - ## Interfaces One of the fundamental ideas of the Sylvia framework is the interface, allowing the @@ -175,7 +174,7 @@ grouping of messages into their semantical groups. Let's define a Sylvia interfa pub mod group { use super::*; use sylvia::interface; - use sylvia::types::ExecCtx; + use sylvia::ctx::{ExecCtx, QueryCtx}; use sylvia::cw_std::StdError; #[cw_serde] @@ -285,23 +284,22 @@ impl MyContract { } ``` - * `sv::error` is used by both `contract` and `entry_point` macros. It is necessary in case a custom - error is being used by your contract. If omitted generated code will use `StdError`. - - * `sv::messages` is the attribute for the `contract` macro. Its purpose is to inform Sylvia - about interfaces implemented for the contract. If the implemented interface does not use a - default `Empty` message response for query and/or exec then the `: custom(query)`, - `: custom(msg)` or `: custom(msg, query)` should be indicated. +- `sv::error` is used by both `contract` and `entry_point` macros. It is necessary in case a custom + error is being used by your contract. If omitted generated code will use `StdError`. - * `sv::override_entry_point` - refer to the `Overriding entry points` section. +- `sv::messages` is the attribute for the `contract` macro. Its purpose is to inform Sylvia + about interfaces implemented for the contract. If the implemented interface does not use a + default `Empty` message response for query and/or exec then the `: custom(query)`, + `: custom(msg)` or `: custom(msg, query)` should be indicated. - * `sv::custom` allows to define CustomMsg and CustomQuery for the contract. By default generated code - will return `Response` and will use `Deps` and `DepsMut`. +- `sv::override_entry_point` - refer to the `Overriding entry points` section. - * `sv::msg_attr` forwards any attribute to the message's type. +- `sv::custom` allows to define CustomMsg and CustomQuery for the contract. By default generated code + will return `Response` and will use `Deps` and `DepsMut`. - * `sv::attr` forwards any attribute to the enum's variant. +- `sv::msg_attr` forwards any attribute to the message's type. +- `sv::attr` forwards any attribute to the enum's variant. ## Usage in external crates @@ -352,10 +350,9 @@ with `ExecMsg/QueryMsg` - the former is generated only for contract, not for int and is not meant to be used to send messages to the contract - their purpose is for proper messages dispatching only, and should not be used besides the entry points. - ## Query helpers -To make querying more user-friendly `Sylvia` provides users with `sylvia::types::BoundQuerier` and +To make querying more user-friendly `Sylvia` provides users with `sylvia::types::BoundQuerier` and `sylvia::types::Remote` helpers. The latter is meant to store the address of some remote contract. For each query method in the contract, Sylvia will add a method in a generated `sv::Querier` trait. The `sv::Querier` is then implemented for `sylvia::types::BoundQuerier` so the user can call the method. @@ -388,7 +385,6 @@ pub fn evaluate_member(&self, ctx: ExecCtx, ...) -> StdResult { } ``` - ## Executor message builder Sylvia defines the @@ -496,7 +492,7 @@ It is possible to define a custom `exec` message that will dispatch over one gen by your contract and one defined by you. To use this custom entry point with `contract` macro you can add the `sv::override_entry_point(...)` attribute. -```rust +```rust #[contract] #[sv::override_entry_point(exec=crate::entry_points::execute(crate::exec::CustomExecMsg))] #[sv::override_entry_point(sudo=crate::entry_points::sudo(crate::SudoMsg))] @@ -613,7 +609,6 @@ All the instantiation and execution functions return the `Result` type, where `ContractError` is an error type of the contract. - ## Interface items in multitest Trait declaring all the interface methods is directly implemented on @@ -678,8 +673,8 @@ Generics in a contract might be either used as generic field types or as generic types in the messages. When Sylvia generates the messages' enums, only generics used in respective methods will be part of a given generated message type. - Example of usage: + ```rust pub struct GenericContract< InstantiateParam, @@ -766,7 +761,6 @@ where } ``` - ## Generating schema Sylvia is designed to generate all the code that `cosmwasm-schema` relies on - this diff --git a/examples/interfaces/custom-and-generic/src/lib.rs b/examples/interfaces/custom-and-generic/src/lib.rs index 1569ddeb..e8b38277 100644 --- a/examples/interfaces/custom-and-generic/src/lib.rs +++ b/examples/interfaces/custom-and-generic/src/lib.rs @@ -69,11 +69,9 @@ pub trait CustomAndGeneric { } #[cfg(test)] -#[allow(deprecated)] mod tests { use sylvia::cw_std::testing::mock_dependencies; use sylvia::cw_std::{Addr, CosmosMsg, Empty, QuerierWrapper}; - use sylvia::types::InterfaceApi; use crate::sv::Querier; @@ -234,130 +232,5 @@ mod tests { CosmosMsg::Custom(SvCustomMsg {}), CosmosMsg::Custom(SvCustomMsg {}), ); - - let _ = as super::sv::InterfaceMessagesApi>::Querier::borrowed( - &contract, &querier_wrapper - ); - - // Construct messages with InterfaceApi - let _ = as InterfaceApi>::Query::custom_generic_query_one( - SvCustomMsg {}, SvCustomMsg {} - ); - - let _ = as InterfaceApi>::Query::custom_generic_query_two( - SvCustomMsg {}, SvCustomMsg {} - ); - - let _ = as InterfaceApi>::Exec::custom_generic_execute_one( - vec![CosmosMsg::Custom(SvCustomMsg {})], - vec![CosmosMsg::Custom(SvCustomMsg {})], - ); - - let _ = as InterfaceApi>::Exec::custom_generic_execute_two( - vec![CosmosMsg::Custom(SvCustomMsg {})], - vec![CosmosMsg::Custom(SvCustomMsg {})], - ); - - let _ = as InterfaceApi>::Sudo::custom_generic_sudo_one( - CosmosMsg::Custom(SvCustomMsg {}), - CosmosMsg::Custom(SvCustomMsg {}), - ); - - let _ = as InterfaceApi>::Sudo::custom_generic_sudo_two( - CosmosMsg::Custom(SvCustomMsg {}), - CosmosMsg::Custom(SvCustomMsg {}), - ); } } diff --git a/examples/interfaces/generic/src/lib.rs b/examples/interfaces/generic/src/lib.rs index 2c7690dd..90b98cf5 100644 --- a/examples/interfaces/generic/src/lib.rs +++ b/examples/interfaces/generic/src/lib.rs @@ -69,11 +69,9 @@ pub trait Generic { } #[cfg(test)] -#[allow(deprecated)] mod tests { use sylvia::cw_std::testing::mock_dependencies; use sylvia::cw_std::{Addr, CosmosMsg, Empty, QuerierWrapper}; - use sylvia::types::InterfaceApi; use crate::sv::Querier; @@ -229,112 +227,5 @@ mod tests { CosmosMsg::Custom(SvCustomMsg {}), CosmosMsg::Custom(SvCustomMsg {}), ); - - let _ = as super::sv::InterfaceMessagesApi>::Querier::borrowed( - &contract, &querier_wrapper - ); - - // Construct messages with InterfaceApi - let _ = as InterfaceApi>::Query::generic_query_one(SvCustomMsg {}, SvCustomMsg {}); - - let _ = as InterfaceApi>::Query::generic_query_two(SvCustomMsg {}, SvCustomMsg {}); - - let _ = as InterfaceApi>::Exec::generic_exec_one( - vec![CosmosMsg::Custom(SvCustomMsg {})], - vec![CosmosMsg::Custom(SvCustomMsg {})], - ); - - let _ = as InterfaceApi>::Exec::generic_exec_two( - vec![CosmosMsg::Custom(SvCustomMsg {})], - vec![CosmosMsg::Custom(SvCustomMsg {})], - ); - - let _ = as InterfaceApi>::Sudo::generic_sudo_one( - CosmosMsg::Custom(SvCustomMsg {}), - CosmosMsg::Custom(SvCustomMsg {}), - ); - - let _ = as InterfaceApi>::Sudo::generic_sudo_two( - CosmosMsg::Custom(SvCustomMsg {}), - CosmosMsg::Custom(SvCustomMsg {}), - ); } } diff --git a/sylvia-derive/src/interface.rs b/sylvia-derive/src/interface.rs index 5f956cc9..8909452b 100644 --- a/sylvia-derive/src/interface.rs +++ b/sylvia-derive/src/interface.rs @@ -96,7 +96,7 @@ impl<'a> InterfaceInput<'a> { let Self { associated_types, item, - custom, + .. } = self; let messages = self.emit_messages(); let associated_names: Vec<_> = associated_types @@ -113,7 +113,7 @@ impl<'a> InterfaceInput<'a> { let querier = Querier::new(&query_variants, associated_types, &item.ident).emit_querier_trait(); - let interface_messages = Api::new(item, custom, associated_types).emit(); + let interface_messages = Api::new(item, associated_types).emit(); let multitest_helpers = self.emit_multitest_helpers(); diff --git a/sylvia-derive/src/interface/communication/api.rs b/sylvia-derive/src/interface/communication/api.rs index 1288c9b5..082b5e2a 100644 --- a/sylvia-derive/src/interface/communication/api.rs +++ b/sylvia-derive/src/interface/communication/api.rs @@ -1,6 +1,5 @@ -use crate::crate_module; use crate::parser::variant_descs::AsVariantDescs; -use crate::parser::{Custom, MsgType}; +use crate::parser::MsgType; use crate::types::associated_types::{AssociatedTypes, ItemType}; use crate::types::msg_variant::MsgVariants; use proc_macro2::TokenStream; @@ -14,33 +13,23 @@ use syn::ItemTrait; /// It ease the dispatch of generic types. pub struct Api<'a> { source: &'a ItemTrait, - custom: &'a Custom, associated_types: &'a AssociatedTypes<'a>, } impl<'a> Api<'a> { - pub fn new( - source: &'a ItemTrait, - custom: &'a Custom, - associated_types: &'a AssociatedTypes<'a>, - ) -> Self { + pub fn new(source: &'a ItemTrait, associated_types: &'a AssociatedTypes<'a>) -> Self { Self { source, - custom, associated_types, } } pub fn emit(&self) -> TokenStream { - let sylvia = crate_module(); let Self { source, - custom, associated_types, } = self; - let where_clause = &self.associated_types.as_where_clause(); - let custom_query = custom.query_or_default(); let interface_name = &source.ident; let generics: Vec<_> = associated_types .without_error() @@ -69,46 +58,23 @@ impl<'a> Api<'a> { let query_generics = &query_variants.used_generics(); let sudo_generics = &sudo_variants.used_generics(); - let phantom = if !generics.is_empty() { - quote! { - _phantom: std::marker::PhantomData<( #(#generics,)* )>, - } - } else { - quote! {} - }; - quote! { pub trait InterfaceMessagesApi { type Exec; type Query; type Sudo; - type Querier<'querier>; } impl InterfaceMessagesApi for Contract { type Exec = ExecMsg < #(:: #exec_generics,)* >; type Query = QueryMsg < #(:: #query_generics,)* >; type Sudo = SudoMsg < #(:: #sudo_generics ,)* >; - type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Contract >; } impl<'sv_iface_msg_api, Error, #(#generics),*> InterfaceMessagesApi for dyn #interface_name < Error = Error, #(#generics = #generics,)* > + 'sv_iface_msg_api { type Exec = ExecMsg < #(#exec_generics,)* >; type Query = QueryMsg < #(#query_generics,)* >; type Sudo = SudoMsg < #(#sudo_generics,)* >; - type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Self >; - } - - pub struct Api < #(#generics,)* > { - #phantom - } - - #[allow(deprecated)] - impl < #(#generics,)* > #sylvia ::types::InterfaceApi for Api < #(#generics,)* > #where_clause { - type Exec = ExecMsg < #(#exec_generics,)* >; - type Query = QueryMsg < #(#query_generics,)* >; - type Sudo = SudoMsg < #(#sudo_generics,)* >; - type Querier<'querier, Contract> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Contract >; } } } diff --git a/sylvia/src/types.rs b/sylvia/src/types.rs index aafccc59..d0bafd23 100644 --- a/sylvia/src/types.rs +++ b/sylvia/src/types.rs @@ -1,6 +1,6 @@ //! Module providing utilities to build and use sylvia contracts. -use cosmwasm_std::{Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, WasmMsg}; +use cosmwasm_std::{Binary, Coin, WasmMsg}; use schemars::JsonSchema; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -457,145 +457,6 @@ impl AsRef for Remote<'_, Contract> { } } -/// Represantation of `reply` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::ReplyCtx` in 2.0.0.\n - You can use `sylvia::ctx::ReplyCtx` before the 2.0.0 release by using `#[sv::features(replies)]` attribute." -)] -pub struct ReplyCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: DepsMut<'a, C>, - pub env: Env, -} - -/// Represantation of `migrate` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::MigrateCtx` in 2.0.0." -)] -pub struct MigrateCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: DepsMut<'a, C>, - pub env: Env, -} - -/// Represantation of `execute` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::ExecCtx` in 2.0.0." -)] -pub struct ExecCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: DepsMut<'a, C>, - pub env: Env, - pub info: MessageInfo, -} - -/// Represantation of `instantiate` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::InstantiateCtx` in 2.0.0." -)] -pub struct InstantiateCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: DepsMut<'a, C>, - pub env: Env, - pub info: MessageInfo, -} - -/// Represantation of `query` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::QueryCtx` in 2.0.0." -)] -pub struct QueryCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: Deps<'a, C>, - pub env: Env, -} - -/// Represantation of `sudo` context received in entry point. -#[deprecated( - since = "1.3.0", - note = "This type will be replaced with `sylvia::ctx::SudoCtx` in 2.0.0." -)] -pub struct SudoCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { - pub deps: DepsMut<'a, C>, - pub env: Env, -} - -#[allow(deprecated)] -impl ExecCtx<'_, C> { - pub fn branch(&'_ mut self) -> ExecCtx<'_, C> { - ExecCtx { - deps: self.deps.branch(), - env: self.env.clone(), - info: self.info.clone(), - } - } -} - -#[allow(deprecated)] -impl InstantiateCtx<'_, C> { - pub fn branch(&'_ mut self) -> InstantiateCtx<'_, C> { - InstantiateCtx { - deps: self.deps.branch(), - env: self.env.clone(), - info: self.info.clone(), - } - } -} - -#[allow(deprecated)] -impl SudoCtx<'_, C> { - pub fn branch(&'_ mut self) -> SudoCtx<'_, C> { - SudoCtx { - deps: self.deps.branch(), - env: self.env.clone(), - } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env)> for MigrateCtx<'a, C> { - fn from((deps, env): (DepsMut<'a, C>, Env)) -> Self { - Self { deps, env } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env)> for ReplyCtx<'a, C> { - fn from((deps, env): (DepsMut<'a, C>, Env)) -> Self { - Self { deps, env } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env, MessageInfo)> for ExecCtx<'a, C> { - fn from((deps, env, info): (DepsMut<'a, C>, Env, MessageInfo)) -> Self { - Self { deps, env, info } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env, MessageInfo)> - for InstantiateCtx<'a, C> -{ - fn from((deps, env, info): (DepsMut<'a, C>, Env, MessageInfo)) -> Self { - Self { deps, env, info } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(Deps<'a, C>, Env)> for QueryCtx<'a, C> { - fn from((deps, env): (Deps<'a, C>, Env)) -> Self { - Self { deps, env } - } -} - -#[allow(deprecated)] -impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env)> for SudoCtx<'a, C> { - fn from((deps, env): (DepsMut<'a, C>, Env)) -> Self { - Self { deps, env } - } -} - /// Set of trait bounds for custom messages. pub trait CustomMsg: cosmwasm_std::CustomMsg + DeserializeOwned + JsonSchema {} @@ -606,18 +467,6 @@ pub trait CustomQuery: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema impl CustomQuery for T where T: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema {} -/// Api trait for easier access to generated types and messages. -#[deprecated( - since = "1.2.1", - note = "InterfaceApi will be removed in 2.0.0. Please use generated sv::InterfaceMessagesApi instead." -)] -pub trait InterfaceApi { - type Exec; - type Query; - type Sudo; - type Querier<'querier, Contract>; -} - /// Api trait for easier access to generated types and messages. pub trait ContractApi { type Instantiate; diff --git a/sylvia/tests/legacy_replies.rs b/sylvia/tests/legacy_replies.rs deleted file mode 100644 index af00f66a..00000000 --- a/sylvia/tests/legacy_replies.rs +++ /dev/null @@ -1,126 +0,0 @@ -#[cfg(all(test, feature = "mt"))] -use cw_multi_test::IntoBech32; -use sylvia::cw_std::testing::{mock_dependencies, mock_env}; -use sylvia::cw_std::{from_json, Reply, SubMsgResponse, SubMsgResult}; - -#[allow(dead_code)] -mod noop_contract { - use sylvia::ctx::{ExecCtx, InstantiateCtx}; - use sylvia::{contract, entry_points}; - - use sylvia::cw_std::{Response, StdResult}; - - pub struct NoopContract; - - #[entry_points] - #[contract] - impl NoopContract { - pub const fn new() -> Self { - Self - } - - #[sv::msg(instantiate)] - fn instantiate(&self, _ctx: InstantiateCtx) -> StdResult { - Ok(Response::new()) - } - - #[sv::msg(exec)] - fn noop(&self, _ctx: ExecCtx) -> StdResult { - Ok(Response::new()) - } - } -} - -mod reply_contract { - use cosmwasm_std::Reply; - use sylvia::ctx::{ExecCtx, InstantiateCtx}; - #[allow(deprecated)] - use sylvia::types::ReplyCtx; - use sylvia::{contract, entry_points}; - - use sylvia::cw_std::{to_json_binary, Response, StdResult, SubMsg, WasmMsg}; - - use super::noop_contract; - - pub struct ReplyContract; - - #[allow(dead_code)] - #[entry_points] - #[contract] - impl ReplyContract { - pub const fn new() -> Self { - Self - } - - #[sv::msg(instantiate)] - fn instantiate(&self, _ctx: InstantiateCtx) -> StdResult { - Ok(Response::new()) - } - - #[sv::msg(exec)] - fn poke(&self, _ctx: ExecCtx, noop: String) -> StdResult { - let msg = noop_contract::sv::ExecMsg::Noop {}; - let msg = WasmMsg::Execute { - contract_addr: noop, - msg: to_json_binary(&msg)?, - funds: vec![], - }; - let msg = SubMsg::reply_always(msg, 1); - - let resp = Response::new().add_submessage(msg); - Ok(resp) - } - - #[sv::msg(reply)] - #[allow(deprecated)] - fn reply(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { - let resp = Response::new().set_data(to_json_binary("data")?); - Ok(resp) - } - } -} - -#[test] -fn entry_point_generation() { - let msg = Reply { - id: 0, - payload: Default::default(), - gas_used: 0, - #[allow(deprecated)] - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: None, - msg_responses: vec![], - }), - }; - let mut deps = mock_dependencies(); - let env = mock_env(); - - let resp = reply_contract::entry_points::reply(deps.as_mut(), env, msg).unwrap(); - let data: String = from_json(resp.data.unwrap()).unwrap(); - - assert_eq!(data, "data"); -} - -#[cfg(all(test, feature = "mt"))] -#[test] -fn mt_helper_generation() { - use crate::reply_contract::sv::mt::ReplyContractProxy; - let app = sylvia::multitest::App::default(); - let owner = "owner".into_bech32(); - - let noop_contract_code = noop_contract::sv::mt::CodeId::store_code(&app); - let noop_contract = noop_contract_code.instantiate().call(&owner).unwrap(); - - let reply_contract_code = reply_contract::sv::mt::CodeId::store_code(&app); - let reply_contract = reply_contract_code.instantiate().call(&owner).unwrap(); - - let resp = reply_contract - .poke(noop_contract.contract_addr.to_string()) - .call(&owner) - .unwrap(); - - let data: String = from_json(resp.data.unwrap()).unwrap(); - - assert_eq!(data, "data"); -}