Some NFTs have royalty information attached to them. Marketplaces may utilize this information to allocate a portion of sales to a designated recipient.
A Royalty has the following characteristics:
Cut: What percentage of a sale should go to this Royalty?
Receiver: A FungibleToken Receiver Capability to send tokens to
Description (Optional): A description of what this Royalty is for
Flowty doesn't display these Royalties anywhere but does make use of them inside of our smart contracts.
One challenge many platforms on Flow (because of its capabilities based language) encounter with Royalties is how to handle sending tokens to a receiver that is not configured properly.
To solve this, Flowty does the following:
Every token we support has a mapping of the receiver path it should go to
When we read a royalty during a sale, we will check what address the royalty is for
Using that address, we will rebuild the capability that the royalty is meant go to
If a royalty receiver is not configured properly, Flowty makes use of the Lost and Found tool to send tokens somewhere that the receiver can redeem at any time.
NOTE: Lost and Found is a safety mechanism to prevent anyone from being able to prevent an NFT from being sold by making royalties invalid. You can learn more about Lost and Found here.
In the case of Dapper Wallet, any invalid royalties cannot be sent to Lost and Found. Instead, these royalties will be given to the seller of an NFT.
pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
// ...
pub fun resolveView(_ view: Type): AnyStruct? {
switch view {
case Type<MetadataViews.Royalties>():
// note: Royalties are not aware of the token being used with, so the path is not useful right now
// eventually the FungibleTokenSwitchboard might be an option
// https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenSwitchboard.cdc
let cut = MetadataViews.Royalty(
receiver: Avataaars.account.getCapability<&{FungibleToken.Receiver}>(/public/somePath),
cut: 0.025, // 2.5% royalty
description: "Creator Royalty"
)
var royalties: [MetadataViews.Royalty] = [cut]
return MetadataViews.Royalties(royalties)
// ...
}
return nil
}
// ...
}
/// View that defines the composable royalty standard that gives marketplaces a
/// unified interface to support NFT royalties.
///
pub struct Royalty {
/// Generic FungibleToken Receiver for the beneficiary of the royalty
/// Can get the concrete type of the receiver with receiver.getType()
/// Recommendation - Users should create a new link for a FlowToken
/// receiver for this using `getRoyaltyReceiverPublicPath()`, and not
/// use the default FlowToken receiver. This will allow users to update
/// the capability in the future to use a more generic capability
pub let receiver: Capability<&AnyResource{FungibleToken.Receiver}>
/// Multiplier used to calculate the amount of sale value transferred to
/// royalty receiver. Note - It should be between 0.0 and 1.0
/// Ex - If the sale value is x and multiplier is 0.56 then the royalty
/// value would be 0.56 * x.
/// Generally percentage get represented in terms of basis points
/// in solidity based smart contracts while cadence offers `UFix64`
/// that already supports the basis points use case because its
/// operations are entirely deterministic integer operations and support
/// up to 8 points of precision.
pub let cut: UFix64
/// Optional description: This can be the cause of paying the royalty,
/// the relationship between the `wallet` and the NFT, or anything else
/// that the owner might want to specify.
pub let description: String
// truncated
}
/// Wrapper view for multiple Royalty views.
/// Marketplaces can query this `Royalties` struct from NFTs
/// and are expected to pay royalties based on these specifications.
///
pub struct Royalties {
/// Array that tracks the individual royalties
access(self) let cutInfos: [Royalty]
// truncated
}