TZIP-12 Token Metadata

The @taquito/tzip12 package allows retrieving metadata associated with tokens of FA2 contract. You can find more information about the TZIP-12 standard here.

How to use the tzip12 package#

The package can act as an extension to the well-known Taquito contract abstraction.

  1. We first need to create an instance of Tzip12Module and add it as an extension to our TezosToolkit

The constructor of the Tzip12Module takes an optional MetadataProvider as a parameter. When none is passed, the default MetadataProvider of Taquito is instantiated, and the default handlers (HttpHandler, IpfsHandler, and TezosStorageHandler) are used.

import { TezosToolkit } from '@taquito/taquito';
import { Tzip12Module } from '@taquito/tzip12';
const Tezos = new TezosToolkit('rpcUrl');
Tezos.addExtension(new Tzip12Module());

Note that the Tzip16Module and Tzip12Module use the same MetadataProvider. If you have already set Tezos.addExtension(new Tzip16Module());, you can omit this step.

  1. Use the tzip12 function to extend a contract abstraction
const contract = await Tezos.contract.at("contractAddress", tzip12)

The compose function
The contract abstraction can also be extended to a Tzip12ContractAbstraction and a Tzip16ContractAbstraction (at the same time) by using the compose function. Thus, all methods of the ContractAbstraction, Tzip12ContractAbstraction and Tzip16ContractAbstraction classes will be available on the contract abstraction instance.

import { compose } from '@taquito/taquito';
const contract = await Tezos.contract.at('contractAddress', compose(tzip16, tzip12));
await contract.storage(); // ContractAbstraction method
await contract.tzip12().getTokenMetadata(1); // Tzip12ContractAbstraction method
await contract.tzip16().getMetadata(); // Tzip16ContractAbstraction method

Get the token metadata#

There are two scenarios to obtain the metadata of a token:

  1. They can be obtained from executing an off-chain view named token_metadata present in the contract metadata
  2. or from a big map named token_metadata in the contract storage.

The getTokenMetadata method of the Tzip12ContractAbstraction class will find the token metadata with precedence for the off-chain view, if there is one, as specified in the standard.

The getTokenMetadata method returns an object matching this interface :

interface TokenMetadata {
token_id: number,
decimals: number
name?: string,
symbol?: string,
}
note

If additional metadata values are provided for a token_id, they will also be returned.

Here is a flowchart that summarizes the logic perform internally when calling the getTokenMetadata method:

Flowchart

*Note: If there is a URI in the token_info map and other keys/values in the map, all properties will be returned (properties fetched from the URI and properties found in the map). If the same key is found at the URI location and in the map token_info and that their value is different, precedence is accorded to the value from the URI.

Example where the token metadata are obtained from an off-chain view token_metadata#

Live Editor
Result

The same result can also be obtained by calling the off-chain view token_metadata using the taquito-tzip16 package:

Live Editor
Result

Note that an off-chain view all-tokens should also be present in the contract metadata allowing the user to know with which token ID the token_metadata can be called.

Example where the token metadata are found in the big map %token_metadata#

note

To be Tzip-012 compliant, the type of the big map %token_metadata in the storage of the contract should match the following type:

(big_map %token_metadata nat
(pair (nat %token_id)
(map %token_info string bytes)))

Otherwise, the token metadata won't be found by the getTokenMetadata method, and a TokenMetadataNotFound error will be thrown.

Live Editor
Result

For more information on the contracts used in the examples:#

integration-tests/tzip12-token-metadata.spec.ts