-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from CosmWasm/cw2981_extension
CW-2981 extension
- Loading branch information
Showing
24 changed files
with
1,999 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,8 @@ target/ | |
.vscode/ | ||
.idea/ | ||
*.iml | ||
\#*\# | ||
.\#* | ||
|
||
# Auto-gen | ||
.cargo-ok | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[alias] | ||
wasm = "build --release --target wasm32-unknown-unknown" | ||
wasm-debug = "build --target wasm32-unknown-unknown" | ||
unit-test = "test --lib" | ||
schema = "run --example schema" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
[package] | ||
name = "cw2981-royalties" | ||
version = "0.10.0" | ||
authors = ["Alex Lynham <alex@lynh.am>"] | ||
edition = "2018" | ||
description = "Basic implementation of royalties for cw721 NFTs with token level royalties" | ||
license = "Apache-2.0" | ||
repository = "https://github.com/CosmWasm/cw-nfts" | ||
homepage = "https://cosmwasm.com" | ||
documentation = "https://docs.cosmwasm.com" | ||
|
||
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. | ||
"artifacts/*", | ||
] | ||
|
||
# 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] | ||
cw721 = { path = "../../packages/cw721", version = "0.11" } | ||
cw721-base = { path = "../cw721-base", version = "0.11", features = ["library"] } | ||
cosmwasm-std = { version = "1.0.0-beta" } | ||
schemars = "0.8.1" | ||
serde = { version = "1.0.103", default-features = false, features = ["derive"] } | ||
thiserror = { version = "1.0.23" } | ||
|
||
[dev-dependencies] | ||
cosmwasm-schema = { version = "0.16.0" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
CW-2981 Token-level Royalties | ||
Copyright (C) 2021 Envoy Labs Limited | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# CW-2981 Token-level Royalties | ||
|
||
An example of porting EIP-2981 to implement royalties at a token mint level. | ||
|
||
Builds on top of the metadata pattern in `cw721-metadata-onchain`. | ||
|
||
All of the CW-721 logic and behaviour you would expect for an NFT is implemented as normal, but additionally at mint time, royalty information can be attached to a token. | ||
|
||
Exposes two new query message types that can be called: | ||
|
||
```rust | ||
// Should be called on sale to see if royalties are owed | ||
// by the marketplace selling the NFT. | ||
// See https://eips.ethereum.org/EIPS/eip-2981 | ||
RoyaltyInfo { | ||
token_id: String, | ||
// the denom of this sale must also be the denom returned by RoyaltiesInfoResponse | ||
sale_price: Uint128, | ||
}, | ||
// Called against the contract to signal that CW-2981 is implemented | ||
CheckRoyalties {}, | ||
``` | ||
|
||
The responses are: | ||
|
||
```rust | ||
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] | ||
pub struct RoyaltiesInfoResponse { | ||
pub address: String, | ||
// Note that this must be the same denom as that passed in to RoyaltyInfo | ||
// rounding up or down is at the discretion of the implementer | ||
pub royalty_amount: Uint128, | ||
} | ||
|
||
/// Shows if the contract implements royalties | ||
/// if royalty_payments is true, marketplaces should pay them | ||
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] | ||
pub struct CheckRoyaltiesResponse { | ||
pub royalty_payments: bool, | ||
} | ||
``` | ||
|
||
|
||
To set this information, new meta fields are available on mint: | ||
|
||
```rust | ||
/// specify whether royalties are set on this token | ||
pub royalty_payments: bool, | ||
/// This is how much the minter takes as a cut when sold | ||
pub royalty_percentage: Option<u64>, | ||
/// The payment address, may be different to or the same | ||
/// as the minter addr | ||
/// question: how do we validate this? | ||
pub royalty_payment_address: Option<String>, | ||
``` | ||
|
||
Note that the `royalty_payment_address` could of course be a single address, a multisig, or a DAO. | ||
|
||
## A note on CheckRoyalties | ||
|
||
For this contract, there's nothing to check. This hook is expected to be present to check if the contract does implement CW2981 and signal that on sale royalties should be checked. With the implementation at token level it should always return true because it's up to the token. | ||
|
||
Of course contracts that extend this can determine their own behaviour and replace this function if they have more complex behaviour (for example, you could maintain a secondary index of which tokens actually have royalties). | ||
|
||
In this super simple case that isn't necessary. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use std::env::current_dir; | ||
use std::fs::create_dir_all; | ||
|
||
use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; | ||
|
||
use cw721::{ | ||
AllNftInfoResponse, ContractInfoResponse, NftInfoResponse, NumTokensResponse, | ||
OperatorsResponse, OwnerOfResponse, TokensResponse, | ||
}; | ||
use cw721_base::{ExecuteMsg, Extension, InstantiateMsg, MinterResponse, QueryMsg}; | ||
|
||
use cw2981_royalties::msg::{CheckRoyaltiesResponse, Cw2981QueryMsg, RoyaltiesInfoResponse}; | ||
|
||
fn main() { | ||
let mut out_dir = current_dir().unwrap(); | ||
out_dir.push("schema"); | ||
create_dir_all(&out_dir).unwrap(); | ||
remove_schemas(&out_dir).unwrap(); | ||
|
||
export_schema(&schema_for!(InstantiateMsg), &out_dir); | ||
export_schema_with_title(&schema_for!(ExecuteMsg<Extension>), &out_dir, "ExecuteMsg"); | ||
export_schema(&schema_for!(QueryMsg), &out_dir); | ||
export_schema_with_title( | ||
&schema_for!(AllNftInfoResponse<Extension>), | ||
&out_dir, | ||
"AllNftInfoResponse", | ||
); | ||
export_schema(&schema_for!(OperatorsResponse), &out_dir); | ||
export_schema(&schema_for!(ContractInfoResponse), &out_dir); | ||
export_schema(&schema_for!(MinterResponse), &out_dir); | ||
export_schema_with_title( | ||
&schema_for!(NftInfoResponse<Extension>), | ||
&out_dir, | ||
"NftInfoResponse", | ||
); | ||
export_schema(&schema_for!(NumTokensResponse), &out_dir); | ||
export_schema(&schema_for!(OwnerOfResponse), &out_dir); | ||
export_schema(&schema_for!(TokensResponse), &out_dir); | ||
export_schema(&schema_for!(Cw2981QueryMsg), &out_dir); | ||
export_schema(&schema_for!(RoyaltiesInfoResponse), &out_dir); | ||
export_schema(&schema_for!(CheckRoyaltiesResponse), &out_dir); | ||
} |
Oops, something went wrong.