Module of Collection RoyaltyDomain
RoyaltyDomain
allows creators to define custom royalty strategies,
collect royalties for their collections. Additionally, creators and their
respective royalty share are tracked.
royalty
does not provide a generic calculate
function that takes into
account all royalty strategies defined on the domain, as the OriginByte
standard does not know how to read strategies not otherwise defined by it.
The module relies on an external contract to drive the royalty gathering and dirtribution flow.
Structs
royalty::RoyaltyDomain has store
royalty::RoyaltyDomain has store
Fields:
Name | Type | Description |
---|---|---|
strategies
|
object::UID
|
Royalty strategies |
aggregations
|
object::UID
|
Aggregates received royalties across different coins |
royalty_shares_bps
|
vec_map::VecMap<address, u16>
|
Royalty share received by addresses |
RoyaltyDomain
stores royalty strategies for Collection
and
distributes them among creators
Usage
RoyaltyDomain
can only calculate royalties owed and distribute them
to shareholders, as a result, it relies on trusted price execution.
The usage example shows how to derive the owed royalties from the
example collection, Suimarines
, which uses TradePayment
as the
price oracle, but is also responsible for deconstructing it. For more
information read royalties.
module nft_protocol::suimarines {
struct Witness has drop {}
public entry fun collect_royalty<FT>(
payment: &mut TradePayment<SUIMARINES, FT>,
collection: &mut Collection<SUIMARINES>,
ctx: &mut TxContext,
) {
let b = royalties::balance_mut(Witness {}, payment);
let domain = royalty::royalty_domain(collection);
let royalty_owed =
royalty::calculate_proportional_royalty(domain, balance::value(b));
royalty::collect_royalty(collection, b, royalty_owed);
royalties::transfer_remaining_to_beneficiary(Witness {}, payment, ctx);
}
}
Methods
public fun new_empty(ctx: &mut tx_context::TxContext):
royalty::RoyaltyDomain
public fun new_empty(ctx: &mut tx_context::TxContext):
royalty::RoyaltyDomain
Creates an empty RoyaltyDomain
object
By not attributing any addresses, nobody will ever be able to claim
royalties from this RoyaltyDomain
object.
public fun from_address(
who: address,
ctx: &mut tx_context::TxContext,
): royalty::RoyaltyDomain
public fun from_address(
who: address,
ctx: &mut tx_context::TxContext,
): royalty::RoyaltyDomain
Creates a RoyaltyDomain
object with only one address attribution
Only the single address will be able to claim royalties from this
RoyaltyDomain
object.
public fun from_shares(
royalty_shares_bps: vec_map::VecMap<address, u16>,
ctx: &mut tx_context::TxContext,
): royalty::RoyaltyDomain
public fun from_shares(
royalty_shares_bps: vec_map::VecMap<address, u16>,
ctx: &mut tx_context::TxContext,
): royalty::RoyaltyDomain
Creates a RoyaltyDomain
with multiple attributions
Attributed addresses will be able to claim royalties weighted by their share in the total royalties.
Panics
Panics if total sum of creator basis point share is not equal to 10000
public fun borrow_share(
domain: &royalty::RoyaltyDomain,
who: &address,
): &u16
public fun borrow_share(
domain: &royalty::RoyaltyDomain,
who: &address,
): &u16
Returns the Creator
type for the given address
Panics
Panics if the provided address is not an attributed creator
public fun contains_share(
domain: &royalty::RoyaltyDomain,
who: &address,
): bool
public fun contains_share(
domain: &royalty::RoyaltyDomain,
who: &address,
): bool
Returns true when address is a defined creator
public fun contains_shares(domain: &royalty::RoyaltyDomain):
bool
public fun contains_shares(domain: &royalty::RoyaltyDomain):
bool
Returns true when a share attribution exists
public fun borrow_shares(domain: &royalty::RoyaltyDomain):
&vec_map::VecMap<address, u16>
public fun borrow_shares(domain: &royalty::RoyaltyDomain):
&vec_map::VecMap<address, u16>
Returns the list of creators defined on the CreatorsDomain
public fun add_share(
domain: &mut royalty::RoyaltyDomain,
who: address,
share: u16,
ctx: &mut tx_context::TxContext,
)
public fun add_share(
domain: &mut royalty::RoyaltyDomain,
who: address,
share: u16,
ctx: &mut tx_context::TxContext,
)
Attribute a share of royalties to an address
This must be done by an address which already has an attribution and partially gives up a share of their royalties for the benefit of the new attribution. Ensures that the total sum of shares remains constant.
Panics
Panics if the transaction sender does not have a large enough royalty share to transfer to the new creator or is not attributed in the first place.
public fun add_share_to_empty(
domain: &mut royalty::RoyaltyDomain,
who: address,
)
public fun add_share_to_empty(
domain: &mut royalty::RoyaltyDomain,
who: address,
)
Attribute royalties to an address
Panics
Panics if a share attribution already exists
public fun add_shares_to_empty(
domain: &mut royalty::RoyaltyDomain,
royalty_shares_bps: vec_map::VecMap<address, u16>,
)
public fun add_shares_to_empty(
domain: &mut royalty::RoyaltyDomain,
royalty_shares_bps: vec_map::VecMap<address, u16>,
)
Attribute royalties to addresses
Panics
Panics if a share attribution already exists
public fun remove_creator_by_transfer(
domain: &mut royalty::RoyaltyDomain,
to: address,
ctx: &mut tx_context::TxContext,
)
public fun remove_creator_by_transfer(
domain: &mut royalty::RoyaltyDomain,
to: address,
ctx: &mut tx_context::TxContext,
)
Remove a share attribution from an address and transfer attribution to another address
Shares of the removed attribution are allocated to the provided address, ensures that the total sum of shares remains constant.
Panics
Panics if attempting to remove attribution which doesn't belong to the transaction sender
public fun add_royalty_strategy<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
strategy: Strategy,
)
public fun add_royalty_strategy<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
strategy: Strategy,
)
Add a generic royalty strategy
Royalty strategies which are not part of the OriginByte standard must
implement their own calculation methods. Prefer using
add_proportional_royalty
and add_constant_royalty
if only adding
standard royalty strategies.
Panics
Panics if royalty strategy of the same type was already registered
public fun remove_strategy<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
): Strategy
public fun remove_strategy<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
): Strategy
Remove a royalty strategy
Prefer using remove_proportional_royalty
and
remove_constant_royalty
if only removing standard royalty strategies.
Panics
Panics if strategy was not defined
public fun contains_strategy<Strategy: drop + store>(
domain: &royalty::RoyaltyDomain,
): bool
public fun contains_strategy<Strategy: drop + store>(
domain: &royalty::RoyaltyDomain,
): bool
Check whether a royalty strategy is defined
public fun borrow_strategy<Strategy: drop + store>(
domain: &royalty::RoyaltyDomain,
): &Strategy
public fun borrow_strategy<Strategy: drop + store>(
domain: &royalty::RoyaltyDomain,
): &Strategy
Borrow a royalty strategy
Panics
Panics if strategy was not defined
public fun borrow_strategy_mut<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
): &mut Strategy
public fun borrow_strategy_mut<Strategy: drop + store>(
domain: &mut royalty::RoyaltyDomain,
): &mut Strategy
Mutably borrow a royalty strategy
Panics
Panics if strategy was not defined
public fun add_proportional_royalty(
domain: &mut royalty::RoyaltyDomain,
royalty_fee_bps: u64,
)
public fun add_proportional_royalty(
domain: &mut royalty::RoyaltyDomain,
royalty_fee_bps: u64,
)
Add proportional royalty policy
public fun add_constant_royalty(
domain: &mut royalty::RoyaltyDomain,
royalty_fee: u64,
)
public fun add_constant_royalty(
domain: &mut royalty::RoyaltyDomain,
royalty_fee: u64,
)
Add constant royalty policy
public fun remove_proportional_royalty(
domain: &mut royalty::RoyaltyDomain,
): royalty_strategy_bps::BpsRoyaltyStrategy
public fun remove_proportional_royalty(
domain: &mut royalty::RoyaltyDomain,
): royalty_strategy_bps::BpsRoyaltyStrategy
Remove proportional royalty policy
public fun remove_constant_royalty(
domain: &mut royalty::RoyaltyDomain,
): royalty_strategy_constant::ConstantRoyaltyStrategy
public fun remove_constant_royalty(
domain: &mut royalty::RoyaltyDomain,
): royalty_strategy_constant::ConstantRoyaltyStrategy
Remove constant royalty policy
public fun calculate_proportional_royalty(
domain: &royalty::RoyaltyDomain,
amount: u64,
): u64
public fun calculate_proportional_royalty(
domain: &royalty::RoyaltyDomain,
amount: u64,
): u64
Calculate how many tokens are due for the defined proportional royalty strategy.
Zero if strategy is undefined.
public fun calculate_constant_royalty(
domain: &royalty::RoyaltyDomain,
): u64
public fun calculate_constant_royalty(
domain: &royalty::RoyaltyDomain,
): u64
Calculate how many tokens are due for the defined constant royalty strategy.
Zero if strategy is undefined.
public fun collect_royalty<C, FT>(
collection: &mut collection::Collection<C>,
source: &mut balance::Balance<FT>,
amount: u64,
)
public fun collect_royalty<C, FT>(
collection: &mut collection::Collection<C>,
source: &mut balance::Balance<FT>,
amount: u64,
)
Collects an amount
of tokens from the provided balance into the
aggregate balance of the RoyaltyDomain
registered on the Collection
Requires that a RoyaltyDomain
is registered on the collection
public entry fun distribute_royalties<C, FT>(
collection: &mut collection::Collection<C>,
ctx: &mut tx_context::TxContext,
)
public entry fun distribute_royalties<C, FT>(
collection: &mut collection::Collection<C>,
ctx: &mut tx_context::TxContext,
)
Distributes the aggregated royalties for fungible token, FT
, among
the creators defined in CreatorsDomain
.
This endpoint is permissionless and can be called by anyone.
Panics
Panics if there is no aggregate for token FT
.
public fun distribute_balance<FT>(
shares: &vec_map::VecMap<address, u16>,
aggregate: &mut balance::Balance<FT>,
ctx: &mut tx_context::TxContext,
)
public fun distribute_balance<FT>(
shares: &vec_map::VecMap<address, u16>,
aggregate: &mut balance::Balance<FT>,
ctx: &mut tx_context::TxContext,
)
Distributes the contents of a Balance<FT>
among the addresses defined
in VecMap<address, u16>
VecMap<address, u16>
is treated as the basis point share in total
royalties due to the address.
public fun royalty_domain<C>(
collection: &collection::Collection<C>,
): &royalty::RoyaltyDomain
public fun royalty_domain<C>(
collection: &collection::Collection<C>,
): &royalty::RoyaltyDomain
Get reference to RoyaltyDomain
public fun royalty_domain_mut<C>(
_witness: witness::Witness<C>,
collection: &mut collection::Collection<C>,
): &mut royalty::RoyaltyDomain
public fun royalty_domain_mut<C>(
_witness: witness::Witness<C>,
collection: &mut collection::Collection<C>,
): &mut royalty::RoyaltyDomain
Get mutable reference to RoyaltyDomain
Requires that CreatorsDomain
is defined and sender is a creator
public fun add_royalty_domain<C, W>(
witness: &W,
collection: &mut collection::Collection<C>,
domain: royalty::RoyaltyDomain,
)
public fun add_royalty_domain<C, W>(
witness: &W,
collection: &mut collection::Collection<C>,
domain: royalty::RoyaltyDomain,
)
Registers RoyaltyDomain
on the given Collection