From 0bcc37c52dfeb40d6ec791df939af76fbe0da16e Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 12:31:57 +0100 Subject: [PATCH 01/26] Add VIP initial contracts --- contracts/vip/README.md | 67 ++++++++++++++ contracts/vip/collection/.cargo/config | 4 + contracts/vip/collection/Cargo.toml | 41 +++++++++ contracts/vip/collection/src/bin/schema.rs | 11 +++ contracts/vip/collection/src/contract.rs | 100 +++++++++++++++++++++ contracts/vip/collection/src/error.rs | 15 ++++ contracts/vip/collection/src/helpers.rs | 27 ++++++ contracts/vip/collection/src/lib.rs | 7 ++ contracts/vip/collection/src/msg.rs | 31 +++++++ contracts/vip/collection/src/state.rs | 9 ++ contracts/vip/minter/.cargo/config | 4 + contracts/vip/minter/Cargo.toml | 41 +++++++++ contracts/vip/minter/src/bin/schema.rs | 11 +++ contracts/vip/minter/src/contract.rs | 67 ++++++++++++++ contracts/vip/minter/src/error.rs | 13 +++ contracts/vip/minter/src/helpers.rs | 27 ++++++ contracts/vip/minter/src/lib.rs | 7 ++ contracts/vip/minter/src/msg.rs | 14 +++ contracts/vip/minter/src/state.rs | 1 + 19 files changed, 497 insertions(+) create mode 100644 contracts/vip/README.md create mode 100644 contracts/vip/collection/.cargo/config create mode 100644 contracts/vip/collection/Cargo.toml create mode 100644 contracts/vip/collection/src/bin/schema.rs create mode 100644 contracts/vip/collection/src/contract.rs create mode 100644 contracts/vip/collection/src/error.rs create mode 100644 contracts/vip/collection/src/helpers.rs create mode 100644 contracts/vip/collection/src/lib.rs create mode 100644 contracts/vip/collection/src/msg.rs create mode 100644 contracts/vip/collection/src/state.rs create mode 100644 contracts/vip/minter/.cargo/config create mode 100644 contracts/vip/minter/Cargo.toml create mode 100644 contracts/vip/minter/src/bin/schema.rs create mode 100644 contracts/vip/minter/src/contract.rs create mode 100644 contracts/vip/minter/src/error.rs create mode 100644 contracts/vip/minter/src/helpers.rs create mode 100644 contracts/vip/minter/src/lib.rs create mode 100644 contracts/vip/minter/src/msg.rs create mode 100644 contracts/vip/minter/src/state.rs diff --git a/contracts/vip/README.md b/contracts/vip/README.md new file mode 100644 index 0000000..ab48ebb --- /dev/null +++ b/contracts/vip/README.md @@ -0,0 +1,67 @@ +# Stargaze Core Contracts + +## Stargaze Loyalty Program (SLP) + +The Stargaze Loyalty Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. + +A user mints a Stargaze Loyalty NFT (LNFT) to join the Stargaze Loyalty Program. It contains metadata that includes the amount of STARS they have staked that is populated via an oracle. + +A set of privileged operators as determined by governance are allowed to update the metadata of the LNFT. This is done via an oracle that reads the amount of STARS staked by the user and updates the LNFT metadata. + +## Loyalty Collection (sg721-loyalty) + +The Loyalty Collection is a contract that stores all the LNFTs, and allows operators to update the metadata of the LNFTs. + +```rs +pub struct LoyaltyMetadata { + pub staked_amount: [Coin], + pub data: Option, + pub updated_at: u64, +} +``` + +An optional `data` field makes the metadata future-proof and open for extension. + +### Messages + +```rs +pub enum ExecuteMsg { + UpdateMetadata { + address: String, + staked_amount: [Coin], + data: Option, + }, +} +``` + +```rs +pub enum SudoMsg { + AddOperator { operator: String }, + RemoveOperator { operator: String }, +} +``` + +### Queries + +```rs +pub enum QueryMsg { + Metadata { address: String }, + Operators {}, + TotalStakedAmount { owner: String }, +} +``` + +Note that a user may have multiple wallets that stake. For example they may have a cold wallet that does the majority of staking, and a hot wallet for use for minting on Stargaze. To determine the tier of a user, we need to sum up the amount of STARS staked across all wallets. To associate wallets, a user can transfer their LNFT to their hot wallet. The `TotalStakedAmount` query returns the total amount of STARS staked by a user across all wallets. + +## Loyalty Minter (loyalty-minter) + +The Loyalty Minter is a contract that allows users to mint LNFTs. + +```rs +pub struct MintMsg { + pub token_id: String, // auto-incrementing ID + pub owner: String, + pub token_uri: Option, // ignored + pub extension: T, // `LoyaltyMetadata` +} +``` diff --git a/contracts/vip/collection/.cargo/config b/contracts/vip/collection/.cargo/config new file mode 100644 index 0000000..af5698e --- /dev/null +++ b/contracts/vip/collection/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml new file mode 100644 index 0000000..cedd461 --- /dev/null +++ b/contracts/vip/collection/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "stargaze-loyalty-collection" +authors = ["Shane Vitarana "] +description = "Stargaze Loyalty Collection" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +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"] + +[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 = { workspace = true } +cosmwasm-std = { workspace = true } +cosmwasm-storage = { workspace = true } +cw-ownable = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } + +[dev-dependencies] +cw-multi-test = { workspace = true } diff --git a/contracts/vip/collection/src/bin/schema.rs b/contracts/vip/collection/src/bin/schema.rs new file mode 100644 index 0000000..ff0e721 --- /dev/null +++ b/contracts/vip/collection/src/bin/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use stargaze_loyalty_collection::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs new file mode 100644 index 0000000..d5ba7c7 --- /dev/null +++ b/contracts/vip/collection/src/contract.rs @@ -0,0 +1,100 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, +}; +use cw2::set_contract_version; +use cw_ownable::get_ownership; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +const CONTRACT_NAME: &str = "crates.io:stargaze-loyalty-collection"; +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)?; + + deps.api.addr_validate(&msg.owner)?; + cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; + + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::UpdateOwnership(action) => update_ownership(deps, env, info, action), + ExecuteMsg::UpdateMetadata { + address, + staked_amount, + data, + } => execute_update_metadata(deps, env, info, address, staked_amount, data), + } +} + +pub fn execute_update_metadata( + deps: DepsMut, + _env: Env, + info: MessageInfo, + _address: String, + _staked_amount: Uint128, + _data: Option, +) -> Result { + cw_ownable::assert_owner(deps.storage, &info.sender)?; + + // TODO: get the nft based on the address (which is the token_id) + // TODO: update metadata + + Ok(Response::new()) +} + +/// Wraps around cw_ownable::update_ownership to extract the result and wrap it in a Stargaze Response +fn update_ownership( + deps: DepsMut, + env: Env, + info: MessageInfo, + action: cw_ownable::Action, +) -> Result { + let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; + Ok(Response::new().add_attributes(ownership.into_attributes())) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::Ownership {} => to_binary(&get_ownership(deps.storage)?), + QueryMsg::Metadata { address } => to_binary(&query_metadata(deps, address)?), + QueryMsg::TotalStaked { owner } => to_binary(&query_total_staked(deps, owner)?), + } +} + +pub fn query_metadata(deps: Deps, address: String) -> StdResult { + // TODO: get metadata by address (token_id) + + todo!() +} + +/// Total staked is the sum of all staked amounts for a given owner. If +/// an owner has multiple items, it will iterate through all of them and +/// sum the staked amounts. +pub fn query_total_staked(deps: Deps, owner: String) -> StdResult { + // TODO: get all tokens by owner of `address` (token_id) + // TODO: iterate through metdata to get total stake weight + + todo!() +} + +#[cfg(test)] +mod tests {} diff --git a/contracts/vip/collection/src/error.rs b/contracts/vip/collection/src/error.rs new file mode 100644 index 0000000..0fb99f1 --- /dev/null +++ b/contracts/vip/collection/src/error.rs @@ -0,0 +1,15 @@ +use cosmwasm_std::StdError; +use cw_ownable::OwnershipError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("{0}")] + Ownership(#[from] OwnershipError), + + #[error("Unauthorized")] + Unauthorized {}, +} diff --git a/contracts/vip/collection/src/helpers.rs b/contracts/vip/collection/src/helpers.rs new file mode 100644 index 0000000..a39b155 --- /dev/null +++ b/contracts/vip/collection/src/helpers.rs @@ -0,0 +1,27 @@ +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>(&self, msg: T) -> StdResult { + let msg = to_binary(&msg.into())?; + Ok(WasmMsg::Execute { + contract_addr: self.addr().into(), + msg, + funds: vec![], + } + .into()) + } +} diff --git a/contracts/vip/collection/src/lib.rs b/contracts/vip/collection/src/lib.rs new file mode 100644 index 0000000..233dbf5 --- /dev/null +++ b/contracts/vip/collection/src/lib.rs @@ -0,0 +1,7 @@ +pub mod contract; +mod error; +pub mod helpers; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs new file mode 100644 index 0000000..0a77d96 --- /dev/null +++ b/contracts/vip/collection/src/msg.rs @@ -0,0 +1,31 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Uint128; +use cw_ownable::{cw_ownable_execute, cw_ownable_query}; + +use crate::state::Metadata; + +#[cw_serde] +pub struct InstantiateMsg { + pub owner: String, +} + +#[cw_ownable_execute] +#[cw_serde] +pub enum ExecuteMsg { + // TODO: move this to the minter? + UpdateMetadata { + address: String, + staked_amount: Uint128, + data: Option, + }, +} + +#[cw_ownable_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(Metadata)] + Metadata { address: String }, + #[returns(Uint128)] + TotalStaked { owner: String }, +} diff --git a/contracts/vip/collection/src/state.rs b/contracts/vip/collection/src/state.rs new file mode 100644 index 0000000..3e8f0ec --- /dev/null +++ b/contracts/vip/collection/src/state.rs @@ -0,0 +1,9 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Timestamp, Uint128}; + +#[cw_serde] +pub struct Metadata { + pub staked_amount: Uint128, + pub data: Option, + pub updated_at: Timestamp, +} diff --git a/contracts/vip/minter/.cargo/config b/contracts/vip/minter/.cargo/config new file mode 100644 index 0000000..af5698e --- /dev/null +++ b/contracts/vip/minter/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml new file mode 100644 index 0000000..b4fb344 --- /dev/null +++ b/contracts/vip/minter/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "loyalty-minter" +authors = ["Shane Vitarana "] +description = "Stargaze Loyalty Minter" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +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"] + +[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 = { workspace = true } +cosmwasm-std = { workspace = true } +cosmwasm-storage = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +stargaze-loyalty-collection = { path = "../collection" } + +[dev-dependencies] +cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/src/bin/schema.rs b/contracts/vip/minter/src/bin/schema.rs new file mode 100644 index 0000000..4f54744 --- /dev/null +++ b/contracts/vip/minter/src/bin/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use loyalty_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs new file mode 100644 index 0000000..5d39230 --- /dev/null +++ b/contracts/vip/minter/src/contract.rs @@ -0,0 +1,67 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; +use cw2::set_contract_version; +use stargaze_loyalty_collection::state::Metadata; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +const CONTRACT_NAME: &str = "crates.io:stargaze-loyalty-minter"; +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)?; + + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Mint { address } => execute_mint(deps, env, address), + } +} + +pub fn execute_mint(deps: DepsMut, env: Env, address: String) -> Result { + // TODO: get the total staked for the address + let delegations = deps.querier.query_all_delegations(address)?; + // NOTE: assuming the staked denom is the same as the stake weight denom + let total_staked = delegations + .iter() + .fold(0, |acc, d| acc + d.amount.amount.u128()); + + let metadata = Metadata { + staked_amount: Uint128::from(total_staked), + data: None, + updated_at: env.block.time, + }; + + // TODO: get collection and mint token with metadata + + // TODO: add the address to an end block queue + + Ok(Response::new()) +} + +// TODO: add end block function +// TODO: pop address off the queue and update metadata + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { + unimplemented!() +} + +#[cfg(test)] +mod tests {} diff --git a/contracts/vip/minter/src/error.rs b/contracts/vip/minter/src/error.rs new file mode 100644 index 0000000..4a69d8f --- /dev/null +++ b/contracts/vip/minter/src/error.rs @@ -0,0 +1,13 @@ +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. +} diff --git a/contracts/vip/minter/src/helpers.rs b/contracts/vip/minter/src/helpers.rs new file mode 100644 index 0000000..a39b155 --- /dev/null +++ b/contracts/vip/minter/src/helpers.rs @@ -0,0 +1,27 @@ +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>(&self, msg: T) -> StdResult { + let msg = to_binary(&msg.into())?; + Ok(WasmMsg::Execute { + contract_addr: self.addr().into(), + msg, + funds: vec![], + } + .into()) + } +} diff --git a/contracts/vip/minter/src/lib.rs b/contracts/vip/minter/src/lib.rs new file mode 100644 index 0000000..233dbf5 --- /dev/null +++ b/contracts/vip/minter/src/lib.rs @@ -0,0 +1,7 @@ +pub mod contract; +mod error; +pub mod helpers; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs new file mode 100644 index 0000000..2353ea0 --- /dev/null +++ b/contracts/vip/minter/src/msg.rs @@ -0,0 +1,14 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + /// Mint a loyalty token for the given address + Mint { address: String }, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg {} diff --git a/contracts/vip/minter/src/state.rs b/contracts/vip/minter/src/state.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/contracts/vip/minter/src/state.rs @@ -0,0 +1 @@ + From 531ed23a818fe44052f0a312bd62f5eedbf84c42 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 12:58:57 +0100 Subject: [PATCH 02/26] Update README --- contracts/vip/README.md | 62 +++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/contracts/vip/README.md b/contracts/vip/README.md index ab48ebb..57d1414 100644 --- a/contracts/vip/README.md +++ b/contracts/vip/README.md @@ -1,43 +1,59 @@ -# Stargaze Core Contracts +# Stargaze VIP Program (SVP) -## Stargaze Loyalty Program (SLP) +The Stargaze VIP Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. -The Stargaze Loyalty Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. +A user mints a Stargaze VIP NFT (vNFT) to join the Stargaze VIP Program. It contains metadata that includes the amount of STARS they have staked that is periodically updated via end blocker. vNFTs are non-transferrable. -A user mints a Stargaze Loyalty NFT (LNFT) to join the Stargaze Loyalty Program. It contains metadata that includes the amount of STARS they have staked that is populated via an oracle. +A Stargaze Name is required to mint a vNFT. -A set of privileged operators as determined by governance are allowed to update the metadata of the LNFT. This is done via an oracle that reads the amount of STARS staked by the user and updates the LNFT metadata. +## VIP Collection (sg721-vip) -## Loyalty Collection (sg721-loyalty) +The VIP Collection is a contract that stores all the vNFTs, and periodically updates the metadata of each vNFT. -The Loyalty Collection is a contract that stores all the LNFTs, and allows operators to update the metadata of the LNFTs. +vNFTs are indexed by Stargaze Names, using the name for the `token_id`. If a name is transferred or burned, the associated vNFT is burned. This happens via a hook in the Stargaze Name collection contract. ```rs -pub struct LoyaltyMetadata { +pub struct VipMetadata { pub staked_amount: [Coin], pub data: Option, - pub updated_at: u64, + pub updated_at: Timestamp, } ``` -An optional `data` field makes the metadata future-proof and open for extension. +The stake weight metadata can only be updated at specific intervals. The `updated_at` field is used to determine when the metadata can be updated. The `updated_at` field is set to the current block time when the vNFT is minted. The metadata can be updated when the current block time is greater than the `updated_at` field plus the `update_period` field in the config. + +```rs +pub struct Config { + pub update_period: Duration, +} +``` ### Messages +```rs +pub struct InstantiateMsg { + pub update_period: Duration, +} +``` + +This updates the metadata of a vNFT immediately instead of waiting for the end blocker. + ```rs pub enum ExecuteMsg { UpdateMetadata { address: String, - staked_amount: [Coin], data: Option, }, } ``` ```rs -pub enum SudoMsg { - AddOperator { operator: String }, - RemoveOperator { operator: String }, +pub enum SudoMsg{ + BeginBlock {}, // Is called by x/cron module BeginBlocker + EndBlock {}, // Is called by x/cron module EndBlocker + UpdateConfig { + config: Config, + }, } ``` @@ -45,23 +61,27 @@ pub enum SudoMsg { ```rs pub enum QueryMsg { + Config {}, Metadata { address: String }, - Operators {}, - TotalStakedAmount { owner: String }, + TotalStakedAmount { name: String }, } ``` -Note that a user may have multiple wallets that stake. For example they may have a cold wallet that does the majority of staking, and a hot wallet for use for minting on Stargaze. To determine the tier of a user, we need to sum up the amount of STARS staked across all wallets. To associate wallets, a user can transfer their LNFT to their hot wallet. The `TotalStakedAmount` query returns the total amount of STARS staked by a user across all wallets. +Note that a user may have multiple wallets that stake. For example they may have a cold wallet that does the majority of staking, and a hot wallet for use for minting on Stargaze. To determine the tier of a user, we need to sum up the amount of STARS staked across all wallets. To associate wallets, a user can link their accounts in their Stargaze Name. The `TotalStakedAmount` query returns the total amount of STARS staked by a user across all wallets. + +#### TODO + +- [ ] Come up with a consistent way to link multiple accounts to one name -## Loyalty Minter (loyalty-minter) +## vNFT Minter (vip-minter) -The Loyalty Minter is a contract that allows users to mint LNFTs. +The vNFT Minter is a contract that allows users to mint vNFTs. ```rs pub struct MintMsg { - pub token_id: String, // auto-incrementing ID + pub name: String, pub owner: String, pub token_uri: Option, // ignored - pub extension: T, // `LoyaltyMetadata` + pub extension: T, // `VipMetadata` } ``` From d29b0b6d336c6e88fbfaa77e9093fdef35fb25c5 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 13:57:26 +0100 Subject: [PATCH 03/26] Setup manifest --- Cargo.lock | 31 +++++++++++++++++++++++++++++ Cargo.toml | 8 +++++++- contracts/vip/collection/Cargo.toml | 12 +++++------ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ffd4ef..b9a2bb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1191,6 +1191,22 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "loyalty-minter" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus", + "cw2", + "schemars", + "serde", + "stargaze-loyalty-collection", + "thiserror", +] + [[package]] name = "matchit" version = "0.7.0" @@ -1969,6 +1985,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "stargaze-loyalty-collection" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus", + "cw2", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 4cffeac..2a80796 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,11 @@ [workspace] -members = ["packages/*", "contracts/fair-burn", "test/*"] +members = [ + "packages/*", + "contracts/fair-burn", + "contracts/vip/collection", + "contracts/vip/minter", + "test/*", +] resolver = "2" [workspace.package] diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index cedd461..ec98051 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -30,12 +30,12 @@ library = [] cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cosmwasm-storage = { workspace = true } -cw-ownable = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } +# cw-ownable = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } From e822d3cd3646ad09b542ad8d263c0a6741a066ff Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 13:58:44 +0100 Subject: [PATCH 04/26] Remove cw_ownable --- contracts/vip/collection/src/contract.rs | 17 ----------------- contracts/vip/collection/src/error.rs | 4 ---- contracts/vip/collection/src/msg.rs | 3 --- 3 files changed, 24 deletions(-) diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index d5ba7c7..ad7403e 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -4,7 +4,6 @@ use cosmwasm_std::{ to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, }; use cw2::set_contract_version; -use cw_ownable::get_ownership; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -22,7 +21,6 @@ pub fn instantiate( set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; deps.api.addr_validate(&msg.owner)?; - cw_ownable::initialize_owner(deps.storage, deps.api, Some(&msg.owner))?; Ok(Response::new()) } @@ -35,7 +33,6 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::UpdateOwnership(action) => update_ownership(deps, env, info, action), ExecuteMsg::UpdateMetadata { address, staked_amount, @@ -52,29 +49,15 @@ pub fn execute_update_metadata( _staked_amount: Uint128, _data: Option, ) -> Result { - cw_ownable::assert_owner(deps.storage, &info.sender)?; - // TODO: get the nft based on the address (which is the token_id) // TODO: update metadata Ok(Response::new()) } -/// Wraps around cw_ownable::update_ownership to extract the result and wrap it in a Stargaze Response -fn update_ownership( - deps: DepsMut, - env: Env, - info: MessageInfo, - action: cw_ownable::Action, -) -> Result { - let ownership = cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?; - Ok(Response::new().add_attributes(ownership.into_attributes())) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Ownership {} => to_binary(&get_ownership(deps.storage)?), QueryMsg::Metadata { address } => to_binary(&query_metadata(deps, address)?), QueryMsg::TotalStaked { owner } => to_binary(&query_total_staked(deps, owner)?), } diff --git a/contracts/vip/collection/src/error.rs b/contracts/vip/collection/src/error.rs index 0fb99f1..dc19f10 100644 --- a/contracts/vip/collection/src/error.rs +++ b/contracts/vip/collection/src/error.rs @@ -1,5 +1,4 @@ use cosmwasm_std::StdError; -use cw_ownable::OwnershipError; use thiserror::Error; #[derive(Error, Debug)] @@ -7,9 +6,6 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), - #[error("{0}")] - Ownership(#[from] OwnershipError), - #[error("Unauthorized")] Unauthorized {}, } diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 0a77d96..2e2f807 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -1,6 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; -use cw_ownable::{cw_ownable_execute, cw_ownable_query}; use crate::state::Metadata; @@ -9,7 +8,6 @@ pub struct InstantiateMsg { pub owner: String, } -#[cw_ownable_execute] #[cw_serde] pub enum ExecuteMsg { // TODO: move this to the minter? @@ -20,7 +18,6 @@ pub enum ExecuteMsg { }, } -#[cw_ownable_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { From 4465deee80ba20b39dd8937f6ed950b8d1080d34 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 14:09:16 +0100 Subject: [PATCH 05/26] Rename from loyalty --- Cargo.lock | 34 +++++++++++----------- contracts/vip/collection/Cargo.toml | 15 +++++----- contracts/vip/collection/src/bin/schema.rs | 2 +- contracts/vip/collection/src/contract.rs | 2 +- contracts/vip/minter/Cargo.toml | 22 +++++++------- contracts/vip/minter/src/bin/schema.rs | 2 +- contracts/vip/minter/src/contract.rs | 4 +-- 7 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9a2bb3..4520790 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1191,22 +1191,6 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" -[[package]] -name = "loyalty-minter" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "stargaze-loyalty-collection", - "thiserror", -] - [[package]] name = "matchit" version = "0.7.0" @@ -1986,7 +1970,7 @@ dependencies = [ ] [[package]] -name = "stargaze-loyalty-collection" +name = "stargaze-vip-collection" version = "0.1.0" dependencies = [ "cosmwasm-schema", @@ -2488,6 +2472,22 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vip-minter" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus", + "cw2", + "schemars", + "serde", + "stargaze-vip-collection", + "thiserror", +] + [[package]] name = "walkdir" version = "2.3.3" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index ec98051..5be630e 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "stargaze-loyalty-collection" +name = "stargaze-vip-collection" authors = ["Shane Vitarana "] -description = "Stargaze Loyalty Collection" +description = "Stargaze VIP Collection" version = { workspace = true } edition = { workspace = true } homepage = { workspace = true } @@ -30,12 +30,11 @@ library = [] cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cosmwasm-storage = { workspace = true } -# cw-ownable = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/collection/src/bin/schema.rs b/contracts/vip/collection/src/bin/schema.rs index ff0e721..bbaa88e 100644 --- a/contracts/vip/collection/src/bin/schema.rs +++ b/contracts/vip/collection/src/bin/schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use stargaze_loyalty_collection::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use stargaze_vip_collection::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index ad7403e..54e3a3d 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -8,7 +8,7 @@ use cw2::set_contract_version; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -const CONTRACT_NAME: &str = "crates.io:stargaze-loyalty-collection"; +const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index b4fb344..a0462a5 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "loyalty-minter" +name = "vip-minter" authors = ["Shane Vitarana "] -description = "Stargaze Loyalty Minter" +description = "Stargaze vNFT Minter" version = { workspace = true } edition = { workspace = true } homepage = { workspace = true } @@ -27,15 +27,15 @@ library = [] [dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -stargaze-loyalty-collection = { path = "../collection" } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +cosmwasm-storage = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +stargaze-vip-collection = { path = "../collection" } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/src/bin/schema.rs b/contracts/vip/minter/src/bin/schema.rs index 4f54744..3c9e62b 100644 --- a/contracts/vip/minter/src/bin/schema.rs +++ b/contracts/vip/minter/src/bin/schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use loyalty_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use vip_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 5d39230..b716bcf 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -2,12 +2,12 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; use cw2::set_contract_version; -use stargaze_loyalty_collection::state::Metadata; +use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -const CONTRACT_NAME: &str = "crates.io:stargaze-loyalty-minter"; +const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] From be6519c9bb4a662e6bdf5b3a4a55a664d8cc3ef6 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 14:17:35 +0100 Subject: [PATCH 06/26] Implement stake weight --- contracts/vip/collection/src/contract.rs | 8 ++++++++ contracts/vip/minter/Cargo.toml | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 54e3a3d..66c5355 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -55,6 +55,14 @@ pub fn execute_update_metadata( Ok(Response::new()) } +// TODO: move to a common place to minter and collection can use the same logic +// fn stake_weight() -> u128 { + +// // + +// 0u128 +// } + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index a0462a5..609f0d3 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -28,14 +28,14 @@ library = [] [dependencies] cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -stargaze-vip-collection = { path = "../collection" } +stargaze-vip-collection = { path = "../collection", features = ["library"] } [dev-dependencies] cw-multi-test = { workspace = true } From bfbfa390c90ea1670d179e6cda2ce22e0f17f7b5 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 30 Jul 2023 14:26:35 +0100 Subject: [PATCH 07/26] Upgrade CW --- Cargo.lock | 63 +++++++++++++++++++----- contracts/vip/collection/src/contract.rs | 16 +++--- contracts/vip/minter/src/contract.rs | 8 +-- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4520790..8ebecaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,8 +479,8 @@ checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" dependencies = [ "anyhow", "cosmwasm-std", - "cw-storage-plus", - "cw-utils", + "cw-storage-plus 1.1.0", + "cw-utils 1.0.1", "derivative", "itertools", "k256", @@ -501,6 +501,32 @@ dependencies = [ "serde", ] +[[package]] +name = "cw-storage-plus" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a84c6c1c0acc3616398eba50783934bd6c964bad6974241eaee3460c8f5b26" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2 0.16.0", + "schemars", + "semver", + "serde", + "thiserror", +] + [[package]] name = "cw-utils" version = "1.0.1" @@ -509,7 +535,7 @@ checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2", + "cw2 1.1.0", "schemars", "semver", "serde", @@ -524,7 +550,20 @@ checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 0.16.0", + "schemars", + "serde", +] + +[[package]] +name = "cw2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.1.0", "schemars", "serde", "thiserror", @@ -604,7 +643,7 @@ dependencies = [ "cosm-orc", "cosm-tome", "cosmwasm-std", - "cw-utils", + "cw-utils 1.0.1", "env_logger", "itertools", "once_cell", @@ -1959,9 +1998,9 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", - "cw-storage-plus", - "cw-utils", - "cw2", + "cw-storage-plus 1.1.0", + "cw-utils 1.0.1", + "cw2 1.1.0", "schemars", "serde", "sg-multi-test", @@ -1977,8 +2016,8 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", - "cw-storage-plus", - "cw2", + "cw-storage-plus 1.1.0", + "cw2 1.1.0", "schemars", "serde", "thiserror", @@ -2480,8 +2519,8 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", - "cw-storage-plus", - "cw2", + "cw-storage-plus 1.1.0", + "cw2 1.1.0", "schemars", "serde", "stargaze-vip-collection", diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 66c5355..f1b85ec 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, + to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, }; use cw2::set_contract_version; @@ -55,13 +55,15 @@ pub fn execute_update_metadata( Ok(Response::new()) } -// TODO: move to a common place to minter and collection can use the same logic -// fn stake_weight() -> u128 { +pub fn total_staked(deps: Deps, address: Addr) -> StdResult { + let total = deps + .querier + .query_all_delegations(address)? + .iter() + .fold(0, |acc, d| acc + d.amount.amount.u128()); -// // - -// 0u128 -// } + Ok(total) +} #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index b716bcf..6f284c1 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -2,6 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; use cw2::set_contract_version; +use stargaze_vip_collection::contract::total_staked; use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; @@ -35,12 +36,7 @@ pub fn execute( } pub fn execute_mint(deps: DepsMut, env: Env, address: String) -> Result { - // TODO: get the total staked for the address - let delegations = deps.querier.query_all_delegations(address)?; - // NOTE: assuming the staked denom is the same as the stake weight denom - let total_staked = delegations - .iter() - .fold(0, |acc, d| acc + d.amount.amount.u128()); + let total_staked = total_staked(deps.as_ref(), deps.api.addr_validate(&address)?)?; let metadata = Metadata { staked_amount: Uint128::from(total_staked), From bd721de073973470390941d283d8090d894c21ea Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Tue, 1 Aug 2023 22:52:25 +0100 Subject: [PATCH 08/26] Add state --- contracts/vip/collection/src/contract.rs | 1 + contracts/vip/minter/src/state.rs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index f1b85ec..b6a59b1 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -49,6 +49,7 @@ pub fn execute_update_metadata( _staked_amount: Uint128, _data: Option, ) -> Result { + // TODO: only_owner... // TODO: get the nft based on the address (which is the token_id) // TODO: update metadata diff --git a/contracts/vip/minter/src/state.rs b/contracts/vip/minter/src/state.rs index 8b13789..5a3bb6c 100644 --- a/contracts/vip/minter/src/state.rs +++ b/contracts/vip/minter/src/state.rs @@ -1 +1,4 @@ +use cosmwasm_std::Addr; +use cw_storage_plus::Item; +pub const COLLECTION: Item = Item::new("collection"); From a08b774bbd2cd62f3ea4b738138220f9c782623d Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 2 Aug 2023 19:46:05 +0100 Subject: [PATCH 09/26] Mint --- Cargo.lock | 123 ++++++++++++++++++--- contracts/vip/collection/Cargo.toml | 4 +- contracts/vip/collection/src/bin/schema.rs | 3 +- contracts/vip/collection/src/contract.rs | 36 ++++-- contracts/vip/collection/src/lib.rs | 6 + contracts/vip/collection/src/msg.rs | 8 +- contracts/vip/minter/Cargo.toml | 4 +- contracts/vip/minter/src/bin/schema.rs | 2 +- contracts/vip/minter/src/contract.rs | 26 ++++- contracts/vip/minter/src/msg.rs | 8 +- 10 files changed, 180 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ebecaa..161a607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -471,6 +471,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cw-address-like" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" +dependencies = [ + "cosmwasm-std", +] + [[package]] name = "cw-multi-test" version = "0.16.5" @@ -490,6 +499,32 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-ownable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-ownable-derive", + "cw-storage-plus 1.1.0", + "cw-utils 1.0.1", + "thiserror", +] + +[[package]] +name = "cw-ownable-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "cw-storage-plus" version = "1.1.0" @@ -582,6 +617,55 @@ dependencies = [ "serde", ] +[[package]] +name = "cw721" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.1", + "schemars", + "serde", +] + +[[package]] +name = "cw721-base" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77518e27431d43214cff4cdfbd788a7508f68d9b1f32389e6fce513e7eaccbef" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 0.16.0", + "cw-utils 0.16.0", + "cw2 0.16.0", + "cw721 0.16.0", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw721-base" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da518d9f68bfda7d972cbaca2e8fcf04651d0edc3de72b04ae2bcd9289c81614" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ownable", + "cw-storage-plus 1.1.0", + "cw-utils 1.0.1", + "cw2 1.1.0", + "cw721 0.18.0", + "cw721-base 0.16.0", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "der" version = "0.6.1" @@ -1893,8 +1977,8 @@ version = "3.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils", - "cw721", + "cw-utils 0.16.0", + "cw721 0.16.0", "schemars", "serde", "thiserror", @@ -2018,11 +2102,30 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.1.0", "cw2 1.1.0", + "cw721-base 0.18.0", "schemars", "serde", "thiserror", ] +[[package]] +name = "stargaze-vip-minter" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus 1.1.0", + "cw2 1.1.0", + "cw721 0.18.0", + "cw721-base 0.18.0", + "schemars", + "serde", + "stargaze-vip-collection", + "thiserror", +] + [[package]] name = "subtle" version = "2.5.0" @@ -2511,22 +2614,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "vip-minter" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw2 1.1.0", - "schemars", - "serde", - "stargaze-vip-collection", - "thiserror", -] - [[package]] name = "walkdir" version = "2.3.3" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index 5be630e..058e5e4 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -28,13 +28,15 @@ library = [] [dependencies] cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } +cosmwasm-std = { workspace = true, features = ["cosmwasm_1_2"] } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } +cw721-base = { workspace = true, features = ["library"] } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } +# stargaze-vip-minter = { path = "../minter", features = ["library"] } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/collection/src/bin/schema.rs b/contracts/vip/collection/src/bin/schema.rs index bbaa88e..73db019 100644 --- a/contracts/vip/collection/src/bin/schema.rs +++ b/contracts/vip/collection/src/bin/schema.rs @@ -1,6 +1,7 @@ use cosmwasm_schema::write_api; -use stargaze_vip_collection::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cw721_base::InstantiateMsg; +use stargaze_vip_collection::msg::{ExecuteMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index b6a59b1..41443e1 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -1,28 +1,48 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, + instantiate2_address, to_binary, Addr, Binary, CodeInfoResponse, ContractInfoResponse, Deps, + DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, }; use cw2::set_contract_version; +use cw721_base::InstantiateMsg; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, QueryMsg}; +use crate::VipCollection; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, + mut deps: DepsMut, + env: Env, + info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> StdResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - deps.api.addr_validate(&msg.owner)?; + // create minter address with instantiate2 + let contract_addr = env.contract.address.as_str(); - Ok(Response::new()) + let canonical_creator = deps.api.addr_canonicalize(contract_addr)?; + let ContractInfoResponse { code_id, .. } = + deps.querier.query_wasm_contract_info(contract_addr)?; + let CodeInfoResponse { checksum, .. } = deps.querier.query_wasm_code_info(code_id)?; + let salt = b"vip_minter1"; + + let canonical_addr = instantiate2_address(&checksum, &canonical_creator, salt) + .map_err(|_| StdError::generic_err("Could not calculate addr"))?; + + let addr = deps.api.addr_humanize(&canonical_addr)?; + + // TODO: query minter to see if it exists... + + // TODO: instantiate minter with collection address + + // instantiate collection + VipCollection::default().instantiate(deps.branch(), env, info, msg) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/collection/src/lib.rs b/contracts/vip/collection/src/lib.rs index 233dbf5..e4c8693 100644 --- a/contracts/vip/collection/src/lib.rs +++ b/contracts/vip/collection/src/lib.rs @@ -3,5 +3,11 @@ mod error; pub mod helpers; pub mod msg; pub mod state; +use cosmwasm_std::Empty; +use state::Metadata; pub use crate::error::ContractError; + +pub type VipCollection<'a> = cw721_base::Cw721Contract<'a, Metadata, Empty, Empty, Empty>; + +pub type ExecuteMsg = cw721_base::ExecuteMsg; diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 2e2f807..7752ece 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -3,10 +3,10 @@ use cosmwasm_std::Uint128; use crate::state::Metadata; -#[cw_serde] -pub struct InstantiateMsg { - pub owner: String, -} +// #[cw_serde] +// pub struct InstantiateMsg { +// pub owner: String, +// } #[cw_serde] pub enum ExecuteMsg { diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index 609f0d3..d693916 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "vip-minter" +name = "stargaze-vip-minter" authors = ["Shane Vitarana "] description = "Stargaze vNFT Minter" version = { workspace = true } @@ -32,6 +32,8 @@ cosmwasm-std = { workspace = true, features = ["staking"] } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } +cw721 = { workspace = true } +cw721-base = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } diff --git a/contracts/vip/minter/src/bin/schema.rs b/contracts/vip/minter/src/bin/schema.rs index 3c9e62b..f160419 100644 --- a/contracts/vip/minter/src/bin/schema.rs +++ b/contracts/vip/minter/src/bin/schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use vip_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use stargaze_vip_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 6f284c1..beab611 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -7,6 +7,7 @@ use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::COLLECTION; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -16,10 +17,12 @@ pub fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, - _msg: InstantiateMsg, + msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + COLLECTION.save(deps.storage, &deps.api.addr_validate(&msg.collection)?)?; + Ok(Response::new()) } @@ -31,11 +34,13 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Mint { address } => execute_mint(deps, env, address), + ExecuteMsg::Mint { name } => execute_mint(deps, env, name), } } -pub fn execute_mint(deps: DepsMut, env: Env, address: String) -> Result { +pub fn execute_mint(deps: DepsMut, env: Env, name: String) -> Result { + // TODO: query name to get associated address + let address = "address".to_string(); let total_staked = total_staked(deps.as_ref(), deps.api.addr_validate(&address)?)?; let metadata = Metadata { @@ -45,6 +50,21 @@ pub fn execute_mint(deps: DepsMut, env: Env, address: String) -> Result::Mint { + // token_id: increment_token_index(deps.storage)?.to_string(), + // owner: info.sender.to_string(), + // token_uri: Some(token_uri.clone()), + // extension: None, + // }; + // let msg = CosmosMsg::Wasm(WasmMsg::Execute { + // contract_addr: collection_address.to_string(), + // msg: to_binary(&mint_msg)?, + // funds: vec![], + // }); + // res = res.add_message(msg); // TODO: add the address to an end block queue diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs index 2353ea0..6620c84 100644 --- a/contracts/vip/minter/src/msg.rs +++ b/contracts/vip/minter/src/msg.rs @@ -1,12 +1,14 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; #[cw_serde] -pub struct InstantiateMsg {} +pub struct InstantiateMsg { + pub collection: String, +} #[cw_serde] pub enum ExecuteMsg { - /// Mint a loyalty token for the given address - Mint { address: String }, + /// Mint a loyalty token for the given name + Mint { name: String }, } #[cw_serde] From eeb6333f53aa48590c6a708b1955291230920f67 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sat, 5 Aug 2023 14:07:32 -0400 Subject: [PATCH 10/26] Add sg-vip package --- Cargo.lock | 10 ++++++++++ Cargo.toml | 2 ++ contracts/vip/collection/Cargo.toml | 3 ++- contracts/vip/minter/Cargo.toml | 1 + contracts/vip/minter/src/bin/schema.rs | 3 ++- contracts/vip/minter/src/contract.rs | 3 ++- contracts/vip/minter/src/msg.rs | 8 ++++---- packages/sg-vip/Cargo.toml | 10 ++++++++++ packages/sg-vip/src/lib.rs | 8 ++++++++ 9 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 packages/sg-vip/Cargo.toml create mode 100644 packages/sg-vip/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 161a607..c5a806e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1984,6 +1984,14 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sg-vip" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "serde", +] + [[package]] name = "sha1" version = "0.10.5" @@ -2105,6 +2113,7 @@ dependencies = [ "cw721-base 0.18.0", "schemars", "serde", + "sg-vip", "thiserror", ] @@ -2122,6 +2131,7 @@ dependencies = [ "cw721-base 0.18.0", "schemars", "serde", + "sg-vip", "stargaze-vip-collection", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 2a80796..af28036 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "contracts/vip/collection", "contracts/vip/minter", "test/*", + "packages/sg-vip", ] resolver = "2" @@ -34,6 +35,7 @@ thiserror = "1.0.31" anyhow = "1.0.41" sg-std = { version = "3.1.0", path = "packages/sg-std" } sg-multi-test = { version = "3.1.0", path = "packages/sg-multi-test" } +sg-vip = { path = "packages/sg-vip" } # dev-dependencies cw-multi-test = "0.16.5" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index 058e5e4..e5915ce 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -36,7 +36,8 @@ cw721-base = { workspace = true, features = ["library"] } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -# stargaze-vip-minter = { path = "../minter", features = ["library"] } +sg-vip = { workspace = true } + [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index d693916..ca237be 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -38,6 +38,7 @@ schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } stargaze-vip-collection = { path = "../collection", features = ["library"] } +sg-vip = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/src/bin/schema.rs b/contracts/vip/minter/src/bin/schema.rs index f160419..4f6b2b2 100644 --- a/contracts/vip/minter/src/bin/schema.rs +++ b/contracts/vip/minter/src/bin/schema.rs @@ -1,6 +1,7 @@ use cosmwasm_schema::write_api; -use stargaze_vip_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use sg_vip::minter::InstantiateMsg; +use stargaze_vip_minter::msg::{ExecuteMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index beab611..1b218c9 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -2,11 +2,12 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; use cw2::set_contract_version; +use sg_vip::minter::InstantiateMsg; use stargaze_vip_collection::contract::total_staked; use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, QueryMsg}; use crate::state::COLLECTION; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs index 6620c84..a074cc8 100644 --- a/contracts/vip/minter/src/msg.rs +++ b/contracts/vip/minter/src/msg.rs @@ -1,9 +1,9 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -#[cw_serde] -pub struct InstantiateMsg { - pub collection: String, -} +// #[cw_serde] +// pub struct InstantiateMsg { +// pub collection: String, +// } #[cw_serde] pub enum ExecuteMsg { diff --git a/packages/sg-vip/Cargo.toml b/packages/sg-vip/Cargo.toml new file mode 100644 index 0000000..05a8096 --- /dev/null +++ b/packages/sg-vip/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sg-vip" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cosmwasm-schema = { workspace = true } +serde = { workspace = true } diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs new file mode 100644 index 0000000..150187f --- /dev/null +++ b/packages/sg-vip/src/lib.rs @@ -0,0 +1,8 @@ +pub mod minter { + use cosmwasm_schema::cw_serde; + + #[cw_serde] + pub struct InstantiateMsg { + pub collection: String, + } +} From 15f003fd27221af20d83ff24ab882e564ddf7e6b Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sat, 5 Aug 2023 15:19:14 -0400 Subject: [PATCH 11/26] Init minter --- contracts/vip/collection/src/contract.rs | 52 +++++++++++++++--------- contracts/vip/collection/src/msg.rs | 8 ++-- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 41443e1..ddb8143 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -2,13 +2,12 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ instantiate2_address, to_binary, Addr, Binary, CodeInfoResponse, ContractInfoResponse, Deps, - DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, + DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw2::set_contract_version; -use cw721_base::InstantiateMsg; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::VipCollection; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; @@ -23,26 +22,41 @@ pub fn instantiate( ) -> StdResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // create minter address with instantiate2 - let contract_addr = env.contract.address.as_str(); - - let canonical_creator = deps.api.addr_canonicalize(contract_addr)?; - let ContractInfoResponse { code_id, .. } = - deps.querier.query_wasm_contract_info(contract_addr)?; - let CodeInfoResponse { checksum, .. } = deps.querier.query_wasm_code_info(code_id)?; + let collection = env.contract.address.as_str(); + let canonical_creator = deps.api.addr_canonicalize(collection)?; + let CodeInfoResponse { checksum, .. } = + deps.querier.query_wasm_code_info(msg.minter_code_id)?; let salt = b"vip_minter1"; + // create minter address with instantiate2 let canonical_addr = instantiate2_address(&checksum, &canonical_creator, salt) .map_err(|_| StdError::generic_err("Could not calculate addr"))?; - - let addr = deps.api.addr_humanize(&canonical_addr)?; - - // TODO: query minter to see if it exists... - - // TODO: instantiate minter with collection address - - // instantiate collection - VipCollection::default().instantiate(deps.branch(), env, info, msg) + let minter = deps.api.addr_humanize(&canonical_addr)?; + + let ContractInfoResponse { admin, .. } = deps.querier.query_wasm_contract_info(collection)?; + + let minter_init_msg = WasmMsg::Instantiate2 { + admin, + code_id: msg.minter_code_id, + label: String::from("vip-minter"), + msg: to_binary(&sg_vip::minter::InstantiateMsg { + collection: collection.to_string(), + })?, + funds: vec![], + salt: Binary::from(salt.to_vec()), + }; + + let collection_init_msg = cw721_base::msg::InstantiateMsg { + name: String::from("Stargaze VIP Collection"), + symbol: String::from("SGVIP"), + minter: minter.to_string(), + }; + + VipCollection::default().instantiate(deps.branch(), env, info, collection_init_msg)?; + + Ok(Response::new() + .add_message(minter_init_msg) + .add_attribute("vip-minter", minter)) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 7752ece..46979e3 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -3,10 +3,10 @@ use cosmwasm_std::Uint128; use crate::state::Metadata; -// #[cw_serde] -// pub struct InstantiateMsg { -// pub owner: String, -// } +#[cw_serde] +pub struct InstantiateMsg { + pub minter_code_id: u64, +} #[cw_serde] pub enum ExecuteMsg { From 7d9d149838fd569bdac8cf66873c64120f81df18 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 6 Aug 2023 11:18:18 -0400 Subject: [PATCH 12/26] Mint name --- Cargo.lock | 13 ++++ contracts/vip/collection/src/contract.rs | 4 +- contracts/vip/collection/src/msg.rs | 1 + contracts/vip/minter/Cargo.toml | 1 + contracts/vip/minter/src/contract.rs | 76 ++++++++++++++++-------- contracts/vip/minter/src/msg.rs | 4 ++ contracts/vip/minter/src/state.rs | 9 ++- packages/sg-vip/src/lib.rs | 3 +- 8 files changed, 82 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5a806e..82cd77e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1971,6 +1971,18 @@ dependencies = [ "sg-std", ] +[[package]] +name = "sg-name" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba179e312060ca767f809353a3181a9f7a94932f2498d9b0f337229063a6b93" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "schemars", + "serde", +] + [[package]] name = "sg-std" version = "3.1.0" @@ -2131,6 +2143,7 @@ dependencies = [ "cw721-base 0.18.0", "schemars", "serde", + "sg-name", "sg-vip", "stargaze-vip-collection", "thiserror", diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index ddb8143..b5c79f0 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -40,7 +40,8 @@ pub fn instantiate( code_id: msg.minter_code_id, label: String::from("vip-minter"), msg: to_binary(&sg_vip::minter::InstantiateMsg { - collection: collection.to_string(), + vip_collection: collection.to_string(), + name_collection: msg.name_collection, })?, funds: vec![], salt: Binary::from(salt.to_vec()), @@ -52,6 +53,7 @@ pub fn instantiate( minter: minter.to_string(), }; + // This configures the collection with the minter as the owner, the only one that can mint. VipCollection::default().instantiate(deps.branch(), env, info, collection_init_msg)?; Ok(Response::new() diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 46979e3..7236bed 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -6,6 +6,7 @@ use crate::state::Metadata; #[cw_serde] pub struct InstantiateMsg { pub minter_code_id: u64, + pub name_collection: String, } #[cw_serde] diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index ca237be..d47c328 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -39,6 +39,7 @@ serde = { workspace = true } thiserror = { workspace = true } stargaze-vip-collection = { path = "../collection", features = ["library"] } sg-vip = { workspace = true } +sg-name = "1.2.5" [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 1b218c9..11cb733 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -1,6 +1,9 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128}; +use cosmwasm_std::{ + ensure, to_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult, + Uint128, WasmMsg, +}; use cw2::set_contract_version; use sg_vip::minter::InstantiateMsg; use stargaze_vip_collection::contract::total_staked; @@ -8,7 +11,7 @@ use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; use crate::msg::{ExecuteMsg, QueryMsg}; -use crate::state::COLLECTION; +use crate::state::{Config, CONFIG}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -22,7 +25,13 @@ pub fn instantiate( ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - COLLECTION.save(deps.storage, &deps.api.addr_validate(&msg.collection)?)?; + CONFIG.save( + deps.storage, + &Config { + vip_collection: deps.api.addr_validate(&msg.vip_collection)?, + name_collection: deps.api.addr_validate(&msg.name_collection)?, + }, + )?; Ok(Response::new()) } @@ -31,18 +40,38 @@ pub fn instantiate( pub fn execute( deps: DepsMut, env: Env, - _info: MessageInfo, + info: MessageInfo, msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Mint { name } => execute_mint(deps, env, name), + ExecuteMsg::Mint { name } => execute_mint(deps, env, info, name), + ExecuteMsg::Update { name } => todo!(), + ExecuteMsg::Pause {} => todo!(), } } -pub fn execute_mint(deps: DepsMut, env: Env, name: String) -> Result { - // TODO: query name to get associated address - let address = "address".to_string(); - let total_staked = total_staked(deps.as_ref(), deps.api.addr_validate(&address)?)?; +pub fn execute_mint( + deps: DepsMut, + env: Env, + info: MessageInfo, + name: String, +) -> Result { + let Config { + vip_collection, + name_collection, + } = CONFIG.load(deps.storage)?; + + // query name so we know the name is associated with an address + let associated_addr: Addr = deps.querier.query_wasm_smart( + name_collection, + &sg_name::SgNameQueryMsg::AssociatedAddress { name: name.clone() }, + )?; + ensure!( + info.sender == associated_addr, + ContractError::Unauthorized {} + ); + + let total_staked = total_staked(deps.as_ref(), associated_addr)?; let metadata = Metadata { staked_amount: Uint128::from(total_staked), @@ -50,26 +79,21 @@ pub fn execute_mint(deps: DepsMut, env: Env, name: String) -> Result::Mint { - // token_id: increment_token_index(deps.storage)?.to_string(), - // owner: info.sender.to_string(), - // token_uri: Some(token_uri.clone()), - // extension: None, - // }; - // let msg = CosmosMsg::Wasm(WasmMsg::Execute { - // contract_addr: collection_address.to_string(), - // msg: to_binary(&mint_msg)?, - // funds: vec![], - // }); - // res = res.add_message(msg); + let msg = cw721_base::ExecuteMsg::::Mint { + token_id: name, + owner: info.sender.to_string(), + token_uri: None, + extension: metadata, + }; + let mint_msg = WasmMsg::Execute { + contract_addr: vip_collection.to_string(), + msg: to_binary(&msg)?, + funds: vec![], + }; // TODO: add the address to an end block queue - Ok(Response::new()) + Ok(Response::new().add_message(mint_msg)) } // TODO: add end block function diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs index a074cc8..f0ce094 100644 --- a/contracts/vip/minter/src/msg.rs +++ b/contracts/vip/minter/src/msg.rs @@ -9,6 +9,10 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; pub enum ExecuteMsg { /// Mint a loyalty token for the given name Mint { name: String }, + /// Update the stake amount for the given name + Update { name: String }, + /// So we can pause before migrating names, etc. + Pause {}, } #[cw_serde] diff --git a/contracts/vip/minter/src/state.rs b/contracts/vip/minter/src/state.rs index 5a3bb6c..3d4e0b8 100644 --- a/contracts/vip/minter/src/state.rs +++ b/contracts/vip/minter/src/state.rs @@ -1,4 +1,11 @@ +use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; use cw_storage_plus::Item; -pub const COLLECTION: Item = Item::new("collection"); +#[cw_serde] +pub struct Config { + pub vip_collection: Addr, + pub name_collection: Addr, +} + +pub const CONFIG: Item = Item::new("config"); diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 150187f..48b0b2f 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -3,6 +3,7 @@ pub mod minter { #[cw_serde] pub struct InstantiateMsg { - pub collection: String, + pub vip_collection: String, + pub name_collection: String, } } From aa773964fb84c06da88fe253593fa1de9805dc16 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 6 Aug 2023 12:53:21 -0400 Subject: [PATCH 13/26] Update metadata --- Cargo.lock | 1 + contracts/vip/collection/src/bin/schema.rs | 3 +- contracts/vip/collection/src/contract.rs | 18 +++++++--- contracts/vip/collection/src/helpers.rs | 9 ++--- contracts/vip/collection/src/msg.rs | 17 +++++---- contracts/vip/minter/src/contract.rs | 41 ++++++++++++++++++---- packages/sg-vip/Cargo.toml | 1 + packages/sg-vip/src/lib.rs | 36 +++++++++++++++++++ 8 files changed, 98 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82cd77e..cfff36b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2001,6 +2001,7 @@ name = "sg-vip" version = "0.1.0" dependencies = [ "cosmwasm-schema", + "cosmwasm-std", "serde", ] diff --git a/contracts/vip/collection/src/bin/schema.rs b/contracts/vip/collection/src/bin/schema.rs index 73db019..5408d1c 100644 --- a/contracts/vip/collection/src/bin/schema.rs +++ b/contracts/vip/collection/src/bin/schema.rs @@ -1,7 +1,8 @@ use cosmwasm_schema::write_api; use cw721_base::InstantiateMsg; -use stargaze_vip_collection::msg::{ExecuteMsg, QueryMsg}; +use sg_vip::collection::ExecuteMsg; +use stargaze_vip_collection::msg::QueryMsg; fn main() { write_api! { diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index b5c79f0..33592bc 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -5,9 +5,10 @@ use cosmwasm_std::{ DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw2::set_contract_version; +use sg_vip::collection::ExecuteMsg; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{InstantiateMsg, QueryMsg}; use crate::VipCollection; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; @@ -70,10 +71,10 @@ pub fn execute( ) -> Result { match msg { ExecuteMsg::UpdateMetadata { - address, + name, staked_amount, data, - } => execute_update_metadata(deps, env, info, address, staked_amount, data), + } => execute_update_metadata(deps, env, info, name, staked_amount, data), } } @@ -81,17 +82,24 @@ pub fn execute_update_metadata( deps: DepsMut, _env: Env, info: MessageInfo, - _address: String, + name: String, _staked_amount: Uint128, _data: Option, ) -> Result { + // make sure only the minter can call this + let minter = VipCollection::default() + .minter(deps.as_ref())? + .minter + .ok_or(ContractError::Unauthorized {})?; + // TODO: only_owner... - // TODO: get the nft based on the address (which is the token_id) + // TODO: get the nft based on the name (which is the token_id) // TODO: update metadata Ok(Response::new()) } +// TODO: move this into the minter? pub fn total_staked(deps: Deps, address: Addr) -> StdResult { let total = deps .querier diff --git a/contracts/vip/collection/src/helpers.rs b/contracts/vip/collection/src/helpers.rs index a39b155..1cba7f0 100644 --- a/contracts/vip/collection/src/helpers.rs +++ b/contracts/vip/collection/src/helpers.rs @@ -2,15 +2,12 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use sg_vip::collection::ExecuteMsg; -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); +pub struct SgVipCollection(pub Addr); -impl CwTemplateContract { +impl SgVipCollection { pub fn addr(&self) -> Addr { self.0.clone() } diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 7236bed..4624268 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -9,15 +9,14 @@ pub struct InstantiateMsg { pub name_collection: String, } -#[cw_serde] -pub enum ExecuteMsg { - // TODO: move this to the minter? - UpdateMetadata { - address: String, - staked_amount: Uint128, - data: Option, - }, -} +// #[cw_serde] +// pub enum ExecuteMsg { +// UpdateMetadata { +// name: String, +// staked_amount: Uint128, +// data: Option, +// }, +// } #[cw_serde] #[derive(QueryResponses)] diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 11cb733..28669b0 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -61,17 +61,12 @@ pub fn execute_mint( name_collection, } = CONFIG.load(deps.storage)?; - // query name so we know the name is associated with an address - let associated_addr: Addr = deps.querier.query_wasm_smart( - name_collection, - &sg_name::SgNameQueryMsg::AssociatedAddress { name: name.clone() }, - )?; ensure!( - info.sender == associated_addr, + info.sender == associated_address(deps.as_ref(), name.clone())?, ContractError::Unauthorized {} ); - let total_staked = total_staked(deps.as_ref(), associated_addr)?; + let total_staked = total_staked(deps.as_ref(), info.sender.clone())?; let metadata = Metadata { staked_amount: Uint128::from(total_staked), @@ -96,6 +91,38 @@ pub fn execute_mint( Ok(Response::new().add_message(mint_msg)) } +fn associated_address(deps: Deps, name: String) -> Result { + let associated_addr: Addr = deps.querier.query_wasm_smart( + CONFIG.load(deps.storage)?.name_collection, + &sg_name::SgNameQueryMsg::AssociatedAddress { name }, + )?; + + Ok(associated_addr) +} + +pub fn execute_update( + deps: DepsMut, + env: Env, + info: MessageInfo, + name: String, +) -> Result { + let Config { + vip_collection, + name_collection, + } = CONFIG.load(deps.storage)?; + + ensure!( + info.sender == associated_address(deps.as_ref(), name)?, + ContractError::Unauthorized {} + ); + + let total_staked = total_staked(deps.as_ref(), info.sender)?; + + // TODO: update metadata and call update on collection contract + + Ok(Response::new()) +} + // TODO: add end block function // TODO: pop address off the queue and update metadata diff --git a/packages/sg-vip/Cargo.toml b/packages/sg-vip/Cargo.toml index 05a8096..9188810 100644 --- a/packages/sg-vip/Cargo.toml +++ b/packages/sg-vip/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } serde = { workspace = true } diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 48b0b2f..4e92538 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -7,3 +7,39 @@ pub mod minter { pub name_collection: String, } } + +pub mod collection { + use cosmwasm_schema::cw_serde; + use cosmwasm_std::Uint128; + + // #[cw_serde] + // pub struct Metadata { + // pub staked_amount: Uint128, + // pub data: Option, + // pub updated_at: Timestamp, + // } + + // #[cw_serde] + // pub struct InstantiateMsg { + // pub minter_code_id: u64, + // pub name_collection: String, + // } + + #[cw_serde] + pub enum ExecuteMsg { + UpdateMetadata { + name: String, + staked_amount: Uint128, + data: Option, + }, + } + + // #[cw_serde] + // #[derive(QueryResponses)] + // pub enum QueryMsg { + // #[returns(Metadata)] + // Metadata { address: String }, + // #[returns(Uint128)] + // TotalStaked { owner: String }, + // } +} From 1a651f67ae2cc77d7d53ac10b08fa4ba890291fb Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 6 Aug 2023 17:43:01 -0400 Subject: [PATCH 14/26] Refactor mint --- Cargo.lock | 1 - contracts/vip/README.md | 4 ++ contracts/vip/collection/Cargo.toml | 1 - contracts/vip/collection/README.md | 3 + contracts/vip/collection/src/contract.rs | 74 +++++++++++++++--------- contracts/vip/collection/src/error.rs | 3 + contracts/vip/collection/src/msg.rs | 9 --- contracts/vip/minter/Cargo.toml | 25 ++++---- contracts/vip/minter/README.md | 3 + contracts/vip/minter/src/contract.rs | 70 +++++++++++++--------- packages/sg-vip/src/lib.rs | 16 ++--- 11 files changed, 122 insertions(+), 87 deletions(-) create mode 100644 contracts/vip/collection/README.md create mode 100644 contracts/vip/minter/README.md diff --git a/Cargo.lock b/Cargo.lock index cfff36b..e8d70d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2146,7 +2146,6 @@ dependencies = [ "serde", "sg-name", "sg-vip", - "stargaze-vip-collection", "thiserror", ] diff --git a/contracts/vip/README.md b/contracts/vip/README.md index 57d1414..933561a 100644 --- a/contracts/vip/README.md +++ b/contracts/vip/README.md @@ -1,5 +1,9 @@ # Stargaze VIP Program (SVP) +TODO: + +- [ ] `program` contract to define tiers + The Stargaze VIP Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. A user mints a Stargaze VIP NFT (vNFT) to join the Stargaze VIP Program. It contains metadata that includes the amount of STARS they have staked that is periodically updated via end blocker. vNFTs are non-transferrable. diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index e5915ce..b3b7d7f 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -38,6 +38,5 @@ serde = { workspace = true } thiserror = { workspace = true } sg-vip = { workspace = true } - [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/collection/README.md b/contracts/vip/collection/README.md new file mode 100644 index 0000000..d39ba23 --- /dev/null +++ b/contracts/vip/collection/README.md @@ -0,0 +1,3 @@ +# Stargaze VIP Collection + +This contract wraps the `cw721_base::Cw721Contract` struct to represent a collection that stores vNFTs (Stargaze VIP NFTs) with onchain metadata. The stake weight is stored as onchain metadata. diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 33592bc..a2134e2 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -1,14 +1,15 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - instantiate2_address, to_binary, Addr, Binary, CodeInfoResponse, ContractInfoResponse, Deps, - DepsMut, Env, MessageInfo, Response, StdError, StdResult, Uint128, WasmMsg, + instantiate2_address, to_binary, Binary, CodeInfoResponse, ContractInfoResponse, Deps, DepsMut, + Env, MessageInfo, Response, StdError, StdResult, Uint128, WasmMsg, }; use cw2::set_contract_version; use sg_vip::collection::ExecuteMsg; use crate::error::ContractError; use crate::msg::{InstantiateMsg, QueryMsg}; +use crate::state::Metadata; use crate::VipCollection; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; @@ -48,6 +49,7 @@ pub fn instantiate( salt: Binary::from(salt.to_vec()), }; + // TODO: `minter` may need to change to be this contract instead let collection_init_msg = cw721_base::msg::InstantiateMsg { name: String::from("Stargaze VIP Collection"), symbol: String::from("SGVIP"), @@ -55,9 +57,10 @@ pub fn instantiate( }; // This configures the collection with the minter as the owner, the only one that can mint. - VipCollection::default().instantiate(deps.branch(), env, info, collection_init_msg)?; + let res = + VipCollection::default().instantiate(deps.branch(), env, info, collection_init_msg)?; - Ok(Response::new() + Ok(res .add_message(minter_init_msg) .add_attribute("vip-minter", minter)) } @@ -70,44 +73,61 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::UpdateMetadata { + ExecuteMsg::Mint { name, + owner, staked_amount, data, - } => execute_update_metadata(deps, env, info, name, staked_amount, data), + } => execute_mint(deps, env, info, name, owner, staked_amount, data), + ExecuteMsg::UpdateToken { + name, + owner, + staked_amount, + data, + } => execute_update_token(deps, env, info, name, owner, staked_amount, data), } } -pub fn execute_update_metadata( +pub fn execute_mint( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, name: String, - _staked_amount: Uint128, - _data: Option, + owner: String, + staked_amount: Uint128, + data: Option, ) -> Result { - // make sure only the minter can call this - let minter = VipCollection::default() - .minter(deps.as_ref())? - .minter - .ok_or(ContractError::Unauthorized {})?; + only_minter(deps.as_ref())?; - // TODO: only_owner... - // TODO: get the nft based on the name (which is the token_id) - // TODO: update metadata + let extension = Metadata { + staked_amount, + data, + updated_at: env.block.time, + }; - Ok(Response::new()) + VipCollection::default() + .mint(deps, info, name, owner, None, extension) + .map_err(ContractError::Cw721Base) } -// TODO: move this into the minter? -pub fn total_staked(deps: Deps, address: Addr) -> StdResult { - let total = deps - .querier - .query_all_delegations(address)? - .iter() - .fold(0, |acc, d| acc + d.amount.amount.u128()); +pub fn execute_update_token( + deps: DepsMut, + env: Env, + info: MessageInfo, + name: String, + owner: String, + staked_amount: Uint128, + data: Option, +) -> Result { + // We can just overwrite the previous token with the new metadata + execute_mint(deps, env, info, name, owner, staked_amount, data) +} - Ok(total) +fn only_minter(deps: Deps) -> Result { + VipCollection::default() + .minter(deps)? + .minter + .ok_or(ContractError::Unauthorized {}) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/collection/src/error.rs b/contracts/vip/collection/src/error.rs index dc19f10..12744d7 100644 --- a/contracts/vip/collection/src/error.rs +++ b/contracts/vip/collection/src/error.rs @@ -6,6 +6,9 @@ pub enum ContractError { #[error("{0}")] Std(#[from] StdError), + #[error("{0}")] + Cw721Base(#[from] cw721_base::ContractError), + #[error("Unauthorized")] Unauthorized {}, } diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 4624268..1dd8cd9 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -9,15 +9,6 @@ pub struct InstantiateMsg { pub name_collection: String, } -// #[cw_serde] -// pub enum ExecuteMsg { -// UpdateMetadata { -// name: String, -// staked_amount: Uint128, -// data: Option, -// }, -// } - #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index d47c328..0d91bbd 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -27,19 +27,18 @@ library = [] [dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true, features = ["staking"] } -cosmwasm-storage = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -cw721 = { workspace = true } -cw721-base = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -stargaze-vip-collection = { path = "../collection", features = ["library"] } -sg-vip = { workspace = true } -sg-name = "1.2.5" +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cosmwasm-storage = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +cw721 = { workspace = true } +cw721-base = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +sg-vip = { workspace = true } +sg-name = "1.2.5" [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/README.md b/contracts/vip/minter/README.md new file mode 100644 index 0000000..e81cf31 --- /dev/null +++ b/contracts/vip/minter/README.md @@ -0,0 +1,3 @@ +# Stargaze VIP Minter + +This contract is responsible for writing to the Stargaze VIP Collection contract. diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 28669b0..9c5a8c6 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -1,13 +1,11 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, to_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult, - Uint128, WasmMsg, + ensure, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, + WasmMsg, }; use cw2::set_contract_version; use sg_vip::minter::InstantiateMsg; -use stargaze_vip_collection::contract::total_staked; -use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; use crate::msg::{ExecuteMsg, QueryMsg}; @@ -52,7 +50,7 @@ pub fn execute( pub fn execute_mint( deps: DepsMut, - env: Env, + _env: Env, info: MessageInfo, name: String, ) -> Result { @@ -66,19 +64,13 @@ pub fn execute_mint( ContractError::Unauthorized {} ); - let total_staked = total_staked(deps.as_ref(), info.sender.clone())?; - - let metadata = Metadata { - staked_amount: Uint128::from(total_staked), - data: None, - updated_at: env.block.time, - }; + let staked_amount = total_staked(deps.as_ref(), info.sender.clone())?; - let msg = cw721_base::ExecuteMsg::::Mint { - token_id: name, + let msg = sg_vip::collection::ExecuteMsg::Mint { + name, owner: info.sender.to_string(), - token_uri: None, - extension: metadata, + staked_amount: Uint128::from(staked_amount), + data: None, }; let mint_msg = WasmMsg::Execute { contract_addr: vip_collection.to_string(), @@ -86,20 +78,11 @@ pub fn execute_mint( funds: vec![], }; - // TODO: add the address to an end block queue + // TODO: add the `token_id` to an end block queue Ok(Response::new().add_message(mint_msg)) } -fn associated_address(deps: Deps, name: String) -> Result { - let associated_addr: Addr = deps.querier.query_wasm_smart( - CONFIG.load(deps.storage)?.name_collection, - &sg_name::SgNameQueryMsg::AssociatedAddress { name }, - )?; - - Ok(associated_addr) -} - pub fn execute_update( deps: DepsMut, env: Env, @@ -112,17 +95,48 @@ pub fn execute_update( } = CONFIG.load(deps.storage)?; ensure!( - info.sender == associated_address(deps.as_ref(), name)?, + info.sender == associated_address(deps.as_ref(), name.clone())?, ContractError::Unauthorized {} ); - let total_staked = total_staked(deps.as_ref(), info.sender)?; + let staked_amount = total_staked(deps.as_ref(), info.sender.clone())?; + + let msg = sg_vip::collection::ExecuteMsg::Mint { + name, + owner: info.sender.to_string(), + staked_amount: Uint128::from(staked_amount), + data: None, + }; + let mint_msg = WasmMsg::Execute { + contract_addr: vip_collection.to_string(), + msg: to_binary(&msg)?, + funds: vec![], + }; // TODO: update metadata and call update on collection contract Ok(Response::new()) } +fn associated_address(deps: Deps, name: String) -> Result { + let associated_addr: Addr = deps.querier.query_wasm_smart( + CONFIG.load(deps.storage)?.name_collection, + &sg_name::SgNameQueryMsg::AssociatedAddress { name }, + )?; + + Ok(associated_addr) +} + +fn total_staked(deps: Deps, address: Addr) -> StdResult { + let total = deps + .querier + .query_all_delegations(address)? + .iter() + .fold(0, |acc, d| acc + d.amount.amount.u128()); + + Ok(total) +} + // TODO: add end block function // TODO: pop address off the queue and update metadata diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 4e92538..75c9a9f 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -12,13 +12,6 @@ pub mod collection { use cosmwasm_schema::cw_serde; use cosmwasm_std::Uint128; - // #[cw_serde] - // pub struct Metadata { - // pub staked_amount: Uint128, - // pub data: Option, - // pub updated_at: Timestamp, - // } - // #[cw_serde] // pub struct InstantiateMsg { // pub minter_code_id: u64, @@ -27,8 +20,15 @@ pub mod collection { #[cw_serde] pub enum ExecuteMsg { - UpdateMetadata { + Mint { + name: String, + owner: String, + staked_amount: Uint128, + data: Option, + }, + UpdateToken { name: String, + owner: String, staked_amount: Uint128, data: Option, }, From de64c7a59f534a69a418cb9e2b204a5bd3b83793 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Sun, 6 Aug 2023 20:28:08 -0400 Subject: [PATCH 15/26] Add program smart contract --- Cargo.lock | 15 +++++++ Cargo.toml | 1 + contracts/vip/program/.cargo/config | 4 ++ contracts/vip/program/Cargo.toml | 53 +++++++++++++++++++++++++ contracts/vip/program/README.md | 4 ++ contracts/vip/program/src/bin/schema.rs | 11 +++++ contracts/vip/program/src/contract.rs | 50 +++++++++++++++++++++++ contracts/vip/program/src/error.rs | 13 ++++++ contracts/vip/program/src/helpers.rs | 27 +++++++++++++ contracts/vip/program/src/lib.rs | 7 ++++ contracts/vip/program/src/msg.rs | 21 ++++++++++ contracts/vip/program/src/state.rs | 13 ++++++ 12 files changed, 219 insertions(+) create mode 100644 contracts/vip/program/.cargo/config create mode 100644 contracts/vip/program/Cargo.toml create mode 100644 contracts/vip/program/README.md create mode 100644 contracts/vip/program/src/bin/schema.rs create mode 100644 contracts/vip/program/src/contract.rs create mode 100644 contracts/vip/program/src/error.rs create mode 100644 contracts/vip/program/src/helpers.rs create mode 100644 contracts/vip/program/src/lib.rs create mode 100644 contracts/vip/program/src/msg.rs create mode 100644 contracts/vip/program/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index e8d70d9..6f3b492 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1572,6 +1572,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "program" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus 1.1.0", + "cw2 1.1.0", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "prost" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index af28036..bf2613b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "contracts/fair-burn", "contracts/vip/collection", "contracts/vip/minter", + "contracts/vip/program", "test/*", "packages/sg-vip", ] diff --git a/contracts/vip/program/.cargo/config b/contracts/vip/program/.cargo/config new file mode 100644 index 0000000..af5698e --- /dev/null +++ b/contracts/vip/program/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/vip/program/Cargo.toml b/contracts/vip/program/Cargo.toml new file mode 100644 index 0000000..a67b163 --- /dev/null +++ b/contracts/vip/program/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "program" +version = "0.1.0" +authors = ["Shane Vitarana "] +edition = "2021" + +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] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[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 +""" + +[dependencies] +cosmwasm-schema = "1.1.3" +cosmwasm-std = "1.1.3" +cosmwasm-storage = "1.1.3" +cw-storage-plus = "1.0.1" +cw2 = "1.0.1" +schemars = "0.8.10" +serde = { version = "1.0.145", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.31" } + +[dev-dependencies] +cw-multi-test = "0.16.2" diff --git a/contracts/vip/program/README.md b/contracts/vip/program/README.md new file mode 100644 index 0000000..2430f1d --- /dev/null +++ b/contracts/vip/program/README.md @@ -0,0 +1,4 @@ +# Stargaze VIP Program + +This contract implements the logic of the Stargaze VIP Program. It queries the VIP collection and determines which tier the account is in. It also manages tier limits. + diff --git a/contracts/vip/program/src/bin/schema.rs b/contracts/vip/program/src/bin/schema.rs new file mode 100644 index 0000000..3f13608 --- /dev/null +++ b/contracts/vip/program/src/bin/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use program::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/vip/program/src/contract.rs b/contracts/vip/program/src/contract.rs new file mode 100644 index 0000000..f51071d --- /dev/null +++ b/contracts/vip/program/src/contract.rs @@ -0,0 +1,50 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{coin, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cw2::set_contract_version; + +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{COLLECTION, TIERS}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:stargaze-vip-program"; +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)?; + + // TODO: add cw_ownable so an admin can update tier limits + + COLLECTION.save(deps.storage, &deps.api.addr_validate(&msg.collection)?)?; + + for t in msg.tiers.iter() { + TIERS.save(deps.storage, t.tier, &t.amount)?; + } + + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: ExecuteMsg, +) -> Result { + unimplemented!() +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { + unimplemented!() +} + +#[cfg(test)] +mod tests {} diff --git a/contracts/vip/program/src/error.rs b/contracts/vip/program/src/error.rs new file mode 100644 index 0000000..4a69d8f --- /dev/null +++ b/contracts/vip/program/src/error.rs @@ -0,0 +1,13 @@ +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. +} diff --git a/contracts/vip/program/src/helpers.rs b/contracts/vip/program/src/helpers.rs new file mode 100644 index 0000000..a39b155 --- /dev/null +++ b/contracts/vip/program/src/helpers.rs @@ -0,0 +1,27 @@ +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>(&self, msg: T) -> StdResult { + let msg = to_binary(&msg.into())?; + Ok(WasmMsg::Execute { + contract_addr: self.addr().into(), + msg, + funds: vec![], + } + .into()) + } +} diff --git a/contracts/vip/program/src/lib.rs b/contracts/vip/program/src/lib.rs new file mode 100644 index 0000000..233dbf5 --- /dev/null +++ b/contracts/vip/program/src/lib.rs @@ -0,0 +1,7 @@ +pub mod contract; +mod error; +pub mod helpers; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; diff --git a/contracts/vip/program/src/msg.rs b/contracts/vip/program/src/msg.rs new file mode 100644 index 0000000..de75695 --- /dev/null +++ b/contracts/vip/program/src/msg.rs @@ -0,0 +1,21 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Coin; + +#[cw_serde] +pub struct TierMsg { + pub tier: u16, + pub amount: Vec, +} + +#[cw_serde] +pub struct InstantiateMsg { + pub collection: String, + pub tiers: Vec, +} + +#[cw_serde] +pub enum ExecuteMsg {} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg {} diff --git a/contracts/vip/program/src/state.rs b/contracts/vip/program/src/state.rs new file mode 100644 index 0000000..4fe7b4f --- /dev/null +++ b/contracts/vip/program/src/state.rs @@ -0,0 +1,13 @@ +use std::collections::BTreeMap; + +use cosmwasm_std::{Addr, Coin, Coins, Uint128}; +use cw_storage_plus::{Item, Map}; + +pub const COLLECTION: Item = Item::new("collection"); + +// TODO: waiting on https://github.com/CosmWasm/cosmwasm/pull/1809 +// pub const TIERS: Map = Map::new("t"); + +pub const TIERS: Map> = Map::new("t"); + +// pub const TIERS: Map> = Map::new("t"); From 583b2abe2a1be156d4adda38199c63e80f00c79a Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Mon, 7 Aug 2023 18:45:14 -0400 Subject: [PATCH 16/26] Extend properly --- Cargo.lock | 2 + contracts/vip/collection/Cargo.toml | 1 + contracts/vip/collection/src/bin/schema.rs | 3 +- contracts/vip/collection/src/contract.rs | 97 +++++++++++++--------- contracts/vip/collection/src/helpers.rs | 24 ------ contracts/vip/collection/src/lib.rs | 6 +- contracts/vip/collection/src/msg.rs | 20 ++++- contracts/vip/minter/Cargo.toml | 25 +++--- contracts/vip/minter/src/contract.rs | 36 +++----- contracts/vip/program/src/contract.rs | 10 ++- contracts/vip/program/src/msg.rs | 5 +- packages/sg-vip/src/lib.rs | 30 +++---- 12 files changed, 136 insertions(+), 123 deletions(-) delete mode 100644 contracts/vip/collection/src/helpers.rs diff --git a/Cargo.lock b/Cargo.lock index 6f3b492..b8fc05b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2138,6 +2138,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.1.0", "cw2 1.1.0", + "cw721 0.18.0", "cw721-base 0.18.0", "schemars", "serde", @@ -2161,6 +2162,7 @@ dependencies = [ "serde", "sg-name", "sg-vip", + "stargaze-vip-collection", "thiserror", ] diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index b3b7d7f..7b29f14 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -32,6 +32,7 @@ cosmwasm-std = { workspace = true, features = ["cosmwasm_1_2"] } cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } +cw721 = { workspace = true } cw721-base = { workspace = true, features = ["library"] } schemars = { workspace = true } serde = { workspace = true } diff --git a/contracts/vip/collection/src/bin/schema.rs b/contracts/vip/collection/src/bin/schema.rs index 5408d1c..cbd2a58 100644 --- a/contracts/vip/collection/src/bin/schema.rs +++ b/contracts/vip/collection/src/bin/schema.rs @@ -1,8 +1,7 @@ use cosmwasm_schema::write_api; use cw721_base::InstantiateMsg; -use sg_vip::collection::ExecuteMsg; -use stargaze_vip_collection::msg::QueryMsg; +use stargaze_vip_collection::{msg::QueryMsg, ExecuteMsg}; fn main() { write_api! { diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index a2134e2..280a5fc 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -2,15 +2,14 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ instantiate2_address, to_binary, Binary, CodeInfoResponse, ContractInfoResponse, Deps, DepsMut, - Env, MessageInfo, Response, StdError, StdResult, Uint128, WasmMsg, + Env, MessageInfo, Response, StdError, StdResult, WasmMsg, }; use cw2::set_contract_version; -use sg_vip::collection::ExecuteMsg; use crate::error::ContractError; -use crate::msg::{InstantiateMsg, QueryMsg}; +use crate::msg::{ExecuteExt, InstantiateMsg, QueryMsg}; use crate::state::Metadata; -use crate::VipCollection; +use crate::{ExecuteMsg, VipCollection}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -73,56 +72,62 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Mint { - name, - owner, - staked_amount, - data, - } => execute_mint(deps, env, info, name, owner, staked_amount, data), - ExecuteMsg::UpdateToken { - name, - owner, - staked_amount, - data, - } => execute_update_token(deps, env, info, name, owner, staked_amount, data), + cw721_base::ExecuteMsg::TransferNft { + recipient, + token_id, + } => Err(ContractError::Unauthorized {}), + cw721_base::ExecuteMsg::SendNft { + contract, + token_id, + msg, + } => Err(ContractError::Unauthorized {}), + cw721_base::ExecuteMsg::Approve { + spender, + token_id, + expires, + } => Err(ContractError::Unauthorized {}), + cw721_base::ExecuteMsg::Revoke { spender, token_id } => Err(ContractError::Unauthorized {}), + cw721_base::ExecuteMsg::ApproveAll { operator, expires } => { + Err(ContractError::Unauthorized {}) + } + cw721_base::ExecuteMsg::RevokeAll { operator } => Err(ContractError::Unauthorized {}), + // cw721_base::ExecuteMsg::Mint { + // token_id, + // owner, + // token_uri, + // extension, + // } => todo!(), + // cw721_base::ExecuteMsg::Burn { token_id } => todo!(), + cw721_base::ExecuteMsg::Extension { msg } => match msg { + ExecuteExt::UpdateToken { + token_id, + owner, + token_uri, + extension, + } => todo!(), + }, + // cw721_base::ExecuteMsg::UpdateOwnership(_) => todo!(), + _ => VipCollection::default() + .execute(deps, env, info, msg) + .map_err(Into::into), } } -pub fn execute_mint( +pub fn execute_update_token( deps: DepsMut, - env: Env, info: MessageInfo, - name: String, + token_id: String, owner: String, - staked_amount: Uint128, - data: Option, + extension: Metadata, ) -> Result { only_minter(deps.as_ref())?; - let extension = Metadata { - staked_amount, - data, - updated_at: env.block.time, - }; - + // We can just overwrite the previous token with the new metadata VipCollection::default() - .mint(deps, info, name, owner, None, extension) + .mint(deps, info, token_id, owner, None, extension) .map_err(ContractError::Cw721Base) } -pub fn execute_update_token( - deps: DepsMut, - env: Env, - info: MessageInfo, - name: String, - owner: String, - staked_amount: Uint128, - data: Option, -) -> Result { - // We can just overwrite the previous token with the new metadata - execute_mint(deps, env, info, name, owner, staked_amount, data) -} - fn only_minter(deps: Deps) -> Result { VipCollection::default() .minter(deps)? @@ -154,5 +159,15 @@ pub fn query_total_staked(deps: Deps, owner: String) -> StdResult { todo!() } +// pub fn query_stake_weight(deps: Deps, env: Env, name: String) -> StdResult { +// let res: NftInfoResponse = VipCollection::default().query( +// deps, +// env, +// cw721_base::msg::QueryMsg::NftInfo { token_id: name }, +// ); + +// res.extension.staked_amount +// } + #[cfg(test)] mod tests {} diff --git a/contracts/vip/collection/src/helpers.rs b/contracts/vip/collection/src/helpers.rs deleted file mode 100644 index 1cba7f0..0000000 --- a/contracts/vip/collection/src/helpers.rs +++ /dev/null @@ -1,24 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; -use sg_vip::collection::ExecuteMsg; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct SgVipCollection(pub Addr); - -impl SgVipCollection { - pub fn addr(&self) -> Addr { - self.0.clone() - } - - pub fn call>(&self, msg: T) -> StdResult { - let msg = to_binary(&msg.into())?; - Ok(WasmMsg::Execute { - contract_addr: self.addr().into(), - msg, - funds: vec![], - } - .into()) - } -} diff --git a/contracts/vip/collection/src/lib.rs b/contracts/vip/collection/src/lib.rs index e4c8693..13708fb 100644 --- a/contracts/vip/collection/src/lib.rs +++ b/contracts/vip/collection/src/lib.rs @@ -1,13 +1,13 @@ pub mod contract; mod error; -pub mod helpers; pub mod msg; pub mod state; use cosmwasm_std::Empty; +use msg::ExecuteExt; use state::Metadata; pub use crate::error::ContractError; -pub type VipCollection<'a> = cw721_base::Cw721Contract<'a, Metadata, Empty, Empty, Empty>; +pub type VipCollection<'a> = cw721_base::Cw721Contract<'a, Metadata, Empty, ExecuteExt, Empty>; -pub type ExecuteMsg = cw721_base::ExecuteMsg; +pub type ExecuteMsg = cw721_base::ExecuteMsg; diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 1dd8cd9..5790e74 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Uint128; +use cosmwasm_std::{CustomMsg, Uint128}; use crate::state::Metadata; @@ -9,6 +9,24 @@ pub struct InstantiateMsg { pub name_collection: String, } +// cw721_base::ExecuteMsg::Mint { +// token_id, +// owner, +// token_uri, +// extension, +// } => todo!(), + +#[cw_serde] +pub enum ExecuteExt { + UpdateToken { + token_id: String, + owner: String, + token_uri: Option, + extension: Metadata, + }, +} +impl CustomMsg for ExecuteExt {} + #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index 0d91bbd..028135c 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -27,18 +27,19 @@ library = [] [dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true, features = ["staking"] } -cosmwasm-storage = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -cw721 = { workspace = true } -cw721-base = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -sg-vip = { workspace = true } -sg-name = "1.2.5" +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cosmwasm-storage = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +cw721 = { workspace = true } +cw721-base = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +sg-vip = { workspace = true } +sg-name = "1.2.5" +stargaze-vip-collection = { path = "../collection", features = ["library"] } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 9c5a8c6..211645b 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -1,3 +1,5 @@ +use std::env; + #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -50,7 +52,7 @@ pub fn execute( pub fn execute_mint( deps: DepsMut, - _env: Env, + env: Env, info: MessageInfo, name: String, ) -> Result { @@ -66,11 +68,15 @@ pub fn execute_mint( let staked_amount = total_staked(deps.as_ref(), info.sender.clone())?; - let msg = sg_vip::collection::ExecuteMsg::Mint { - name, + let msg = stargaze_vip_collection::ExecuteMsg::Mint { + token_id: name, owner: info.sender.to_string(), - staked_amount: Uint128::from(staked_amount), - data: None, + token_uri: None, + extension: stargaze_vip_collection::state::Metadata { + staked_amount: Uint128::from(staked_amount), + data: None, + updated_at: env.block.time, + }, }; let mint_msg = WasmMsg::Execute { contract_addr: vip_collection.to_string(), @@ -94,24 +100,8 @@ pub fn execute_update( name_collection, } = CONFIG.load(deps.storage)?; - ensure!( - info.sender == associated_address(deps.as_ref(), name.clone())?, - ContractError::Unauthorized {} - ); - - let staked_amount = total_staked(deps.as_ref(), info.sender.clone())?; - - let msg = sg_vip::collection::ExecuteMsg::Mint { - name, - owner: info.sender.to_string(), - staked_amount: Uint128::from(staked_amount), - data: None, - }; - let mint_msg = WasmMsg::Execute { - contract_addr: vip_collection.to_string(), - msg: to_binary(&msg)?, - funds: vec![], - }; + // TODO: except don't add to queue again? + execute_mint(deps, env, info, name)?; // TODO: update metadata and call update on collection contract diff --git a/contracts/vip/program/src/contract.rs b/contracts/vip/program/src/contract.rs index f51071d..195b046 100644 --- a/contracts/vip/program/src/contract.rs +++ b/contracts/vip/program/src/contract.rs @@ -42,7 +42,15 @@ pub fn execute( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + // match msg { + // QueryMsg::Tier { name } => { + // let collection = COLLECTION.load(deps.storage)?; + + // let tier = TIERS.load(deps.storage, 1)?; + // Ok(tier.into()) + // } + // } unimplemented!() } diff --git a/contracts/vip/program/src/msg.rs b/contracts/vip/program/src/msg.rs index de75695..7fb0fcd 100644 --- a/contracts/vip/program/src/msg.rs +++ b/contracts/vip/program/src/msg.rs @@ -18,4 +18,7 @@ pub enum ExecuteMsg {} #[cw_serde] #[derive(QueryResponses)] -pub enum QueryMsg {} +pub enum QueryMsg { + #[returns(u16)] + Tier { name: String }, +} diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 75c9a9f..896fed0 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -18,21 +18,21 @@ pub mod collection { // pub name_collection: String, // } - #[cw_serde] - pub enum ExecuteMsg { - Mint { - name: String, - owner: String, - staked_amount: Uint128, - data: Option, - }, - UpdateToken { - name: String, - owner: String, - staked_amount: Uint128, - data: Option, - }, - } + // #[cw_serde] + // pub enum ExecuteMsg { + // Mint { + // name: String, + // owner: String, + // staked_amount: Uint128, + // data: Option, + // }, + // UpdateToken { + // name: String, + // owner: String, + // staked_amount: Uint128, + // data: Option, + // }, + // } // #[cw_serde] // #[derive(QueryResponses)] From a9a22639d161a49189a6dad66648c422c60e9fbe Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Mon, 7 Aug 2023 23:05:42 -0400 Subject: [PATCH 17/26] Simplify --- contracts/vip/collection/src/contract.rs | 34 ++-------------------- contracts/vip/collection/src/lib.rs | 5 ++-- contracts/vip/collection/src/msg.rs | 20 +------------ contracts/vip/minter/src/contract.rs | 2 +- contracts/vip/program/src/contract.rs | 22 ++++++++------- packages/sg-vip/src/lib.rs | 36 ------------------------ 6 files changed, 18 insertions(+), 101 deletions(-) diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 280a5fc..051f620 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -7,8 +7,7 @@ use cosmwasm_std::{ use cw2::set_contract_version; use crate::error::ContractError; -use crate::msg::{ExecuteExt, InstantiateMsg, QueryMsg}; -use crate::state::Metadata; +use crate::msg::{InstantiateMsg, QueryMsg}; use crate::{ExecuteMsg, VipCollection}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; @@ -98,14 +97,7 @@ pub fn execute( // extension, // } => todo!(), // cw721_base::ExecuteMsg::Burn { token_id } => todo!(), - cw721_base::ExecuteMsg::Extension { msg } => match msg { - ExecuteExt::UpdateToken { - token_id, - owner, - token_uri, - extension, - } => todo!(), - }, + // cw721_base::ExecuteMsg::Extension { msg } => todo!(), // cw721_base::ExecuteMsg::UpdateOwnership(_) => todo!(), _ => VipCollection::default() .execute(deps, env, info, msg) @@ -113,28 +105,6 @@ pub fn execute( } } -pub fn execute_update_token( - deps: DepsMut, - info: MessageInfo, - token_id: String, - owner: String, - extension: Metadata, -) -> Result { - only_minter(deps.as_ref())?; - - // We can just overwrite the previous token with the new metadata - VipCollection::default() - .mint(deps, info, token_id, owner, None, extension) - .map_err(ContractError::Cw721Base) -} - -fn only_minter(deps: Deps) -> Result { - VipCollection::default() - .minter(deps)? - .minter - .ok_or(ContractError::Unauthorized {}) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { diff --git a/contracts/vip/collection/src/lib.rs b/contracts/vip/collection/src/lib.rs index 13708fb..4033b34 100644 --- a/contracts/vip/collection/src/lib.rs +++ b/contracts/vip/collection/src/lib.rs @@ -3,11 +3,10 @@ mod error; pub mod msg; pub mod state; use cosmwasm_std::Empty; -use msg::ExecuteExt; use state::Metadata; pub use crate::error::ContractError; -pub type VipCollection<'a> = cw721_base::Cw721Contract<'a, Metadata, Empty, ExecuteExt, Empty>; +pub type VipCollection<'a> = cw721_base::Cw721Contract<'a, Metadata, Empty, Empty, Empty>; -pub type ExecuteMsg = cw721_base::ExecuteMsg; +pub type ExecuteMsg = cw721_base::ExecuteMsg; diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 5790e74..1dd8cd9 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{CustomMsg, Uint128}; +use cosmwasm_std::Uint128; use crate::state::Metadata; @@ -9,24 +9,6 @@ pub struct InstantiateMsg { pub name_collection: String, } -// cw721_base::ExecuteMsg::Mint { -// token_id, -// owner, -// token_uri, -// extension, -// } => todo!(), - -#[cw_serde] -pub enum ExecuteExt { - UpdateToken { - token_id: String, - owner: String, - token_uri: Option, - extension: Metadata, - }, -} -impl CustomMsg for ExecuteExt {} - #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 211645b..57e8bf1 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -45,7 +45,7 @@ pub fn execute( ) -> Result { match msg { ExecuteMsg::Mint { name } => execute_mint(deps, env, info, name), - ExecuteMsg::Update { name } => todo!(), + ExecuteMsg::Update { name } => execute_update(deps, env, info, name), ExecuteMsg::Pause {} => todo!(), } } diff --git a/contracts/vip/program/src/contract.rs b/contracts/vip/program/src/contract.rs index 195b046..e8921cb 100644 --- a/contracts/vip/program/src/contract.rs +++ b/contracts/vip/program/src/contract.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{coin, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{coin, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; use crate::error::ContractError; @@ -43,15 +43,17 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - // match msg { - // QueryMsg::Tier { name } => { - // let collection = COLLECTION.load(deps.storage)?; - - // let tier = TIERS.load(deps.storage, 1)?; - // Ok(tier.into()) - // } - // } - unimplemented!() + match msg { + QueryMsg::Tier { name } => { + let collection = COLLECTION.load(deps.storage)?; + // TODO: query metadata for name + + // TODO: compare stake weight with tier limits + + let tier = TIERS.load(deps.storage, 1)?; + Ok(to_binary(&tier)?) + } + } } #[cfg(test)] diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 896fed0..48b0b2f 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -7,39 +7,3 @@ pub mod minter { pub name_collection: String, } } - -pub mod collection { - use cosmwasm_schema::cw_serde; - use cosmwasm_std::Uint128; - - // #[cw_serde] - // pub struct InstantiateMsg { - // pub minter_code_id: u64, - // pub name_collection: String, - // } - - // #[cw_serde] - // pub enum ExecuteMsg { - // Mint { - // name: String, - // owner: String, - // staked_amount: Uint128, - // data: Option, - // }, - // UpdateToken { - // name: String, - // owner: String, - // staked_amount: Uint128, - // data: Option, - // }, - // } - - // #[cw_serde] - // #[derive(QueryResponses)] - // pub enum QueryMsg { - // #[returns(Metadata)] - // Metadata { address: String }, - // #[returns(Uint128)] - // TotalStaked { owner: String }, - // } -} From d5a0f2d1ec15af789e55a1270492d6d9b0d2b179 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Tue, 8 Aug 2023 00:30:38 -0400 Subject: [PATCH 18/26] Update program --- Cargo.lock | 35 ++++++++++------- Cargo.toml | 2 +- contracts/vip/collection/Cargo.toml | 2 +- contracts/vip/program/Cargo.toml | 52 +++++++++++-------------- contracts/vip/program/src/bin/schema.rs | 2 +- contracts/vip/program/src/contract.rs | 10 +++-- 6 files changed, 52 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8fc05b..06a6cf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1572,21 +1572,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "program" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw2 1.1.0", - "schemars", - "serde", - "thiserror", -] - [[package]] name = "prost" version = "0.9.0" @@ -2166,6 +2151,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "stargaze-vip-program" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-storage", + "cw-multi-test", + "cw-storage-plus 1.1.0", + "cw2 1.1.0", + "cw721 0.18.0", + "cw721-base 0.18.0", + "schemars", + "serde", + "sg-name", + "sg-vip", + "stargaze-vip-collection", + "thiserror", +] + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index bf2613b..399e9b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ cw-storage-plus = "1.1.0" cw-controllers = "1.1.0" cw2 = "1.1.0" cw721 = "0.18.0" -cw721-base = "0.18.0" +cw721-base = { version = "0.18.0", feature = ["library"] } cw-utils = "1.0.1" schemars = "0.8.11" semver = "1.0.16" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index 7b29f14..20cd9c2 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -33,7 +33,7 @@ cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } cw721 = { workspace = true } -cw721-base = { workspace = true, features = ["library"] } +cw721-base = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } diff --git a/contracts/vip/program/Cargo.toml b/contracts/vip/program/Cargo.toml index a67b163..6f5e247 100644 --- a/contracts/vip/program/Cargo.toml +++ b/contracts/vip/program/Cargo.toml @@ -1,8 +1,12 @@ [package] -name = "program" -version = "0.1.0" -authors = ["Shane Vitarana "] -edition = "2021" +name = "stargaze-vip-program" +authors = ["Shane Vitarana "] +description = "Stargaze vNFT Minter" +version = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +license = { workspace = true } 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. @@ -15,39 +19,27 @@ exclude = [ [lib] crate-type = ["cdylib", "rlib"] -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - [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 -""" [dependencies] -cosmwasm-schema = "1.1.3" -cosmwasm-std = "1.1.3" -cosmwasm-storage = "1.1.3" -cw-storage-plus = "1.0.1" -cw2 = "1.0.1" -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.31" } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cosmwasm-storage = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +cw721 = { workspace = true } +cw721-base = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +sg-vip = { workspace = true } +sg-name = "1.2.5" +stargaze-vip-collection = { path = "../collection", features = ["library"] } [dev-dependencies] -cw-multi-test = "0.16.2" +cw-multi-test = { workspace = true } diff --git a/contracts/vip/program/src/bin/schema.rs b/contracts/vip/program/src/bin/schema.rs index 3f13608..b1561be 100644 --- a/contracts/vip/program/src/bin/schema.rs +++ b/contracts/vip/program/src/bin/schema.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::write_api; -use program::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use stargaze_vip_program::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/program/src/contract.rs b/contracts/vip/program/src/contract.rs index e8921cb..e30f2ca 100644 --- a/contracts/vip/program/src/contract.rs +++ b/contracts/vip/program/src/contract.rs @@ -1,7 +1,8 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{coin, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; +use stargaze_vip_collection::state::Metadata; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -45,8 +46,11 @@ pub fn execute( pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Tier { name } => { - let collection = COLLECTION.load(deps.storage)?; - // TODO: query metadata for name + let token_info: cw721::NftInfoResponse = deps.querier.query_wasm_smart( + COLLECTION.load(deps.storage)?, + &cw721::Cw721QueryMsg::NftInfo { token_id: name }, + )?; + let staked_amount = token_info.extension.staked_amount.u128(); // TODO: compare stake weight with tier limits From c9c65e33fe4ad3bc14078423c48051b859bfd900 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Tue, 8 Aug 2023 01:13:00 -0400 Subject: [PATCH 19/26] Query tier --- contracts/vip/minter/src/helpers.rs | 27 --------------------------- contracts/vip/minter/src/lib.rs | 1 - contracts/vip/program/src/contract.rs | 15 ++++++++------- contracts/vip/program/src/helpers.rs | 27 --------------------------- contracts/vip/program/src/lib.rs | 1 - contracts/vip/program/src/msg.rs | 12 +++--------- contracts/vip/program/src/state.rs | 13 +++---------- 7 files changed, 14 insertions(+), 82 deletions(-) delete mode 100644 contracts/vip/minter/src/helpers.rs delete mode 100644 contracts/vip/program/src/helpers.rs diff --git a/contracts/vip/minter/src/helpers.rs b/contracts/vip/minter/src/helpers.rs deleted file mode 100644 index a39b155..0000000 --- a/contracts/vip/minter/src/helpers.rs +++ /dev/null @@ -1,27 +0,0 @@ -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>(&self, msg: T) -> StdResult { - let msg = to_binary(&msg.into())?; - Ok(WasmMsg::Execute { - contract_addr: self.addr().into(), - msg, - funds: vec![], - } - .into()) - } -} diff --git a/contracts/vip/minter/src/lib.rs b/contracts/vip/minter/src/lib.rs index 233dbf5..dfedc9d 100644 --- a/contracts/vip/minter/src/lib.rs +++ b/contracts/vip/minter/src/lib.rs @@ -1,6 +1,5 @@ pub mod contract; mod error; -pub mod helpers; pub mod msg; pub mod state; diff --git a/contracts/vip/program/src/contract.rs b/contracts/vip/program/src/contract.rs index e30f2ca..bed29f9 100644 --- a/contracts/vip/program/src/contract.rs +++ b/contracts/vip/program/src/contract.rs @@ -25,9 +25,7 @@ pub fn instantiate( COLLECTION.save(deps.storage, &deps.api.addr_validate(&msg.collection)?)?; - for t in msg.tiers.iter() { - TIERS.save(deps.storage, t.tier, &t.amount)?; - } + TIERS.save(deps.storage, &msg.tiers)?; Ok(Response::new()) } @@ -50,12 +48,15 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { COLLECTION.load(deps.storage)?, &cw721::Cw721QueryMsg::NftInfo { token_id: name }, )?; - let staked_amount = token_info.extension.staked_amount.u128(); + let staked_amount = token_info.extension.staked_amount; - // TODO: compare stake weight with tier limits + let tiers = TIERS.load(deps.storage)?; + let index = tiers + .iter() + .position(|&x| x >= staked_amount) + .unwrap_or(tiers.len()); - let tier = TIERS.load(deps.storage, 1)?; - Ok(to_binary(&tier)?) + Ok(to_binary(&index)?) } } } diff --git a/contracts/vip/program/src/helpers.rs b/contracts/vip/program/src/helpers.rs deleted file mode 100644 index a39b155..0000000 --- a/contracts/vip/program/src/helpers.rs +++ /dev/null @@ -1,27 +0,0 @@ -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>(&self, msg: T) -> StdResult { - let msg = to_binary(&msg.into())?; - Ok(WasmMsg::Execute { - contract_addr: self.addr().into(), - msg, - funds: vec![], - } - .into()) - } -} diff --git a/contracts/vip/program/src/lib.rs b/contracts/vip/program/src/lib.rs index 233dbf5..dfedc9d 100644 --- a/contracts/vip/program/src/lib.rs +++ b/contracts/vip/program/src/lib.rs @@ -1,6 +1,5 @@ pub mod contract; mod error; -pub mod helpers; pub mod msg; pub mod state; diff --git a/contracts/vip/program/src/msg.rs b/contracts/vip/program/src/msg.rs index 7fb0fcd..644bc6f 100644 --- a/contracts/vip/program/src/msg.rs +++ b/contracts/vip/program/src/msg.rs @@ -1,16 +1,10 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Coin; - -#[cw_serde] -pub struct TierMsg { - pub tier: u16, - pub amount: Vec, -} +use cosmwasm_std::Uint128; #[cw_serde] pub struct InstantiateMsg { pub collection: String, - pub tiers: Vec, + pub tiers: Vec, } #[cw_serde] @@ -19,6 +13,6 @@ pub enum ExecuteMsg {} #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(u16)] + #[returns(u64)] Tier { name: String }, } diff --git a/contracts/vip/program/src/state.rs b/contracts/vip/program/src/state.rs index 4fe7b4f..33cd571 100644 --- a/contracts/vip/program/src/state.rs +++ b/contracts/vip/program/src/state.rs @@ -1,13 +1,6 @@ -use std::collections::BTreeMap; - -use cosmwasm_std::{Addr, Coin, Coins, Uint128}; -use cw_storage_plus::{Item, Map}; +use cosmwasm_std::{Addr, Uint128}; +use cw_storage_plus::Item; pub const COLLECTION: Item = Item::new("collection"); -// TODO: waiting on https://github.com/CosmWasm/cosmwasm/pull/1809 -// pub const TIERS: Map = Map::new("t"); - -pub const TIERS: Map> = Map::new("t"); - -// pub const TIERS: Map> = Map::new("t"); +pub const TIERS: Item> = Item::new("tiers"); From e28bfdb6b51fa448697f9bcc5d6e4c9ca8627e49 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 11:06:23 -0400 Subject: [PATCH 20/26] Updated lockfile --- Cargo.lock | 429 ++++++++++++++++++++++++++++------------------------- Cargo.toml | 1 - 2 files changed, 226 insertions(+), 204 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06a6cf0..df6e591 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -24,9 +39,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "assert_matches" @@ -53,18 +68,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -86,9 +101,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -129,6 +144,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.1.1" @@ -160,7 +190,7 @@ dependencies = [ "pbkdf2", "rand_core 0.6.4", "ripemd", - "sha2 0.10.6", + "sha2 0.10.7", "subtle", "zeroize", ] @@ -227,9 +257,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -258,9 +291,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "core-foundation" @@ -404,7 +437,7 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", ] @@ -420,9 +453,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -527,9 +560,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d9b6f91c0b94481a3e9ef1ceb183c37d00764f8751e39b45fc09f4d9b970d469" dependencies = [ "cosmwasm-std", "schemars", @@ -579,9 +612,9 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "91398113b806f4d2a8d5f8d05684704a20ffd5968bf87e3473e1973710b884ad" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -606,13 +639,13 @@ dependencies = [ [[package]] name = "cw721" -version = "0.18.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" +checksum = "94a1ea6e6277bdd6dfc043a9b1380697fe29d6e24b072597439523658d21d791" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils", + "cw-utils 0.16.0", "schemars", "serde", ] @@ -676,6 +709,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + [[package]] name = "derivative" version = "2.2.0" @@ -715,9 +754,9 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" [[package]] name = "e2e-tests" @@ -788,9 +827,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" @@ -827,9 +866,9 @@ dependencies = [ [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" dependencies = [ "serde", ] @@ -941,7 +980,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -986,9 +1025,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "js-sys", @@ -997,6 +1036,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "group" version = "0.12.1" @@ -1010,9 +1055,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -1072,12 +1117,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -1136,9 +1178,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -1244,9 +1286,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1277,7 +1319,7 @@ dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "sha2 0.10.7", "sha3", ] @@ -1298,9 +1340,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linked-hash-map" @@ -1316,9 +1358,9 @@ checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "memchr" @@ -1338,6 +1380,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.8" @@ -1346,7 +1397,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1372,28 +1423,37 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.2", "libc", ] +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1419,9 +1479,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pathdiff" @@ -1473,9 +1533,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" dependencies = [ "thiserror", "ucd-trie", @@ -1483,9 +1543,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" +checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" dependencies = [ "pest", "pest_generator", @@ -1493,53 +1553,53 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" +checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] name = "pest_meta" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" +checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" dependencies = [ "once_cell", "pest", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "2c516611246607d0c04186886dbb3a754368ef82c79e9827a802c6d836dd111c" [[package]] name = "pin-utils" @@ -1565,9 +1625,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -1629,9 +1689,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1674,9 +1734,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -1685,9 +1757,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "rfc6979" @@ -1756,6 +1828,12 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustls" version = "0.19.1" @@ -1783,15 +1861,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -1804,11 +1882,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -1861,9 +1939,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags", "core-foundation", @@ -1874,9 +1952,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1884,15 +1962,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] @@ -1908,22 +1986,22 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -1939,9 +2017,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -1950,13 +2028,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.12" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -1989,8 +2067,8 @@ version = "3.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils 0.16.0", - "cw721 0.16.0", + "cw-utils 1.0.1", + "cw721 0.18.0", "schemars", "serde", "thiserror", @@ -2031,9 +2109,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", @@ -2199,9 +2277,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.17" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b6ddbb36c5b969c182aec3c4a0bce7df3fbad4b77114706a49aacc80567388" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -2343,30 +2421,31 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] name = "time" -version = "0.3.22" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ + "deranged", "serde", "time-core", "time-macros", @@ -2380,9 +2459,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -2404,11 +2483,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -2416,7 +2496,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2437,7 +2517,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -2563,13 +2643,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] [[package]] @@ -2605,9 +2685,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-bidi" @@ -2617,9 +2697,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -2705,7 +2785,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -2727,7 +2807,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2798,21 +2878,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -2824,97 +2889,55 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -2947,5 +2970,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.28", ] diff --git a/Cargo.toml b/Cargo.toml index 399e9b0..d6872b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ members = [ "contracts/vip/minter", "contracts/vip/program", "test/*", - "packages/sg-vip", ] resolver = "2" From c17d2bd2e35fbfeb9e0f151240dd95b1ec9dac5d Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 11:25:54 -0400 Subject: [PATCH 21/26] Generate schema --- .../schema/stargaze-vip-collection.json | 556 ++++++++++++++++++ .../minter/schema/stargaze-vip-minter.json | 96 +++ .../program/schema/stargaze-vip-program.json | 76 +++ scripts/schema.sh | 21 +- 4 files changed, 739 insertions(+), 10 deletions(-) create mode 100644 contracts/vip/collection/schema/stargaze-vip-collection.json create mode 100644 contracts/vip/minter/schema/stargaze-vip-minter.json create mode 100644 contracts/vip/program/schema/stargaze-vip-program.json diff --git a/contracts/vip/collection/schema/stargaze-vip-collection.json b/contracts/vip/collection/schema/stargaze-vip-collection.json new file mode 100644 index 0000000..d7dd839 --- /dev/null +++ b/contracts/vip/collection/schema/stargaze-vip-collection.json @@ -0,0 +1,556 @@ +{ + "contract_name": "stargaze-vip-collection", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "minter", + "name", + "symbol" + ], + "properties": { + "minter": { + "description": "The minter is the only one who can create new NFTs. This is designed for a base NFT that is controlled by an external program or contract. You will likely replace this with custom logic in custom NFTs", + "type": "string" + }, + "name": { + "description": "Name of the NFT contract", + "type": "string" + }, + "symbol": { + "description": "Symbol of the NFT contract", + "type": "string" + } + }, + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "description": "This is like Cw721ExecuteMsg but we add a Mint command for an owner to make this stand-alone. You will likely want to remove mint and use other control logic in any contract that inherits this.", + "oneOf": [ + { + "description": "Transfer is a base message to move a token to another account without triggering actions", + "type": "object", + "required": [ + "transfer_nft" + ], + "properties": { + "transfer_nft": { + "type": "object", + "required": [ + "recipient", + "token_id" + ], + "properties": { + "recipient": { + "type": "string" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Send is a base message to transfer a token to a contract and trigger an action on the receiving contract.", + "type": "object", + "required": [ + "send_nft" + ], + "properties": { + "send_nft": { + "type": "object", + "required": [ + "contract", + "msg", + "token_id" + ], + "properties": { + "contract": { + "type": "string" + }, + "msg": { + "$ref": "#/definitions/Binary" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", + "type": "object", + "required": [ + "approve" + ], + "properties": { + "approve": { + "type": "object", + "required": [ + "spender", + "token_id" + ], + "properties": { + "expires": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "spender": { + "type": "string" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove previously granted Approval", + "type": "object", + "required": [ + "revoke" + ], + "properties": { + "revoke": { + "type": "object", + "required": [ + "spender", + "token_id" + ], + "properties": { + "spender": { + "type": "string" + }, + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", + "type": "object", + "required": [ + "approve_all" + ], + "properties": { + "approve_all": { + "type": "object", + "required": [ + "operator" + ], + "properties": { + "expires": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "operator": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove previously granted ApproveAll permission", + "type": "object", + "required": [ + "revoke_all" + ], + "properties": { + "revoke_all": { + "type": "object", + "required": [ + "operator" + ], + "properties": { + "operator": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Mint a new NFT, can only be called by the contract minter", + "type": "object", + "required": [ + "mint" + ], + "properties": { + "mint": { + "type": "object", + "required": [ + "extension", + "owner", + "token_id" + ], + "properties": { + "extension": { + "description": "Any custom extension used by this contract", + "allOf": [ + { + "$ref": "#/definitions/Metadata" + } + ] + }, + "owner": { + "description": "The owner of the newly minter NFT", + "type": "string" + }, + "token_id": { + "description": "Unique ID of the NFT", + "type": "string" + }, + "token_uri": { + "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Burn an NFT the sender has access to", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "token_id" + ], + "properties": { + "token_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Extension msg", + "type": "object", + "required": [ + "extension" + ], + "properties": { + "extension": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the contract's ownership. The `action` to be provided can be either to propose transferring ownership to an account, accept a pending ownership transfer, or renounce the ownership permanently.", + "type": "object", + "required": [ + "update_ownership" + ], + "properties": { + "update_ownership": { + "$ref": "#/definitions/Action" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Action": { + "description": "Actions that can be taken to alter the contract's ownership", + "oneOf": [ + { + "description": "Propose to transfer the contract's ownership to another account, optionally with an expiry time.\n\nCan only be called by the contract's current owner.\n\nAny existing pending ownership transfer is overwritten.", + "type": "object", + "required": [ + "transfer_ownership" + ], + "properties": { + "transfer_ownership": { + "type": "object", + "required": [ + "new_owner" + ], + "properties": { + "expiry": { + "anyOf": [ + { + "$ref": "#/definitions/Expiration" + }, + { + "type": "null" + } + ] + }, + "new_owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept the pending ownership transfer.\n\nCan only be called by the pending owner.", + "type": "string", + "enum": [ + "accept_ownership" + ] + }, + { + "description": "Give up the contract's ownership and the possibility of appointing a new owner.\n\nCan only be invoked by the contract's current owner.\n\nAny existing pending ownership transfer is canceled.", + "type": "string", + "enum": [ + "renounce_ownership" + ] + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "Expiration": { + "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", + "oneOf": [ + { + "description": "AtHeight will expire when `env.block.height` >= height", + "type": "object", + "required": [ + "at_height" + ], + "properties": { + "at_height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "AtTime will expire when `env.block.time` >= time", + "type": "object", + "required": [ + "at_time" + ], + "properties": { + "at_time": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + { + "description": "Never will never expire. Used to express the empty variant", + "type": "object", + "required": [ + "never" + ], + "properties": { + "never": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "Metadata": { + "type": "object", + "required": [ + "staked_amount", + "updated_at" + ], + "properties": { + "data": { + "type": [ + "string", + "null" + ] + }, + "staked_amount": { + "$ref": "#/definitions/Uint128" + }, + "updated_at": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "metadata": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "total_staked" + ], + "properties": { + "total_staked": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": null, + "sudo": null, + "responses": { + "metadata": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Metadata", + "type": "object", + "required": [ + "staked_amount", + "updated_at" + ], + "properties": { + "data": { + "type": [ + "string", + "null" + ] + }, + "staked_amount": { + "$ref": "#/definitions/Uint128" + }, + "updated_at": { + "$ref": "#/definitions/Timestamp" + } + }, + "additionalProperties": false, + "definitions": { + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "total_staked": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Uint128", + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/vip/minter/schema/stargaze-vip-minter.json b/contracts/vip/minter/schema/stargaze-vip-minter.json new file mode 100644 index 0000000..06b1b78 --- /dev/null +++ b/contracts/vip/minter/schema/stargaze-vip-minter.json @@ -0,0 +1,96 @@ +{ + "contract_name": "stargaze-vip-minter", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "name_collection", + "vip_collection" + ], + "properties": { + "name_collection": { + "type": "string" + }, + "vip_collection": { + "type": "string" + } + }, + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Mint a loyalty token for the given name", + "type": "object", + "required": [ + "mint" + ], + "properties": { + "mint": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Update the stake amount for the given name", + "type": "object", + "required": [ + "update" + ], + "properties": { + "update": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "So we can pause before migrating names, etc.", + "type": "object", + "required": [ + "pause" + ], + "properties": { + "pause": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "type": "string", + "enum": [] + }, + "migrate": null, + "sudo": null, + "responses": {} +} diff --git a/contracts/vip/program/schema/stargaze-vip-program.json b/contracts/vip/program/schema/stargaze-vip-program.json new file mode 100644 index 0000000..dfba3ae --- /dev/null +++ b/contracts/vip/program/schema/stargaze-vip-program.json @@ -0,0 +1,76 @@ +{ + "contract_name": "stargaze-vip-program", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "collection", + "tiers" + ], + "properties": { + "collection": { + "type": "string" + }, + "tiers": { + "type": "array", + "items": { + "$ref": "#/definitions/Uint128" + } + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "type": "string", + "enum": [] + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "tier" + ], + "properties": { + "tier": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": null, + "sudo": null, + "responses": { + "tier": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "uint64", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } +} diff --git a/scripts/schema.sh b/scripts/schema.sh index 4fd87ff..49641d8 100755 --- a/scripts/schema.sh +++ b/scripts/schema.sh @@ -1,13 +1,14 @@ -# for d in contracts/*; do -# if [ -d "$d" ]; then -# cd $d -# cargo schema -# rm -rf schema/raw -# cd ../.. -# fi -# done - cd contracts/fair-burn cargo schema rm -rf schema/raw -cd ../.. \ No newline at end of file +cd ../.. + +for d in contracts/vip/*; do + if [ -d "$d" ]; then + cd $d + cargo schema + rm -rf schema/raw + cd ../../.. + fi +done + From cb30c9c7ad7be4f2790935eb8ed8f18a2417f1b0 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 13:43:54 -0400 Subject: [PATCH 22/26] Update queue --- contracts/vip/README.md | 55 +----------- contracts/vip/collection/src/contract.rs | 1 + contracts/vip/collection/src/msg.rs | 1 + contracts/vip/minter/README.md | 1 + contracts/vip/minter/src/contract.rs | 101 +++++++++++++++-------- contracts/vip/minter/src/lib.rs | 1 + contracts/vip/minter/src/msg.rs | 17 ++-- contracts/vip/minter/src/state.rs | 8 +- contracts/vip/minter/src/sudo.rs | 63 ++++++++++++++ packages/sg-vip/src/lib.rs | 1 + 10 files changed, 156 insertions(+), 93 deletions(-) create mode 100644 contracts/vip/minter/src/sudo.rs diff --git a/contracts/vip/README.md b/contracts/vip/README.md index 933561a..4a43c32 100644 --- a/contracts/vip/README.md +++ b/contracts/vip/README.md @@ -2,7 +2,10 @@ TODO: -- [ ] `program` contract to define tiers +- [ ] Add burn and updating queue when name changes +- [ ] Add CI/CD +- [ ] Add deployment scripts +- [ ] Add e2e tests The Stargaze VIP Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. @@ -16,50 +19,8 @@ The VIP Collection is a contract that stores all the vNFTs, and periodically upd vNFTs are indexed by Stargaze Names, using the name for the `token_id`. If a name is transferred or burned, the associated vNFT is burned. This happens via a hook in the Stargaze Name collection contract. -```rs -pub struct VipMetadata { - pub staked_amount: [Coin], - pub data: Option, - pub updated_at: Timestamp, -} -``` - The stake weight metadata can only be updated at specific intervals. The `updated_at` field is used to determine when the metadata can be updated. The `updated_at` field is set to the current block time when the vNFT is minted. The metadata can be updated when the current block time is greater than the `updated_at` field plus the `update_period` field in the config. -```rs -pub struct Config { - pub update_period: Duration, -} -``` - -### Messages - -```rs -pub struct InstantiateMsg { - pub update_period: Duration, -} -``` - -This updates the metadata of a vNFT immediately instead of waiting for the end blocker. - -```rs -pub enum ExecuteMsg { - UpdateMetadata { - address: String, - data: Option, - }, -} -``` - -```rs -pub enum SudoMsg{ - BeginBlock {}, // Is called by x/cron module BeginBlocker - EndBlock {}, // Is called by x/cron module EndBlocker - UpdateConfig { - config: Config, - }, -} -``` ### Queries @@ -81,11 +42,3 @@ Note that a user may have multiple wallets that stake. For example they may have The vNFT Minter is a contract that allows users to mint vNFTs. -```rs -pub struct MintMsg { - pub name: String, - pub owner: String, - pub token_uri: Option, // ignored - pub extension: T, // `VipMetadata` -} -``` diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index 051f620..a1c4fab 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -42,6 +42,7 @@ pub fn instantiate( msg: to_binary(&sg_vip::minter::InstantiateMsg { vip_collection: collection.to_string(), name_collection: msg.name_collection, + update_interval: msg.update_interval, })?, funds: vec![], salt: Binary::from(salt.to_vec()), diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 1dd8cd9..459b4c1 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -7,6 +7,7 @@ use crate::state::Metadata; pub struct InstantiateMsg { pub minter_code_id: u64, pub name_collection: String, + pub update_interval: u64, // in blocks } #[cw_serde] diff --git a/contracts/vip/minter/README.md b/contracts/vip/minter/README.md index e81cf31..a7ddc91 100644 --- a/contracts/vip/minter/README.md +++ b/contracts/vip/minter/README.md @@ -1,3 +1,4 @@ # Stargaze VIP Minter This contract is responsible for writing to the Stargaze VIP Collection contract. + diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index 57e8bf1..c596698 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -3,15 +3,15 @@ use std::env; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, - WasmMsg, + ensure, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, + Timestamp, Uint128, WasmMsg, }; use cw2::set_contract_version; use sg_vip::minter::InstantiateMsg; use crate::error::ContractError; use crate::msg::{ExecuteMsg, QueryMsg}; -use crate::state::{Config, CONFIG}; +use crate::state::{Config, CONFIG, NAME_QUEUE}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -30,6 +30,7 @@ pub fn instantiate( &Config { vip_collection: deps.api.addr_validate(&msg.vip_collection)?, name_collection: deps.api.addr_validate(&msg.name_collection)?, + update_interval: msg.update_interval, }, )?; @@ -56,35 +57,34 @@ pub fn execute_mint( info: MessageInfo, name: String, ) -> Result { - let Config { - vip_collection, - name_collection, - } = CONFIG.load(deps.storage)?; - ensure!( info.sender == associated_address(deps.as_ref(), name.clone())?, ContractError::Unauthorized {} ); - let staked_amount = total_staked(deps.as_ref(), info.sender.clone())?; + let Config { + vip_collection, + update_interval, + .. + } = CONFIG.load(deps.storage)?; - let msg = stargaze_vip_collection::ExecuteMsg::Mint { - token_id: name, - owner: info.sender.to_string(), - token_uri: None, - extension: stargaze_vip_collection::state::Metadata { - staked_amount: Uint128::from(staked_amount), - data: None, - updated_at: env.block.time, - }, - }; - let mint_msg = WasmMsg::Execute { - contract_addr: vip_collection.to_string(), - msg: to_binary(&msg)?, - funds: vec![], - }; + let mint_msg = mint( + deps.as_ref(), + info.sender, + env.block.time, + name.clone(), + vip_collection, + )?; - // TODO: add the `token_id` to an end block queue + NAME_QUEUE.update( + deps.storage, + env.block.height + update_interval, + |names| -> StdResult<_> { + let mut names = names.unwrap_or_default(); + names.push(name); + Ok(names) + }, + )?; Ok(Response::new().add_message(mint_msg)) } @@ -95,20 +95,52 @@ pub fn execute_update( info: MessageInfo, name: String, ) -> Result { - let Config { + ensure!( + info.sender == associated_address(deps.as_ref(), name.clone())?, + ContractError::Unauthorized {} + ); + + let Config { vip_collection, .. } = CONFIG.load(deps.storage)?; + + let mint_msg = mint( + deps.as_ref(), + info.sender, + env.block.time, + name, vip_collection, - name_collection, - } = CONFIG.load(deps.storage)?; + )?; - // TODO: except don't add to queue again? - execute_mint(deps, env, info, name)?; + Ok(Response::new().add_message(mint_msg)) +} - // TODO: update metadata and call update on collection contract +pub fn mint( + deps: Deps, + sender: Addr, + block_time: Timestamp, + name: String, + vip_collection: Addr, +) -> Result { + let staked_amount = total_staked(deps, sender.clone())?; - Ok(Response::new()) + let msg = stargaze_vip_collection::ExecuteMsg::Mint { + token_id: name, + owner: sender.to_string(), + token_uri: None, + extension: stargaze_vip_collection::state::Metadata { + staked_amount: Uint128::from(staked_amount), + data: None, + updated_at: block_time, + }, + }; + + Ok(WasmMsg::Execute { + contract_addr: vip_collection.to_string(), + msg: to_binary(&msg)?, + funds: vec![], + }) } -fn associated_address(deps: Deps, name: String) -> Result { +pub fn associated_address(deps: Deps, name: String) -> Result { let associated_addr: Addr = deps.querier.query_wasm_smart( CONFIG.load(deps.storage)?.name_collection, &sg_name::SgNameQueryMsg::AssociatedAddress { name }, @@ -127,9 +159,6 @@ fn total_staked(deps: Deps, address: Addr) -> StdResult { Ok(total) } -// TODO: add end block function -// TODO: pop address off the queue and update metadata - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { unimplemented!() diff --git a/contracts/vip/minter/src/lib.rs b/contracts/vip/minter/src/lib.rs index dfedc9d..e455cce 100644 --- a/contracts/vip/minter/src/lib.rs +++ b/contracts/vip/minter/src/lib.rs @@ -2,5 +2,6 @@ pub mod contract; mod error; pub mod msg; pub mod state; +pub mod sudo; pub use crate::error::ContractError; diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs index f0ce094..ec6bb21 100644 --- a/contracts/vip/minter/src/msg.rs +++ b/contracts/vip/minter/src/msg.rs @@ -1,10 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -// #[cw_serde] -// pub struct InstantiateMsg { -// pub collection: String, -// } - #[cw_serde] pub enum ExecuteMsg { /// Mint a loyalty token for the given name @@ -15,6 +10,18 @@ pub enum ExecuteMsg { Pause {}, } +// #[allow(clippy::large_enum_variant)] +#[cw_serde] +pub enum SudoMsg { + BeginBlock {}, // Is called by x/cron module BeginBlocker + EndBlock {}, // Is called by x/cron module EndBlocker + // UpdateParams { + // // fair_burn: Option, + // // trading_fee_percent: Option, + // // min_bid_increment_percent: Option, + // }, +} + #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg {} diff --git a/contracts/vip/minter/src/state.rs b/contracts/vip/minter/src/state.rs index 3d4e0b8..01ea6e7 100644 --- a/contracts/vip/minter/src/state.rs +++ b/contracts/vip/minter/src/state.rs @@ -1,11 +1,17 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; -use cw_storage_plus::Item; +use cw_storage_plus::{Item, Map}; #[cw_serde] pub struct Config { pub vip_collection: Addr, pub name_collection: Addr, + pub update_interval: u64, // in blocks } pub const CONFIG: Item = Item::new("config"); + +/// (block_height, [name1, name2, ...]) +pub const NAME_QUEUE: Map> = Map::new("nq"); + +// TODO: need secondary queue for name <> height mapping diff --git a/contracts/vip/minter/src/sudo.rs b/contracts/vip/minter/src/sudo.rs new file mode 100644 index 0000000..cc29fb7 --- /dev/null +++ b/contracts/vip/minter/src/sudo.rs @@ -0,0 +1,63 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{DepsMut, Env, Response}; + +use crate::{ + contract::{associated_address, mint}, + msg::SudoMsg, + state::{Config, CONFIG, NAME_QUEUE}, + ContractError, +}; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> Result { + match msg { + SudoMsg::BeginBlock {} => sudo_begin_block(deps, env), + SudoMsg::EndBlock {} => sudo_end_block(deps, env), + // SudoMsg::UpdateParams { + // fair_burn, + // trading_fee_percent, + // min_bid_increment_percent, + // } => sudo_update_params( + // deps, + // env, + // fair_burn, + // trading_fee_percent, + // min_bid_increment_percent, + // ), + } +} + +pub fn sudo_begin_block(deps: DepsMut, env: Env) -> Result { + Ok(Response::new()) +} + +pub fn sudo_end_block(deps: DepsMut, env: Env) -> Result { + let Config { + vip_collection, + update_interval, + .. + } = CONFIG.load(deps.storage)?; + let names = NAME_QUEUE.load(deps.storage, env.block.height)?; + + let mint_msgs = names + .iter() + .map(|name| { + let name = name.clone(); + let owner = associated_address(deps.as_ref(), name.clone())?; + let mint_msg = mint( + deps.as_ref(), + owner, + env.block.time, + name, + vip_collection.clone(), + )?; + Ok(mint_msg) + }) + .collect::, ContractError>>()?; + + NAME_QUEUE.remove(deps.storage, env.block.height); + NAME_QUEUE.save(deps.storage, env.block.height + update_interval, &names)?; + + Ok(Response::new().add_messages(mint_msgs)) +} diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs index 48b0b2f..c9b71a9 100644 --- a/packages/sg-vip/src/lib.rs +++ b/packages/sg-vip/src/lib.rs @@ -5,5 +5,6 @@ pub mod minter { pub struct InstantiateMsg { pub vip_collection: String, pub name_collection: String, + pub update_interval: u64, // in blocks } } From c24cd3b0e08f52035a4d3df4a5e00bd116db4289 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 14:34:34 -0400 Subject: [PATCH 23/26] Update README --- contracts/vip/README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/contracts/vip/README.md b/contracts/vip/README.md index 4a43c32..4eb9243 100644 --- a/contracts/vip/README.md +++ b/contracts/vip/README.md @@ -1,12 +1,5 @@ # Stargaze VIP Program (SVP) -TODO: - -- [ ] Add burn and updating queue when name changes -- [ ] Add CI/CD -- [ ] Add deployment scripts -- [ ] Add e2e tests - The Stargaze VIP Program is a program that rewards users for staking STARS in the form of reduced fees. The program is implemented as a set of NFT smart contracts. Users are assigned to a tier based on the amount of STARS they have staked. The tier determines the amount of fees they pay. A user mints a Stargaze VIP NFT (vNFT) to join the Stargaze VIP Program. It contains metadata that includes the amount of STARS they have staked that is periodically updated via end blocker. vNFTs are non-transferrable. @@ -36,7 +29,7 @@ Note that a user may have multiple wallets that stake. For example they may have #### TODO -- [ ] Come up with a consistent way to link multiple accounts to one name +- [ ] Come up with a consistent way to link multiple accounts to one name (Version 2) ## vNFT Minter (vip-minter) From 91f48a15f8a24d86ed0b6d7104f635bfa755acd3 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 14:49:06 -0400 Subject: [PATCH 24/26] Fix linter issue --- contracts/vip/collection/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index 20cd9c2..aa0dab9 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -19,6 +19,11 @@ exclude = [ [lib] crate-type = ["cdylib", "rlib"] +[[bin]] +name = "schema" +path = "src/bin/schema.rs" +doc = false + [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] From 432236f86538a80d87908c2817d327c827f80b47 Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 15:05:56 -0400 Subject: [PATCH 25/26] Fix linter issue --- contracts/vip/minter/Cargo.toml | 5 +++++ contracts/vip/program/Cargo.toml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index 028135c..d15a17d 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -19,6 +19,11 @@ exclude = [ [lib] crate-type = ["cdylib", "rlib"] +[[bin]] +name = "schema" +path = "src/bin/schema.rs" +doc = false + [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] diff --git a/contracts/vip/program/Cargo.toml b/contracts/vip/program/Cargo.toml index 6f5e247..45d2b94 100644 --- a/contracts/vip/program/Cargo.toml +++ b/contracts/vip/program/Cargo.toml @@ -19,6 +19,11 @@ exclude = [ [lib] crate-type = ["cdylib", "rlib"] +[[bin]] +name = "schema" +path = "src/bin/schema.rs" +doc = false + [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] From d4b329ae700c16538894a327d8f818698944ddac Mon Sep 17 00:00:00 2001 From: Shane Vitarana Date: Wed, 9 Aug 2023 15:15:31 -0400 Subject: [PATCH 26/26] Refactor --- Cargo.lock | 12 ------ Cargo.toml | 1 - contracts/vip/collection/Cargo.toml | 1 - contracts/vip/collection/src/contract.rs | 50 +++-------------------- contracts/vip/collection/src/msg.rs | 7 ---- contracts/vip/minter/Cargo.toml | 1 - contracts/vip/minter/README.md | 1 + contracts/vip/minter/src/bin/schema.rs | 3 +- contracts/vip/minter/src/contract.rs | 51 ++++++++++++++++++------ contracts/vip/minter/src/msg.rs | 7 ++++ contracts/vip/program/Cargo.toml | 1 - packages/sg-vip/Cargo.toml | 11 ----- packages/sg-vip/src/lib.rs | 10 ----- 13 files changed, 53 insertions(+), 103 deletions(-) delete mode 100644 packages/sg-vip/Cargo.toml delete mode 100644 packages/sg-vip/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index df6e591..dfc7919 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2074,15 +2074,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sg-vip" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "serde", -] - [[package]] name = "sha1" version = "0.10.5" @@ -2205,7 +2196,6 @@ dependencies = [ "cw721-base 0.18.0", "schemars", "serde", - "sg-vip", "thiserror", ] @@ -2224,7 +2214,6 @@ dependencies = [ "schemars", "serde", "sg-name", - "sg-vip", "stargaze-vip-collection", "thiserror", ] @@ -2244,7 +2233,6 @@ dependencies = [ "schemars", "serde", "sg-name", - "sg-vip", "stargaze-vip-collection", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index d6872b4..44978c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ thiserror = "1.0.31" anyhow = "1.0.41" sg-std = { version = "3.1.0", path = "packages/sg-std" } sg-multi-test = { version = "3.1.0", path = "packages/sg-multi-test" } -sg-vip = { path = "packages/sg-vip" } # dev-dependencies cw-multi-test = "0.16.5" diff --git a/contracts/vip/collection/Cargo.toml b/contracts/vip/collection/Cargo.toml index aa0dab9..43cd74d 100644 --- a/contracts/vip/collection/Cargo.toml +++ b/contracts/vip/collection/Cargo.toml @@ -42,7 +42,6 @@ cw721-base = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -sg-vip = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/vip/collection/src/contract.rs b/contracts/vip/collection/src/contract.rs index a1c4fab..7972f2b 100644 --- a/contracts/vip/collection/src/contract.rs +++ b/contracts/vip/collection/src/contract.rs @@ -1,13 +1,11 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{ - instantiate2_address, to_binary, Binary, CodeInfoResponse, ContractInfoResponse, Deps, DepsMut, - Env, MessageInfo, Response, StdError, StdResult, WasmMsg, -}; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw2::set_contract_version; +use cw721_base::InstantiateMsg; use crate::error::ContractError; -use crate::msg::{InstantiateMsg, QueryMsg}; +use crate::msg::QueryMsg; use crate::{ExecuteMsg, VipCollection}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-collection"; @@ -22,46 +20,8 @@ pub fn instantiate( ) -> StdResult { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let collection = env.contract.address.as_str(); - let canonical_creator = deps.api.addr_canonicalize(collection)?; - let CodeInfoResponse { checksum, .. } = - deps.querier.query_wasm_code_info(msg.minter_code_id)?; - let salt = b"vip_minter1"; - - // create minter address with instantiate2 - let canonical_addr = instantiate2_address(&checksum, &canonical_creator, salt) - .map_err(|_| StdError::generic_err("Could not calculate addr"))?; - let minter = deps.api.addr_humanize(&canonical_addr)?; - - let ContractInfoResponse { admin, .. } = deps.querier.query_wasm_contract_info(collection)?; - - let minter_init_msg = WasmMsg::Instantiate2 { - admin, - code_id: msg.minter_code_id, - label: String::from("vip-minter"), - msg: to_binary(&sg_vip::minter::InstantiateMsg { - vip_collection: collection.to_string(), - name_collection: msg.name_collection, - update_interval: msg.update_interval, - })?, - funds: vec![], - salt: Binary::from(salt.to_vec()), - }; - - // TODO: `minter` may need to change to be this contract instead - let collection_init_msg = cw721_base::msg::InstantiateMsg { - name: String::from("Stargaze VIP Collection"), - symbol: String::from("SGVIP"), - minter: minter.to_string(), - }; - - // This configures the collection with the minter as the owner, the only one that can mint. - let res = - VipCollection::default().instantiate(deps.branch(), env, info, collection_init_msg)?; - - Ok(res - .add_message(minter_init_msg) - .add_attribute("vip-minter", minter)) + // This configures the collection with the minter as the owner, the only one that can mint + VipCollection::default().instantiate(deps.branch(), env, info, msg) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/collection/src/msg.rs b/contracts/vip/collection/src/msg.rs index 459b4c1..24fdc1d 100644 --- a/contracts/vip/collection/src/msg.rs +++ b/contracts/vip/collection/src/msg.rs @@ -3,13 +3,6 @@ use cosmwasm_std::Uint128; use crate::state::Metadata; -#[cw_serde] -pub struct InstantiateMsg { - pub minter_code_id: u64, - pub name_collection: String, - pub update_interval: u64, // in blocks -} - #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { diff --git a/contracts/vip/minter/Cargo.toml b/contracts/vip/minter/Cargo.toml index d15a17d..fa4f844 100644 --- a/contracts/vip/minter/Cargo.toml +++ b/contracts/vip/minter/Cargo.toml @@ -42,7 +42,6 @@ cw721-base = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -sg-vip = { workspace = true } sg-name = "1.2.5" stargaze-vip-collection = { path = "../collection", features = ["library"] } diff --git a/contracts/vip/minter/README.md b/contracts/vip/minter/README.md index a7ddc91..c4f983e 100644 --- a/contracts/vip/minter/README.md +++ b/contracts/vip/minter/README.md @@ -2,3 +2,4 @@ This contract is responsible for writing to the Stargaze VIP Collection contract. +Upon instantiation, a collection contract is also instantiated via `instantiate2`. The collection address is derived from the minter contract address, the collection contract code hash, and a salt. It is outputted as an attribute when the contract is instantiated and saved in `Config`. diff --git a/contracts/vip/minter/src/bin/schema.rs b/contracts/vip/minter/src/bin/schema.rs index 4f6b2b2..f160419 100644 --- a/contracts/vip/minter/src/bin/schema.rs +++ b/contracts/vip/minter/src/bin/schema.rs @@ -1,7 +1,6 @@ use cosmwasm_schema::write_api; -use sg_vip::minter::InstantiateMsg; -use stargaze_vip_minter::msg::{ExecuteMsg, QueryMsg}; +use stargaze_vip_minter::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/vip/minter/src/contract.rs b/contracts/vip/minter/src/contract.rs index c596698..ebd65c9 100644 --- a/contracts/vip/minter/src/contract.rs +++ b/contracts/vip/minter/src/contract.rs @@ -3,14 +3,13 @@ use std::env; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, - Timestamp, Uint128, WasmMsg, + ensure, instantiate2_address, to_binary, Addr, Binary, CodeInfoResponse, ContractInfoResponse, + Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, Timestamp, Uint128, WasmMsg, }; use cw2::set_contract_version; -use sg_vip::minter::InstantiateMsg; use crate::error::ContractError; -use crate::msg::{ExecuteMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{Config, CONFIG, NAME_QUEUE}; const CONTRACT_NAME: &str = "crates.io:stargaze-vip-minter"; @@ -19,22 +18,52 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - _env: Env, + env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> Result { set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + let minter = env.contract.address; + + let canonical_creator = deps.api.addr_canonicalize(minter.as_str())?; + let CodeInfoResponse { checksum, .. } = + deps.querier.query_wasm_code_info(msg.collection_code_id)?; + let salt = b"vip_collection1"; + + // create collection address with instantiate2 + let canonical_addr = instantiate2_address(&checksum, &canonical_creator, salt) + .map_err(|_| StdError::generic_err("Could not calculate addr"))?; + let collection = deps.api.addr_humanize(&canonical_addr)?; + + let ContractInfoResponse { admin, .. } = + deps.querier.query_wasm_contract_info(minter.clone())?; + CONFIG.save( deps.storage, &Config { - vip_collection: deps.api.addr_validate(&msg.vip_collection)?, + vip_collection: deps.api.addr_validate(collection.as_str())?, name_collection: deps.api.addr_validate(&msg.name_collection)?, update_interval: msg.update_interval, }, )?; - Ok(Response::new()) + let collection_init_msg = WasmMsg::Instantiate2 { + admin, + code_id: msg.collection_code_id, + label: String::from("vip-collection"), + msg: to_binary(&cw721_base::InstantiateMsg { + name: "Stargaze VIP Collection".to_string(), + symbol: "SGVIP".to_string(), + minter: minter.to_string(), + })?, + funds: vec![], + salt: Binary::from(salt.to_vec()), + }; + + Ok(Response::new() + .add_message(collection_init_msg) + .add_attribute("collection", collection)) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -120,14 +149,12 @@ pub fn mint( name: String, vip_collection: Addr, ) -> Result { - let staked_amount = total_staked(deps, sender.clone())?; - let msg = stargaze_vip_collection::ExecuteMsg::Mint { token_id: name, owner: sender.to_string(), token_uri: None, extension: stargaze_vip_collection::state::Metadata { - staked_amount: Uint128::from(staked_amount), + staked_amount: total_staked(deps, sender)?, data: None, updated_at: block_time, }, @@ -149,14 +176,14 @@ pub fn associated_address(deps: Deps, name: String) -> Result StdResult { +fn total_staked(deps: Deps, address: Addr) -> StdResult { let total = deps .querier .query_all_delegations(address)? .iter() .fold(0, |acc, d| acc + d.amount.amount.u128()); - Ok(total) + Ok(Uint128::from(total)) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/vip/minter/src/msg.rs b/contracts/vip/minter/src/msg.rs index ec6bb21..89899d1 100644 --- a/contracts/vip/minter/src/msg.rs +++ b/contracts/vip/minter/src/msg.rs @@ -1,5 +1,12 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +#[cw_serde] +pub struct InstantiateMsg { + pub collection_code_id: u64, + pub name_collection: String, + pub update_interval: u64, // in blocks +} + #[cw_serde] pub enum ExecuteMsg { /// Mint a loyalty token for the given name diff --git a/contracts/vip/program/Cargo.toml b/contracts/vip/program/Cargo.toml index 45d2b94..4ff8ffe 100644 --- a/contracts/vip/program/Cargo.toml +++ b/contracts/vip/program/Cargo.toml @@ -42,7 +42,6 @@ cw721-base = { workspace = true } schemars = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -sg-vip = { workspace = true } sg-name = "1.2.5" stargaze-vip-collection = { path = "../collection", features = ["library"] } diff --git a/packages/sg-vip/Cargo.toml b/packages/sg-vip/Cargo.toml deleted file mode 100644 index 9188810..0000000 --- a/packages/sg-vip/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "sg-vip" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } -serde = { workspace = true } diff --git a/packages/sg-vip/src/lib.rs b/packages/sg-vip/src/lib.rs deleted file mode 100644 index c9b71a9..0000000 --- a/packages/sg-vip/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod minter { - use cosmwasm_schema::cw_serde; - - #[cw_serde] - pub struct InstantiateMsg { - pub vip_collection: String, - pub name_collection: String, - pub update_interval: u64, // in blocks - } -}