-
Notifications
You must be signed in to change notification settings - Fork 148
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
feat: add NFT mint/transfer/burn event standard #256
Changes from 14 commits
f9a0885
ecc0d62
8d8af42
f260197
6c68eaa
e8d9a70
285003e
4f54dee
d6ec110
1dcc59f
2bb7941
67660a7
f27284b
bfb082a
a7222af
76655a0
d00daef
6d7d8d4
02b4e3d
b99596d
4dfbd6e
a544365
ebd8412
b3dbea3
e3c7f2a
4de0431
947e575
ab02604
6fafebd
77cb81c
45c6dbe
ad4c8c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Non-Fungible Token Event | ||
|
||
Version `1.0.0` | ||
|
||
## Summary | ||
|
||
Standard interfaces for NFT contract actions. | ||
|
||
## Motivation | ||
|
||
NFT-driven apps such as marketplaces regularly perform many | ||
of the same actions such as `minting`, `burning` and `transferring`. | ||
Each app have their own way of performing these actions and it | ||
is difficult to consistently capture these events. | ||
This extension addresses that. | ||
|
||
For example, it's common in NFT marketplaces to have | ||
different methods of transfer a single token vs many | ||
tokens. Other applications like wallets, will have | ||
a difficult time tracking consistently this information for many | ||
markets. This makes interactive with many NFT-driven apps | ||
infeasible. | ||
|
||
Due to discussions here | ||
https://github.com/near/NEPs/issues/254, | ||
a standard way to capture these events is needed. | ||
|
||
## Interface | ||
|
||
Many apps may use different mechanisms to perform their batching | ||
requirements. This interface standardizes this process by capturing | ||
events of these activities through logs. | ||
|
||
```ts | ||
// Interface to capture an event | ||
// and return formatted event string. | ||
interface EventJsonLog { | ||
// Takes `EventLogData` and returns | ||
// `EVENT_JSON: <EVENT_LOG_DATA>` | ||
(e:EventLogData):string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's important to mention here that string representation of json should not contain line breaks (Ideally: get rid of all space symbols unless they are in string fields). When Indexer parses these lines, for each line, it just cuts off "EVENT_JSON:", trims everything else, and passes the result into json parsing library. If you pass
It will give an error because there are 3 lines instead of 1, where the first line contains invalid json, second and third lines do not start from "EVENT_JSON:". We also need to decide, are we OK with other messages here (without "EVENT_JSON:" at the beginning). We need to say explicitly in the NEP, whether we ignore or restrict them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we sure that we don't want to put everything into json with the structure like
? It simplifies everything, we don't need to overcomplicate this doc, Indexer does not need the logic with cutting/trimming. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @telezhnaya Individual calls to Proof: https://explorer.testnet.near.org/transactions/326HmzvgRYND7skVCdTpCnHMji6qiU8JFhQMNuvS2b74 Contract: use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::{near_bindgen, setup_alloc};
setup_alloc!();
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, Default)]
pub struct Test {}
#[near_bindgen]
impl Test {
pub fn test_log(&mut self) {
near_sdk::env::log(r#"EVENT_JSON:{
"standard": "nep",
"version": "1.0.0",
"event": "mint",
"data": [
{"owner_id": "frol.near", "token_ids": ["house"]}
]
}"#.as_bytes());
near_sdk::env::log("EVENT_JSON:{\"standard\": \"nep\", \n \"version\": \"1.0.0\", \n \"event\": \"burn\", \"data\": [{\"owner_id\": \"frol.near\", \"token_ids\": [\"house\"]}]}".as_bytes());
}
} |
||
} | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
|
||
// Interface to capture data | ||
// about an event | ||
// Arguments | ||
// * `standard`: name of standard e.g. nep171 | ||
// * `version`: e.g. 1.0.0 | ||
// * `event`: `nft_mint` | `nft_burn` | `nft_transfer` | ||
// * `data`: associate event data | ||
interface EventLogData { | ||
standard:string, | ||
version:string, | ||
event:string, | ||
data: NftMintLog[]|NftTransferLog[]|NftBurnLog | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// An event log to capture token minting | ||
// Arguments | ||
// * `account_id`: "account.near" | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
// * `token_id`: "1" | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
interface NftMintLog { | ||
owner_id:string, | ||
token_id:string | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// An event log to capture token burning | ||
// Arguments | ||
// * `owner_id`: owner of tokens to burn | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
// * `token_ids`: ["1","2"] | ||
interface NftBurnLog { | ||
owner_id:string, | ||
token_ids:string[] | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// An event log to capture token transfer | ||
// Arguments | ||
// * `sender_id`: "account.near" | ||
// * `receiver_id`: "receiver.near" | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
// * `token_id`: "12345abc" | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
interface NftTransferLog { | ||
sender_id:string, | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
receiver_id:string, | ||
token_id:string | ||
} | ||
``` | ||
|
||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
## Further methods | ||
|
||
Note that the example events covered above cover two different kinds of events: | ||
1. Events that are not specified in the NFT Standard (`nft_mint`, `nft_burn`) | ||
2. An event that is covered in the [NFT Core Standard](https://nomicon.io/Standards/NonFungibleToken/Core.html#nft-interface). | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
|
||
This event standard also applies beyond the three events highlighted here, where future events follow the same convention of as the second type. For instance, if an NFT contract uses the [approval management standard](https://nomicon.io/Standards/NonFungibleToken/ApprovalManagement.html), it may emit an event for `nft_approve` if that's deemed as important by the developer community. | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
|
||
Please feel free to open pull requests for extending the events standard detailed here as needs arise. | ||
## Drawbacks | ||
|
||
There is a known limitation of 16kb strings when capturing logs. | ||
This can be observed from `token_ids` that may vary in length | ||
for different apps so the amount of logs that can | ||
be executed may vary. |
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.
It's better to write one sentence per line
https://asciidoctor.org/docs/asciidoc-recommended-practices/#one-sentence-per-line
near/core-contracts#144 (comment)
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.
Even though I like the ascii docs I don't agree here because in markdown a line break continues a paragraph which helps word wrapping. Asciidocs are not a standard that governs markdown files. To comply I will update.
If this is the standard of NEPs can we make it official.