- 07 Jun 2024
- 3 Minutes to read
- DarkLight
- PDF
Using Royalties
- Updated on 07 Jun 2024
- 3 Minutes to read
- DarkLight
- PDF
Royalties can be configured on methods and functions by a package publisher, or an instantiator, and are paid by transactions interacting with the given package or component as part of the transaction fee.
A package publisher may configure "developer royalties" to be applied to a package blueprint’s functions, or to component methods such that any component instantiated from that blueprint pays these royalties.
A component owner may additionally configure "owner royalties" to the methods of the component.
Example uses might include:
A developer adding a package-level royalty on a blueprint’s constructor, to charge the instantiator.
A developer adding a small package-level royalty for blueprint methods, to charge end-users.
An oracle owner charging a small (fixed) component royalty for using an oracle component, to help cover costs to maintain the oracle.
Royalty Amount
A royalty is always charged in XRD as part of the transaction fee, but a royalty amount may be configured as either XRD or "approximate USD equivalent".
When specified as "approximate USD equivalent", a constant multiplier is used to calculate the XRD charged. This constant is defined for a given protocol version, and updating of this multiplier is done at a protocol update. A large shift in the price of XRD will trigger creation of a protocol update to adjust this value, as per the policy in this blog post.
As such, charging a royalty as an "approximate USD equivalent" will likely be more stable in terms of real-world cost to end-users, in cases where the XRD price has large changes since the royalty was set.
There is also a maximum cap which can be charged as a royalty per method, this may be updated at future protocol updates.
Component Royalties
In order to charge component royalties, they must be enabled at instantiation time.
See the example below:
.instantiate()
//..
.enable_component_royalties(component_royalties! {
// The roles section is optional, if missing, all roles default to OWNER
roles {
royalty_setter => rule!(allow_all);
royalty_setter_updater => OWNER;
royalty_locker => OWNER;
royalty_locker_updater => rule!(deny_all);
royalty_claimer => OWNER;
royalty_claimer_updater => rule!(deny_all);
},
init {
public_method => Xrd(1.into()), updatable;
public_method_2 => Usd(1.into()), updatable;
protected_method => Free, locked;
}
})
.globalize()
Component royalties can be claimed, set and updated with proofs for the relevant role present, using this manifest instruction:
CLAIM_COMPONENT_ROYALTIES
Address("${component_address}");
SET_COMPONENT_ROYALTY
Address("${component_address}")
"my_method"
# OR Enum<RoyaltyAmount::Xrd>(Decimal("1"))
# OR Enum<RoyaltyAmount::Usd>(Decimal("1"))
Enum<RoyaltyAmount::Free>();
LOCK_COMPONENT_ROYALTY
Address("${component_address}")
"my_method";
Royalty Updating
A component royalty on a method can be set as either locked or updatable. An updatable royalty can later be locked.
Note that having an updatable royalty on a method may discourage people from using your component or package.
Package Royalties
Package royalties are optionally defined inside the blueprint’s module using the enable_package_royalties! invocation, and are fixed.
#[blueprint]
mod my_component {
enable_package_royalties! {
new => Xrd(2.into());
another_function => Xrd(2.into());
public_method => Free;
protected_method => Free;
}
struct MyComponent {
//...
}
impl MyComponent {
//...
}
}
Claiming Package Royalties
Package royalties can be claimed by the package owner using the following manifest instruction:
CLAIM_PACKAGE_ROYALTIES
Address("${package_address}");
All royalties generated by the package are directed to the package royalty accumulator vault. They can be claimed using the CLAIM_PACKAGE_ROYALTIES
instruction.
Full Example
We recommended giving Package Owners the ability to claim Package Royalties. In the following example, the Package Owner provides proof using create_proof_of_non_fungibles
.
You can verify the required proof in the Administrative Roles section of the Package on Mainnet and Stokenet (Search for your package > Configuration > Administrative Roles).
You can submit a Raw Transaction on the Mainnet Console and Stokenet Console.
CALL_METHOD
Address("account_rdx12xuhw6v30chdkhcu7qznz9vu926vxefr4h4tdvc0mdckg9rq4afx9t")
"create_proof_of_non_fungibles"
Address("resource_rdx1nfxxxxxxxxxxpkgwnrxxxxxxxxx002558553505xxxxxxxxxpkgwnr")
Array<NonFungibleLocalId>(
NonFungibleLocalId("[0da90c7658d1ba2299bfb87939519cff4ae59772e8fa7efb16f7c61dfbcf]")
)
;
CLAIM_PACKAGE_ROYALTIES
Address("package_rdx1pk5scajc6xaz9xdlhpunj5vula9wt9mjara8a7ck7lrpm770698ygs");
CALL_METHOD
Address("account_rdx12xuhw6v30chdkhcu7qznz9vu926vxefr4h4tdvc0mdckg9rq4afx9t")
"deposit_batch"
Expression("ENTIRE_WORKTOP");