Non-Fungible Token

A non-fungible token (NFT) is a representation of an non-monetary assets in the form of cryptographic token; non-fungible tokens are thus not mutually interchangeable by their individual specification. This is in contrast with cryptocurrencies like Zcash, and many network or utility tokens that are fungible in nature.


General Workflow

_images/NFT.jpg

Firstly, a non-fungible token must be created. It can be created by any wallet, but it has to be authorized through a KYC process before it can be used.

Authorization might get rejected.

Creating Instances

Creating non-fungible token requires approval from authorities.

NonFungibleToken . create ( nonFungibleTokenProperties, signerOrProvider )   => Promise<NonFungibleToken>

Creates a new instance reference from signerOrProvider, then sends non fungible token creation transaction to network and returns a Promise that resolves to a NonFungibleToken instance.

The valid non-fungible token properties are:

  • name: string (name of the token)
  • symbol: string (symbol of the token)
  • fee: int (application fee)
  • properties: string (properties of the token)
  • metadata: string (remarks)

Note

Token name and symbol must be unique;
metadata can be changed after the token is created, but not properties.
create non-fungible token
let wallet = new mxw.Wallet(0x00000000000000000000000000000000000000000000000070726f7669646572, networkProvider);
let nonFungibleTokenProperties: NonFungibleTokenProperties;
nonFungibleTokenProperties = {
    name: "MY " + "symbol",
    symbol: "symbol",
    fee: {
        to: "address",
        value: bigNumberify("1")
    },
    metadata: ["Wallet able to manage their own metadata"],
    properties:["Decentralised identifier"]
};

var nonFungibleToken = new NonFungibleToken("symbol", wallet);
nonFungibleToken.create(nonFungibleTokenProperties, wallet).then((token) => {
    console.log(JSON.stringify(token));
});
NonFungibleToken . fromSymbol ( symbol, signerOrProvider )   => Promise<NonFungibleToken>
Queries non-fungible token by symbol from network and returns a Promise that resolves to a NonFungibleToken instance.
check token state
    mxw.nonFungibleToken.NonFungibleToken.fromSymbol("symbol","issuer address").then((token)=>{
        console.log(JSON.stringify(token));
    });

Prototype

prototype . state   => NFTokenState

(Read-only)
The valid token states are:
  • flagsuint (number)
  • namestring (unique token name)
  • symbolstring (unique token symbol)
  • ownersting (token owner’s address)
  • newOwnerstring (token receiver’s address)
  • metadatastring (metadata/remarks of token)
  • mintLimitBigNumber (token’s maximum mint limit of token)
  • transferLimitBigNumber (token’s maximum transfer limit)
  • endorserListstring[] list of endorsers
  • totalSupplyBigNumber (total items minted by the token)
  • endorserListLimitBigNumber (token’s maximum endorser list limit)

Note

All token must be authorized, before it can use to mint item or transfer ownership. All token state must be assigned.

authorize token action
    let provider = new mxw.Wallet(0x00000000000000000000000000000000000000000000000070726f7669646572, networkProvider);
    let issuer = new mxw.Wallet(0x0000000000000000000000000000000000000000000000000000697373756572, networkProvider);
    let middleware = new mxw.Wallet(0x000000000000000000000000000000000000000000006d6964646c6577617265m ,networkProvider);

    let tokenState = {
    tokenFees: [
                { action: NonFungibleTokenActions.transfer, feeName: "default" },
                { action: NonFungibleTokenActions.transferOwnership, feeName: "default" },
                { action: NonFungibleTokenActions.acceptOwnership, feeName: "default" }
                ],
    endorserList: [],
    mintLimit: 1,
    transferLimit: 1,
    burnable: false,
    pub: false,
    endorserListLimit: 10
    };

    token.NonFungibleToken.approveNonFungibleToken("symbol",provider, tokenState).then((transaction) => {
        token.NonFungibleToken.signNonFungibleTokenStatusTransaction(transaction, issuer).then((transaction) => {
            token.NonFungibleToken.sendNonFungibleTokenStatusTransaction(transaction, middleware).then((receipt) => {
                console.log("approve"+receipt);
            });
        });
    });
