Skip to content

Commit

Permalink
fix: adjust mt_transfer* and mt_resolve to provide granular resolution
Browse files Browse the repository at this point in the history
Prior to this fix, we had singular representation for token_ids that
may have many owners. There was no way to resolve approvals for those
types of tokens, typically ft style tokens.

This change links together the owners of the accounts to the ft. So
when an approval occurs we can resolve which account to transfer the
tokens from as well as handle resolution of transfer failures from
a singular token id with many owners.
  • Loading branch information
zcstarr committed Mar 31, 2022
1 parent d030776 commit d413ca3
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 39 deletions.
65 changes: 45 additions & 20 deletions neps/nep-0245.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
NEP: 245
Title: Multi Token Standard
Author: Zane Starr <[email protected]>, @riqi, @marcos.sun
Author: Zane Starr <[email protected]>, @riqi, @jriemann, @marcos.sun
DiscussionsTo: https://github.com/near/NEPs/discussions/246
Status: Draft
Type: Standards Track
Expand Down Expand Up @@ -92,9 +92,11 @@ type Token = {
// * `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
// * `approval_id`: expected approval ID. A number smaller than
// * `approval` (optional): is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer

Expand All @@ -103,7 +105,7 @@ function mt_transfer(
receiver_id: string,
token_id: string,
amount: string,
approval_id: number|null,
approval: [owner_id: string, approval_id: number]|null,
memo: string|null,
) {}

Expand All @@ -128,10 +130,14 @@ function mt_transfer(
// * `amounts`: the number of tokens to transfer, wrapped in quotes and treated
// like an array of strings, although the numbers will be stored as an array of unsigned integer
// with 128 bits.
// * `approval_ids`: expected approval IDs per `token_ids`. If a `token_id` does
// not have a corresponding approval id then the entry in the array must be marked null.
// The `approval_ids` are numbers smaller than 2^53, and therefore representable as JSON.
// See Approval Management standard for full explanation.
// * `approvals` (optional): is an array of expected `approval` per `token_ids`.
// If a `token_id` does not have a corresponding `approval` then the entry in the array
// must be marked null.
// `approval` is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer

Expand All @@ -140,7 +146,7 @@ function mt_batch_transfer(
receiver_id: string,
token_ids: string[],
amounts: string[],
approval_ids: (number | null)[] | null,
approvals: ([owner_id: string, approval_id: number]| null)[]| null,
memo: string|null,
) {}

Expand Down Expand Up @@ -174,9 +180,11 @@ function mt_batch_transfer(
// * `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
// * `approval_id`: expected approval ID. A number smaller than
// * `owner_id`: the valid NEAR account that owns the token
// * `approval` (optional): is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer.
// * `msg`: specifies information needed by the receiving contract in
Expand All @@ -188,7 +196,7 @@ function mt_transfer_call(
receiver_id: string,
token_id: string,
amount: string,
approval_id: number|null,
approval: [owner_id: string, approval_id: number]|null,
memo: string|null,
msg: string,
): Promise {}
Expand Down Expand Up @@ -226,10 +234,14 @@ function mt_transfer_call(
// * `amounts`: the number of tokens to transfer, wrapped in quotes and treated
// like an array of string, although the numbers will be stored as an array of
// unsigned integer with 128 bits.
// * `approval_ids`: expected approval IDs per `token_ids`. If a `token_id` does
// not have a corresponding approval id then the entry in the array must be marked null.
// The `approval_ids` are numbers smaller than 2^53, and therefore representable as JSON.
// ApprovalId See Approval Management standard for full explanation.
// * `approvals` (optional): is an array of expected `approval` per `token_ids`.
// If a `token_id` does not have a corresponding `approval` then the entry in the array
// must be marked null.
// `approval` is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer.
// * `msg`: specifies information needed by the receiving contract in
Expand All @@ -241,7 +253,7 @@ function mt_batch_transfer_call(
receiver_id: string,
token_ids: string[],
amounts: string[],
approval_ids: (number|null)[] | null,
approvals: ([owner_id: string, approval_id: number]|null)[] | null,
memo: string|null,
msg: string,
): Promise {}
Expand Down Expand Up @@ -307,9 +319,22 @@ The following behavior is required, but contract authors may name this function
// * `receiver_id`: the `receiver_id` argument given to `mt_transfer_call`
// * `token_ids`: the `token_ids` argument given to `mt_transfer_call`
// * `amounts`: the `token_ids` argument given to `mt_transfer_call`
// * `approved_token_ids`: if using Approval Management, contract MUST provide
// set of original approved accounts in this argument, and restore these
// * `approvals (optional)`: if using Approval Management, contract MUST provide
// set of original approvals in this argument, and restore the
// approved accounts in case of revert.
// `approvals` is an array of expected `approval_list` per `token_ids`.
// If a `token_id` does not have a corresponding `approvals_list` then the entry in the
// array must be marked null.
// `approvals_list` is an array of triplets of [`owner_id`,`approval_id`,`amount`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
//
//
//
// Returns total amount spent by the `receiver_id`, corresponding to the `token_id`.
// The amounts returned, though wrapped in quotes and treated like strings,
Expand All @@ -323,7 +348,7 @@ function mt_resolve_transfer(
sender_id: string,
receiver_id: string,
token_ids: string[],
approved_account_ids: (null | string[])[] | null,
approvals: (null | [owner_id: string, approval_id: number, amount: string][]) []| null
):string[] {}
```

Expand Down
64 changes: 45 additions & 19 deletions specs/Standards/MultiToken/Core.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type Token = {
owner_id: string | null
}


/******************/
/* CHANGE METHODS */
/******************/
Expand All @@ -83,9 +84,11 @@ type Token = {
// * `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
// * `approval_id`: expected approval ID. A number smaller than
// * `approval` (optional): is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer

Expand All @@ -94,7 +97,7 @@ function mt_transfer(
receiver_id: string,
token_id: string,
amount: string,
approval_id: number|null,
approval: [owner_id: string, approval_id: number]|null,
memo: string|null,
) {}

Expand All @@ -119,10 +122,14 @@ function mt_transfer(
// * `amounts`: the number of tokens to transfer, wrapped in quotes and treated
// like an array of strings, although the numbers will be stored as an array of unsigned integer
// with 128 bits.
// * `approval_ids`: expected approval IDs per `token_ids`. If a `token_id` does
// not have a corresponding approval id then the entry in the array must be marked null.
// The `approval_ids` are numbers smaller than 2^53, and therefore representable as JSON.
// See Approval Management standard for full explanation.
// * `approvals` (optional): is an array of expected `approval` per `token_ids`.
// If a `token_id` does not have a corresponding `approval` then the entry in the array
// must be marked null.
// `approval` is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer

Expand All @@ -131,7 +138,7 @@ function mt_batch_transfer(
receiver_id: string,
token_ids: string[],
amounts: string[],
approval_ids: (number | null)[] | null,
approvals: ([owner_id: string, approval_id: number]| null)[]| null,
memo: string|null,
) {}

Expand Down Expand Up @@ -165,9 +172,11 @@ function mt_batch_transfer(
// * `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
// * `approval_id`: expected approval ID. A number smaller than
// * `owner_id`: the valid NEAR account that owns the token
// * `approval` (optional): is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer.
// * `msg`: specifies information needed by the receiving contract in
Expand All @@ -179,7 +188,7 @@ function mt_transfer_call(
receiver_id: string,
token_id: string,
amount: string,
approval_id: number|null,
approval: [owner_id: string, approval_id: number]|null,
memo: string|null,
msg: string,
): Promise {}
Expand Down Expand Up @@ -217,10 +226,14 @@ function mt_transfer_call(
// * `amounts`: the number of tokens to transfer, wrapped in quotes and treated
// like an array of string, although the numbers will be stored as an array of
// unsigned integer with 128 bits.
// * `approval_ids`: expected approval IDs per `token_ids`. If a `token_id` does
// not have a corresponding approval id then the entry in the array must be marked null.
// The `approval_ids` are numbers smaller than 2^53, and therefore representable as JSON.
// ApprovalId See Approval Management standard for full explanation.
// * `approvals` (optional): is an array of expected `approval` per `token_ids`.
// If a `token_id` does not have a corresponding `approval` then the entry in the array
// must be marked null.
// `approval` is a tuple of [`owner_id`,`approval_id`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// * `memo` (optional): for use cases that may benefit from indexing or
// providing information for a transfer.
// * `msg`: specifies information needed by the receiving contract in
Expand All @@ -232,7 +245,7 @@ function mt_batch_transfer_call(
receiver_id: string,
token_ids: string[],
amounts: string[],
approval_ids: (number|null)[] | null,
approvals: ([owner_id: string, approval_id: number]|null)[] | null,
memo: string|null,
msg: string,
): Promise {}
Expand Down Expand Up @@ -298,9 +311,22 @@ The following behavior is required, but contract authors may name this function
// * `receiver_id`: the `receiver_id` argument given to `mt_transfer_call`
// * `token_ids`: the `token_ids` argument given to `mt_transfer_call`
// * `amounts`: the `token_ids` argument given to `mt_transfer_call`
// * `approved_token_ids`: if using Approval Management, contract MUST provide
// set of original approved accounts in this argument, and restore these
// * `approvals (optional)`: if using Approval Management, contract MUST provide
// set of original approvals in this argument, and restore the
// approved accounts in case of revert.
// `approvals` is an array of expected `approval_list` per `token_ids`.
// If a `token_id` does not have a corresponding `approvals_list` then the entry in the
// array must be marked null.
// `approvals_list` is an array of triplets of [`owner_id`,`approval_id`,`amount`].
// `owner_id` is the valid Near account that owns the tokens.
// `approval_id` is the expected approval ID. A number smaller than
// 2^53, and therefore representable as JSON. See Approval Management
// standard for full explanation.
// `amount`: the number of tokens to transfer, wrapped in quotes and treated
// like a string, although the number will be stored as an unsigned integer
// with 128 bits.
//
//
//
// Returns total amount spent by the `receiver_id`, corresponding to the `token_id`.
// The amounts returned, though wrapped in quotes and treated like strings,
Expand All @@ -314,7 +340,7 @@ function mt_resolve_transfer(
sender_id: string,
receiver_id: string,
token_ids: string[],
approved_account_ids: (null | string[])[] | null,
approvals: (null | [owner_id: string, approval_id: number, amount: string][]) []| null
):string[] {}
```

Expand Down

0 comments on commit d413ca3

Please sign in to comment.