NFT Trader
Ask or search…
K

Fees and Royalties configuration

Discover how to setup properly the fees and the royalties

Fees

The NFT Trader SDK allows configuring custom fees. To do this correctly, you must first compose an array of so-called Fee. This array will be automatically managed by the smart contract, which will handle the proper division of amounts and send them to the respective recipients. To configure the fees, it is necessary to call the createTrade() method of the TradeClient class. Let's analyze the following pseudocode to understand how to set them correctly.
type Fee = {
recipient: string;
basisPoints: number;
}
const fees : Array<Fee> = []
fees.push({
recipient: "0x69Fc3a866a963d4A0a05B2Fb27B167E0012dFEa5", //the recipient of the fee
basisPoints: 50 // a basis point of 50 means a 0.5% fee on the total amount
})
//it's possible to setup more than one fee by pushing another element on the array
fees.push({
recipient: "0xE2B85dDb12eFf59E69eF8781cF693A4325d21721", //the recipient of the fee
basisPoints: 50 // a basis point of 50 means a 0.5% fee on the total amount
})
sdk.createTrade(
maker, //the maker, this is just pseudo-code, pay attention to the fees array instead
taker, //the taker, this is just pseudo-code, pay attention to the fees array instead
duration, // duration of the trade, this is just pseudo-code, pay attention to the fees array instead
signature, // signature, this is just pseudo-code, pay attention to the fees array instead
fees,
undefined
).then(() => {
//trade setup correctly
})
.catch((error) => {
//trade setup error
})
It is important to note the following considerations:
  1. 1.
    The buyer, who is the counterparty providing the tokens (native or ERC20), is the one who will pay the fees, whether they are fixed or percentage-based.
  2. 2.
    The buyer, who is the counterparty providing the tokens (native or ERC20), is the one who will pay the royalty fees to the collection creator (if supported through Manifold; for all details, please refer to the next section).
  3. 3.
    It is possible to configure more than one fee.

Royalties

The NFT Trader SDK provides highly flexible configuration options for royalties. However, the calculation of royalties is not included in the library, so you will need to find a suitable method on your own. We can suggest a system that you could use, which is the Manifold platform.
Manifold is a platform that has been operating in the web3 space for some time and has created various standards to simplify the development of decentralized applications (dApps). One of the services offered by Manifold is specifically related to calculating royalties for an NFT collection.
The obvious advantage is that since the royalties system is developed around a smart contract, it allows you to query a single source of information rather than multiple resources, thus simplifying the developer's work.
Using the Manifold platform for calculating royalties in conjunction with the NFT Trader SDK can provide a robust and streamlined solution for managing royalties in your NFT trading application.

Manifold Royalties Registry

The system for calculating royalties offered by Manifold is called the "Royalties Registry." As mentioned earlier, it is a smart contract that contains information about the royalties for NFT collections. Each creator is free to add their collection to the registry and configure the royalties according to their preferences. However, this guide will not describe how to configure royalties within the Manifold system. To understand how to set them up correctly, it is recommended to consult the documentation on the official website of the platform. As of the current state when this documentation was generated, the Royalties Registry of Manifold supports the following blockchains:
  • Ethereum
  • Polygon
  • Optimism
  • Arbitrum
  • Avalanche
  • Binance Smart Chain (BNB)
  • Goerli (Ethereum Testnet)
  • Mumbai (Polygon Testnet)
Please note that the blockchain support provided by Manifold may evolve over time, so it's essential to refer to the official documentation or the Manifold platform for the most up-to-date and accurate information regarding supported blockchains.

Concepts

Calculating royalties is conceptually simple. It involves extracting the correct royalty amount to be allocated to the creator of the collection for each NFT involved in a trading operation. There are various scenarios in which a royalty can be paid directly to the creator of a collection, depending on the platform's willingness to distribute these amounts and the platform's specific logic.
Let's consider the simplest scenario, which is the sale of one or more NFTs from the same collection. In a sale, one party will provide one or more NFTs from a collection, while the other party will provide an amount composed of either a native blockchain token (e.g., ETH) or an ERC20 token (e.g., WETH).
Following the logic of this scenario, the following operations need to be performed:
  1. 1.
    Determine if the collection is supported within the Manifold Royalties Registry.
  2. 2.
    Retrieve the royalty fee amount for that collection concerning the specific NFT under consideration.
  3. 3.
    Determine if that particular NFT has multiple royalty recipients (look the hint below), if applicable.
  4. 4.
    Calculate the amount to deduct from the amount provided by the counterparty offering tokens (native or ERC20).
  5. 5.
    Simultaneously with step 4, properly set the array of royalties within the createTrade method provided by the TradeClient class of the SDK.
These steps provide a basic understanding of how to calculate and set royalties using the NFT Trader SDK in conjunction with the Manifold Royalties Registry.
Yes, it is possible for the same NFT to have multiple recipients for royalty commissions. This means that when the NFT is traded, the royalty amount may need to be divided among multiple creators or rights holders who are entitled to receive a portion of the royalty. Indeed, it is common to find NFTs from the Art Blocks collection that have multiple recipients for royalty commissions. Art Blocks is known for its generative art projects, and many of these projects involve collaborations among different artists or contributors. As a result, when a trading transaction occurs involving an NFT from an Art Blocks collection, the royalty commission may need to be distributed among multiple creators or rights holders involved in the project.

