<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fred Kyung-jin Rezeau</title>
    <description>The latest articles on DEV Community by Fred Kyung-jin Rezeau (@kyung_jin).</description>
    <link>https://dev.to/kyung_jin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F155873%2Fc2ece736-fba9-46f2-9535-2677b773f80d.jpg</url>
      <title>DEV Community: Fred Kyung-jin Rezeau</title>
      <link>https://dev.to/kyung_jin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kyung_jin"/>
    <language>en</language>
    <item>
      <title>Litemint: Embracing Stellar Protocol 20 and Soroban Smart Contracts</title>
      <dc:creator>Fred Kyung-jin Rezeau</dc:creator>
      <pubDate>Tue, 20 Feb 2024 17:23:15 +0000</pubDate>
      <link>https://dev.to/kyung_jin/litemint-embracing-stellar-protocol-20-and-soroban-smart-contracts-10nd</link>
      <guid>https://dev.to/kyung_jin/litemint-embracing-stellar-protocol-20-and-soroban-smart-contracts-10nd</guid>
      <description>&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1759989655280463933-376" src="https://platform.twitter.com/embed/Tweet.html?id=1759989655280463933"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1759989655280463933-376');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1759989655280463933&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;p&gt;As the Stellar network embraces a new era with Protocol 20 and Soroban smart contracts, we at Litemint are set to leverage these advancements fully.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ soroban contract deploy --network mainnet&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In sync with Stellar's phased rollout—starting with limited Soroban transaction capacity—we are committing to a parallel strategy for our deployment.&lt;/p&gt;

&lt;p&gt;During Phase 1, we aim to test and monitor our auction and royalty smart contracts on mainnet, prioritizing security, network stability, and fee optimization.&lt;/p&gt;

&lt;p&gt;With the network moving towards full capacity in Phase 2, we are releasing the new Litemint marketplace and wallet app.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Litemint App: Zero blockchain babble
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Zero blockchain babble&lt;/em&gt; is the motto for our new app release, (&lt;a href="https://twitter.com/LitemintHQ/status/1759989655280463933"&gt;check out our video on X&lt;/a&gt; to see it in action).&lt;/p&gt;

&lt;p&gt;Similar to how gamers aren't required to know the game engines powering their favorite titles, our end-users should be able to focus solely on their immersive experience. We recognize that making the underlying technology invisible is crucial to Web3 adoption—and we have achieved just that.&lt;/p&gt;

&lt;p&gt;Features designed to ensure a frictionless user journey include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passwordless sign-ups and non-custodial wallet creation.&lt;/li&gt;
&lt;li&gt;Instant Usability. Craft. Sell. Collect.&lt;/li&gt;
&lt;li&gt;Mobile-first, state-of-the-art user interface.&lt;/li&gt;
&lt;li&gt;Fully integrated wallet with blockchain abstraction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Litemint app will be available on Android, iOS, Windows, Mac, and as a WebApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Royalty Smart Contract
&lt;/h2&gt;

&lt;p&gt;Our Royalty smart contract implements multiple royalty payment schemes for non-fungible tokens, including fixed, subscription, and percentage-based models.&lt;/p&gt;

&lt;p&gt;A key feature is its ability to enforce royalty payments without isolating NFTs from the Stellar DEX, ensuring full access to the liquidity layer. Our approach ensures that NFT creators and collectors can freely hold and trade their NFTs from any Stellar DEX compatible service, enjoying an unrestricted sales funnel.&lt;/p&gt;

&lt;p&gt;Read the full technical article &lt;a href="https://dev.to/kyung_jin/royalties-with-soroban-smart-contracts-an-interoperable-on-chain-solution-1dbm"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/litemint/litemint-soroban-contracts/tree/main/crates/litemint-royalty-contract"&gt;Source code&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Auction Smart Contract
&lt;/h2&gt;

&lt;p&gt;Our contract implements timed auctions with support for both open and sealed bid auctions, ascending and descending price mechanisms with linear or compound discount, customizable frequency/rate, buy now option, concurrent and cancellable bids, configurable marketplace commission rate, extendable auctions, easy behaviors plugin via strategy design pattern.&lt;/p&gt;

