{"id":13566348,"url":"https://github.com/osmosis-labs/beaker","last_synced_at":"2025-07-29T09:37:13.396Z","repository":{"id":36952799,"uuid":"491711177","full_name":"osmosis-labs/beaker","owner":"osmosis-labs","description":"Beaker helps streamlining CosmWasm development workflow.","archived":false,"fork":false,"pushed_at":"2024-01-22T13:39:25.000Z","size":1050,"stargazers_count":106,"open_issues_count":34,"forks_count":30,"subscribers_count":10,"default_branch":"main","last_synced_at":"2024-12-09T10:38:02.346Z","etag":null,"topics":["cosmwasm","rust","wasm"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/osmosis-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-Apache","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-05-13T00:48:44.000Z","updated_at":"2024-09-01T06:43:48.000Z","dependencies_parsed_at":"2024-01-07T16:32:54.743Z","dependency_job_id":"46a4e6d6-2b0d-4025-8e87-47fb6a62775e","html_url":"https://github.com/osmosis-labs/beaker","commit_stats":{"total_commits":317,"total_committers":8,"mean_commits":39.625,"dds":"0.10725552050473186","last_synced_commit":"f8e6701889e6470017fed30bcacc090d92efbec4"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osmosis-labs%2Fbeaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osmosis-labs%2Fbeaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osmosis-labs%2Fbeaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osmosis-labs%2Fbeaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osmosis-labs","download_url":"https://codeload.github.com/osmosis-labs/beaker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230326793,"owners_count":18209049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cosmwasm","rust","wasm"],"created_at":"2024-08-01T13:02:07.680Z","updated_at":"2024-12-18T19:06:19.033Z","avatar_url":"https://github.com/osmosis-labs.png","language":"Rust","funding_links":[],"categories":["Rust","Tooling"],"sub_categories":["Other Contracts"],"readme":"# Beaker\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://docs.osmosis.zone/developing/dapps/get_started/\"\u003e\n    \u003cimg src=\"https://github.com/osmosis-labs/beaker/blob/main/assets/beaker.png?raw=true\" alt=\"Beaker logo\" title=\"Beaker\" align=\"center\" height=\"150\" /\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg  height=\"20\" src=\"https://github.com/osmosis-labs/beaker/actions/workflows/doctest.yml/badge.svg\"\u003e\n    \u003cimg height=\"20\" src=\"https://github.com/osmosis-labs/beaker/actions/workflows/lint.yml/badge.svg\"\u003e\n    \u003ca href=\"https://github.com/osmosis-labs/beaker/blob/main/LICENSE-APACHE\"\u003e\u003cimg height=\"20\" src=\"https://img.shields.io/badge/license-APACHE-blue.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/osmosis-labs/beaker/blob/main/LICENSE-MIT\"\u003e\u003cimg height=\"20\" src=\"https://img.shields.io/badge/license-MIT-blue.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://deps.rs/repo/github/osmosis-labs/beaker\"\u003e\u003cimg height=\"20\" src=\"https://deps.rs/repo/github/osmosis-labs/beaker/status.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://crates.io/crates/beaker\"\u003e\u003cimg height=\"20\" src=\"https://img.shields.io/crates/v/beaker.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[Beaker](https://github.com/osmosis-labs/beaker) is a versatile toolkit that simplifies interactions with CosmWasm smart contracts. It offers project scaffolding, seamless deployment, upgrades, execution, querying, an interactive console, task scripting capabilities and more for a streamlined development experience.\n\n---\n\n## Table of Contents\n\n### Getting Started\n\n- [Installation](#installation)\n- [Prerequisites](#prerequisites)\n- [Scaffolding your new dapp project](#scaffolding-your-new-dapp-project)\n  - [`frontend` and `contracts`](#frontend-and-contracts)\n  - [`Cargo.toml`](#cargotoml)\n  - [`Beaker.toml`](#beakertoml)\n  - [`.beaker`](#beaker-1)\n- [Your first CosmWasm contract with Beaker](#your-first-cosmwasm-contract-with-beaker)\n- [Deploy contract on LocalOsmosis](#deploy-contract-on-localosmosis)\n- [Contract Upgrade](#contract-upgrade)\n- [Signers](#signers)\n- [Tasks](#tasks)\n- [Console](#console)\n- [Typescript SDK Generation](#typescript-sdk-generation)\n- [Frontend](#frontend)\n\n### Reference\n\n- [Command](./docs/commands)\n- [Config](./docs/config)\n- [Migration](./MIGRATION.md)\n\n---\n\n## Getting Started\n\nThis section is intended to give you an introduction to `Beaker`, for more detailed reference, you can find them [here](./docs/commands/README.md).\n\n### Prerequisites\n\n- [Rust](https://www.rust-lang.org/tools/install) for building cosmwasm contract\n  - [Rustup](https://rustup.rs/) for dealing with wasm target\n- [Docker](https://docs.docker.com/get-docker/) for running wasm `rust-optimizer` and spinning up [LocalOsmosis](https://github.com/osmosis-labs/localosmosis)\n- [Node](https://nodejs.org/en/) for frontend related stuffs and `beaker-console`\n  - [Yarn](https://yarnpkg.com/) over NPM, since it will not have package resolving issue and causes weird errors down the road\n\n### Installation\n\nBeaker is available via [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) which is a rust toolchain. Once cargo is ready on your machine, run:\n\n```sh\ncargo install -f beaker # `-f` flag for up-to-date version\n```\n\nNow `beaker` is ready to use!\n\n### Scaffolding your new dapp project\n\nIn the directory you want your project to reside, run:\n\n```sh\nbeaker new counter-dapp\n```\n\nThis gives you 2 template options to choose from.\nFor the sake of this tutorial, let's use `counter-example` but you might want to use `minimal` option in your real work since it has zero assumption about your dapp logic or frontend.\n\n```\n? 🤷   Which starting template would you like to use? ›\n  minimal\n❯ counter-example\n```\n\nThis will generate new directory called `counter-dapp` which, by default, come from [this template](https://github.com/osmosis-labs/beaker/tree/main/templates/project).\n\nSo what's in the template? Let's have a look...\n\n```\n.\n├── frontend\n├── contracts\n├── Cargo.toml\n├── Beaker.toml\n├── .gitignore\n└── .beaker\n```\n\n#### `frontend`\n\nThis should be self explanatory, it's where frontend and contracts are stored.\n\nWith `counter-example` template, it demonstrate how frontend app can access deployed code/contract's info through [`.beaker`](#beaker-1). It does so by symlinking `.beaker` into frontend directory, and since states in `.beaker` are in json format, javascript code can just import them.\n\nWith `minimal` template, this directory does not exist, which means it does not assume your frontend choice. In that case, you might want to checkout [create-cosmos-app](https://github.com/cosmology-tech/create-cosmos-app) for scaffolding your frontend or just create one from scratch.\n\n#### `contracts`\n\nThis is where smart contracts are stored. Single workspace can contain multiple contracts.\n\nWith `counter-example` template, this should have `counter` contract pregenerated.\n\n#### `Cargo.toml`\n\nThere is a `Cargo.toml` here which specifies [cargo workspace](https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html).\n\n```\n[workspace]\n\nmembers = [\n  'contracts/*',\n]\n\n[profile.release]\n...\n```\n\nAll the crates (rust packages) in contracts directory are included, with unified release profile. With this, when we have to optimize multiple contracts deterministically, we can do that with ease (see [Contracts as Workspace Members section in rust-optimizer](https://github.com/CosmWasm/rust-optimizer#contracts-as-workspace-members)).\n\n#### `Beaker.toml`\n\nThis is our configuration file, you can find more information about it [here](./docs/config/README.md).\n\n#### `.beaker`\n\nLast but not least, `.beaker` which is the most unusal part. It contains 2 files:\n\n```\n├── state.json\n└── state.local.json\n```\n\nThese 2 files has similar functionality, which are containing beaker related state such as `address`, `code-id`, `label` for each contract on each network for later use.\n\nWhile `state.json` is there for mainnet and testnet state. `state.local.json` is intended to use locally and _being gitignored_ since its state will not make any sense on other's machine.\n\nAnd I don't think we have to explain about `.gitignore` don't we?\n\n---\n\n### Scaffolding new CosmWasm contract\n\nWe can scaffold new contract using the following command:\n\n```sh\ncd counter-dapp\nbeaker wasm new \u003ccontract_name\u003e\n```\n\nDefault template is from [osmosis-labs/cw-minimal-template](https://github.com/osmosis-labs/cw-minimal-template)\n\nThe `cw-minimal-template` has no logic in it unlike `cw-template`, only the skeleton is provided, which makes it ideal to start writing new contract.\n\nNow your new contract will be avaiable on `contracts/multiplier`.\n\nIf you want to use other contract template, you can change the configuration, for example:\n\n```\n# Beaker.toml\n\n[wasm]\ntemplate_repo = \"https://github.com/CosmWasm/cw-template\"\n```\n\nThis step is not required for the rest of the guide since `counter` contract is already in place, but you can just try it out.\n\n### Deploy contract on LocalOsmosis\n\nLocalOsmosis, as it's name suggest, is Osmosis for local development. In the upcoming release, Beaker will have more complete integration with LocalOsmosis, it has to be installed and run separately.\n\nYou can use the osmosis installer and select option 3:\n\n```sh\ncurl -sL https://get.osmosis.zone/install \u003e i.py \u0026\u0026 python3 i.py\n```\n\nOr if you want to use a specific / modified version of LocalOsmosis, you can build from source by\n\n```sh\ngit clone https://github.com/osmosis-labs/osmosis.git\n\nmake localnet-build # build docker image\nmake localnet-start # docker-compose up\n```\n\nNow, with LocalOsmosis up and running, `counter` contract can be deployed (build + store-code + instantiate) using the following command:\n\n```sh\nbeaker wasm deploy counter --signer-account test1 --no-wasm-opt --raw '{ \"count\": 0 }'\n```\n\nWhat's happending here equivalent to the following command sequence:\n\n```sh\n# build .wasm file\n# stored in `target/wasm32-unknown-unknown/release/\u003cCONTRACT_NAME\u003e.wasm`\n# `--no-wasm-opt` is suitable for development, explained below\nbeaker wasm build --no-wasm-opt\n\n# read .wasm in `target/wasm32-unknown-unknown/release/\u003cCONTRACT_NAME\u003e.wasm` due to `--no-wasm-opt` flag\n# use `--signer-account test1` which is predefined.\n# The list of all predefined accounts are here: https://github.com/osmosis-labs/LocalOsmosis#accounts\n# `code-id` is stored in the beaker state, local by default\nbeaker wasm store-code counter --signer-account test1 --no-wasm-opt\n\n# instantiate counter contract\n# with instantiate msg: '{ \"count\": 0 }'\nbeaker wasm instanitate counter --signer-account test1 --raw '{ \"count\": 0 }'\n```\n\nThe flag `--no-wasm-opt` is skipping [rust-optimizer](https://github.com/CosmWasm/rust-optimizer) for faster development iteration.\n\nFor testnet/mainnet deployment, use:\n\n```sh\nbeaker wasm deploy counter --signer-account \u003cACCOUNT\u003e --raw '{ \"count\": 0 }' --network testnet\nbeaker wasm deploy counter --signer-account \u003cACCOUNT\u003e --raw '{ \"count\": 0 }' --network mainnet\n```\n\nInstantiate message can be stored for later use:\n\n```sh\nmkdir contracts/counter/instantiate-msgs\necho '{ \"count\": 0 }' \u003e contracts/counter/instantiate-msgs/default.json\nbeaker wasm deploy counter --signer-account test1 --no-wasm-opt\n```\n\nYou can find references for [`beaker wasm` subcommand here](./docs/commands/beaker_wasm.md).\n\n### Contract Upgrade\n\nContract upgrade in CosmWasm goes through the following steps:\n\n1. store new code on to the chain\n2. broadcast migrate msg, targeting the contract address that wanted to be upgraded with the newly stored code\n\nTo make a contract migratable, the contract needs to have proper entrypoint and admin designated.\n\nTo create the contract entrypoint for migration, first, define `MigrateMsg` in `msg.rs`, this could have any information you want to pass for migration.\n\n```rust\n#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]\npub struct MigrateMsg {}\n```\n\nWith MigrateMsg defined we need to update `contract.rs`. First update the import from `crate::msg` to include `MigrateMsg`:\n\n```rust\nuse crate::msg::{CountResponse, ExecuteMsg, InstantiateMsg, QueryMsg, MigrateMsg};\n```\n\n```rust\n#[cfg_attr(not(feature = \"library\"), entry_point)]\npub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -\u003e StdResult\u003cResponse\u003e {\n    // perform state update or anything neccessary for the migration\n    Ok(Response::default())\n}\n```\n\nNow deploy the contract with admin assigned\n\n```sh\n# `--admin signer` use signer address (test1's address in this case) as designated admin\n# raw address could be passed in as well\nbeaker wasm deploy counter --signer-account test1 --no-wasm-opt --raw '{ \"count\": 0 }' --admin signer\n```\n\nNow try to change the execute logic a bit to see if the upgrade works:\n\n```rust\npub fn try_increment(deps: DepsMut) -\u003e Result\u003cResponse, ContractError\u003e {\n    STATE.update(deps.storage, |mut state| -\u003e Result\u003c_, ContractError\u003e {\n        state.count += 1000000000; // 1 -\u003e 1000000000\n        Ok(state)\n    })?;\n\n    Ok(Response::new().add_attribute(\"method\", \"try_increment\"))\n}\n```\n\nWith admin as `test1`, only `test1` can upgrade the contract\n\n```sh\nbeaker wasm upgrade counter --signer-account test1 --raw '{}' --no-wasm-opt\n```\n\nSimilar to `deploy`, `upgrade` is basiaclly running sequences of commands behind the scene:\n\n```sh\nbeaker wasm build --no-wasm-opt\nbeaker wasm store-code counter --signer-account test1 --no-wasm-opt\nbeaker wasm migrate counter --signer-account test1 --raw '{}'\n```\n\nAnd, like before, `--no-wasm-opt` only means for developement. For mainnet, use:\n\n```sh\nbeaker wasm upgrade counter --signer-account test1 --raw '{}' --network mainnet\n```\n\nMigrate message can be stored for later use:\n\n```sh\nmkdir contracts/counter/migrate-msgs\necho '{}' \u003e contracts/counter/migrate-msgs/default.json\nbeaker wasm upgrade counter --signer-account test1 --no-wasm-opt\n```\n\nYou can find more information about their options [here](./docs/commands/beaker_wasm.md).\n\n### Execute Contract Messages\n\nContract messages can be executed using the `beaker wasm execute` subcommand. For example:\n\n```sh\nbeaker wasm execute counter --raw '{ \"increment\": {} }' --signer-account test1\n```\n\n### Query Contract State\n\nYou can query contract state by submitting query messages with the `beaker wasm query` command. For example:\n\n```sh\nbeaker wasm query counter --raw '{\"get_count\": {}}'\n```\n\n### Signers\n\nWhenever you run command that requires signing transactions, there are 3 options you can reference your private keys:\n\n- `--signer-account` input of this option refer to the accounts defined in the [config file](./docs/config/global.md), which is not encrypted, so it should be used only for testing\n- `--signer-mnemonic` input of this option is the raw mnemonic string to construct a signer\n- `--signer-private-key` input of this option is the same as `--signer-mnemonic` except it expects base64 encoded private key\n- `--signer-keyring` use the OS secure store as backend to securely store your key. To manage them, you can find more information [here](./docs/commands/beaker_key.md).\n\n### Tasks\nSometimes you want to run a series of commands in a single command. For example, you want to deploy a set of contracts that one contract instantiation depends on another contract. You can do this by defining a task in the `tasks` directory.\n\n```sh\nbeaker task new deploy\n```\n\nThis will create a new task file in `tasks/deploy.rhai`.\n\nTask is written in `Rhai` which is an embedded scripting language in Rust. You can find example of how to write Rhai [here](https://rhai.rs/book/start/examples/scripts.html).\n\nUsing Rhai as a scripting language makes exposing all existing functionality of Beaker to the task script relatively simple. Currently, all the subcommands of `beaker wasm` are exposed to the task script. So you can do things like:\n\n```rhai\nlet counter_contract = wasm::deploy(merge(\n    #{\n        signer_account: \"test1\"\n        contract_name: \"counter\",\n        msg: #{}\n    }\n));\n\nlet counter_proxy_contract = wasm::deploy(merge(\n    #{\n        signer_account: \"test1\"\n        contract_name: \"counter\",\n        msg: #{\n            counter_contract_address: counter_contract.address\n        }\n    }\n));\n\n```\n\nThe interface of `wasm::deploy` the same as the `beaker wasm deploy` command. Other functions in `wasm` module are also similar to their corresponding subcommands so you can refer to the [documentation](./docs/commands/beaker_wasm.md) for more information about what is avialable in the script.\n\nNote that additional feature here is that `msg` can also be passed as an object rather than passing JSON string to `raw`.\n\nThere are also some additional helper function and macros that are exposed to the task script.\n\n#### `fs` module\nThis module provides access to the file system. It is similar to the `std::fs` module in Rust. Morre information about the module can be found [here](https://github.com/rhaiscript/rhai-fs#rhai-script). This is how it can be used in the task script:\n\n```rhai\nfile = fs::open_file(\"params.json\");\n```\n\n#### `match_args`\n\nMatching command line arguments passed to the script and returns a map of the arguments\n\n```rhai\n// beaker task run deploy -- --signer test1 --build-flags no_wasm_opt\nlet cli_args = match_args([\"signer\", \"build_flags\"]);\n\nprint(cli_args) // =\u003e #{ signer: \"test1\", \"build_flags\": \"no_wasm_opt\" }\n```\n\n#### `merge`\nMerges 2 objects together. If there are duplicate keys, the value from the second object will be used.\n\n```rhai\nlet a = #{ a: 1, b: 2 };\nlet b = #{ b: 3, c: 4 };\n\nlet merged = merge(a, b);\n\nprint(merged) // =\u003e #{ a: 1, b: 3, c: 4 }\n```\n\n#### `@assert`\nPerform assertion on the given condition. If the condition is false, the script will exit with an error.\nThis is useful for ensuring that the script is running as expected.\n\n```rhai\n@assert(1 == 1); // pass\n@assert(1 == 2); // fail\n\n@assert(1 != 2); // pass\n@assert(1 != 1); // fail\n\n@assert(1 \u003c 2); // pass\n@assert(1 \u003e 2); // fail\n\n@assert(1 \u003c= 2); // pass\n@assert(1 \u003e= 2); // fail\n```\n\nFor more example on how to use task, you can refer to the [example tasks](./examples/scripting-cookbook/tasks/).\n\n### Console\n\nAfter deployed, you can play with the deployed contract using:\n\n```sh\nbeaker console\n```\n\nIt might prompt you like the following:\n\n```\n? Project's Typescript SDK seems to be missing, would you like to generate?\n```\n\nPress `enter` to proceed for now, and we will discuss about it in detail in the [Typescript SDK Generation](#typescript-sdk-generation) section.\n\nThis will launch custom node repl, where `contract`, `account` are available.\n`contract` contains deployed contract.\n`account` contains [pre-defined accounts in localosmosis](https://github.com/osmosis-labs/LocalOsmosis#accounts).\n\nSo you can interact with the recently deployed contract like this:\n\n```js\nawait contract.counter.signer(account.test1).execute({ increment: {} });\nawait contract.counter.query({ get_count: {} });\n```\n\nYou can find avaialable methods for the aforementioned instances here:\n\n- [Account](./ts/beaker-console/docs/classes//Account.md#methods-1)\n- [Contract](./ts/beaker-console/docs/classes//Contract.md#methods-1)\n\nYou can remove `contract` and/or `account` namespace by changing config.\n\n```\n# Beaker.toml\n\n[console]\naccount_namespace = false\ncontract_namespace = false\n```\n\n```js\nawait counter.signer(test1).execute({ increment: {} });\nawait counter.query({ get_count: {} });\n```\n\nWith the Typescript SDK which was previously mentioned, it is used to extend the `Contract` instance with method generated ftom execute and query messages. For example:\n\n```js\nawait counter.getCount();\n\nsc = counter.signer(test1); // create signing client for `counter` with `test1`\n\nawait sc.increment();\nawait sc.getCount();\n```\n\nWith this, it's more convenient than the previous interaction method since you can use tab completion for the methods as well.\n\nBeaker console is also allowed to deploy contract, so that you don't another terminal tab to do so.\n\n```js\n.deploy counter -- --signer-account test1 --raw '{ \"count\": 999 }'\n```\n\n`.build`, `.storeCode`, `.instantiate` commands are also available and has the same options as Beaker cli command, except that `--no-wasm-opt` are in by default since it is being intended to use in the development phase.\n\n`.help` to see all avaiable commands.\n\nApart from that, in the console, you can access Beaker's state, configuration and sdk from `state`, `conf` and `sdk` variables accordingly.\n\n### Typescript SDK Generation\n\nBeaker leverage [ts-codegen](https://github.com/CosmWasm/ts-codegen) to generate typescript client for cosmwasm contract. By default, Beaker's template prepare `ts/sdk` directory where typescript compiler and bundler are setup, so the generated client definition could be used by `beaker-console`, frontend or published as library for others to use.\n\nTo generate sdk for contract, run\n\n```sh\nbeaker wasm ts-gen counter # replace `counter` with any of contract name\n```\n\nWith this a package is avaiable in `ts/sdk` with name `\u003cproject-name\u003e-sdk` which can be used by any node / js / ts project.\n\nThe underlying code that actually calls `ts-codegen` with configuration is located in `ts/sdk/scripts/codegen.js`.\n\nLet's try adding `multiply` method to our contract and see how this works.\n\n```rust\n// msg.rs\n\n#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]\n#[serde(rename_all = \"snake_case\")]\npub enum ExecuteMsg {\n    Increment {},\n    Multiply { times: i32 }, // [1] add this enum variant\n    Reset { count: i32 },\n}\n```\n\n```rust\n// contract.rs\n\n#[cfg_attr(not(feature = \"library\"), entry_point)]\npub fn execute(\n    deps: DepsMut,\n    _env: Env,\n    info: MessageInfo,\n    msg: ExecuteMsg,\n) -\u003e Result\u003cResponse, ContractError\u003e {\n    match msg {\n        ExecuteMsg::Increment {} =\u003e try_increment(deps),\n        ExecuteMsg::Multiply { times } =\u003e try_multiply(deps, times), // [2] add this match arm\n        ExecuteMsg::Reset { count } =\u003e try_reset(deps, info, count),\n    }\n}\n\n// [3] add this function\nfn try_multiply(deps: DepsMut, times: i32) -\u003e Result\u003cResponse, ContractError\u003e {\n    STATE.update(deps.storage, |mut state| -\u003e Result\u003c_, ContractError\u003e {\n        state.count *= times;\n        Ok(state)\n    })?;\n\n    Ok(Response::new().add_attribute(\"method\", \"try_multiply\"))\n}\n```\n\nThen redeploy the contract:\n\n```sh\nbeaker wasm deploy counter --signer-account test1 --no-wasm-opt --raw '{ \"count\": 0 }'\n```\n\nThen regenerate `counter`'s client\n\n```sh\nbeaker wasm ts-gen counter\n```\n\nNow we can test it out in the `beaker console`\n\n```js\nsc = counter.signer(test1);\n\nawait sc.increment();\nawait sc.getCount();\n// =\u003e { count: 1 }\n\nawait sc.multiply({ times: 2 });\nawait sc.getCount();\n// =\u003e { count: 2 }\n\nawait sc.multiply({ times: 10 });\nawait sc.getCount();\n// =\u003e { count: 20 }\n```\n\n`sc` is an instance of `CounterContract` which you can find it in `ts/sdk/src/contracts/CounterContract.ts`.\n\n### Frontend\n\nBeaker project template also come with frontend template. But in order to interact with it you need:\n\n- [Keplr installed](https://www.keplr.app/)\n- [Keplr chain setup for LocalOsmosis](https://github.com/osmosis-labs/LocalOsmosis/tree/main/localKeplr)\n- Add test account to Keplr\n  - [Add account via mnemonic in Keplr](https://help.keplr.app/getting-started/connecting-additional-accounts).\n    The account `test1` can be added by copy-pasting `notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius` to the Import account screen on Keplr. It contains 100,000 test OSMOs.\n  - [List of test accounts and its mnemonics in LocalOsmosis](https://github.com/osmosis-labs/LocalOsmosis#accounts)\n\nNow we are good to go! Let's dive in\n\n```sh\ncd frontend\nyarn \u0026\u0026 yarn dev\n```\n\nThen open `http://localhost:3000/` in the browser.\n\nIn frontend directory, you will see that `.beaker` is in here. It is actually symlinked to the one in the root so that frontend code can access beaker state.\n\n---\n\n## License\n\nThe crates in this repository are licensed under either of the following licenses, at your discretion.\n\n    Apache License Version 2.0 (LICENSE-APACHE or apache.org license link)\n    MIT license (LICENSE-MIT or opensource.org license link)\n\nUnless you explicitly state otherwise, any contribution submitted for inclusion in this library by you shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosmosis-labs%2Fbeaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosmosis-labs%2Fbeaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosmosis-labs%2Fbeaker/lists"}