-
Notifications
You must be signed in to change notification settings - Fork 355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nft 721 spec #50
Merged
Merged
Nft 721 spec #50
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
1cc6de7
Write README for cw721 package
ethanfrey ca04bb6
Implement basic HandleMsg and QueryMsg types
ethanfrey 981f8a4
Add metadata and enumeration extensions
ethanfrey 2d07697
Update extensions, implement with types
ethanfrey fe20d66
Add Cw721RecieveMsg
ethanfrey 41cde2c
Clean up query responses
ethanfrey d8e0049
Add query helpers
ethanfrey 4f27016
Add cw721 to CI
ethanfrey b79dab6
Allow N approvals for one NFT, fix some wording
ethanfrey 539487a
Add Pagination details
ethanfrey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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,4 @@ | ||
[alias] | ||
wasm = "build --release --target wasm32-unknown-unknown" | ||
wasm-debug = "build --target wasm32-unknown-unknown" | ||
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,15 @@ | ||
[package] | ||
name = "cw721" | ||
version = "0.1.1" | ||
authors = ["Ethan Frey <ethanfrey@users.noreply.github.com>"] | ||
edition = "2018" | ||
description = "Definition and types for the CosmWasm-721 NFT interface" | ||
license = "Apache-2.0" | ||
|
||
[dependencies] | ||
cosmwasm-std = { version = "0.10.0" } | ||
schemars = "0.7" | ||
serde = { version = "1.0.103", default-features = false, features = ["derive"] } | ||
|
||
[dev-dependencies] | ||
cosmwasm-schema = { version = "0.10.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 @@ | ||
CW721: A CosmWasm spec for non-fungible token contracts | ||
Copyright (C) 2020 Confio OÜ | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. |
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,120 @@ | ||
# CW721 Spec: Non Fungible Tokens | ||
|
||
CW721 is a specification for non-fungible tokens based on CosmWasm. | ||
The name and design is based on Ethereum's ERC721 standard, | ||
with some enhancements. The types in here can be imported by | ||
contracts that wish to implement this spec, or by contracts that call | ||
to any standard cw721 contract. | ||
|
||
The specification is split into multiple sections, a contract may only | ||
implement some of this functionality, but must implement the base. | ||
|
||
## Base | ||
|
||
This handles ownership, transfers, and allowances. These must be supported | ||
as is by all CW721 contracts. Note that all tokens must have an owner, | ||
as well as an ID. The ID is an arbitrary string, unique within the contract. | ||
|
||
### Messages | ||
|
||
`TransferNft{recipient, token_id}` - | ||
This transfers ownership of the token to `recipient` account. This is | ||
designed to send to an address controlled by a private key and *does not* | ||
trigger any actions on the recipient if it is a contract. | ||
|
||
Requires `token_id` to point to a valid token, and `env.sender` to be | ||
the owner of it, or have an allowance to transfer it. | ||
|
||
`SendNft{contract, token_id, msg}` - | ||
This transfers ownership of the token to `contract` account. `contract` | ||
must be an address controlled by a smart contract, which implements | ||
the CW721Receiver interface. The `msg` will be passed to the recipient | ||
contract, along with the token_id. | ||
|
||
Requires `token_id` to point to a valid token, and `env.sender` to be | ||
the owner of it, or have an allowance to transfer it. | ||
|
||
`Approve{spender, token_id, expires}` - Grants permission to `spender` to | ||
transfer or send the given token. This can only be performed when | ||
`env.sender` is the owner of the given `token_id` or an `operator`. | ||
There can multiple spender accounts per token, and they are cleared once | ||
the token is transfered or sent. | ||
|
||
`Revoke{spender, token_id}` - This revokes a previously granted permission | ||
to transfer the given `token_id`. This can only be granted when | ||
`env.sender` is the owner of the given `token_id` or an `operator`. | ||
|
||
`ApproveAll{operator, expires}` - Grant `operator` permission to transfer or send | ||
all tokens owned by `env.sender`. This approval is tied to the owner, not the | ||
tokens and applies to any future token that the owner receives as well. | ||
|
||
`RevokeAll{operator}` - Revoke a previous `ApproveAll` permission granted | ||
to the given `operator`. | ||
|
||
### Queries | ||
|
||
`OwnerOf{token_id}` - Returns the owner of the given token, | ||
as well as anyone with approval on this particular token. | ||
If the token is unknown, returns an error. Return type is | ||
`OwnerResponse{owner}`. | ||
|
||
ethanfrey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
`ApprovedForAll{owner}` - List all operators that can access all of | ||
the owner's tokens. Return type is `ApprovedForAllResponse` | ||
|
||
`NumTokens{}` - Total number of tokens issued | ||
|
||
### Receiver | ||
|
||
The counter-part to `SendNft` is `ReceiveNft`, which must be implemented by | ||
any contract that wishes to manage CW721 tokens. This is generally *not* | ||
implemented by any CW721 contract. | ||
|
||
`ReceiveNft{sender, token_id, msg}` - This is designed to handle `SendNft` | ||
messages. The address of the contract is stored in `env.sender` | ||
so it cannot be faked. The contract should ensure the sender matches | ||
the token contract it expects to handle, and not allow arbitrary addresses. | ||
|
||
The `sender` is the original account requesting to move the token | ||
and `msg` is a `Binary` data that can be decoded into a contract-specific | ||
message. This can be empty if we have only one default action, | ||
or it may be a `ReceiveMsg` variant to clarify the intention. For example, | ||
if I send to an exchange, I can specify the price I want to list the token | ||
for. | ||
|
||
## Metadata | ||
|
||
### Queries | ||
|
||
`ContractInfo{}` - This returns top-level metadata about the contract. | ||
Namely, `name` and `symbol`. | ||
|
||
`NftInfo{token_id}` - This returns metadata about one particular token. | ||
The return value is based on *ERC721 Metadata JSON Schema*, but directly | ||
from the contract, not as a Uri. Only the image link is a Uri. | ||
|
||
`AllNftInfo{token_id}` - This returns the result of both `NftInfo` | ||
and `OwnerOf` as one query as an optimization for clients, which may | ||
want both info to display one NFT. | ||
|
||
## Enumerable | ||
|
||
### Queries | ||
|
||
Pagination is acheived via `start_after` and `limit`. Limit is a request | ||
set by the client, if unset, the contract will automatically set it to | ||
`DefaultLimit` (suggested 10). If set, it will be used up to a `MaxLimit` | ||
value (suggested 30). Contracts can define other `DefaultLimit` and `MaxLimit` | ||
values without violating the CW721 spec, and clients should not rely on | ||
any particular values. | ||
|
||
If `start_after` is unset, the query returns the first results, ordered by | ||
lexogaphically by `token_id`. If `start_after` is set, then it returns the | ||
first `limit` tokens *after* the given one. This allows straight-forward | ||
pagination by taking the last result returned (a `token_id`) and using it | ||
as the `start_after` value in a future query. | ||
|
||
`Tokens{owner, start_after, limit}` - List all token_ids that belong to a given owner. | ||
Return type is `TokensResponse{tokens: Vec<token_id>}`. | ||
|
||
`AllTokens{start_after, limit}` - Requires pagination. Lists all token_ids controlled by | ||
the contract. |
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,28 @@ | ||
use std::env::current_dir; | ||
use std::fs::create_dir_all; | ||
|
||
use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; | ||
|
||
use cw721::{ | ||
AllNftInfoResponse, ApprovedForAllResponse, ContractInfoResponse, Cw721HandleMsg, | ||
Cw721QueryMsg, Cw721ReceiveMsg, NftInfoResponse, NumTokensResponse, OwnerOfResponse, | ||
TokensResponse, | ||
}; | ||
|
||
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!(Cw721HandleMsg), &out_dir); | ||
export_schema(&schema_for!(Cw721QueryMsg), &out_dir); | ||
export_schema(&schema_for!(Cw721ReceiveMsg), &out_dir); | ||
export_schema(&schema_for!(AllNftInfoResponse), &out_dir); | ||
export_schema(&schema_for!(ApprovedForAllResponse), &out_dir); | ||
export_schema(&schema_for!(ContractInfoResponse), &out_dir); | ||
export_schema(&schema_for!(OwnerOfResponse), &out_dir); | ||
export_schema(&schema_for!(NftInfoResponse), &out_dir); | ||
export_schema(&schema_for!(NumTokensResponse), &out_dir); | ||
export_schema(&schema_for!(TokensResponse), &out_dir); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can
ApproveAll
be given to more than one operator at once?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, any number. Again taken from her 721 specs. Not sure why this is unlimited and approval is limited