&lt;p&gt;Read the full technical article &lt;a href="https://dev.to/kyung_jin/oracles-with-soroban-smart-contracts-a-practical-and-flexible-on-chain-framework-f3g"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/litemint/litemint-soroban-contracts/tree/main/crates/litemint-auction-contract"&gt;Source code&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Go!
&lt;/h2&gt;

&lt;p&gt;As the Stellar network takes a significant step forward with Protocol 20, Litemint is ready to embrace the new possibilities that Soroban smart contracts bring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://litemint.io"&gt;Litemint.io&lt;/a&gt; new season is also set to start once our new platform and apps are deployed during phase 2. Keep posted for news on a new epic tournament and make sure you follow us on X for live discussions like this one.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1761691245641183653-69" src="https://platform.twitter.com/embed/Tweet.html?id=1761691245641183653"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1761691245641183653-69');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1761691245641183653&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;p&gt;We are fully committed to unlocking new horizons for creators, collectors, and gamers paving the way for unparalleled innovation in the creative economy.&lt;/p&gt;

&lt;p&gt;If you have any questions, don't hesitate to reach out. I'm usually active on &lt;a href="https://x.com/FredericRezeau"&gt;X @FredericRezeau&lt;/a&gt; and Discord where you can find me in the &lt;a href="https://litemint.gg"&gt;Litemint&lt;/a&gt;, &lt;a href="https://discord.gg/stellar-global-761985725453303838"&gt;Stellar Global&lt;/a&gt; and &lt;a href="https://discord.gg/stellardev"&gt;Stellar Developers&lt;/a&gt; servers!&lt;/p&gt;

&lt;p&gt;Feel free to reach out on &lt;a href="https://github.com/FredericRezeau"&gt;GitHub&lt;/a&gt; too.&lt;/p&gt;

</description>
      <category>soroban</category>
      <category>stellar</category>
      <category>litemint</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Royalties with Soroban Smart Contracts: An Interoperable On-Chain Solution</title>
      <dc:creator>Fred Kyung-jin Rezeau</dc:creator>
      <pubDate>Fri, 29 Dec 2023 17:19:39 +0000</pubDate>
      <link>https://dev.to/kyung_jin/royalties-with-soroban-smart-contracts-an-interoperable-on-chain-solution-1dbm</link>
      <guid>https://dev.to/kyung_jin/royalties-with-soroban-smart-contracts-an-interoperable-on-chain-solution-1dbm</guid>
      <description>&lt;p&gt;Returning for the second article in our series, this time we are tackling royalties and on-chain payment enforcements.&lt;/p&gt;

&lt;p&gt;Royalties play a pivotal role in digital economies, yet the web3 industry still faces many challenges in implementing decentralized royalty payments.&lt;/p&gt;

&lt;p&gt;Two key issues stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized control&lt;/strong&gt;: Echoing Web2, NFT marketplaces maintain significant control over royalty payments. The issues arising from optional royalties (&lt;a href="https://eips.ethereum.org/EIPS/eip-2981" rel="noopener noreferrer"&gt;EIP-2981&lt;/a&gt;) were discussed during our session on the &lt;a href="https://twitter.com/LitemintHQ/status/1581565573112401925" rel="noopener noreferrer"&gt;Future of NFT&lt;/a&gt; at Meridian 2022 in Rome—far-reaching implications for both builders and creators and still a lot of work needed here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Narrowed markets&lt;/strong&gt;: 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. &lt;a href="https://opensea.io/blog/articles/creator-fees-update" rel="noopener noreferrer"&gt;Their blog article&lt;/a&gt; provides very insightful details into this issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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 &lt;em&gt;bridging&lt;/em&gt; with Soroban in detail).&lt;/p&gt;

