Tatum
Searchโ€ฆ
How to create royalty NFTs with percentage cashback and provenance data
Create NFTs that payout cashback as a percentage of every sale and record provenance data with every transaction.
The ERC-721 token is a standardized smart contract with a predefined set of features. The tokens are non-fungible, which means that each one is unique. You can think of them as one-of-a-kind collectibles.

How can creators keep getting paid?

NFTs have surged in popularity, and many NFT marketplaces have implemented functionality to allow creators to receive a portion of every subsequent sale of their work. This is great for creators, as it allows them to continue getting paid each time their NFT changes hands.
However, there's one critical flaw. Once the NFT leaves the marketplace on which it was originally sold, the creator has no way to collect any money ever again. This is because the mechanism for collecting portions of subsequent sales is only implemented at the application level, not at the blockchain level.
For this reason, we have created instantly deployable NFT smart contracts that implement this functionality at the blockchain level. Payouts for subsequent sales to the original creators happen automatically, and forever. Creators will keep getting paid for as long as their NFT exists.
Tatum royalty NFTs can currently be created on:
  • Ethereum
  • Celo
  • Binance Smart Chain
  • Polygon
  • Harmony.ONE

What is provenance data?

While NFTs exist on the blockchain and their authenticity can be verified, there have still been attempts at forging high-value NFTs. To ensure the authenticity of NFTs, we have created NFT smart contracts that record metadata about each transaction every time the token is transferred. The token's entire transaction history is included in the token itself and its authenticity can be verified quickly and easily.
Tatum royalty NFTs are ERC-721 tokens with specialized smart contracts that pay creators cashback with each subsequent transaction. They can either pay a fixed amount of cashback or cashback percentages.
In this guide, we will learn how to use NFTs that payout cashback as a percentage of each sale and record provenance data with each transaction.
For information on creating NFTs that payout cashback as a fixed value without provenance data, please see this guide.
Tatum royalty NFTs are primarily intended for higher-value NFTs. The royalty functionality is currently incompatible with OpenSea and must be transferred using smart contract methods not currently supported within the platform.
As soon as OpenSea allows this standard and method calls, our royalty NFTs will be fully compatible with the platform.

Import required libraries

In this guide, we will be using the Tatum JavaScript SDK to create and work with NFTs. First, we'll need to download and import the required libraries for the commands we'll be using. Download the Tatum JS SDK here.
Now, import the required libraries:
1
import { deployNFT, mintNFTWithUri, mintMultipleNFTWithUri } from '@tatumio/tatum';
Copied!

Creating an NFT smart contract

Normally, to create an NFT you'd need to learn Solidity and code your own smart contract. To speed things up, we've created prebuilt and validated smart contracts for you. You can instantly deploy them with just a few lines of code.
In this example, we will be deploying an NFT on Ethereum. The required parameters are:
  • The name of the NFT
  • The name of the blockchain
  • The NFT symbol
  • Provenance: true. Enabling provenance in this call also enables percentage royalty cashback.
JavaScript
cURL + KMS
cURL + private key
1
const transactionHash = await deployNFT(false, {
2
name: 'MY_NFT',
3
chain: Currency.ETH,
4
symbol: 'NFT_SYMBOL',
5
provenance: true
6
});
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/deploy \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data {
7
"chain": "ETH",
8
"name": "My ERC721",
9
"provenance": true,
10
"symbol": "ERC_SYMBOL",
11
"index": 0,
12
"signatureId": "26d3883e-4e17-48b3-a0ee-09a3e484ac83",
13
"nonce": 0,
14
"fee": {
15
"gasLimit": "40000",
16
"gasPrice": "20"
17
}
18
}
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/deploy \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data {
7
"chain": "ETH",
8
"name": "My ERC721",
9
"symbol": "ERC_SYMBOL",
10
"fromPrivateKey": "0x05e150c73f1920ec14caa1e0b6aa09940899678051a78542840c2668ce5080c2",
11
"provenance": true,
12
"nonce": 0,
13
"fee": {
14
"gasLimit": "40000",
15
"gasPrice": "20"
16
}
17
}
Copied!
And that's it, you've now deployed an NFT smart contract.

Getting the address of the smart contract

To get the address of the smart contract, use the transaction ID in the response to the previous call with the Get NFT contract address endpoint:
1
const contractAddress = await getNFTContractAddress(Currency.ETH, '0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492');
Copied!
The response will be the address of your NFT smart contract.

Uploading metadata

Before we mint NFTS, we have to upload the metadata (image, audio, video, etc.) that we will include in the NFT. Please check this guide to learn how to upload metadata to IPFS for free using Tatum.

Minting a new unique ERC-721 token

