---
# System prepended metadata

title: Upgrade guide

---

# Upgrade guide

This is an upgrade guide for users of `@cennznet/api.js` from `1.5.x` to `2.1.x` versions. It does not attempt to detail each version the [CHANGELOG](https://github.com/cennznet/api.js/blob/master/packages/api/CHANGELOG.md) has all the changes between versions), but tries to explain the rationale behind major changes and how users of the API should handle this.


## API.js Version Mapping

### Version `1.5.3 or lower`

`yarn add @cennznet/api`

- Node version `10`
- CENNZnet Image [cennznet/cennznet:2.0.0](https://hub.docker.com/layers/cennznet/cennznet/2.0.0/images/sha256-a3719cd7b0dc7d3c4553ca1c07ffdde084f910dde1a8cc25c65fae45c8495229?context=explore) (Mainnet as of 15th March)
- Dependent on the following `@polkadot` packages
    ```json
    "@polkadot/api|types|metadata": "3.7.1",
    "@polkadot/util": "^4.2.1",
    "@polkadot/util-crypto": "^4.2.1",
    ```

### Version `2.1.0 or newer`
`yarn add @cennznet/api@2.1.0-rc.1`

- Node version `14`
- CENNZnet Image [cennznet/cennznet:2.1.0-rc4](https://hub.docker.com/layers/cennznet/cennznet/2.1.0-rc4/images/sha256-121f1a99f0fbe4d2ee9648f9e02903e17d86d5651a4e9af8b51834ac4fb9dc5e?context=explore)
- Dependent on the following `@polkadot` packages
    ```json
    "@polkadot/api|types|rpc-provider": "7.7.1",
    "@polkadot/util": "^8.3.3",
    "@polkadot/util-crypto": "^8.3.3",
    ```

## Breaking Changes

### Polkadot Packages

* With the support for v14 Metadata parsing, the `documentation` fields on metadata was renamed to `docs` for consistency, aligning with the SCALE type generators.

* The `@polkadot/metadata` package has been removed, adjust imports to ``@polkadot/types`
   ```js
    // OLD
    import { Metadata } from '@polkadot/metadata';
    // NEW
    import { Metadata } from '@polkadot/types/metadata';
    ```
* The `@polkadot/api-derive` types have been moved to a new location
    ```js
    // OLD
    import { HeaderExtended } from '@polkadot/api-derive'; 
    // NEW
    import type { HeaderExtended } from '@polkadot/api-derive/types';
    ```

### NFT Module
1. Deprecate the `mintUnique` method, use `mintSeries` instead
2. Use new NFT Metadata Standards as described [here](https://wiki.cennz.net/#/Dapp-development/Guides/NFT-metadata-standard)
3. Change NFT data model to more closely resemble the ERC721 structure for future cross-chain compatibility.
    ```
    'Collections' are a grouping of series
    'Series' are equivalent to ERC721 home contracts
    'Serial numbers' are equivalent to ERC721 token address
    ```
4. Removes the concept of SFT/copies/unique enforced by the module, all tokens are NFTs by default. It is much simpler to leave to the token metadata to denote/manage copies.
    ```js
    // OLD
    const attributes = [
        {'Text': 'Hello World'},
      ];
    const collectionId = 1; // created using api.tx.nft.createCollection
    const owner = '0x...';
    const metadataPath = null;
    const royaltiesSchedule = null;
    await api.tx.nft.mintUnique(collectionId, owner, attributes, metadataPath, royaltiesSchedule)
    .signAndSend(collectionOwner, async ({ status, events }) => {
      if (status.isInBlock) {
    events.forEach(({ event: {data, method }}) => {
      if (method == 'CreateToken') {
        tokenId = data[1];
        console.log(`got token: ${tokenId}`);
      }
    });

    // NEW
    const quantity = 1;
    const metadataPath = {"Https": "example.com/nft/metadata" };
    const collectionId = 1; // created using api.tx.nft.createCollection
    const owner = '0x...';
    const royaltiesSchedule = null;
    await api.tx.nft.mintSeries(collectionId, quantity, owner, metadataPath, royaltiesSchedule)
    .signAndSend(collectionOwner, async ({ status, events }) => {
      if (status.isInBlock) {
        events.forEach(({ event: {data, method }}) => {
          if (method == 'CreateToken') {
            tokenId = data[1];
            console.log(`got token: ${tokenId}`);
          }
    });
    ```
5. Metadata Reference Schemes
    - `MetadataBaseUri` renamed to `MetadataScheme`
    - Users can choose to store token metadata using 1 of 2 reference schemes,  either:
        1) https. token URIs assembled like `https://api.example.com/metadata/<serialNumber>.json`
        2) IPFS directory. token URIs assembled like: `ipfs://<directoryCID/<serialNumber>.json`
[more details](https://github.com/cennznet/cennznet/issues/442#issuecomment-992086784)

6. `SeriesAttributes` only exist for NFT created in runtime version `< 50`
7.  To get series metadata URI, use following derived query. Internally derive query uses api.query.nft.seriesMetadataURI (for older runtime version 45 ) and for new ones (api.query.nft.seriesMetadataScheme)
    ```js
    const collectionId = 192;
    const seriesId = 0;
    const uri = await api.derive.nft.seriesMetadataUri(collectionId, seriesId);
       ```

9.  Introduced new listing derived query which gives you list of all tokens for all the listing given a collection.
    ```js
    const collectionId = '16';
    const listedTokenInfo = await api.derive.nft.openCollectionListingsV2('16'); 
    /*
     [{
        listingId: 12, 
        tokens: [
            {owner: '0x..', tokenId: [16,0,1]},
            {owner: '0x..', tokenId: [16,0,2]}
        ]
    }];
    */

    ```
        
### Staking Module
- All staking derive queries are moved to `stakingCennznet`

    ```
    api.derive.staking.* --> api.derive.stakingCennznet.*
    ```
    