&lt;p&gt;Leveraging the &lt;em&gt;first-class citizen&lt;/em&gt; assets model of &lt;a href="https://stellar.org/" rel="noopener noreferrer"&gt;Stellar&lt;/a&gt; and &lt;a href="https://soroban.stellar.org/" rel="noopener noreferrer"&gt;Soroban&lt;/a&gt; smart contracts, this solution is being integrated into Litemint (&lt;a href="https://github.com/litemint/litemint-soroban-contracts/tree/main/crates/litemint-royalty-contract" rel="noopener noreferrer"&gt;source on Github&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;At its core, the system models an on-chain &lt;em&gt;&lt;strong&gt;security interest&lt;/strong&gt;&lt;/em&gt; framework, where a Non-Fungible Token (NFT) is the collateral.&lt;/p&gt;

&lt;p&gt;Effectively abstracting the NFT property from the royalty payment process, this approach offers two significant advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open and Interoperable&lt;/strong&gt;: 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 &lt;a href="https://developers.stellar.org/docs/issuing-assets/control-asset-access#controlling-access-to-an-asset-with-flags" rel="noopener noreferrer"&gt;authorization flags&lt;/a&gt;). Seamless NFT compatibility with all SDEX-based services is maintained.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized and Unobtrusive&lt;/strong&gt;: 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. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a diagram of the process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0slwu1nrpuv0d0tu2hu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0slwu1nrpuv0d0tu2hu.png" alt="Sequence diagram royalties"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

&lt;h2&gt;
  
  
  Understanding Stellar NFTs
&lt;/h2&gt;

&lt;p&gt;Although Stellar provides &lt;a href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0039.md" rel="noopener noreferrer"&gt;recommendations&lt;/a&gt;, 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—&lt;a href="https://blog.m-ou.se/rust-standard/" rel="noopener noreferrer"&gt;…Do we need one?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

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

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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1hgyek8vbtbg0i5qw30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1hgyek8vbtbg0i5qw30.png" alt="NFTs are Assets on Stellar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this ecosystem, using Soroban smart contracts for NFT issuance or trading isn't a prerequisite—thereby avoiding the complexities mentioned previously.&lt;/p&gt;

&lt;p&gt;Instead, smart contracts can be effectively leveraged to implement and enforce creators attached &lt;em&gt;royalty terms&lt;/em&gt;, coupled with a transparent and decentralized ownership recovery process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With great &lt;em&gt;ownership&lt;/em&gt; comes great responsibility&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the Stellar Ecosystem, as outlined in &lt;a href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md" rel="noopener noreferrer"&gt;SEP-1&lt;/a&gt;, the &lt;code&gt;conditions&lt;/code&gt; field under &lt;code&gt;[CURRENCIES]&lt;/code&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the Code on GitHub
&lt;/h2&gt;

&lt;p&gt;The code for the Litemint royalty smart contract is located in this &lt;a href="https://github.com/litemint/litemint-soroban-contracts/" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; (MIT License).&lt;/p&gt;

