From 2dd2beb61572e104dc271b35b90489166ac1e521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Fri, 12 Jul 2024 16:37:55 +0200 Subject: [PATCH] Sylvia: Interoperability between CosmWasm and Sylvia --- src/pages/sylvia/basics/_meta.json | 3 +- src/pages/sylvia/basics/interoperability.mdx | 127 +++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/pages/sylvia/basics/interoperability.mdx diff --git a/src/pages/sylvia/basics/_meta.json b/src/pages/sylvia/basics/_meta.json index 52a7597b..6d2b8bb1 100644 --- a/src/pages/sylvia/basics/_meta.json +++ b/src/pages/sylvia/basics/_meta.json @@ -1,5 +1,6 @@ { "getting-started": "Getting started", "generate-contract": "Generate contract", - "contract-structure": "Contract structure" + "contract-structure": "Contract structure", + "interoperability": "Interoperability" } diff --git a/src/pages/sylvia/basics/interoperability.mdx b/src/pages/sylvia/basics/interoperability.mdx new file mode 100644 index 00000000..1a61573c --- /dev/null +++ b/src/pages/sylvia/basics/interoperability.mdx @@ -0,0 +1,127 @@ +--- +tags: ["sylvia", "basics"] +--- + +import { Callout, Tabs } from "nextra/components"; + +# Interoperability + + + Sylvia contracts are fully interoperable with classical CosmWasm contracts. + + +Sylvia macros expand into a regular CosmWasm code. Because of that, we can test +and communicate with Sylvia contracts like we would with any CosmWasm contract. + +Sylvia exposes, however additional QoL utilities like +[`Remote`](../types/communication#remote) and [`MultiTest`](../types/multitest) +helpers, which we recommend using alongside the Sylvia contracts. + +## Communication + +We can send messages from Sylvia as we would from any CosmWasm contract. + +Execute messages in Sylvia return the +[`Response`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.Response.html) +on which we can call the +[`add_message`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.Response.html#method.add_message). + +```rust +#[sv::msg(exec)] +fn external_increment(&self, ctx: ExecCtx) -> StdResult { + let remote = self.remote.load(ctx.deps.storage)?; + let msg = WasmMsg::Execute { + contract_addr: remote.to_string(), + msg: to_json_binary(&ExternalExecMsg::Increment {})?, + funds: vec![], + }; + Ok(Response::new().add_message(msg)) +} +``` + +Query messages can also be sent through the +[`query_wasm_smart`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.QuerierWrapper.html#method.query_wasm_smart) +method. We can access the +[`Deps`](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/struct.Deps.html) +through the [`QueryCtx`](../types/context). + +```rust +#[sv::msg(query)] +fn external_count(&self, ctx: QueryCtx) -> StdResult { + let remote = self.remote.load(ctx.deps.storage)?; + + ctx.deps + .querier + .query_wasm_smart(remote, &ExternalQueryMsg::Count {}) +} +``` + +As you see, we can send messages from the Sylvia contract as we would in case of +a CosmWasm contract. + +Although we could send messages to Sylvia contract in the same way, we recommend +using the [`ExecutorBuilder`](../types/communication#executorbuilder) and +[`BoundQuerier`](../types/communication#boundquerier) which wraps construction +of the messages. + + +You can learn more about these helpers in the +[`communication`](../types/communication) section. + + +## Testing + +We test Sylvia contract with MultiTest the same way we would test the classical +CosmWasm contracts, except we use the [`sylvia::App`](../types/multitest#app) in +place of +[`cw_multi_test::App`](https://docs.rs/cw-multi-test/latest/cw_multi_test/struct.App.html). +This type provides all the API as the MultiTest counterpart, exposing the +underlying object but adding support for using the Sylvia-generated helpers. It +can also be used to simulate the execution of standard CosmWasm contracts as +well + +```rust +use sylvia::multitest::App; + +let app = App::>::default(); +``` + + + We must provide the full type for the [`App`](../types/multitest#app), as Rust + cannot deduce it here. + + +We can access the underlying +[`cw_multi_test::App`](https://docs.rs/cw-multi-test/latest/cw_multi_test/struct.App.html) +via +[`app_mut`](https://docs.rs/sylvia/latest/sylvia/multitest/struct.App.html#method.app_mut) +to +[`store_code`](https://docs.rs/cw-multi-test/latest/cw_multi_test/struct.App.html#method.store_code) +of the CosmWasm contract. + +```rust +fn cosmwasm_contract() -> Box> { ... } + +let cosmwasm_code = app.app_mut().store_code(cosmwasm_contract()); +``` + +To instantiate the CosmWasm contract, we will also use the +[`app_mut`](https://docs.rs/sylvia/latest/sylvia/multitest/struct.App.html#method.app_mut). + +```rust +let cosmwasm_contract = app + .app_mut() + .instantiate_contract( + cosmwasm_code, + owner.clone(), + &InstantiateMsg {}, + &[], + "cosmwasm_contract", + None, + ) + .unwrap(); +``` + +After that testing will be the same as with any CosmWasm and Sylvia contract. +Check documentation about testing Sylvia's contract [`here`](../types/multitest) +and about testing CosmWasm contracts [`here`](../../cw-multi-test).