From 35014c1c348d82176015af37b39ab92a996b3767 Mon Sep 17 00:00:00 2001 From: ccamel Date: Mon, 28 Aug 2023 09:01:05 +0200 Subject: [PATCH 1/5] build(template): add template for quick smart-contract scaffold --- templates/okp4-smart-contract/.ffizer.yaml | 7 +++ .../{{ contract_name }}/Cargo.ffizer.hbs.toml | 60 +++++++++++++++++++ .../{{ contract_name }}/Makefile.toml | 12 ++++ .../{{ contract_name }}/README.ffizer.hbs.md | 1 + .../src/bin/schema.ffizer.hbs.rs | 11 ++++ .../{{ contract_name }}/src/contract.rs | 44 ++++++++++++++ .../{{ contract_name }}/src/error.rs | 8 +++ .../{{ contract_name }}/src/lib.rs | 6 ++ .../{{ contract_name }}/src/msg.rs | 28 +++++++++ .../{{ contract_name }}/src/state.rs | 1 + 10 files changed, 178 insertions(+) create mode 100644 templates/okp4-smart-contract/.ffizer.yaml create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/Makefile.toml create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/README.ffizer.hbs.md create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/bin/schema.ffizer.hbs.rs create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/contract.rs create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/error.rs create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/lib.rs create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/msg.rs create mode 100644 templates/okp4-smart-contract/{{ contract_name }}/src/state.rs diff --git a/templates/okp4-smart-contract/.ffizer.yaml b/templates/okp4-smart-contract/.ffizer.yaml new file mode 100644 index 00000000..423ec4d0 --- /dev/null +++ b/templates/okp4-smart-contract/.ffizer.yaml @@ -0,0 +1,7 @@ +variables: + - name: contract_name + default_value: okp4-foo + +scripts: + - message: | + 🖨️ Smart contract 🚀 {{ contract_name }} scaffolded! Enjoy! diff --git a/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml b/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml new file mode 100644 index 00000000..297514d3 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml @@ -0,0 +1,60 @@ +[package] +authors = ["OKP4"] +edition = "2021" +name = "{{ contract_name }}" +rust-version = "1.69" +version = "0.0.1" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +codegen-units = 1 +debug = false +debug-assertions = false +incremental = false +lto = true +opt-level = 3 +overflow-checks = true +panic = 'abort' +rpath = false + +[dependencies] +cosmwasm-schema.workspace = true +cosmwasm-std.workspace = true +cosmwasm-storage.workspace = true +cw-storage-plus.workspace = true +cw-utils.workspace = true +cw2.workspace = true +itertools = "0.11.0" +okp4-logic-bindings.workspace = true +okp4-objectarium-client.workspace = true +okp4-objectarium.workspace = true +schemars.workspace = true +serde.workspace = true +thiserror.workspace = true + +[dev-dependencies] +cw-multi-test.workspace = true +url = "2.4.0" + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[package.metadata.scripts] +optimize = """docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.10 +""" diff --git a/templates/okp4-smart-contract/{{ contract_name }}/Makefile.toml b/templates/okp4-smart-contract/{{ contract_name }}/Makefile.toml new file mode 100644 index 00000000..944012e8 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/Makefile.toml @@ -0,0 +1,12 @@ +[tasks.generate_schema] +args = ["run", "--bin", "schema"] +command = "cargo" + +[tasks.schema] +dependencies = ["generate_schema"] +script = ''' +SCHEMA=$(find schema -type f -maxdepth 1 -name '*.json' -print0) +TITLE=$(jq -r .contract_name $SCHEMA) +jq --arg description "$(cat README.md)" '. + {description: $description}' $SCHEMA > $SCHEMA.tmp && mv $SCHEMA.tmp $SCHEMA +jq --arg title $TITLE '. + {title: $title}' $SCHEMA > $SCHEMA.tmp && mv $SCHEMA.tmp $SCHEMA +''' diff --git a/templates/okp4-smart-contract/{{ contract_name }}/README.ffizer.hbs.md b/templates/okp4-smart-contract/{{ contract_name }}/README.ffizer.hbs.md new file mode 100644 index 00000000..c9a12544 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/README.ffizer.hbs.md @@ -0,0 +1 @@ +# {{ contract_name }} diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/bin/schema.ffizer.hbs.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/bin/schema.ffizer.hbs.rs new file mode 100644 index 00000000..a7f7db00 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/bin/schema.ffizer.hbs.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use {{ replace contract_name "-" "_" }}::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/contract.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/contract.rs new file mode 100644 index 00000000..1a8c5ec6 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/contract.rs @@ -0,0 +1,44 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult}; +use cw2::set_contract_version; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +const CONTRACT_NAME: &str = concat!("crates.io:", env!("CARGO_PKG_NAME")); +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut<'_>, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Err(StdError::generic_err("Not implemented").into()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + _deps: DepsMut<'_>, + _env: Env, + _info: MessageInfo, + _msg: ExecuteMsg, +) -> Result { + Err(StdError::generic_err("Not implemented").into()) +} + +pub mod execute {} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps<'_>, _env: Env, _msg: QueryMsg) -> StdResult { + Err(StdError::generic_err("Not implemented")) +} + +pub mod query {} + +#[cfg(test)] +mod tests {} diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/error.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/error.rs new file mode 100644 index 00000000..7155f592 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/error.rs @@ -0,0 +1,8 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), +} diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/lib.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/lib.rs new file mode 100644 index 00000000..dfedc9dc --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/lib.rs @@ -0,0 +1,6 @@ +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/msg.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/msg.rs new file mode 100644 index 00000000..3bb7e8c9 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/msg.rs @@ -0,0 +1,28 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; + +/// Instantiate message +#[cw_serde] +pub struct InstantiateMsg {} + +/// Execute messages +#[cw_serde] +pub enum ExecuteMsg { + /// # Foo + Foo, +} + +/// Query messages +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// # Bar + #[returns(BarResponse)] + Bar { foo: String }, +} + +/// # BarResponse +#[cw_serde] +pub struct BarResponse { + /// The foo value + pub foo: String, +} diff --git a/templates/okp4-smart-contract/{{ contract_name }}/src/state.rs b/templates/okp4-smart-contract/{{ contract_name }}/src/state.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/templates/okp4-smart-contract/{{ contract_name }}/src/state.rs @@ -0,0 +1 @@ + From 5fc21eecee0da685e2f0a1dc1c76bf7e94707a01 Mon Sep 17 00:00:00 2001 From: ccamel Date: Mon, 28 Aug 2023 09:02:28 +0200 Subject: [PATCH 2/5] build(project): add ffizer task for template scaffolding --- Makefile.toml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Makefile.toml b/Makefile.toml index ab510824..aef1a1b5 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -140,6 +140,11 @@ echo "🐾 Generating release binary checksums into ${DIR_WASM}" } ''' +[tasks.scaffold-smart-contract] +args = ["apply", "-s", "templates/okp4-smart-contract", "-d", "contracts"] +command = "ffizer" +dependencies = ["install-ffizer"] + [tasks.chain-clean] condition = { fail_message = "🚫 The chain is running" } condition_script = ["! docker ps -a | grep ${CHAIN} > /dev/null"] @@ -519,6 +524,14 @@ install_crate = { crate_name = "cargo-llvm-cov" } [tasks.install-cosmwasm-check] install_crate = { crate_name = "cosmwasm-check" } +[tasks.install-ffizer] +install_script = ''' +if ! [ -x "$(command -v ffizer)" ]; then + echo '❌ ffizer - https://ffizer.github.io/ not found. Please install it first.' >&2 + exit 1 +fi +''' + [config] default_to_workspace = false min_version = "0.36.3" From 3d1b59d85c84b98d531ba458bb93abb2ae5b1f42 Mon Sep 17 00:00:00 2001 From: ccamel Date: Mon, 28 Aug 2023 09:27:04 +0200 Subject: [PATCH 3/5] docs: add section to describe smart contract scaffolding --- README.md | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 516abdd2..3b4e7e57 100644 --- a/README.md +++ b/README.md @@ -230,11 +230,36 @@ cargo make chain-clean ⚠️ Please be cautious when running this command as it will completely clean the chain's home directory and the action is irreversible. -## Documentation +## Develop + +### Smart Contracts scaffolding + +When developing a new Smart Contract, you can use the scaffolding to generate the Smart Contract's code. + +#### Pre-requisites + +Be sure you have the following tools installed: + +- [ffizer](https://ffizer.github.io/ffizer/book/#install) v2.10.3 or higher + +#### Generate the scaffolding + +To generate the scaffolding, just run: + +```sh +cargo make scaffold-smart-contract +``` + +Then, follow the instructions. + +### Documentation + +The documentation of the smart contracts must be committed to the repository. The documentation is generated from the +smart contracts' schema. To generate the documentation follow the steps below. -### Tools installation +#### Pre-requisites Be sure you have the following tools installed: @@ -246,7 +271,7 @@ Then, install the dependencies: yarn global add @adobe/jsonschema2md@7.1.5 ``` -### Generate the documentation +#### Generate the documentation To generate the documentation, just run: @@ -257,7 +282,7 @@ cargo make docs-generate You'll find the generated documentation under the `docs` folder. -### Commit the documentation +#### Commit the documentation When developing a new contract, you should commit the generated documentation to the repository. For this, gerenate the documentation and commit the changes: From 210b6557d064c3d44d3529c7a4d12e5b508443c4 Mon Sep 17 00:00:00 2001 From: ccamel Date: Mon, 28 Aug 2023 09:43:51 +0200 Subject: [PATCH 4/5] chore: relax rule for duplicated headers --- .markdownlint.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 2e0b914c..83d8ce84 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -1,3 +1,4 @@ line-length: false no-hard-tabs: false no-inline-html: false +no-duplicate-header: false From 17519bdc7ad72469138e1aaf353daaa69c1e344d Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 29 Aug 2023 11:54:11 +0200 Subject: [PATCH 5/5] build(template): clean unecessary dependencies Co-authored-by: Benjamin DENEUX <33665639+bdeneux@users.noreply.github.com> --- .../{{ contract_name }}/Cargo.ffizer.hbs.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml b/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml index 297514d3..8af3dc30 100644 --- a/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml +++ b/templates/okp4-smart-contract/{{ contract_name }}/Cargo.ffizer.hbs.toml @@ -34,7 +34,6 @@ cosmwasm-storage.workspace = true cw-storage-plus.workspace = true cw-utils.workspace = true cw2.workspace = true -itertools = "0.11.0" okp4-logic-bindings.workspace = true okp4-objectarium-client.workspace = true okp4-objectarium.workspace = true @@ -44,7 +43,6 @@ thiserror.workspace = true [dev-dependencies] cw-multi-test.workspace = true -url = "2.4.0" [features] # for more explicit tests, cargo test --features=backtraces