&lt;p&gt;Besides providing an implementation of the system described above, the smart contract also provides the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Percentage-based royalty payments (see &lt;a href="https://github.com/litemint/litemint-soroban-contracts/blob/master/crates/litemint-royalty-contract/src/agreement/compensation_percentage.rs" rel="noopener noreferrer"&gt;compensation_percentage.rs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Fixed royalty payments (see &lt;a href="https://github.com/litemint/litemint-soroban-contracts/blob/master/crates/litemint-royalty-contract/src/agreement/compensation_fixed.rs" rel="noopener noreferrer"&gt;compensation_fixed.rs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Subscription royalty payments (see &lt;a href="https://github.com/litemint/litemint-soroban-contracts/blob/master/crates/litemint-royalty-contract/src/agreement/compensation_subscription.rs" rel="noopener noreferrer"&gt;compensation_subscription.rs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Support for all currencies and markets.&lt;/li&gt;
&lt;li&gt;Optional NFT transfer fee.&lt;/li&gt;
&lt;li&gt;Configurable grace period and marketplace commission rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; The compensation scheme implementation uses the strategy design pattern so you can easily add new ones to fit your requirements.&lt;/p&gt;

&lt;p&gt;Go ahead and clone the repository. Then, execute the following command to compile the contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Deployment and Configuration
&lt;/h2&gt;

&lt;p&gt;We assume that the following network and identity are pre-configured (&lt;code&gt;soroban config&lt;/code&gt;) and funded. Follow &lt;a href="https://soroban.stellar.org/docs/getting-started/setup" rel="noopener noreferrer"&gt;this link&lt;/a&gt; if you need instructions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TESTNET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stellar Testnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ADMIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contract admin&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To deploy the royalty contract, use the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract deploy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--wasm&lt;/span&gt; target/wasm32-unknown-unknown/release/litemint_royalty_contract.wasm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Configure the &lt;code&gt;ADMIN&lt;/code&gt;. Additionally, the marketplace commission rate is set to 2% with this command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;ID&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; initialize &lt;span class="nt"&gt;--admin&lt;/span&gt; ADMIN &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--commission_rate&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Further Interaction
&lt;/h2&gt;

&lt;p&gt;Until now in this series, we used the &lt;strong&gt;Soroban CLI&lt;/strong&gt; to interact with contracts. However, for practical applications, you will likely need to interact via the &lt;a href="https://www.npmjs.com/package/stellar-sdk" rel="noopener noreferrer"&gt;stellar-sdk&lt;/a&gt; within your own app, especially if you need to interact with accounts and assets on the Stellar blockchain.&lt;/p&gt;

&lt;p&gt;To get you started, the following gist offers a sample script for interacting with the royalty smart contract. It invokes the &lt;code&gt;add_property&lt;/code&gt; method, passing a &lt;code&gt;Terms&lt;/code&gt; 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 &lt;code&gt;execute&lt;/code&gt; the contract and retrieve the updated &lt;code&gt;License&lt;/code&gt; state.&lt;/p&gt;

&lt;p&gt;Don't hesitate to explore further! You can also access the &lt;a href="https://dev.to/kyung_jin/oracles-with-soroban-smart-contracts-a-practical-and-flexible-on-chain-framework-f3g"&gt;oracle subscriber&lt;/a&gt; interface. Indeed, the Litemint royalty contract gets market price feeds via oracles on Soroban!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Two years back, I wrote this article &lt;a href="https://blog.litemint.com/nft-ownership-during-the-apocalypse/" rel="noopener noreferrer"&gt;NFT Ownership During The Apocalypse&lt;/a&gt; discussing how, with the right approach, NFT ownership can remain verifiable—even if Litemint or Stellar disappear!&lt;/p&gt;

&lt;p&gt;Likewise, NFT royalty payments should also &lt;em&gt;work&lt;/em&gt;, 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.&lt;/p&gt;

&lt;p&gt;That's a lot of challenges ahead. However, technologies like Soroban smart contracts provide opportunities to tackle them.&lt;/p&gt;

&lt;p&gt;I hope you found this enjoyable! Stay tuned for more detailed tutorials showcasing the full range of &lt;a href="https://github.com/FredericRezeau/soroban-kit" rel="noopener noreferrer"&gt;soroban-kit&lt;/a&gt; features!&lt;/p&gt;

&lt;p&gt;If you have any questions, don't hesitate to reach out. I'm usually active on &lt;a href="https://x.com/FredericRezeau" rel="noopener noreferrer"&gt;X @FredericRezeau&lt;/a&gt; and Discord where you can find me in the &lt;a href="https://litemint.gg" rel="noopener noreferrer"&gt;Litemint&lt;/a&gt;, &lt;a href="https://discord.gg/stellar-global-761985725453303838" rel="noopener noreferrer"&gt;Stellar Global&lt;/a&gt; and &lt;a href="https://discord.gg/stellardev" rel="noopener noreferrer"&gt;Stellar Developers&lt;/a&gt; servers!&lt;/p&gt;

&lt;p&gt;Feel free to reach out on &lt;a href="https://github.com/FredericRezeau" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>nft</category>
      <category>web3</category>
      <category>royalties</category>
      <category>soroban</category>
    </item>
    <item>
      <title>Oracles with Soroban Smart Contracts: A Practical and Flexible On-Chain Framework</title>
      <dc:creator>Fred Kyung-jin Rezeau</dc:creator>
      <pubDate>Fri, 22 Dec 2023 16:25:55 +0000</pubDate>
      <link>https://dev.to/kyung_jin/oracles-with-soroban-smart-contracts-a-practical-and-flexible-on-chain-framework-f3g</link>
      <guid>https://dev.to/kyung_jin/oracles-with-soroban-smart-contracts-a-practical-and-flexible-on-chain-framework-f3g</guid>
      <description>&lt;p&gt;The latest release of &lt;a href="https://github.com/FredericRezeau/soroban-kit"&gt;soroban-kit 0.1.8&lt;/a&gt; is now available, and it brings a set of tools designed to streamline both synchronous and asynchronous cross-contract communication, particularly for building more robust oracle systems with &lt;a href="https://soroban.stellar.org"&gt;soroban&lt;/a&gt;—exciting topic for my first post on dev.to!&lt;/p&gt;

&lt;p&gt;In this article, I'm going to walk you through the new &lt;code&gt;soroban-kit::oracle&lt;/code&gt; module step-by-step. You will learn how to build a flexible and extensible oracle system leveraging the &lt;em&gt;pub/sub&lt;/em&gt; pattern for asynchronous communication between multiple &lt;strong&gt;on-chain&lt;/strong&gt; oracle subscribers and brokers.&lt;/p&gt;

&lt;p&gt;We are implementing this system for our Soroban-powered &lt;a href="https://github.com/litemint/litemint-soroban-contracts"&gt;smart contracts on Litemint&lt;/a&gt;, specifically for feeding royalty contracts with market prices.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/FredericRezeau/soroban-kit"&gt;soroban-kit 0.1.8&lt;/a&gt; introduces two procedural attribute macros, &lt;code&gt;oracle_broker&lt;/code&gt; and &lt;code&gt;oracle_subscriber&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Applying these macros to your contract &lt;code&gt;struct&lt;/code&gt; automatically generates a lightweight messaging framework that enables both synchronous and asynchronous cross-contract communication, as demonstrated in the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CqikNUg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dok561ulnksvs1y8nmcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CqikNUg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dok561ulnksvs1y8nmcl.png" alt="Sequence diagram - soroban-kit::oracle" width="685" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By leveraging the publisher-subscriber pattern, we can enable multiplicity between oracle subscribers, brokers and publishers. Not only this enhances deployment flexibility but also allows for a gradual increase in system resilience and robustness—mitigating the risks associated with reliance on a single point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bhodWsiN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tftsztedlrohyfbx5ioi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bhodWsiN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tftsztedlrohyfbx5ioi.png" alt="Deployment diagram - soroban-kit::oracle" width="385" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The best part is, setting up your contracts for this requires &lt;strong&gt;only a single line of code&lt;/strong&gt;, all thanks to Rust's sophisticated macro system. For those curious about the inner workings and mechanics, take a look at &lt;a href="https://github.com/FredericRezeau/soroban-kit/blob/master/crates/soroban-macros/src/oracle.rs"&gt;oracle.rs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Alternatively, you can run &lt;code&gt;cargo expand&lt;/code&gt; command to view the expanded code generated by the macros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Implement the oracle broker interface for your contract.&lt;/span&gt;
&lt;span class="nd"&gt;#[contract]&lt;/span&gt;
&lt;span class="nd"&gt;#[oracle_broker(Bytes,&lt;/span&gt; &lt;span class="nd"&gt;Bytes)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OracleBrokerContract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Implement the oracle subscriber interface for your contract.&lt;/span&gt;
&lt;span class="nd"&gt;#[contract]&lt;/span&gt;
&lt;span class="nd"&gt;#[oracle_subscriber(Bytes,&lt;/span&gt; &lt;span class="nd"&gt;Bytes)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OracleSubscriberContract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These macros also allow you to customize the types for both the &lt;code&gt;topic&lt;/code&gt; and the &lt;code&gt;data&lt;/code&gt;. We use &lt;code&gt;Bytes&lt;/code&gt; in this example but any built-in type and user-defined type is supported, Soroban transparently provides for all our serialization needs!&lt;/p&gt;

&lt;p&gt;After setting it up, all that's required is to implement the &lt;code&gt;soroban-kit::oracle::Events&lt;/code&gt; trait to manage and process the workflow.&lt;/p&gt;

&lt;p&gt;Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the Code on Github
&lt;/h2&gt;

&lt;p&gt;The code for the example oracle project is located in this &lt;a href="https://github.com/FredericRezeau/soroban-oracle-example"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It consists of 2 smart contracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Oracle Broker Contract&lt;/strong&gt; (see &lt;a href="https://github.com/FredericRezeau/soroban-oracle-example/blob/master/crates/broker/src/lib.rs"&gt;lib.rs&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handling sync/async topic-based subscriber requests.&lt;/li&gt;
&lt;li&gt;Handling publishing requests.&lt;/li&gt;
&lt;li&gt;Collecting subscriber fees.&lt;/li&gt;
&lt;li&gt;Managing envelopes for async routing.&lt;/li&gt;
&lt;li&gt;Managing publishers whitelist.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Oracle Subscriber Contract&lt;/strong&gt; (see &lt;a href="https://github.com/FredericRezeau/soroban-oracle-example/blob/master/crates/subscriber/src/lib.rs"&gt;lib.rs&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routing topic-based data requests to broker contract.&lt;/li&gt;
&lt;li&gt;Handling sync/async responses.&lt;/li&gt;
&lt;li&gt;Managing brokers whitelist.&lt;/li&gt;
&lt;li&gt;Providing data reconciliation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note that our example &lt;strong&gt;data reconciliation&lt;/strong&gt; function simply replaces the old data with the new but more elaborate mechanisms can be implemented, including price aggregation, average computation, validation and coalescing of results, based on specific use cases.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;First, clone the repository. Then, execute the following command to compile the contracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once compiled, you'll find two oracle contracts &lt;em&gt;ready to deploy&lt;/em&gt; in the target directory.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; While they are already compact, using the optimization command (&lt;code&gt;soroban contract optimize&lt;/code&gt;) can shrink their sizes even more (to less than 3.5K for the broker contract and 2.5K for the subscriber one):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; broker.optimized.wasm subscriber.optimized.wasm
&lt;span class="nt"&gt;-rwxrwxrwx&lt;/span&gt; 1 3.4K Dec 22 22:29 broker.optimized.wasm
&lt;span class="nt"&gt;-rwxrwxrwx&lt;/span&gt; 1 2.5K Dec 22 22:29 subscriber.optimized.wasm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step-by-Step Deployment and Setup
&lt;/h2&gt;

&lt;p&gt;For our scenario below, we will need &lt;strong&gt;2 subscribers&lt;/strong&gt; and &lt;strong&gt;2 brokers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember, you always have the option to deploy additional nodes at any time. &lt;code&gt;soroban-kit::oracle&lt;/code&gt; ensures consistency for communication with decoupled, events-driven, interactions between your contracts (as long as the types are consistent, they can communicate).&lt;/p&gt;

&lt;p&gt;We assume that the following network and identities are pre-configured (&lt;code&gt;soroban config&lt;/code&gt;) and funded. Follow &lt;a href="https://soroban.stellar.org/docs/getting-started/setup"&gt;this link&lt;/a&gt; if you need instructions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TESTNET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stellar Testnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ADMIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contracts admin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALICE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Subscriber operator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BOB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publisher&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To deploy the oracle broker contracts and simultaneously save their &lt;em&gt;IDs&lt;/em&gt;, use the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract deploy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--wasm&lt;/span&gt; target/wasm32-unknown-unknown/release/broker.wasm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; BROKER1

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract deploy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--wasm&lt;/span&gt; target/wasm32-unknown-unknown/release/broker.wasm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; BROKER2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do the same for the oracle subscriber contracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract deploy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--wasm&lt;/span&gt; target/wasm32-unknown-unknown/release/subscriber.wasm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; SUBSCRIBER1

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract deploy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--wasm&lt;/span&gt; target/wasm32-unknown-unknown/release/subscriber.wasm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; SUBSCRIBER2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup the &lt;code&gt;ADMIN&lt;/code&gt; for all contracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; set_admin &lt;span class="nt"&gt;--admin&lt;/span&gt; ADMIN

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; set_admin &lt;span class="nt"&gt;--admin&lt;/span&gt; ADMIN

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; set_admin &lt;span class="nt"&gt;--admin&lt;/span&gt; ADMIN

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; set_admin &lt;span class="nt"&gt;--admin&lt;/span&gt; ADMIN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whitelist the publisher (&lt;code&gt;BOB&lt;/code&gt;) for both oracle brokers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_publisher &lt;span class="nt"&gt;--publisher&lt;/span&gt; BOB

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_publisher &lt;span class="nt"&gt;--publisher&lt;/span&gt; BOB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whitelist the brokers (&lt;code&gt;BROKER1&lt;/code&gt; and &lt;code&gt;BROKER2&lt;/code&gt;) for both oracle subscribers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_broker &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_broker &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_broker &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; allow_broker &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Executing a Test Scenario
&lt;/h2&gt;

&lt;p&gt;Everything is now ready! &lt;code&gt;ALICE&lt;/code&gt; is initiating data requests for &lt;strong&gt;&lt;code&gt;Topic 21&lt;/code&gt;&lt;/strong&gt; through &lt;code&gt;SUBSCRIBER1&lt;/code&gt; and &lt;code&gt;SUBSCRIBER2&lt;/code&gt; to both &lt;code&gt;BROKER1&lt;/code&gt; and &lt;code&gt;BROKER2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a deployment diagram to provide a clearer visual representation of the setup:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iXngKX6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x45uroq9a7pi1wsvrr6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iXngKX6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x45uroq9a7pi1wsvrr6v.png" alt="Alice deployment setup" width="431" height="149"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the commands to do so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ALICE &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; request &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--subscriber&lt;/span&gt; ALICE &lt;span class="nt"&gt;--topic&lt;/span&gt; 21 &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; null

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ALICE &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; request &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--subscriber&lt;/span&gt; ALICE &lt;span class="nt"&gt;--topic&lt;/span&gt; 21 &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; null

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ALICE &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; request &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--subscriber&lt;/span&gt; ALICE &lt;span class="nt"&gt;--topic&lt;/span&gt; 21 &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; null

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ALICE &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; request &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--subscriber&lt;/span&gt; ALICE &lt;span class="nt"&gt;--topic&lt;/span&gt; 21 &lt;span class="nt"&gt;--broker&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;BOB&lt;/code&gt; is setup to publish data exclusively to &lt;code&gt;BROKER2&lt;/code&gt;, and note that &lt;code&gt;BROKER1&lt;/code&gt; will not receive this data. Here's the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;BROKER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; BOB &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; publish &lt;span class="nt"&gt;--topic&lt;/span&gt; 21 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--publisher&lt;/span&gt; BOB &lt;span class="nt"&gt;--data&lt;/span&gt; 21000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because both subscribers were connected to &lt;code&gt;BROKER2&lt;/code&gt;, they have received and can now serve the data synchronously. Here are some example commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER1&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; get_data &lt;span class="nt"&gt;--topic&lt;/span&gt; 21

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 21000000

&lt;span class="nv"&gt;$ &lt;/span&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;SUBSCRIBER2&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source&lt;/span&gt; ADMIN &lt;span class="nt"&gt;--network&lt;/span&gt; TESTNET &lt;span class="nt"&gt;--&lt;/span&gt; get_data &lt;span class="nt"&gt;--topic&lt;/span&gt; 21

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 21000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Oracles serve as bridges between blockchains and external data sources. There are many key challenges in implementing Oracle services, including decentralization, synchronicity, decoupling and multiplicity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/FredericRezeau/soroban-kit"&gt;soroban-kit&lt;/a&gt; proposes a lightweight solution for implementing the pub/sub messaging pattern to help address these challenges for cross-contract communication. Allowing you to deploy nodes gradually to achieve resilience and robustness for your oracle system.&lt;/p&gt;

&lt;p&gt;I hope you found this enjoyable! Stay tuned for more detailed tutorials showcasing the full range of &lt;a href="https://github.com/FredericRezeau/soroban-kit"&gt;soroban-kit&lt;/a&gt; features!&lt;/p&gt;

&lt;p&gt;If you have any questions, don't hesitate to reach out. I'm usually active on &lt;a href="https://x.com/FredericRezeau"&gt;X @FredericRezeau&lt;/a&gt; and Discord where you can find me in the &lt;a href="https://litemint.gg"&gt;Litemint&lt;/a&gt;, &lt;a href="https://discord.gg/stellar-global-761985725453303838"&gt;Stellar Global&lt;/a&gt; and &lt;a href="https://discord.gg/stellardev"&gt;Stellar Developers&lt;/a&gt; servers!&lt;/p&gt;

&lt;p&gt;Feel free to reach out on &lt;a href="https://github.com/FredericRezeau"&gt;GitHub&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>rust</category>
      <category>soroban</category>
      <category>smartcontract</category>
    </item>
  </channel>
</rss>
