diff --git a/book.toml b/book.toml index 7bf88ce..d734ccb 100644 --- a/book.toml +++ b/book.toml @@ -3,8 +3,10 @@ authors = ["Jan Woźniak", "Bartłomiej Kuras"] language = "en" multilingual = false src = "src" -title = "Sylvia book" +title = "The Sylvia Book" description = "Guide to building CosmWasm smart contracts" [rust] edition = "2021" + +[preprocessor.yapp] diff --git a/src/README.md b/src/README.md index 31bf7f2..f7e4c05 100644 --- a/src/README.md +++ b/src/README.md @@ -1,16 +1,16 @@ # Introduction -This book is a guide for creating CosmWasm smart contracts with the Sylvia framework. +This book is a guide for creating CosmWasm smart contracts with the ^sylvia framework. It will lead you step by step and explain relevant topics from easiest to trickiest. The idea of the book is not only to tell you about smart contract development but also to show you how to do it clean and maintainable. I will show you some good practices -for using `Sylvia`. +for using ^sylvia. This book is not meant to teach you about the `CosmWasm`. To learn about that, read [The CosmWasm Book](https://book.cosmwasm.com). -This book covers `Sylvia` in version 0.9.0. +> ^note This book covers ^sylvia in version **^sylvia-version**. ## Prerequisites diff --git a/src/advanced.md b/src/advanced.md index cf56b3e..3b810a6 100644 --- a/src/advanced.md +++ b/src/advanced.md @@ -1,7 +1,7 @@ # Advanced -The previous chapter explained basics of `sylvia`. If you read it you should be familiar -with general usage of `sylvia` framework. +The previous chapter explained basics of ^sylvia. If you read it you should be familiar +with general usage of ^sylvia framework. -In this chapter we will go through some "advanced" features of `sylvia` like ability +In this chapter we will go through some "advanced" features of ^sylvia like ability to override entry points and creating custom messages. diff --git a/src/advanced/custom.md b/src/advanced/custom.md index dd8755b..0a9f77f 100644 --- a/src/advanced/custom.md +++ b/src/advanced/custom.md @@ -5,7 +5,7 @@ Blockchain creators might define chain-specific logic triggered through defined by them messages. `CosmWasm` provides a way to send such messages through `cosmwasm_std::CosmosMsg::Custom(..)` variant. -`Sylvia` supports this feature, allowing both custom interfaces and contracts. +^Sylvia supports this feature, allowing both custom interfaces and contracts. ## Custom interface @@ -278,10 +278,10 @@ pub mod impl_non_custom { } ``` -As you can see, although it's non-custom, we still have to inform `sylvia` custom types from the contract. +As you can see, although it's non-custom, we still have to inform ^sylvia custom types from the contract. It's required for the `MultiTest` helpers to be generic over the same types as the contract. -Let's add the last `messages` attribute to the contract. It has to end with `: custom(msg query)`. This way `sylvia` +Let's add the last `messages` attribute to the contract. It has to end with `: custom(msg query)`. This way ^sylvia will know that it has to cast `Response` to `Response` for `msg` and `Deps` to `Deps` for `query`. `src/contract.rs` diff --git a/src/advanced/entry_points_overriding.md b/src/advanced/entry_points_overriding.md index 3eef49d..3d99fd0 100644 --- a/src/advanced/entry_points_overriding.md +++ b/src/advanced/entry_points_overriding.md @@ -1,12 +1,12 @@ # Override entry point -`Sylvia` is still developing and lacks features like f.e. `sudo` support. +^Sylvia is still developing and lacks features like f.e. `sudo` support. If you need to use a lacking feature of `CosmWasm` or prefer to define some custom entry point, it is possible to use the `#[sv::override_entry_point(...)]` attribute. ## Example -To make `sylvia` generate multitest helpers with `sudo` support, you first need to define your +To make ^sylvia generate multitest helpers with `sudo` support, you first need to define your `entry point`. ```rust,noplayground diff --git a/src/advanced/generics.md b/src/advanced/generics.md index a3a975b..24b7c58 100644 --- a/src/advanced/generics.md +++ b/src/advanced/generics.md @@ -2,7 +2,7 @@ When implementing a contract, users might want to define some generic data it should store. One might even want the message to have some generic parameters or return type. -`Sylvia` supports generics in the contracts and interfaces. +^Sylvia supports generics in the contracts and interfaces. ## Prepare project @@ -61,7 +61,7 @@ where Simple and expected behavior. What if we want to extend the `custom` functionality with generics? In such a case, we would have to add `#[sv::custom(..)]` attribute to the trait with the name of our generics. -It is a standard approach when using `CustomMsg` and `CustomQuery` in `sylvia` so there is nothing new here. +It is a standard approach when using `CustomMsg` and `CustomQuery` in ^sylvia so there is nothing new here. `src/generic.rs` ```rust @@ -174,7 +174,7 @@ impl Generic for NonGenericContract { ``` To implement a generic interface, we have to specify the types. Here we use `MyMsg` and `MyQuery` -we defined earlier. No additional attributes have to be passed as `sylvia` will read them +we defined earlier. No additional attributes have to be passed as ^sylvia will read them from the interface type. Because we defined the interface as `custom` we have to pass these types into `sv::custom(..)` attribute same as in the interface definition. @@ -215,7 +215,7 @@ We also had to add `#[sv::custom(..)]` attribute to the contract definition and ## Generic contract -Using generic interfaces in `sylvia` is simple. Let's see how it works with generic contracts. +Using generic interfaces in ^sylvia is simple. Let's see how it works with generic contracts. Let us define a new module in which we will define a generic contract. @@ -260,7 +260,7 @@ This example showcases two usages of generics in contract: - Generic field - Generic message parameter -`Sylvia` works in both cases, and you can expand your generics to every message type, return type, or `custom_queries` as shown in the case of the `interface`. For the readability of this example, we will +^Sylvia works in both cases, and you can expand your generics to every message type, return type, or `custom_queries` as shown in the case of the `interface`. For the readability of this example, we will keep just these two generic types. `InstantiateParam` is passed as a field to the `InstantiateMsg`. This enforces some bounds @@ -443,7 +443,7 @@ Our contract is ready to use. We can test it in the last step of this chapter. ## Test generic contract -`Sylvia` enforces the user to specify a solid type while implementing a generic interface on the contract. +^Sylvia enforces the user to specify a solid type while implementing a generic interface on the contract. Due to this, we test `NonGenericContract` as a regular contract. In case of the generic contract, we have to pass the types while constructing `CodeId`. diff --git a/src/basics.md b/src/basics.md index 6a1caff..71e3969 100644 --- a/src/basics.md +++ b/src/basics.md @@ -1,4 +1,4 @@ # Basics This chapter will guide you through creating basic smart contract, step by step. -I will explain the core features of `Sylvia` framework and some good practices. +I will explain the core features of ^sylvia framework and some good practices. diff --git a/src/basics/create-project.md b/src/basics/create-project.md index 2e9e97f..abe03f2 100644 --- a/src/basics/create-project.md +++ b/src/basics/create-project.md @@ -38,12 +38,12 @@ Additionally, we added some core dependencies for smart contracts: standard library for smart contracts. It provides essential utilities for communication with the outside world, helper functions, and types. Every smart contract we will build will use this dependency. -- [`sylvia`](https://docs.rs/sylvia/0.7.0/sylvia/) - Crate, we will learn in this +- [`sylvia`](https://docs.rs/sylvia/0.9.3/sylvia/) - Crate, we will learn in this book. It provides us with three procedural macros: `entry_points`, `contract` and `interface`. I will expand on them later in the book. - [`schemars`](https://docs.rs/schemars/0.8.12/schemars/index.html) - Crate used to create JSON schema documents for our contracts. It is automatically derived on types generated by -`sylvia` and will be later used to provide concise API for blockchain users, who might not be Rust developers. +^sylvia and will be later used to provide concise API for blockchain users, who might not be Rust developers. - [`cosmwasm-schema`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/) - Similar to `schemars`. This crate expands on `schemars` and provides us with trait [`QueryResponses`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/trait.QueryResponses.html) diff --git a/src/basics/entry-points.md b/src/basics/entry-points.md index b15724c..38b5e46 100644 --- a/src/basics/entry-points.md +++ b/src/basics/entry-points.md @@ -17,7 +17,7 @@ To start, we will go with three basic entry points: ## Generate entry points -`Sylvia` provides an attribute macro named [`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html). +^Sylvia provides an attribute macro named [`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html). In most cases, your entry point will just dispatch received messages to the handler, so it's not necessary to manually create them, and we can rely on a macro to do that for us. @@ -49,7 +49,7 @@ It is because **`#[contract]`** removes attributes like **`#[msg(...)]`** on whi Always remember to place **`#[entry_points]`** first. -`Sylvia` generates entry points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) +^Sylvia generates entry points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) attribute macro. Its purpose is to wrap the whole entry point to the form the Wasm runtime understands. The proper Wasm entry points can use only basic types supported natively by Wasm specification, and Rust structures and enums are not in this set. Working with such entry points would be diff --git a/src/basics/error_handling.md b/src/basics/error_handling.md index edad30f..774e56b 100644 --- a/src/basics/error_handling.md +++ b/src/basics/error_handling.md @@ -128,8 +128,8 @@ A little to explain here. We load the count, and check if it's equal to zero. If our newly defined error variant. If not, then we decrement its value. However, this won't work. If you would try to build this you will receive: `error[E0277]: the trait bound `cosmwasm_std::StdError: From` is not satisfied`. -It is because `sylvia` by default generates `dispatch` returning `Result<_, StdError>`. To -inform `sylvia` that it should be using a new type we add `#[error(ContractError)]` attribute to +It is because ^sylvia by default generates `dispatch` returning `Result<_, StdError>`. To +inform ^sylvia that it should be using a new type we add `#[error(ContractError)]` attribute to the `contract` macro call. ```rust,noplayground @@ -198,5 +198,5 @@ newly defined error variant. # Next step -We introduced proper error handling to our contract. Now we will learn about `interfaces`. `Sylvia` feature allowing to +We introduced proper error handling to our contract. Now we will learn about `interfaces`. ^Sylvia feature allowing to split our contract into semantic parts. diff --git a/src/basics/first-messages.md b/src/basics/first-messages.md index 5b2bc4f..a331f54 100644 --- a/src/basics/first-messages.md +++ b/src/basics/first-messages.md @@ -56,7 +56,7 @@ which uses standard `CosmWasm` error It's generic over [`Response`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/struct.Response.html). For now, we will return the `default` value of it. -I recommend expanding the macro now and seeing what `Sylvia` generates. +I recommend expanding the macro now and seeing what ^Sylvia generates. It might be overwhelming, as there will be a lot of things generated that seem not relevant to our code, so for the bare minimum check the `InstantiateMsg` and its `impl` block. diff --git a/src/basics/good-practices.md b/src/basics/good-practices.md index bb50457..5a29286 100644 --- a/src/basics/good-practices.md +++ b/src/basics/good-practices.md @@ -212,6 +212,6 @@ my_contract = { version = "0.1", features = ["library"] } ## Single file/single macro call -I talked about it in some previous chapters. I cannot guarantee that future `sylvia` changes won't +I talked about it in some previous chapters. I cannot guarantee that future ^sylvia changes won't cause code generation to overlap. To avoid future problems, I recommend restricting yourself to single macro call per file. diff --git a/src/basics/multitest-intro.md b/src/basics/multitest-intro.md index c54c50e..651cd5b 100644 --- a/src/basics/multitest-intro.md +++ b/src/basics/multitest-intro.md @@ -10,7 +10,7 @@ well, but it is also an excellent tool for testing single-contract scenarios. ## Update dependencies -First, we need to add `sylvia` with `mt` feature enabled to our +First, we need to add ^sylvia with `mt` feature enabled to our [`dev-dependencies`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies). ```toml @@ -69,9 +69,9 @@ fn instantiate() { } ``` -`Sylvia` generates a lot of helpers for us to make testing as easy as possible. +^Sylvia generates a lot of helpers for us to make testing as easy as possible. To simulate blockchain, we create `sylvia::multitest::App`. Then we will use it to store the code id -of our contract on the blockchain using `sylvia` generated `CodeId`. +of our contract on the blockchain using ^sylvia generated `CodeId`. Code id identifies our contract on the blockchain and allows us to instantiate the contract on it. We do that using `CodeId::instantiate` method. It returns the `InstantiateProxy` type, allowing us diff --git a/src/basics/query.md b/src/basics/query.md index 1861a19..d91e249 100644 --- a/src/basics/query.md +++ b/src/basics/query.md @@ -111,7 +111,7 @@ when we will talk about generating schema. `QueryMsg` is an enum that will contain every `query` declared in your expanded `impl`. Thanks to that you can focus solely on defining the behavior of the contract on receiving a message, and you -can leave it to `sylvia` to generate the messages and the `dispatch`. +can leave it to ^sylvia to generate the messages and the `dispatch`. Note that our enum has no type assigned to the only `Count` variant. Typically in Rust, we create variants without additional `{}` after the variant name. Here the @@ -123,7 +123,7 @@ Instead of returning the `Response` type on the success case, we return an arbit object. It's because queries are not using a typical actor model message flow - they cannot trigger any actions nor communicate with other contracts in ways different than querying them (which is handled by the `deps` argument). The query always returns plain data, which should be presented -directly to the querier. `Sylvia` does that by returning encoded response as +directly to the querier. ^Sylvia does that by returning encoded response as [`Binary`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/struct.Binary.html) by calling [`to_binary`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/fn.to_binary.html) function in dispatch. diff --git a/src/basics/remote.md b/src/basics/remote.md index df85069..b07df8d 100644 --- a/src/basics/remote.md +++ b/src/basics/remote.md @@ -2,12 +2,12 @@ Your contract may rely on communication with another one. For example, it could `instantiate` a `CW20` contract and, during the workflow, send `Mint` messages to it. If `CW20` -contract was created using `sylvia`, it would have a `Remote` type generated which would make this +contract was created using ^sylvia, it would have a `Remote` type generated which would make this process more user friendly. Currently, it is only possible to send queries using `Remote` but support for the `execute` messages is on the way. -To check some examples, checkout the [`sylvia`](https://github.com/CosmWasm/sylvia) repository +To check some examples, checkout the [^sylvia](https://github.com/CosmWasm/sylvia) repository and go to `sylvia/tests/remote.rs`. ## Working with Remote @@ -49,5 +49,5 @@ self.cw20 # Next step -Phew.. that was a journey. We learned most of the `sylvia` features and should be ready to create our first contracts. +Phew.. that was a journey. We learned most of the ^sylvia features and should be ready to create our first contracts. In the last chapter, we will learn about some of the best practices that will make our code more readable and maintainable. diff --git a/src/basics/reusability.md b/src/basics/reusability.md index 941f057..6658c16 100644 --- a/src/basics/reusability.md +++ b/src/basics/reusability.md @@ -1,8 +1,8 @@ # Reusability -We have covered almost all the basics of writing smart contracts with `sylvia`. +We have covered almost all the basics of writing smart contracts with ^sylvia. In this last chapter of the `basics` section, I will tell you about the ability to define -[`interface`](https://docs.rs/sylvia/latest/sylvia/attr.interface.html) in `sylvia`. +[`interface`](https://docs.rs/sylvia/latest/sylvia/attr.interface.html) in ^sylvia. ## Problem @@ -15,8 +15,8 @@ into semantically compatible parts. ## Solution -`Sylvia` has a feature to reuse already defined messages and apply them in new contracts. -Clone and open [`sylvia`](https://github.com/CosmWasm/sylvia) repository. Go to +^Sylvia has a feature to reuse already defined messages and apply them in new contracts. +Clone and open [^sylvia](https://github.com/CosmWasm/sylvia) repository. Go to `contracts/cw1-subkeys/src/contract.rs`. You can notice that the `impl` block for the `Cw1SubkeysContract` is preceded by `#[messages(...)]` attribute. @@ -65,7 +65,7 @@ impl ContractQueryMsg { ``` We can finally see why we need these `ContractQueryMsg` and `ContractExecMsg` next to our -regular message enums. `Sylvia` generated three tuple variants: +regular message enums. ^Sylvia generated three tuple variants: - `Cw1` - which contains query msg defined in `cw1`; @@ -74,7 +74,7 @@ regular message enums. `Sylvia` generated three tuple variants: - `Cw1SubkeysContract` - which contains query msg defined in our contract. We use this wrapper to match with the proper variant and then call `dispatch` on this message. -`Sylvia` also ensure that no message overlaps between interfaces and contract so that +^Sylvia also ensure that no message overlaps between interfaces and contract so that contracts API won't break. ## Declaring interface @@ -162,7 +162,7 @@ otherwise we would have to either expect `StdError` or our custom error in the r but we don't know what contracts will use this interface. Our trait defines three methods. Let's implement them on our contract. -`Sylvia` still grows and there can be some type duplications in the future. I recommend keeping all +^Sylvia still grows and there can be some type duplications in the future. I recommend keeping all three: contract implementation, interface definition and interface implementation on contract in separate modules. @@ -218,7 +218,7 @@ the macro where our contract is defined. It's required for pathing. You can expa and check where it is used. Next, there is the attribute mentioned before - `messages`. Its purpose is similar to the `module` -with the difference that it provides `sylvia` with path to the interface. We also have to provide +with the difference that it provides ^sylvia with path to the interface. We also have to provide the interface's name, although it should be optional in the future. We need to do one more thing, which is to add the `messages` attribute to the contract definition. @@ -342,5 +342,5 @@ of one. # Next step -We have learned about almost all of the `sylvia` features. The next chapter will be about talking +We have learned about almost all of the ^sylvia features. The next chapter will be about talking with remotes. diff --git a/src/basics/state.md b/src/basics/state.md index 4b8eb65..29ffdcd 100644 --- a/src/basics/state.md +++ b/src/basics/state.md @@ -6,7 +6,7 @@ Let's make it more usable. In this chapter, we will introduce the contract's sta ## Adding contract state The name of our contract is a little spoiler. We will add the `counter` state. It's not a real world -usage of smart contracts, but it helps to see the usage of `Sylvia` without getting into business logic. +usage of smart contracts, but it helps to see the usage of ^Sylvia without getting into business logic. The first thing to do, is to update `Cargo.toml` with yet another dependency - the [`storage-plus`](https://crates.io/crates/cw-storage-plus) crate with high-level bindings for diff --git a/src/setting-up-env.md b/src/setting-up-env.md index 0925579..ca08b05 100644 --- a/src/setting-up-env.md +++ b/src/setting-up-env.md @@ -44,7 +44,7 @@ sylvia $ cargo test You should see that everything in the repository gets compiled and all tests pass. -`Sylvia` framework contains some examples of contracts. To find them go to `examples/contracts` +^Sylvia framework contains some examples of contracts. To find them go to `examples/contracts` directory. These contracts are maintained by CosmWasm creators, so contracts in there should follow good practices. diff --git a/yapp.conf b/yapp.conf new file mode 100644 index 0000000..41c1baf --- /dev/null +++ b/yapp.conf @@ -0,0 +1,11 @@ +^sylvia-version +0.9.x + +^sylvia +[**sylvia**](https://github.com/CosmWasm/sylvia) + +^Sylvia +[**Sylvia**](https://github.com/CosmWasm/sylvia) + +^note +**NOTE**: