Developer Royalties

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.

A full example is here:

.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 {
        //...
    }
}

Package royalties can be claimed by the Package owner, using this manifest instruction:

CLAIM_PACKAGE_ROYALTIES
    Address("${package_address}");