Royalties with Soroban Smart Contracts: An Interoperable On-Chain Solution

Returning for the second article in our series, this time we are tackling royalties and on-chain payment enforcements.

Royalties play a pivotal role in digital economies, yet the web3 industry still faces many challenges in implementing decentralized royalty payments.

Two key issues stand out:

  • Centralized control: Echoing Web2, NFT marketplaces maintain significant control over royalty payments. The issues arising from optional royalties (EIP-2981) were discussed during our session on the Future of NFT at Meridian 2022 in Rome—far-reaching implications for both builders and creators and still a lot of work needed here.
  • Narrowed markets: Specialized smart contract solutions, while being decentralized, often constrict sales and cross-chain bridging opportunities for creators and collectors—also impacting the perception of asset ownership. A prime example is OpenSea’s recent decision to discontinue their on-chain Operator Filter. Their blog article provides very insightful details into this issue.

In this article, I present a decentralized solution for enforcing royalty payments, simultaneously ensuring that creators and collectors can openly trade their NFTs—anywhere they want (as this series progresses, we’ll explore bridging with Soroban in detail).

Leveraging the first-class citizen assets model of Stellar and Soroban smart contracts, this solution is being integrated into Litemint (source on Github).

How It Works

At its core, the system models an on-chain security interest framework, where a Non-Fungible Token (NFT) is the collateral.

Effectively abstracting the NFT property from the royalty payment process, this approach offers two significant advantages:

  • Open and Interoperable: The royalty smart contract does not need to take custody of or even interact with the NFT asset. This decoupling allows for complete freedom in issuance and transfer (i.e., eliminating the need for authorization flags). Seamless NFT compatibility with all SDEX-based services is maintained.
  • Decentralized and Unobtrusive: The process for reclaiming ownership is managed autonomously by the smart contract. This setup provides collectors with a transparent guarantee of ownership, provided their royalty payment obligations are fulfilled. Notably, collecting royalties does not require control over the trade execution of NFTs.

Here’s a diagram of the process:

Sequence diagram royalties

As illustrated above, a repossession lien token is issued to the royalty smart contract. The smart contract is designed to transfer the lien to the NFT creator exclusively when royalty payment obligations are not met. The creator can then execute a lien-dependent pre-authorized transaction to reclaim ownership of the asset.

💡 Tip: Although several strategies can be implemented with recovery depending on specific use cases (from an account_merge operation to a less destructive re-issuance), it should be executed atomically with a pre-auth transaction for predictability.

Understanding Stellar NFTs

Although Stellar provides recommendations, there is no NFT standard on Stellar. This brings to mind the question posed by Mara Bos, Rust team lead, about the necessity of a Rust standard—…Do we need one?.

In the tech world, late arrivals frequently improve upon existing models—they bring effective solutions that simply work. And just like Rust, I see Soroban and Stellar as perfect examples of this.

Contrasting with account-based ledger models like Ethereum, Stellar treats all assets, both native and user-defined, as first-class abstractions. This includes NFTs, as we can model non-fungibility through asset properties, eliminating the need for smart contract-based issuance or separate asset classes.

As illustrated below, on Stellar an NFT is just a regular asset with a single stroop supply amount and no signers. They have similar access to the interoperability layer, including the Layer 1 decentralized exchange (SDEX), cross-currency payments, liquidity pools, and are de facto compatible with any Stellar wallet.

NFTs are Assets on Stellar

In this ecosystem, using Soroban smart contracts for NFT issuance or trading isn’t a prerequisite—thereby avoiding the complexities mentioned previously.

Instead, smart contracts can be effectively leveraged to implement and enforce creators attached royalty terms, coupled with a transparent and decentralized ownership recovery process.

With great ownership comes great responsibility

In the Stellar Ecosystem, as outlined in SEP-1, the conditions field under [CURRENCIES] already serves to communicate specific asset conditions for holders. Royalty NFTs can readily take advantage of this field. We are also introducing accessible tools to assist collectors and buyers in managing their obligations, getting notifications for subscriptions and more.

Getting the Code on GitHub

The code for the Litemint royalty smart contract is located in this GitHub repo (MIT License).

Besides providing an implementation of the system described above, the smart contract also provides the following features:

💡 Tip: The compensation scheme implementation uses the strategy design pattern so you can easily add new ones to fit your requirements.

Go ahead and clone the repository. Then, execute the following command to compile the contract:

$ soroban contract build

Deployment and Configuration

We assume that the following network and identity are pre-configured (soroban config) and funded. Follow this link if you need instructions.

NetworkTESTNETStellar Testnet
AccountADMINContract admin

To deploy the royalty contract, use the following command:

$ soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/litemint_royalty_contract.wasm \
--source ADMIN --network TESTNET > ID

Configure the ADMIN. Additionally, the marketplace commission rate is set to 2% with this command:

$ soroban contract invoke --id $(cat ID) \
--source ADMIN --network TESTNET \
-- initialize --admin ADMIN \
--commission_rate 2

Further Interaction

Until now in this series, we used the Soroban CLI to interact with contracts. However, for practical applications, you will likely need to interact via the stellar-sdk within your own app, especially if you need to interact with accounts and assets on the Stellar blockchain.

To get you started, the following gist offers a sample script for interacting with the royalty smart contract. It invokes the add_property method, passing a Terms object that lets you define the NFT and various settings like compensation scheme (fixed, percentage, subscription), grace period, and transfer fees. It also shows how to execute the contract and retrieve the updated License state.

Don’t hesitate to explore further! You can also access the oracle subscriber interface. Indeed, the Litemint royalty contract gets market price feeds via oracles on Soroban!

Wrapping Up

Two years back, I wrote this article NFT Ownership During The Apocalypse discussing how, with the right approach, NFT ownership can remain verifiable—even if Litemint or Stellar disappear!

Likewise, NFT royalty payments should also work, sans intermediaries, for years to come. Web3 is all about creating a more open, fairer, less centralized environment, empowering creators to set their own rules for distributing their works.

That’s a lot of challenges ahead. However, technologies like Soroban smart contracts provide opportunities to tackle them.

I hope you found this enjoyable! Stay tuned for more detailed tutorials showcasing the full range of soroban-kit features!

If you have any questions, don’t hesitate to reach out. I’m usually active on X @FredericRezeau and Discord where you can find me in the Litemint, Stellar Global and Stellar Developers servers!

Feel free to reach out on GitHub too.

Happy coding!