Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: Multi Token Standard Contract [NEP] #245

Merged
merged 108 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from 107 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
e01a2fc
feat: initial work for an emerging multi token standard
zcstarr Jul 28, 2021
d13899f
chore: wrong issue link
zcstarr Jul 28, 2021
e5c00d9
chore: fix example comment on metadata
zcstarr Jul 30, 2021
f1609fc
fix: add missing memo field to guide level entry for batch transfer
zcstarr Aug 10, 2021
f384184
fix: add missing memo field to guide level entry for transfer
zcstarr Aug 10, 2021
d744486
fix: consolidate batch versions of balance_of and balance_bounds
zcstarr Aug 10, 2021
987eb81
feat: add decimals to the contract to support tokens with precision reqs
zcstarr Aug 10, 2021
4390c5c
fix: This refactors metadata to be one token metadata.
zcstarr Aug 18, 2021
c059657
feat: add answers to the unresolved questions in the NEP
zcstarr Aug 18, 2021
6a258f8
fix: missing mt prefix from balance and suppky methods
zcstarr Sep 3, 2021
4af4107
chore: typo correction
zcstarr Sep 3, 2021
fa4cd9d
chore: typo correction
zcstarr Sep 3, 2021
4c821ae
fix: this makes symbol optional to be more in alignment with the
zcstarr Sep 3, 2021
3ea9de1
fix: add verson information at the top
zcstarr Sep 9, 2021
85643b2
fix: remove gnr8 example doesn't adhere to standard
zcstarr Sep 9, 2021
20c3ad6
chore: typo correction
zcstarr Sep 10, 2021
36ada8c
chore: consistency of layout
zcstarr Sep 10, 2021
a41e551
chore: lint typo
zcstarr Sep 10, 2021
677cc74
chore: correct wording to make things more clear
zcstarr Sep 10, 2021
f5d7631
chore: tidy
zcstarr Sep 10, 2021
caee79b
chore: tidy and clarify
zcstarr Sep 10, 2021
96f6188
chore: typo correction and tidy
zcstarr Sep 10, 2021
08f0adc
chore: lint correction
zcstarr Sep 10, 2021
3519b34
chore: tidy
zcstarr Sep 10, 2021
567dfe6
chore: typo correction
zcstarr Sep 10, 2021
d2501f2
chore: clarify
zcstarr Sep 10, 2021
8dafe7c
chore: lint tidy
zcstarr Sep 10, 2021
5be2439
fix: refactor to full spec naming
zcstarr Sep 10, 2021
6697f42
fix: refactor to full spec naming
zcstarr Sep 10, 2021
eb0b7da
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
c090e46
fix: refactor to full spec naming
zcstarr Sep 10, 2021
a2ce801
fix: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
90d5605
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
ddda893
chore: refactor to full spec naming
zcstarr Sep 10, 2021
9ae02d7
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
00bb5cf
chore: refactor to full spec naming
zcstarr Sep 10, 2021
65cbea1
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
95b4b01
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
a9d2afc
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
97f29ce
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
15d87ff
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
7061c20
chore: refactor to full spec naming and tidy
zcstarr Sep 10, 2021
7c5210a
chore: tidy
zcstarr Sep 10, 2021
913f58c
chore: clarification
zcstarr Sep 10, 2021
133381a
chore: typo correction
zcstarr Sep 13, 2021
9a53499
feat: add an approval management standard proposal for discussion
zcstarr Sep 13, 2021
46ae3b3
chore: clarify guide level explanation of balance
zcstarr Sep 14, 2021
6bae0ec
chore: clarify guide level explanation of supply
zcstarr Sep 14, 2021
6d73586
chore: clarify transfer tokens guide-level explanation
zcstarr Sep 14, 2021
9208acf
chore: reorder key for guide-level explanation
zcstarr Sep 14, 2021
917894a
chore: add missing comments for balance_bounds and balance_of
zcstarr Sep 15, 2021
aa3f085
fix: update standard to only support approvals by specific id
zcstarr Sep 15, 2021
04f5a41
feat: refactor and add approval management back into the spec
zcstarr Sep 16, 2021
2e56a4d
chore: tidy
zcstarr Sep 17, 2021
799f5bc
fix: refactor metadata to split out metadata into it's own md
zcstarr Sep 23, 2021
0339e58
feat: add enumeration standard to multi token standard
zcstarr Sep 23, 2021
c148a83
chore: fix typos
zcstarr Sep 28, 2021
d5e0752
fix: add MT prefixed datastructure descritpion and mt_prefixed methods
zcstarr Sep 28, 2021
90451e3
fix: refactor to have MT and mt_metadata prefixes and describe new MT…
zcstarr Sep 28, 2021
561ba59
chore: fix typos
zcstarr Sep 28, 2021
77ada21
fix: refactor Core description into typescript
zcstarr Sep 28, 2021
4a6c164
chore: fix typos and lint
zcstarr Sep 28, 2021
e583a5b
chore: lint and fix typos
zcstarr Sep 29, 2021
585dbc9
fix: add support for mt_tokens
zcstarr Sep 29, 2021
d1c58a3
chore: fix typo and lint
zcstarr Sep 29, 2021
bf162c5
fix: typos and lint
zcstarr Sep 29, 2021
b290fc8
feat: add event spec for mt
zcstarr Sep 29, 2021
08e244a
fix: refactor README to match other standards
zcstarr Sep 29, 2021
6fdf26c
chore: lint, tidy, and typo correction to core
zcstarr Oct 1, 2021
9b4fc8f
chore: fix typos with enumeration
zcstarr Oct 1, 2021
42d0e3b
chore: typos, lint, and tidy with approval management
zcstarr Oct 1, 2021
b29ddca
chore: refactor naming consistency , typo, lint with events
zcstarr Oct 1, 2021
791e5ec
chore: refactor to match event description
zcstarr Oct 1, 2021
44ee2a9
chore: typos and lint with metadata
zcstarr Oct 1, 2021
35a610a
chore: rm dead code for mt_approvals
zcstarr Oct 1, 2021
49a356e
chore: comment argument order matches impl order
zcstarr Oct 1, 2021
23b8c0a
chore: reorder comments to match impl args
zcstarr Oct 1, 2021
46365af
chore: rm duplicate event description
zcstarr Oct 1, 2021
025d5e9
fix: adjust consistency between standards for mt_tokens
zcstarr Oct 1, 2021
807aa0e
chore: fix comments referencing Token and MTBaseTokenMetadata
zcstarr Oct 1, 2021
4d9a8a5
chore: consistent spacing between metadata fields
zcstarr Oct 1, 2021
3849190
chore: newline
zcstarr Oct 1, 2021
8dc2bc9
fix: refactor events to match NFT events per standard spec
zcstarr Oct 26, 2021
dc57e04
chore: fix link consistency within markdown
zcstarr Nov 2, 2021
1adf7b6
fix: token_ids to be an array for batch_balance_of
zcstarr Nov 2, 2021
37940cd
fix: confusing comment on the return for mt_resolve_transfer
zcstarr Nov 2, 2021
5422f18
chore: remove misleading comment from transfer methods
zcstarr Nov 2, 2021
e2a2385
fix: base_by_metadata_id should return array
zcstarr Nov 2, 2021
f9c5c9d
feat: add rationale section to further clarify decisions
zcstarr Dec 3, 2021
6f32cd3
chore: tidy account to account_id
zcstarr Dec 16, 2021
f1a91b9
chore: reword rationale to be more clear and less broad and more spec…
zcstarr Dec 15, 2021
d3c77b4
chore: bring clarity to token type explanation
zcstarr Dec 16, 2021
c8af57e
fix: add additional examples of authorized_id and clarify account_id
zcstarr Dec 16, 2021
6c93dd1
fix: align mt standard wth nft standard ref/ event standard
zcstarr Feb 4, 2022
cecb1a2
fix: update approvals to approved_account_ids to match other specs
zcstarr Mar 22, 2022
fce6f7d
fix: update specs to use token_id vs. id to align with other specs
zcstarr Mar 22, 2022
7a1f8b2
fix: add new summary format for mt token spec
zcstarr Mar 28, 2022
9d9d00a
chore: refactor nep from 246 to 245
zcstarr Mar 29, 2022
414fdcd
chore: set status to draft
zcstarr Mar 29, 2022
dcbb0ed
fix: refactor approvals to be iterative, vs included in Token.
zcstarr Mar 30, 2022
d030776
fix: add approval view logic for singular request
zcstarr Mar 30, 2022
d413ca3
fix: adjust mt_transfer* and mt_resolve to provide granular resolution
zcstarr Mar 31, 2022
c8a856e
fix: add summary listing to main readme
zcstarr Mar 31, 2022
65af2d1
fix: refactor approval owner_id to approval_owner_id
zcstarr Mar 31, 2022
86de2f8
fix: add reference current reference implementation locations
zcstarr Mar 31, 2022
2568f90
chore: add caution warning label to specification
zcstarr Apr 2, 2022
c7c9d14
chore: update links to latest reference implementation
zcstarr Apr 2, 2022
763b7d6
chore: correct typos
zcstarr Apr 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Changes to the protocol specification and standards are called NEAR Enhancement
|[0178](https://github.com/near/NEPs/blob/master/neps/nep-0178.md) | Non Fungible Token Approval Management | @chadoh @thor314 | Final |
|[0181](https://github.com/near/NEPs/blob/master/neps/nep-0181.md) | Non Fungible Token Enumeration | @chadoh @thor314 | Final |
|[0199](https://github.com/near/NEPs/blob/master/neps/nep-0199.md) | Non Fungible Token Royalties and Payouts | @thor314 @mattlockyer | Final |
|[0245](https://github.com/near/NEPs/blob/master/neps/nep-0245.md) | Multi Token Standard | @zcstarr @riqi @jriemann @marcos.sun | Draft |
|[0297](https://github.com/near/NEPs/blob/master/neps/nep-0297.md) | Contract Events Standard | @telezhnaya | Final |
|[0330](https://github.com/near/NEPs/blob/master/neps/nep-0330.md) | Contract Metadata | @BenKurrek | Review |

Expand Down
583 changes: 583 additions & 0 deletions neps/nep-0245.md

Large diffs are not rendered by default.

503 changes: 503 additions & 0 deletions specs/Standards/MultiToken/ApprovalManagement.md

Large diffs are not rendered by default.

399 changes: 399 additions & 0 deletions specs/Standards/MultiToken/Core.md

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions specs/Standards/MultiToken/Enumeration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Multi Token Enumeration([NEP-245](https://github.com/near/NEPs/discussions/246))
zcstarr marked this conversation as resolved.
Show resolved Hide resolved

:::caution
This is part of the proposed spec [NEP-245](https://github.com/near/NEPs/blob/master/neps/nep-0245.md) and is subject to change.
:::

Version `1.0.0`

## Summary

Standard interfaces for counting & fetching tokens, for an entire Multi Token contract or for a given owner.

## Motivation

Apps such as marketplaces and wallets need a way to show all tokens owned by a given account and to show statistics about all tokens for a given contract. This extension provides a standard way to do so.

While some Multi Token contracts may forego this extension to save [storage] costs, this requires apps to have custom off-chain indexing layers. This makes it harder for apps to integrate with such Multi Token contracts. Apps which integrate only with Multi Token Standards that use the Enumeration extension do not even need a server-side component at all, since they can retrieve all information they need directly from the blockchain.

Prior art:

- [ERC-721]'s enumeration extension
- [Non Fungible Token Standard's](../NonFungibleToken/Enumeration.md) enumeration extension

## Interface

The contract must implement the following view methods:

// Metadata field is optional if metadata extension is implemented. Includes the base token metadata id and the token_metadata object, that represents the token specific metadata.

```ts
// Get a list of all tokens
//
// Arguments:
// * `from_index`: a string representing an unsigned 128-bit integer,
// representing the starting index of tokens to return
// * `limit`: the maximum number of tokens to return
//
// Returns an array of `Token` objects, as described in the Core standard,
// and an empty array if there are no tokens
function mt_tokens(
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
from_index: string|null, // default: "0"
limit: number|null, // default: unlimited (could fail due to gas limit)
): Token[] {}

// Get list of all tokens owned by a given account
//
// Arguments:
// * `account_id`: a valid NEAR account
// * `from_index`: a string representing an unsigned 128-bit integer,
// representing the starting index of tokens to return
// * `limit`: the maximum number of tokens to return
//
// Returns a paginated list of all tokens owned by this account, and an empty array if there are no tokens
function mt_tokens_for_owner(
account_id: string,
from_index: string|null, // default: 0
limit: number|null, // default: unlimited (could fail due to gas limit)
): Token[] {}
```

The contract must implement the following view methods if using metadata extension:

```ts
// Get list of all base metadata for the contract
//
// Arguments:
// * `from_index`: a string representing an unsigned 128-bit integer,
// representing the starting index of tokens to return
// * `limit`: the maximum number of tokens to return
//
// Returns an array of `MTBaseTokenMetadata` objects, as described in the Metadata standard, and an empty array if there are no tokens
function mt_tokens_base_metadata_all(
from_index: string | null,
limit: number | null
): MTBaseTokenMetadata[]
```


## Notes

At the time of this writing, the specialized collections in the `near-sdk` Rust crate are iterable, but not all of them have implemented an `iter_from` solution. There may be efficiency gains for large collections and contract developers are encouraged to test their data structures with a large amount of entries.

[ERC-721]: https://eips.ethereum.org/EIPS/eip-721
[storage]: https://docs.near.org/docs/concepts/storage-staking
187 changes: 187 additions & 0 deletions specs/Standards/MultiToken/Events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# Multi Token Event([NEP-245](https://github.com/near/NEPs/discussions/246))

zcstarr marked this conversation as resolved.
Show resolved Hide resolved
:::caution
This is part of the proposed spec [NEP-245](https://github.com/near/NEPs/blob/master/neps/nep-0245.md) and is subject to change.
:::

Version `1.0.0`

## Summary

Standard interfaces for Multi Token Contract actions.
Extension of [NEP-297](../EventsFormat.md)

## Motivation

NEAR and third-party applications need to track
`mint`, `burn`, `transfer` events for all MT-driven apps consistently. This exension addresses that.

Note that applications, including NEAR Wallet, could require implementing additional methods to display tokens correctly such as [`mt_metadata`](Metadata.md) and [`mt_tokens_for_owner`](Enumeration.md).

## Interface
Multi Token Events MUST have `standard` set to `"nep245"`, standard version set to `"1.0.0"`, `event` value is one of `mt_mint`, `mt_burn`, `mt_transfer`, and `data` must be of one of the following relavant types: `MtMintLog[] | MtBurnLog[] | MtTransferLog[]`:



```ts
interface MtEventLogData {
EVENT_JSON: {
standard: "nep245",
version: "1.0.0",
event: MtEvent,
data: MtMintLog[] | MtBurnLog[] | MtTransferLog[]
}
}
```

```ts
// Minting event log. Emitted when a token is minted/created.
// Requirements
// * Contract MUST emit event when minting a token
// Fields
// * Contract token_ids and amounts MUST be the same length
// * `owner_id`: the account receiving the minted token
// * `token_ids`: the tokens minted
// * `amounts`: the number of tokens minted, wrapped in quotes and treated
// like a string, although the numbers will be stored as an unsigned integer
// array with 128 bits.
// * `memo`: optional message
interface MtMintLog {
owner_id: string,
token_ids: string[],
amounts: string[],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in all other logs:

These arrays should be the same length. Users could mess that up.

I'd prefer to have 1 array of jsons, something like

tokens: [
    {token_id: "1", amount: "5"},
    {token_id: "awesome", amount: "10"},
]

But I guess it's too wordy.
Maybe we can create a third idea of how to work with that in a more elegant way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be a couple of the data. I think that's maybe harder to communicate though.
MtMintLog {
owner_id: string
tokens: [ ["1","5"], ["awesome","10"]]
}

I think in terms of user familiarity with the restrictions, there's already a precedent set from the core implementations, They all have the same restrictions. These restrictions exist in the mirror standard 1155 as well . So users shouldn't be blindsided by it, and in most situations I think they could just pass the data along. 🤔

memo?: string
telezhnaya marked this conversation as resolved.
Show resolved Hide resolved
}

// Burning event log. Emitted when a token is burned.
// Requirements
// * Contract MUST emit event when minting a token
// Fields
// * Contract token_ids and amounts MUST be the same length
// * `owner_id`: the account whose token(s) are being burned
// * `authorized_id`: approved account_id to burn, if applicable
// * `token_ids`: the tokens being burned
// * `amounts`: the number of tokens burned, wrapped in quotes and treated
// like a string, although the numbers will be stored as an unsigned integer
// array with 128 bits.
// * `memo`: optional message
interface MtBurnLog {
owner_id: string,
authorized_id?: string,
token_ids: string[],
amounts: string[],
memo?: string
}

// Transfer event log. Emitted when a token is transfered.
zcstarr marked this conversation as resolved.
Show resolved Hide resolved
// Requirements
// * Contract MUST emit event when transferring a token
// Fields
// * `authorized_id`: approved account_id to transfer
// * `old_owner_id`: the account sending the tokens "sender.near"
// * `new_owner_id`: the account receiving the tokens "receiver.near"
// * `token_ids`: the tokens to transfer
// * `amounts`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the numbers will be stored as an unsigned integer
// array with 128 bits.
interface MtTransferLog {
authorized_id?: string,
old_owner_id: string,
new_owner_id: string,
token_ids: string[],
amounts: string[],
memo?: string
}
```

## Examples

Single owner minting (pretty-formatted for readability purposes):

```js
EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_mint",
"data": [
{"owner_id": "foundation.near", "token_ids": ["aurora", "proximitylabs_ft"], "amounts":["1", "100"]}
]
}
```

Different owners minting:

```js
EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_mint",
"data": [
{"owner_id": "foundation.near", "token_ids": ["aurora", "proximitylabs_ft"], "amounts":["1","100"]},
{"owner_id": "user1.near", "token_ids": ["meme"], "amounts": ["1"]}
]
}
```

Different events (separate log entries):

```js
EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_burn",
"data": [
{"owner_id": "foundation.near", "token_ids": ["aurora", "proximitylabs_ft"], "amounts": ["1","100"]},
]
}
```

Authorized id:

```js
EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_burn",
"data": [
{"owner_id": "foundation.near", "token_ids": ["aurora_alpha", "proximitylabs_ft"], "amounts": ["1","100"], "authorized_id": "thirdparty.near" },
]
}
```

```js
EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_transfer",
"data": [
{"old_owner_id": "user1.near", "new_owner_id": "user2.near", "token_ids": ["meme"], "amounts":["1"], "memo": "have fun!"}
]
}

EVENT_JSON:{
"standard": "nep245",
"version": "1.0.0",
"event": "mt_transfer",
"data": [
{"old_owner_id": "user2.near", "new_owner_id": "user3.near", "token_ids": ["meme"], "amounts":["1"], "authorized_id": "thirdparty.near", "memo": "have fun!"}
]
}
```

zcstarr marked this conversation 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 MT Standard (`mt_mint`, `mt_burn`)
2. An event that is covered in the [Multi Token Core Standard](https://nomicon.io/Standards/MultiToken/Core.html#mt-interface). (`mt_transfer`)

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 MT contract uses the [approval management standard](https://nomicon.io/Standards/MultiToken/ApprovalManagement.html), it may emit an event for `mt_approve` if that's deemed as important by the developer community.

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.
Loading