Using Royalties
  • 07 Jun 2024
  • 3 Minutes to read
  • Dark
    Light
  • PDF

Using Royalties

  • Dark
    Light
  • PDF

Article summary

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");


Was this article helpful?

What's Next