prototype . transferOwnership ( AddressOrName )   => Promise<TransactionReceipt>
Transfer the non-fungible token ownership from token owner’s wallet to another wallrt and returns a Promise that resolves to a Transaction Receipt.
prototype . acceptOwnership ()   => Promise<TransactionReceipt>
Accept the non-fungible token ownership which transfer from another person and returns a Promise that resolves to a Transaction Receipt.
transfer and accept token ownership
    let transfereePrivateKey = "0x0123abcdefabcdef0123456789abcdef0123456789abcdef0123456789abcdef";
    let transfereeWallet = new mxw.Wallet(transfereePrivateKey, networkProvider);
    let transferorPrivateKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
    let transferorWallet = new mxw.Wallet(transferorPrivateKey, networkProvider);

    // transferor transfering token ownership
    token.NonFungibleToken.fromSymbol(nftSymbol, transferorWallet).then((nft)=>{
        nft.transferOwnership(transfereeWallet.address).then((receipt) => {
            console.log(JSON.stringify(receipt));
        })
    })

    // after verified the wallet owner done transfering the token ownership
    // then this action must get approval from authorities

    // transferee accepting token ownership
    token.NonFungibleToken.fromSymbol(nftSymbol, transfereeWallet).then((nft) =>{
        nft.acceptOwnership().then((receipt) => {
            console.log(JSON.stringify(receipt));
        })
    })


    /* nftSymbol is the symbol from a token, which already been created and approved by authorities */
prototype . mint ( AddressOrName, NonFungibleTokenItem)   => Promise<TransactionReceipt>

Sends the mint non-fungible token transaction to the network and returns a Promise that resolves to a Transaction Receipt.

The AddressOrName can be set to recipient’s alias or wallet address.

mint an NFT item
    let issuer : mxw.Wallet;
    let item = {
        symbol: "symbol",
        itemID: "itemId",
        properties: "prop1",
        metadata: "str1"
    } ;

    var minterNFT = new NonFungibleToken(symbol, issuer);

    minterNFT.mint(issuer.address, item).then((receipt) => {
        console.log(JSON.stringify(receipt));
    });

Note

Symbol of the minted item must be the same as the token symbol.

prototype . updateMetadata(string metadata)   => Promise<TransactionReceipt>
Update the metadata of NFT or NFT item to the network and returns a Promise.
update metadata of an NFT
let wallet = new mxw.Wallet(0x00000000000000000000000000000000000000000000000070726f7669646572, networkProvider);
let nonFungibleTokenProperties: NonFungibleTokenProperties;
nonFungibleTokenProperties = {
    name: "MY " + symbol,
    symbol: symbol,
    fee: {
        to: nodeProvider.nonFungibleToken.feeCollector,
        value: bigNumberify("1")
    },
    metadata: ["Wallet is able to manage their own metadata"],
    properties:["Decentralised identifier"]
};

let nftInstance = new NonFungibleTokenItem(nonFungibleTokenProperties, wallet);

//overwrite the token metadata with string "overwrite"
nftInstance.updateMetadata("overwite").then((receipt) => {
        console.log(JSON.stringify(receipt));
});

//adding new info into the token metadata
let nftItemStatus = nftInstance.getState();
nftInstance.updateMetadata(nftItemStatus.metadata + "overwrite").then((receipt) => {
        console.log(JSON.stringify(receipt));
});

Additional Actions

Freeze and unfreeze an item.

