Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cw721-template #120

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions cargo-generate.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[template]
sub_templates = ["templates/cw721-template"]
5 changes: 5 additions & 0 deletions templates/cw721-template/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
wasm-debug = "build --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --example schema"
69 changes: 69 additions & 0 deletions templates/cw721-template/.github/workflows/basic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml
# As well as: https://github.com/DA0-DA0/dao-contracts/blob/main/.github/workflows/basic.yml

on: [push, pull_request]

name: Basic

jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2

- name: Install latest nightly toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
target: wasm32-unknown-unknown
override: true

- name: Run tests
uses: actions-rs/cargo@v1
with:
toolchain: nightly
command: unit-test
args: --locked
env:
RUST_BACKTRACE: 1

- name: Compile WASM contract
uses: actions-rs/cargo@v1
with:
toolchain: nightly
command: wasm
args: --locked
env:
RUSTFLAGS: "-C link-arg=-s"

lints:
name: Lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
components: rustfmt, clippy

- name: Run cargo fmt
uses: actions-rs/cargo@v1
with:
toolchain: nightly
command: fmt
args: --all -- --check

- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
toolchain: nightly
command: clippy
args: --all-targets -- -D warnings
16 changes: 16 additions & 0 deletions templates/cw721-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Build results
/target
/schema

# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
.cargo-ok