Now that we have the address of our smart contract and have uploaded our metadata, we can mint NFTs.
The required fields to mint a new NFT are:
  • The recipient's address in the "to" field
  • The URL of our JSON scheme on IPFS
  • The ID of the token to be minted. This can be any unique number and depends on your numbering convention. Some developers use chronological numbering, some do it by date and time, it's up to you to decide how you will organize your token IDs.
  • Provenance: true. Provenance must be enabled in this call as well.
  • Author address is the address, where cashback will be sent.
  • The percentage value of the cashback in the "cashbackValues" field. In the example below, the value "0.5" means that 0.005% of the sale price will be transferred to the author each time the NFT is transferred.
  • The minimum fixed value of the cashback is in the "fixedValues" field. This value is the minimum cashback value that will be paid and is a fixed amount of the blockchain's native currency. If the cashback to be paid from the percentage of the sale is less than the fixed value, the fixed value will be paid to the authors instead.
  • The name of the blockchain
  • The address of the NFT smart contract
  • The address of the custom ERC-20 token smart contract the creators would like to receive cashback in. If this field is absent, cashback will be paid out in the native currency of the blockchain (in this case, ETH).
JavaScript
cURL + KMS
cURL + private key
1
const transactionHash = await mintNFTWithUri(false, {
2
to: '0x0ff64c166a462b31ed657c9d88c5ac4fef6b88b6',
3
url: 'https://my-token-metadata-url',
4
tokenId: '12',
5
provenance: true,
6
cashbackValues: ["0.5"],
7
authorAddresses: ["0x0ff64c166a462b31ed657c9d88c5ac4fef6b88b6"],
8
fixedValues: ["0.5"],
9
chain: Currency.ETH,
10
contractAddress: '0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
11
erc20: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
12
});
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/mint \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"chain": "ETH",
8
"tokenId": "100000",
9
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
10
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
11
"url": "https://my_token_data.com",
12
"provenance": true,
13
"authorAddresses": [
14
"0x687422eEA2cB73B5d3e242bA5456b782919AFc85"
15
],
16
"cashbackValues": [
17
"0.5"
18
],
19
"fixedValues": [
20
"0.5"
21
],
22
"index": 0,
23
"signatureId": "26d3883e-4e17-48b3-a0ee-09a3e484ac83",
24
"nonce": 0,
25
"fee": {
26
"gasLimit": "40000",
27
"gasPrice": "20"
28
}
29
}
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/mint \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"chain": "ETH",
8
"tokenId": "100000",
9
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
10
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
11
"url": "https://my_token_data.com",
12
"provenance": true,
13
"authorAddresses": [
14
"0x687422eEA2cB73B5d3e242bA5456b782919AFc85"
15
],
16
"cashbackValues": [
17
"0.5"
18
],
19
"fixedValues": [
20
"0.5"
21
],
22
"fromPrivateKey": "0x05e150c73f1920ec14caa1e0b6aa09940899678051a78542840c2668ce5080c2",
23
"nonce": 0,
24
"fee": {
25
"gasLimit": "40000",
26
"gasPrice": "20"
27
}
28
}
Copied!

Transferring an NFT

To transfer an NFT, we must enter the price of the sale from which the percentage royalties will be calculated. The required parameters to transfer the NFT are:
  • The recipient address in the "to" field
  • The ID of the token to be transferred
  • The name of the blockchain
  • The address of the NFT smart contract
  • Provenance: true. Provenance must be enabled to transfer the token.
  • Any optional provenance data to be included in the transaction
  • The sale price of the token being transferred
JavaScript
cURL + KMS
cURL + private key
1
const transactionHash = await transferNFT(false, {
2
to: '0x0ff64c166a462b31ed657c9d88c5ac4fef6b88b6',
3
tokenId: '12',
4
chain: Currency.ETH,
5
contractAddress: '0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
6
provenance: true,
7
provenanceData: "test",
8
tokenPrice: "1",
9
});
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/transaction \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"value": "1",
8
"chain": "ETH",
9
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
10
"tokenId": "100000",
11
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
12
"index": 0,
13
"provenance": true,
14
"provenanceData": "test",
15
"tokenPrice": "1",
16
"signatureId": "26d3883e-4e17-48b3-a0ee-09a3e484ac83",
17
"nonce": 1,
18
"fee": {
19
"gasLimit": "40000",
20
"gasPrice": "20"
21
}
22
}
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/nft/transaction \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"value": "1",
8
"chain": "ETH",
9
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
10
"tokenId": "100000",
11
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
12
"provenance": true,
13
"provenanceData": "test",
14
"tokenPrice": "1",
15
"fromPrivateKey": "0x05e150c73f1920ec14caa1e0b6aa09940899678051a78542840c2668ce5080c2",
16
"nonce": 1,
17
"fee": {
18
"gasLimit": "40000",
19
"gasPrice": "20"
20
}
21
}
Copied!

