To enable custom royalty functionality with current Move design, we need to create a system in which collection's own implementation can use priviledge to access the NFT payments, yet anyone can call the royalty logic to finish their trade.
An instance of collection's struct W
(not the one-time-witness!)
enables it to extract funds from TradePayment
. After it calculates the
royalty from the NFT payment, it then transfers the rest to the
beneficiary address, be it the NFT seller or a marketplace/wallet.
The trading contracts can design their commission schemes such that the marketplaces and/or wallets are incentivized to resolve the settlements. That avoids extra txs sent by the user, because the client implementation will be such that they include everything in one batched tx if possible, or have automation.
Structs
royalties::TradePayment<C, FT> has key
royalties::TradePayment<C, FT> has key
Fields:
Name | Type | Description |
---|---|---|
id
|
object::UID
|
|
amount
|
balance::Balance<FT>
|
|
beneficiary
|
address
|
The address where the amount should be transferred to. This could be either the payment for the seller or a marketplace's commission. |
trade
|
option::Option<object::ID>
|
Optionally we enable grouping of payments, e.g. if there are multiple payments for one NFT (such as commission.), it might be useful for the royalty collection logic to distinguish such scenario. |
W
is the collection's witness (not the one time witness!) which
helps us ensure that the right royalty collection logic is operating
on this receipt.
C
ollection one-time-witnessF
ungibleT
oken
royalties::TradePaymentCreatedEvent has copy, drop
royalties::TradePaymentCreatedEvent has copy, drop
Fields:
Name | Type | Description |
---|---|---|
trade_payment
|
object::ID
|
|
amount
|
u64
|
|
beneficiary
|
address
|
|
trade
|
option::Option<object::ID>
|
Methods
public fun create<C, FT>(
amount: balance::Balance<FT>,
beneficiary: address,
ctx: &mut tx_context::TxContext,
)
public fun create<C, FT>(
amount: balance::Balance<FT>,
beneficiary: address,
ctx: &mut tx_context::TxContext,
)
public fun create_with_trade<C, FT>(
amount: balance::Balance<FT>,
beneficiary: address,
trade: object::ID,
ctx: &mut tx_context::TxContext,
)
public fun create_with_trade<C, FT>(
amount: balance::Balance<FT>,
beneficiary: address,
trade: object::ID,
ctx: &mut tx_context::TxContext,
)
public fun balance<C, FT>(
payment: &royalties::TradePayment<C, FT>,
): &balance::Balance<FT>
public fun balance<C, FT>(
payment: &royalties::TradePayment<C, FT>,
): &balance::Balance<FT>
public fun balance_mut<C, W: drop, FT>(
_witness: W,
payment: &mut royalties::TradePayment<C, FT>,
): &mut balance::Balance<FT>
public fun balance_mut<C, W: drop, FT>(
_witness: W,
payment: &mut royalties::TradePayment<C, FT>,
): &mut balance::Balance<FT>
W
is the collection's witness (not the one time witness!) which
helps us ensure that the right royalty collection logic is operating
on this receipt.
Only the designated witness can access the balance.
Typically, this would be a witness exported from the collection contract and it would access the balance to calculate the royalty in its custom implementation.
public fun beneficiary<C, FT>(
payment: &royalties::TradePayment<C, FT>,
): address
public fun beneficiary<C, FT>(
payment: &royalties::TradePayment<C, FT>,
): address
public fun transfer_remaining_to_beneficiary<C, W: drop, FT>(
_witness: W,
payment: &mut royalties::TradePayment<C, FT>,
ctx: &mut tx_context::TxContext,
)
public fun transfer_remaining_to_beneficiary<C, W: drop, FT>(
_witness: W,
payment: &mut royalties::TradePayment<C, FT>,
ctx: &mut tx_context::TxContext,
)
public fun amount<C, FT>(
trade_payment: &royalties::TradePayment<C, FT>,
): &balance::Balance<FT>
public fun amount<C, FT>(
trade_payment: &royalties::TradePayment<C, FT>,
): &balance::Balance<FT>