freeze item
    let provider = new mxw.Wallet(0x00000000000000000000000000000000000000000000000070726f7669646572, networkProvider);
    let issuer = new mxw.Wallet(0x0000000000000000000000000000000000000000000000000000697373756572, networkProvider);
    let middleware = new mxw.Wallet(0x000000000000000000000000000000000000000000006d6964646c6577617265, networkProvider);

    token.NonFungibleToken.freezeNonFungibleTokenItem("symbol","itemID", provider).then((transaction) => {
        token.NonFungibleToken.signNonFungibleTokenItemStatusTransaction(transaction, issuer).then((transaction) => {
            token.NonFungibleToken.sendNonFungibleTokenItemStatusTransaction(transaction, middleware).then((receipt) => {
                console.log(JSON.stringify(receipt));
            });
        });
    });
unfreeze item
    let provider = new mxw.Wallet(0x00000000000000000000000000000000000000000000000070726f7669646572, networkProvider);
    let issuer = new mxw.Wallet(0x0000000000000000000000000000000000000000000000000000697373756572, networkProvider);
    let middleware = new mxw.Wallet(0x000000000000000000000000000000000000000000006d6964646c6577617265, networkProvider);

    token.NonFungibleToken.unfreezeNonFungibleTokenItem("symbol","itemID", provider).then((transaction) => {
        token.NonFungibleToken.signNonFungibleTokenItemStatusTransaction(transaction, issuer).then((transaction) => {
            token.NonFungibleToken.sendNonFungibleTokenItemStatusTransaction(transaction, middleware).then((receipt) => {
                console.log(JSON.stringify(receipt));
            });
        });
    });

Item

Create an item instance, three components must be included: symbol, itemId, and address of issuer.

prototype. getState()   => NFTokenState

Returns to the state of Non-fungible Token Item status

(Read-only)
The valid token state are:
  • symbol — symbol of the NFT item
  • itemID — ID of the NFT item
  • properties — properties of the NFT item
  • metadata — metadata of the NFT item
get item status
    nftInstance.getState().then((result)=>{
        console.log(JSON.stringify(result));
    });
NonFungibleTokenItem . fromSymbol ( symbol, itemID, signerOrProvider )   => Promise<NonFungibleToken>
Queries NFT item by symbol from network and returns a Promise that resolves to a NonFungibleToken instance.
check on item state
    mxw.nonFungibleToken.NonFungibleToken.fromSymbol("symbol", "itemID", wallet).then((token)=>{
        console.log(JSON.stringify(token))
    });
get the state of token that minted this item
    mxw.nonFungibleToken.NonFungibleToken.fromSymbol("symbol", "itemID", wallet).then((token)=>{
        console.log(JSON.stringify(token))
        var mintedNFTItem = nftItem;
        console.log(mintedNFTItem.parent.state);
    });
prototype . burn ()   => Promise<TransactionReceipt>

Sends the burn non-fungible token transaction to the network and returns a Promise that resolves to a Transaction Receipt. To burn item, the burn token flag must be true.

The value is the number of non-fungible token (as a BigNumber) to be burned. Be aware of the number of decimals applied to the token.

burn an NFT item
    let nftInstance = new NonFungibleTokenItem(symbol, itemID, wallet);
    nftInstance.burn().then((receipt) => {
            console.log(receipt);
    });
prototype . endorse(metadata)   => Promise<TransactionReceipt>
Sign/approves endorsement by an endorser
endorse an NFT item
let nftInstance = new NonFungibleTokenItem("symbol", "itemID", wallet);
nftInstance.endorse("Optional endorsement metadata").then((receipt) => {
        console.log(receipt);
});
prototype . updateItemMetadata(metadata)   => Promise<TransactionReceipt>
Updates the metadata of NFT item to the network and returns a Promise.
update metadata of an NFT item
let nftInstance = new NonFungibleTokenItem("symbol", "itemID", wallet);

//overwrite the NFT item metadata with string "overwrite"
nftInstance.updateItemMetadata("overwite").then((receipt) => {
        console.log(receipt);
});

//adding new info into the item metadata
let nftItemStatus = nftInstance.getState(0);
nftInstance.updateItemMetadata(nftItemStatus.metadata + "overwrite").then((receipt) => {
        console.log(receipt);
});