Updating NFT cashback for authors

Now, we must designate the addresses to which the cashback percentages from subsequent transactions will be sent. You can update the cashback percentage for any authors of the NFT at any time. However, the minimum fixed values (in the "fixedValues" field of the mint call) cannot be changed.
To update the cashback percentage, the following parameters are required:
  • The recipient's address
  • The ID of the token
  • The name of the blockchain
  • The address of the NFT smart contract
  • The new cashback value as a percentage (i.e. a value of "15" = 0.15%)
  • The private key to pay for the gas fees of the transaction
JavaScript
cURL + KMS
cURL + private key
1
const transactionHash = await updateCashbackForAuthorNFT(false, {
2
to: '0x0ff64c166a462b31ed657c9d88c5ac4fef6b88b6',
3
tokenId: '12',
4
chain: Currency.ETH,
5
contractAddress: '0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
6
cashbackValue: '15',
7
fromPrivateKey: '0x315ea1dae65c75f088542161a0777525a8de1153904c745cb8131a9e0c632204'
8
});
Copied!
1
curl --request PUT \
2
--url https://api-eu1.tatum.io/v3/nft/royalty \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"chain": "ETH",
8
"tokenId": "100000",
9
"cashbackValue": "0.1",
10
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
11
"index": 0,
12
"signatureId": "26d3883e-4e17-48b3-a0ee-09a3e484ac83",
13
"nonce": 0,
14
"fee": {
15
"gasLimit": "40000",
16
"gasPrice": "20"
17
}
18
}
Copied!
1
curl --request PUT \
2
--url https://api-eu1.tatum.io/v3/nft/royalty \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--header 'x-testnet-type: SOME_STRING_VALUE' \
6
--data '{
7
"chain": "ETH",
8
"tokenId": "100000",
9
"cashbackValue": "0.1",
10
"contractAddress": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
11
"fromPrivateKey": "0x05e150c73f1920ec14caa1e0b6aa09940899678051a78542840c2668ce5080c2",
12
"nonce": 0,
13
"fee": {
14
"gasLimit": "40000",
15
"gasPrice": "20"
16
}
17
}
Copied!

Getting a list of NFTs by address

To find out which NFTs a specific address holds, use the following call. The required parameters are:
  • The name of the blockchain
  • The address or addresses for which we would like to obtain a list of NFTs
JavaScript
cURL
1
const nfts = await getNFTsByAddress(
2
Currency.ETH,
3
'0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
4
'0x0ff64c166a462b31ed657c9d88c5ac4fef6b88b6',
5
);
Copied!
1
curl --request GET \
2
--url https://api-eu1.tatum.io/v3/nft/balance/{chain}/{contractAddress}/{address} \
3
--header 'x-api-key: REPLACE_KEY_VALUE' \
4
--header 'x-testnet-type: SOME_STRING_VALUE'
Copied!

Getting NFT metadata

To get NFT metadata for a specific token, you need:
  • The address where the token is held
  • The token ID of the NFT
JavaScript
cURL
1
const metadataURI = await getNFTMetadataURI(
2
Currency.ETH,
3
'0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
4
'15',
5
);
Copied!
1
curl --request GET \
2
--url 'https://api-eu1.tatum.io/v3/nft/provenance/{chain}/{contractAddress}/{tokenId}?account=0xc1b45bc27b9c61c3' \
3
--header 'x-api-key: REPLACE_KEY_VALUE' \
4
--header 'x-testnet-type: SOME_STRING_VALUE'
Copied!

Get NFT provenance data

Since we've enabled provenance data in the NFTs we've minted, now we can use the get NFT provenance data endpoint to view a record of all of the transactions of the NFT since it was minted. The required parameters are the same as with the get metadata endpoint.
JavaScript
cURL
1
const obj = await getNFTProvenanceData(
2
Currency.ETH,
3
'0x7060694f5ce1feb5a255d06fdcf6e4f7a3507492',
4
'15',
5
);
Copied!
1
curl --request GET \
2
--url 'https://api-eu1.tatum.io/v3/nft/provenance/{chain}/{contractAddress}/{tokenId}?account=0xc1b45bc27b9c61c3' \
3
--header 'x-api-key: REPLACE_KEY_VALUE' \
4
--header 'x-testnet-type: SOME_STRING_VALUE'
Copied!

Well done!

Now you can create and work with NFTs that hold provenance data and payout royalties as percentages. Two in-demand features with just a few lines of code. For the full list of NFT operations available in Tatum, please refer to our API documentation.

โ€‹

โ€‹
Last modified 8d ago