|
| 1 | +--- |
| 2 | +sidebar_position: 8 |
| 3 | +--- |
| 4 | + |
| 5 | +# Schema |
| 6 | + |
| 7 | +In the context of CosmWasm, "schema" refers to the description of the interface between a contract |
| 8 | +and the client (aka. frontend). This interface is always JSON encoded and the schema describes the |
| 9 | +structure of that JSON. In terms of EVM equivalents, it is more or less what the Contract ABI does. |
| 10 | + |
| 11 | +For the execution of contracts the schema is not used. If the contract interface is simple enough |
| 12 | +you can write the JSON by hand in the client code. Then no schema needs to be created ever. |
| 13 | +However, this approach does not scale well and is just mentioned for better understanding. |
| 14 | + |
| 15 | +Sometimes you also see schema generation for storage types but this is usually not needed as long as |
| 16 | +only the contract itself reads and writes storage. There might be cases where a storage schema could |
| 17 | +be useful to allow indexers to better use state data, but that is far from well established |
| 18 | +practice. Also in contrast to the contract-client API, storage is not necessarily JSON encoded. |
| 19 | +These days MessagePack should be the encoding of choice for high efficient storage. |
| 20 | + |
| 21 | +There are two different types of schemas in CosmWasm: |
| 22 | + |
| 23 | +- **JSON Schema** (version 1): the original schema used since 2020 relying on the |
| 24 | + [JSON Schema specification](https://json-schema.org/). In CosmWasm we use the `#[cw_serde]` annotation, |
| 25 | + the `cosmwasm-schema` crate and the `cargo schema` scripts to generate a JSON Schema from Rust message types. |
| 26 | +- **CosmWasm Schema** (version 2): taking the learnings from working with JSON Schema and seeing how |
| 27 | + it is not meant to be a code generator, we developed a new type of schema. This aims to be more |
| 28 | + compact and include more data relevant for generating clients in various programming languages. |
| 29 | + See [this article][New schema format for CosmWasm] for a full explanation of the motivation and |
| 30 | + differences. |
| 31 | + |
| 32 | +CosmWasm Schema is first shipped as part of CosmWasm 3 but for the foreseeable future you are free to |
| 33 | +use any of the formats. |
| 34 | + |
| 35 | +## Generating the schema |
| 36 | + |
| 37 | +Both schemas are generated as follows: |
| 38 | + |
| 39 | +1. Annotate the relevant types with `#[cw_serde]` |
| 40 | +2. Have a `src/bin/schema.rs` that looks more or less like this: |
| 41 | + |
| 42 | + ```rust |
| 43 | + use cosmwasm_schema::write_api; |
| 44 | + |
| 45 | + use hackatom::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, SudoMsg}; |
| 46 | + |
| 47 | + fn main() { |
| 48 | + write_api! { |
| 49 | + instantiate: InstantiateMsg, |
| 50 | + query: QueryMsg, |
| 51 | + execute: ExecuteMsg, |
| 52 | + // 👇 only add those entries if you use the sudo/migrate entry point |
| 53 | + sudo: SudoMsg, |
| 54 | + migrate: MigrateMsg, |
| 55 | + } |
| 56 | + } |
| 57 | + ``` |
| 58 | + |
| 59 | +3. In `.cargo/config.toml`, ensure you have this alias: |
| 60 | + |
| 61 | + ```toml |
| 62 | + [alias] |
| 63 | + # ... |
| 64 | + schema = "run --bin schema" |
| 65 | + ``` |
| 66 | + |
| 67 | +4. In your contract folder, run `cargo schema`. |
| 68 | + |
| 69 | +This generates a folder structure similar to this: |
| 70 | + |
| 71 | +```text |
| 72 | +schema |
| 73 | +├── cw_schema |
| 74 | +│ ├── hackatom.json |
| 75 | +│ └── raw |
| 76 | +│ ├── execute.json |
| 77 | +│ ├── instantiate.json |
| 78 | +│ ├── migrate.json |
| 79 | +│ ├── query.json |
| 80 | +│ ├── response_to_get_int.json |
| 81 | +│ ├── response_to_recurse.json |
| 82 | +│ ├── response_to_verifier.json |
| 83 | +│ └── sudo.json |
| 84 | +├── hackatom.json |
| 85 | +└── raw |
| 86 | + ├── execute.json |
| 87 | + ├── instantiate.json |
| 88 | + ├── migrate.json |
| 89 | + ├── query.json |
| 90 | + ├── response_to_get_int.json |
| 91 | + ├── response_to_recurse.json |
| 92 | + ├── response_to_verifier.json |
| 93 | + └── sudo.json |
| 94 | +``` |
| 95 | + |
| 96 | +Here the `cw_schema` folder contains the schema in the new format and `hackatom.json` plus `raw` is |
| 97 | +the JSON Schema. The raw folder hosts the original JSON Schema output, one file per struct. The |
| 98 | +`hackatom.json` (or more generally `<contract_name>.json`) combined those into a simple API file as |
| 99 | +documented in [CosmWasm IDL v1.0.0][idl]. |
| 100 | + |
| 101 | +## Using the schema |
| 102 | + |
| 103 | +By parsing `<contract_name>.json` or `cw_schema/<contract_name>.json` you can generate client code |
| 104 | +to interact with the contract. One project implementing this is [ts-codegen]. You can also use the |
| 105 | +schema to dynamically generate UIs at runtime for developers and power users. |
| 106 | + |
| 107 | +The `raw` folder is only needed if the code generator cannot handle the container file |
| 108 | +`<contract_name>.json` and you want to get access to the plain JSON Schema. |
| 109 | + |
| 110 | +## Checking in schemas |
| 111 | + |
| 112 | +The files in the `./schema` folder are auto-generated from the source code. So they don't |
| 113 | +necessarily need to be added to your source repository. Other deployment methods like GitHub release |
| 114 | +artifacts could be used for distribution. But often it is just the simplest solution to check them |
| 115 | +in and track schema changes during development in pull requests. This ensures they are up-to-date |
| 116 | +and no interface is changed by accident. |
| 117 | + |
| 118 | +At the end of the day the contract developer and the users of the schema files have to agree on the |
| 119 | +best way to share the files. |
| 120 | + |
| 121 | +[New schema format for CosmWasm]: https://medium.com/cosmwasm/new-schema-format-for-cosmwasm-02002193b638 |
| 122 | +[idl]: https://github.com/CosmWasm/cosmwasm/blob/v3.0.0/docs/idl.md |
| 123 | +[ts-codegen]: https://github.com/hyperweb-io/ts-codegen |
0 commit comments