The XLS-20 standard for NFTs has a preliminary implementation that can be used in test networks, but is not yet available as an amendment to the XRP Ledger protocol. An amendment may be included in a future XRP Ledger release.

The NFTokenPage object represents a collection of NFToken objects owned by the same account. An account can have multiple NFTokenPage ledger objects, which form a doubly-linked list (DLL).

Example NFTokenPage JSON

    "LedgerEntryType": "NFTokenPage",
            /* potentially more objects */

In the interest of minimizing the size of a page and optimizing storage, the Owner field is not present, since it is encoded as part of the object's ledger identifier.

NFTokenPage Fields

An NFTokenPage object can have the following required and optional fields:

Field Name Required? JSON Type Internal Type Description
LedgerEntryType Yes string UInt16 Identifies the type of ledger object. The reserved ledger entry type is 0x0050.
PreviousPageMin No string Hash256 The locator of the previous page, if any. Details about this field and how it should be used are outlined below, after the construction of the NFTokenPageID is explained.
NextPageMin No string Hash256 The locator of the next page, if any. Details about this field and how it should be used are outlined below, after the construction of the NFTokenPageID is explained.
PreviousTxnID No string HASH256 Identifies the transaction ID of the transaction that most recently modified this NFTokenPage object.
PreviousTxnLgrSeq No number UInt32 The sequence of the ledger that contains the transaction that most recently modified this NFTokenPage object.
NonFungibleTokens Yes object TOKEN The collection of NFToken objects contained in this NFTokenPage object. This specification places an upper bound of 32 NFToken objects per page. Objects should be stored in sorted order, from low to high with the TokenID used as the sorting parameter.

TokenPage ID Format

NFTokenPage identifiers are constructed so as to specifically allow for the adoption of a more efficient paging structure, ideally suited for NFTokens.

The identifier of an NFTokenPage is derived by concatenating the 160-bit AccountID of the owner of the page, followed by a 96 bit value that indicates whether a particular TokenID can be contained in this page.

More specifically, and assuming that the function low96(x) returns the low 96 bits of a 256-bit value, an NFT with TokenID A can be included in a page with NFTokenPageID B if and only if low96(A) >= low96(B).

For example, applying the low96 function to the NFT described before, which had an ID of 000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65 the function low96 would return 42540EE208C3098E00000D65.

This curious construct exploits the structure of the SHAMap to allow for efficient lookups of individual NFToken objects without requiring iteration of the doubly-linked list of NFTokenPages.

Searching for an NFToken object

To search for a specific NFToken, compute the NFTokenPageID using the account of the owner and the TokenID of the token, as described above. Search for a ledger entry where the identifier is less than or equal to that value. If that entry does not exist or is not an NFTokenPage, the NFToken is not held by the given account.

Adding an NFToken object

You add an NFToken object by finding the NFTokenPage it should be in (using the same technique as searching for an NFToken object) and adding it to that page. If the page overflows after you add the NFToken, find the next and previous pages (if any) and balance those three pages, inserting a new page as needed.

Removing an NFToken object

An NFToken can be removed by using the same approach. If the number of NFTokens in the page goes below a certain threshold, the server attempts to consolidate the page with a previous or subsequent page to recover the reserve.

Reserve for NFTokenPage object

Each NFTokenPage costs an incremental reserve to the owner account. This specification allows up to 32 NFToken entries per page, which means that for accounts that hold multiple NFTs the effective reserve cost per NFT can be as low as R/32 where R is the incremental reserve.

The reserve in practice

The value of the incremental reserve is, as of this writing, 2 XRP. The table below shows what the effective reserve per token is, if a given page contains 1, 8, 16, 32 and 64 NFTs.

Incremental Reserve 1 NFT 8 NFTs 16 NFTs 32 NFTs 64 NFTs
5 XRP 5 XRP 0.625 XRP 0.3125 XRP 0.15625 XRP 0.07812 XRP
2 XRP 2 XRP 0.25 XRP 0.125 XRP 0.0625 XRP 0.03125 XRP
1 XRP 1 XRP 0.125 XRP 0.0625 XRP 0.03125 XRP 0.01562 XRP