This site requires Javascript to be enabled.

Project Setup

A new Archway project involves creating a Rust-based application that compiles to WebAssembly (wasm), a binary instruction format optimized for efficient execution on chain. Setting up a new Archway project is most straightforward when using the Archway Developer CLI. Let's begin the process of creating a new project with the help of this Developer CLI.

Creating an account

Reminder

If you are on a Linux machine with a distribution different from Ubuntu, you may need to install the GNOME Keyring, or any other keyring compatible with the Secret service API. This is required for creating accounts.

An account is required to execute transactions on-chain. You will also need the chain's native token to execute these transactions. The Constantine testnet uses the CONST native token, which is required for paying transaction fees. To obtain these free testnet tokens, follow the instructions on the Requesting Testnet Tokens page. For Mainnet, you will need to acquire ARCH tokens, which can be done through our Archway Connect platform.

Use the command archway accounts list to view accounts in your environment's keyring, or create a new account using archway accounts new.

Usage:

$ archway accounts new [ACCOUNT-NAME] [STDININPUT] [--json] [--log-level debug|error|info|warn] [--ledger | --recover] [--hd-path <value>] [--keyring-backend file|os|test] [--keyring-path <value>]

Example:

archway accounts new

You will be asked to enter a name for the account.

Example output with certain sensitive details altered or omitted:

✅ Account testwallet successfully created!Address: archway1qs2qnjvzlkgt0gpekr2c3pld0eu3tq8yw2kwgcPublic Key  Algo: secp256k1  Key: Ak++QeiMs4HhXQe3JLpM/R+nU2pzvOWT6GsJZacTfyr6Recovery phrase: <phrase removed>⚠️ Important: write this mnemonic phrase in a safe place. It is the only way to recover your account if you forget your password.Checking for updates...

Creating a project

A smart contract project is a development environment that allows you to write, test, and deploy smart contracts on the Archway blockchain. These projects are structured to include all necessary dependencies and configurations required for building and interacting with smart contracts. The Archway Developer CLI creates a multi-contract project, with the setup process creating the first smart contract from a template.

The archway new command starts a new project. We will be using the Increment contract template for this example.

Usage:

$ archway new [PROJECT-NAME] [--json] [--log-level debug|error|info|warn] [--chain <value>] [--contract] [--contract-name <value>] [--template <value>]

Example

Enter the following command in the terminal:

archway new

You will be asked for the following information:

  1. Enter the name of the new project: Type in a name for your project.
  2. Select a chain to use: Use your keyboard's up and down arrow keys to select one of the available chains for the project. You should see an option for Archway Testnet, which is the stable testnet recommended for dapp development, and Archway, the production network. For this example, select Archway Testnet.
  3. Choose a name for your contract: Each project can have one or more contracts, and this name will be given to the first contract created within the project. Name this contract increment.
  4. Choose a starter template: This is the template your first contract will be built from. Since we are creating a contract based on the Increment template, select Increment from the list.
  5. Which version do you want to generate?: This particular template has two variants: full, which provides the full feature set of the template, and minimal, a more barebones version. For this example, let's go with full.

Example output with certain details altered or omitted:

✔ Enter the name of the new project … Project 1✔ Select a chain to use › Archway✔ Choose a name for your contract … increment✔ Choose a starter template › IncrementCreating Archway project project-1...🔧   Destination: /Users/testuser/project-1 ...🔧   project-name: project-1 ...🔧   Generating template ...[ 1/19]   Done: .cargo/config                                                                                                                                                                                                                               💡   Initializing a fresh Git repository✨   Done! New project created /Users/testuser/project-1🔧   Destination: /Users/testuser/project-1/contracts/increment ...🔧   project-name: increment ...🔧   Generating template ...✔ 🤷   This template has 2 versions:- The full template includes example logic in case you're new to CosmWasm smart contracts.

Info

It should also be noted that the Archway Developer CLI creates a unique project structure and configuration. Therefore, trying to use the Archway Developer CLI on a project not created using the tool will not work and would need to be modified. The best approach is to create an Increment contract using the minimal template and then copy over your contract files.

Configuring a project

When you have created a new project, navigate to the folder where the project was installed and print your config using the command:

archway config show

An example output:

Chain id: constantine-3Contracts path: ./contractsKeyring backend: osKeyring files path: /Users/testuser/.config/archway/keys

If this configuration isn't to your liking, you can always modify it by executing the archway config set with the key and value you would like to update.

Usage:

$ archway config set KEY VALUE [--json] [--log-level debug|error|info|warn] [-g]

Arguments:

KEY (required) (chain-id|contracts-path|default-account|keyring-backend|keyring-path) The config key to setVALUE (required) The config value

The Chain ID specifies the chain the project is currently configured to interact with. You can use the following command to easily switch to the Archway testnet (constantine-3):

$ archway config set chain-id constantine-3

You can find the list of public Archway networks here.

Creating a blank project

We recommend developers utilize the Archway Developer CLI to build their smart contracts. This tool requires a particular structure and specific configurations to function as designed. The CLI offers a few templates to help you get started, but there are several reasons why starting from a blank template is useful:

  • You have an existing project and want to easily port over your code to utilize the CLI.
  • You are starting a new project and want to work from a clean slate.

To create a new project from a blank template, use the Increment contract template and choose the minimal version. Follow these steps:

Step 1

$ archway new

You would then be asked to enter the name of the project:

? Enter the name of the new project › blank-project

Step 2

You would then need to select the chain you want to use:

? Select a chain to use › - Use arrow-keys. Return to submit.
❯   Archway Testnet - Stable testnet - recommended for dapp development
    Archway

Step 3

Now choose a name for your contract:

? Choose a name for your contract ›

Step 4

Next, select the Increment starter template:

? Choose a starter template › - Use arrow-keys. Return to submit.
❯   Increment - [https://github.com/https://github.com/archway-network/archway-templates/tree/main/increment]
    CW20
    CW20 escrow
    CW721 with on-chain metadata

Step 5

The CLI will start creating the project but will then pause for you to select the version to generate. You must select minimal, which will generate a blank contract:

Which version do you want to generate? ›
  full
❯ minimal

The CLI will then complete the process of creating the project.

The following will be the contents of the contract files found under the src directory.

contract.rs

#[cfg(not(feature = "library"))]use cosmwasm_std::entry_point;use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};// use cw2::set_contract_version;use crate::error::ContractError;use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};/*// version info for migration infoconst CONTRACT_NAME: &str = "crates.io:increment";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<Response, ContractError> {    unimplemented!()}#[cfg_attr(not(feature = "library"), entry_point)]pub fn execute(    _deps: DepsMut,    _env: Env,    _info: MessageInfo,    _msg: ExecuteMsg,) -> Result<Response, ContractError> {    unimplemented!()}#[cfg_attr(not(feature = "library"), entry_point)]pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult<Binary> {    unimplemented!()}#[cfg(test)]mod tests {}

errors.rs

use cosmwasm_std::StdError;use thiserror::Error;#[derive(Error, Debug)]pub enum ContractError {    #[error("{0}")]    Std(#[from] StdError),    #[error("Unauthorized")]    Unauthorized {},    // Add any other custom errors you like here.    // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.}

helpers.rs

use schemars::JsonSchema;use serde::{Deserialize, Serialize};use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg};use crate::msg::ExecuteMsg;/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers/// for working with this.#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]pub struct CwTemplateContract(pub Addr);impl CwTemplateContract {    pub fn addr(&self) -> Addr {        self.0.clone()    }    pub fn call<T: Into<ExecuteMsg>>(&self, msg: T) -> StdResult<CosmosMsg> {        let msg = to_binary(&msg.into())?;        Ok(WasmMsg::Execute {            contract_addr: self.addr().into(),            msg,            funds: vec![],        }        .into())    }}

lib.rs

pub mod contract;mod error;pub mod helpers;pub mod msg;pub mod state;pub use crate::error::ContractError;

msg.rs

use cosmwasm_schema::{cw_serde, QueryResponses};#[cw_serde]pub struct InstantiateMsg {}#[cw_serde]pub enum ExecuteMsg {}#[cw_serde]#[derive(QueryResponses)]pub enum QueryMsg {}

state.rs

/// Empty