-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sylvia: Interoperability between CosmWasm and Sylvia
- Loading branch information
Showing
2 changed files
with
121 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"getting-started": "Getting started", | ||
"generate-contract": "Generate contract", | ||
"contract-structure": "Contract structure" | ||
"contract-structure": "Contract structure", | ||
"interoperability": "Interoperability" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
--- | ||
tags: ["sylvia", "basics"] | ||
--- | ||
|
||
import { Callout, Tabs } from "nextra/components"; | ||
|
||
# Interoperability | ||
|
||
<Callout> | ||
Sylvia contracts are fully interoperable with legacy CosmWasm contracts. | ||
</Callout> | ||
|
||
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<Response> { | ||
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.Deps.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<ExternalResponse> { | ||
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 are more user | ||
friendly. | ||
|
||
## Testing | ||
|
||
Although we could use the | ||
[`cw_multi_test::App`](https://docs.rs/cw-multi-test/latest/cw_multi_test/struct.App.html), | ||
we would lose the ability to use the MultiTest helpers generated for Sylvia | ||
contarcts. For this reason, we always recommend to use the Sylvia | ||
[`App`](../types/multitest#app). | ||
|
||
```rust | ||
use sylvia::multitest::App; | ||
|
||
let app = App::<BasicMtApp<Empty, Empty>>::default(); | ||
``` | ||
|
||
<Callout> | ||
We must provide the full type for the [`App`](../types/multitest#app), as Rust | ||
cannot deduce it here. | ||
</Callout> | ||
|
||
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<dyn Contract<Empty>> { ... } | ||
|
||
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). |