# Text file backups
**/*.rs.bk

# macOS
.DS_Store

# IDEs
*.iml
.idea
28 changes: 28 additions & 0 deletions templates/cw721-template/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "{{project-name}}"
description = "A custom cw721 NFT contract."
version = "0.1.0"
authors = ["{{authors}}"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []

[dependencies]
cosmwasm-schema = "1.2.1"
cosmwasm-std = "1.2.1"
cw2 = "1.0.1"
cw20 = "1.0.1"
cw721 = "0.17.0"
cw721-base = { version = "0.17.0", features = ["library"] }
schemars = "0.8.11"
serde = { version = "1.0.152", default-features = false, features = ["derive"] }
thiserror = "1.0.30"
14 changes: 14 additions & 0 deletions templates/cw721-template/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cw721_template
Copyright (C) 2021 Confio OÜ

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
44 changes: 44 additions & 0 deletions templates/cw721-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# CW721 Template

A template for generating custom cw721 NFT contracts. Based on [cw-template](https://github.com/CosmWasm/cw-template).

## Creating a new repo from template

Assuming you have a recent version of Rust and Cargo installed
(via [rustup](https://rustup.rs/)),
then the following should get you a new repo to start a contract:

Install [cargo-generate](https://github.com/ashleygwilliams/cargo-generate) and cargo-run-script.
Unless you did that before, run this line now:

```sh
cargo install cargo-generate --features vendored-openssl
cargo install cargo-run-script
```

Now, use it to create your new contract.

Go to the folder in which you want to place it and run:

**Latest**

```sh
cargo generate --git https://github.com/CosmWasm/cw-nfts.git --name PROJECT_NAME
```

**Older Versions**

Pass version as branch flag:

```sh
cargo generate --git https://github.com/CosmWasm/cw-nfts.git --branch <version> --name PROJECT_NAME
```

Example:

```sh
cargo generate --git https://github.com/CosmWasm/cw-nfts.git --branch 0.16 --name PROJECT_NAME
```

You will now have a new folder called `PROJECT_NAME` (I hope you changed that to something else)
containing a simple working contract and build system that you can customize.
5 changes: 5 additions & 0 deletions templates/cw721-template/cargo-generate.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[template]
# Files listed here will not be processed by the template engine when a project is generated.
# This is needed when files contains curly brackets as in `v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}`.
# The files will be copied 1:1 to the target project. To avoid shipping them completely add them to `.genignore`.
exclude = ["test_generate.sh", "cargo-generate.toml"]
11 changes: 11 additions & 0 deletions templates/cw721-template/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use cosmwasm_schema::write_api;

use {{crate_name}}::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};

fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
}
}
66 changes: 66 additions & 0 deletions templates/cw721-template/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Version info for migration
pub const CONTRACT_NAME: &str = "crates.io:{{project-name}}";
pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[cfg(not(feature = "library"))]
pub mod entry {
use crate::error::ContractError;
use crate::msg::{Cw721Contract, ExecuteMsg, InstantiateMsg, QueryMsg};

use super::*;

use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};

// This makes a conscious choice on the various generics used by the contract
#[entry_point]
pub fn instantiate(
mut deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> StdResult<Response> {
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

// Instantiate the base contract
Cw721Contract::default().instantiate(deps.branch(), env, info, msg)
}

#[entry_point]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
// Optionally override the default cw721-base behavior
// ExecuteMsg::Burn { token_id } => unimplemented!(),

// Implment extension messages here, remove if you don't wish to use
// An ExecuteExt extension
ExecuteMsg::Extension { msg } => match msg {
_ => unimplemented!(),
},

// Use the default cw721-base implementation
_ => Cw721Contract::default()
.execute(deps, env, info, msg)
.map_err(Into::into),
}
}

#[entry_point]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
// Optionally override a default cw721-base query
// QueryMsg::Minter {} => unimplemented!(),
QueryMsg::Extension { msg } => match msg {
_ => unimplemented!(),
},

// Use default cw721-base query implementation
_ => Cw721Contract::default().query(deps, env, msg),
}
}
}
13 changes: 13 additions & 0 deletions templates/cw721-template/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use cosmwasm_std::StdError;
use thiserror::Error;

/// Custom errors for this contract, add additional errors here.
#[derive(Error, Debug, PartialEq)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),

/// This inherits from cw721-base::ContractError to handle the base contract errors
#[error("{0}")]
Cw721Error(#[from] cw721_base::ContractError),
}
5 changes: 5 additions & 0 deletions templates/cw721-template/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod contract;
mod error;
pub mod msg;
#[cfg(test)]
mod tests;
37 changes: 37 additions & 0 deletions templates/cw721-template/src/msg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{CustomMsg, Empty};
pub use cw721_base::msg::InstantiateMsg;

// Implements extended on-chain metadata, by default cw721 NFTs only store a
// token_uri, which is a URL to off-chain metadata (same as ERC721).
#[cw_serde]
#[derive(Default)]
pub struct MetadataExt {}

// This is the custom Execute message extension for this contract.
// Use it to implement custom functionality.
#[cw_serde]
pub enum ExecuteExt {}
impl CustomMsg for ExecuteExt {}

// This is the custom Query message type for this contract.
// Use it to implement custom query messages.
#[cw_serde]
pub enum QueryExt {}
impl CustomMsg for QueryExt {}

// This contrains default cw721 logic with extensions.
// If you don't need a particular extension, replace it with an
// `Empty` type.
pub type Cw721Contract<'a> =
cw721_base::Cw721Contract<'a, MetadataExt, Empty, ExecuteExt, QueryExt>;

// The execute message type for this contract.
// If you don't need the Metadata and Execute extensions, you can use the
// `Empty` type.
pub type ExecuteMsg = cw721_base::ExecuteMsg<MetadataExt, ExecuteExt>;

// The query message type for this contract.
// If you don't need the QueryExt extension, you can use the
// `Empty` type.
pub type QueryMsg = cw721_base::QueryMsg<QueryExt>;
27 changes: 27 additions & 0 deletions templates/cw721-template/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::contract::{entry, CONTRACT_NAME};

use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use cw721_base::InstantiateMsg;

/// Make sure cw2 version info is properly initialized during instantiation,
/// and NOT overwritten by the base contract.
#[test]
fn proper_cw2_initialization() {
let mut deps = mock_dependencies();

entry::instantiate(
deps.as_mut(),
mock_env(),
mock_info("larry", &[]),
InstantiateMsg {
name: "".into(),
symbol: "".into(),
minter: "larry".into(),
},
)
.unwrap();

let version = cw2::get_contract_version(deps.as_ref().storage).unwrap();
assert_eq!(version.contract, CONTRACT_NAME);
assert_ne!(version.contract, cw721_base::CONTRACT_NAME);
}
38 changes: 38 additions & 0 deletions templates/cw721-template/test_generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

# From: https://github.com/CosmWasm/cw-template/blob/main/meta/test_generate.sh

set -o errexit -o nounset -o pipefail
command -v shellcheck > /dev/null && shellcheck "$0"

REPO_ROOT="$(realpath "$(dirname "$0")/..")"

TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/cw-template.XXXXXXXXX")
PROJECT_NAME="testgen-local"

(
echo "Navigating to $TMP_DIR"
cd "$TMP_DIR"

echo "Generating project from local repository ..."
cargo generate --path "$REPO_ROOT" --name "$PROJECT_NAME"

(
cd "$PROJECT_NAME"
echo "This is what was generated"
ls -lA

# Check formatting
echo "Checking formatting ..."
cargo fmt -- --check

# Debug builds first to fail fast
echo "Running unit tests ..."
cargo unit-test
echo "Creating schema ..."
cargo schema

echo "Building wasm ..."
cargo wasm
)
)