Calculating royalties by combining the SDK and the Manifold Royalties Registry.

Now that we have a general understanding of the steps and basic concepts for calculating royalties, let's analyze the following pseudocode to understand how a possible implementation of the Royalties Registry within a project, combining it with the NFT Trader SDK, could look like.
type Maybe<T> = T | null
type Fee = {
recipient: string;
basisPoints: number;
}
interface Asset {
id: Maybe<string>
type: "ERC721" | "ERC1155" | "ERC20" | "NATIVE"
amount: Maybe<string>
amountHumanReadable: Maybe<string>
owner: string
collection: Collection
imageSrc: Maybe<string>
isApproved: boolean
hasPlaceholder: boolean
}
const setupRoyalties = async (
royaltyEngineABI: any,
registryEngineContractAddress: string,
nft: Asset,
counterpartyTokens: Array<Asset>
) => {
const contract = new ethers.Contract(
registryEngineContractAddress,
royaltyEngineABI,
library
)
const NFTAddress: string = nft.collection.address.toLowerCase()
const NFTTokenId: Maybe<string> = nft.id
if (NFTAddress && NFTTokenId) {
const royaltiesArray: Array<{
amount: string
currency: string
visible: boolean
}> = []
const royaltiesFeeArray: Array<Fee> = []
for (const token of counterpartyTokens) {
if (token.amount) {
try {
const {
amounts,
recipients,
}: { amounts: Array<ethers.BigNumber>; recipients: Array<string> } =
await contract.getRoyaltyView(
NFTAddress,
NFTTokenId,
token.amount
)
//if recipients is equal to zero, there aren't royalties to pay
if (recipients.length > 0 && amounts.length > 0) {
//split the royalty per token, in this way we can have a table in the frontend
let totalRoyalty: any
amounts.forEach((amount: ethers.BigNumber, index: number) => {
if (index === 0)
totalRoyalty = amount
else
totalRoyalty = totalRoyalty.add(amount)
let amountBS = new Big(amount.toString())
royaltiesFeeArray.push({
recipient: recipients[index],
basisPoints: amountBS
.div(token.amount!)
.times(10000)
.toNumber(),
})
})
if (token.type === "NATIVE") {
royaltiesArray.push({
amount: ethers.utils.formatUnits(18),
currency: token.collection.symbol,
visible: true,
})
} else {
//erc20
const erc20Contract = new ethers.Contract(
token.collection.address,
token.collection.abi,
library
)
try {
const decimals: number = await erc20Contract.decimals()
royaltiesArray.push({
amount: ethers.utils.formatUnits(
totalRoyalty ? totalRoyalty.toString() : "0",
18 //the number of decimals of the token Eg. ETH
),
currency: token.collection.symbol,
visible: true,
})
} catch (error) {
//error handling
return handleError(error)
}
}
}
return royaltiesArray
} catch (error) {
//error handling
return handleError(error)
}
}
}
}
}
//your application logic
const currentNetworkId = getCurrentNetworkId(...)
const sdk = createNFTTraderSDKInstance(...)
const mappingEngine = sdk.getRoyaltyRegistriesEngines()
const abi: Array<any> = sdk.getRoyaltyRegistryEngineABI()
const rrAddress: string = mappingEngine[currentNetworkId]
const nfts = getNFTsForTheTrade(...)
const counterpartyTokens = getCounterpartyTokensForTheTrade(...)
const royalties = Array<Fee>
for (nft of nfts)
royalties.push(await setupRoyalties(abi, rrAddress, nft, counterpartyTokens))
sdk.createTrade(
maker, //the maker, this is just pseudo-code, pay attention to the royalties array instead
taker, //the taker, this is just pseudo-code, pay attention to the royalties array instead
duration, // duration of the trade, this is just pseudo-code, pay attention to the royalties array instead
signature, // signature, this is just pseudo-code, pay attention to the royalties array instead
royalties,
undefined
).then(() => {
//trade setup correctly
})
.catch((error) => {
//trade setup error
})
Taking into consideration the pseudocode, we can observe that upon obtaining the array of NFTs from the current trade being created, the code queries the royalties registry smart contract to extract the exact commission amount owed to the creator(s) of each individual asset. All of this information is then inserted into an array that holds the respective commission amounts. We can also notice two methods provided by the SDK, namely the getRoyaltyRegistriesEngines() method and the getRoyaltyRegistryEngineABI() method. The first method returns an array containing all the addresses of the royalties registry smart contracts, while the second method returns the ABI array of the corresponding smart contract. It is important to note that individual elements of the address array related to the smart contract can be obtained by using the respective chain code (also known as network ID) as the index. Note: This is just pseudocode representing a possible implementation of the royalties calculation.
Salad Labs Inc. (NFT Trader) assumes no responsibility for how royalties are calculated and distributed to collection creators. The SDK is a tool that can be used at the discretion of the developer, who is free to pursue their own development logic.
NFT Trader is a pro-royalties platform as we believe that the NFT market should be sustainable for artists and collection creators themselves. Therefore, we suggest that those who use this library follow the same principle to support a fairer market."