<?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: Neeraj Choubisa</title>
    <description>The latest articles on DEV Community by Neeraj Choubisa (@kalidecoder).</description>
    <link>https://dev.to/kalidecoder</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%2F801186%2Fc2a7c47c-e040-49b2-9655-17bce26c9fbc.jpeg</url>
      <title>DEV Community: Neeraj Choubisa</title>
      <link>https://dev.to/kalidecoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kalidecoder"/>
    <language>en</language>
    <item>
      <title>Building a Fungible Token in Compact (Midnight)</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Fri, 03 Apr 2026 20:35:07 +0000</pubDate>
      <link>https://dev.to/midnight-aliit/building-a-fungible-token-in-compact-midnight-3nfh</link>
      <guid>https://dev.to/midnight-aliit/building-a-fungible-token-in-compact-midnight-3nfh</guid>
      <description>&lt;p&gt;The rise of privacy-focused blockchains like Midnight is introducing developers to a new paradigm of smart contract development using Compact language.&lt;/p&gt;

&lt;p&gt;If you are coming from Solidity, things may feel unfamiliar at first, especially concepts like inheritance, storage, and function definitions.&lt;/p&gt;

&lt;p&gt;In this article, you will learn how fungible tokens work in Compact, why inheritance does not exist, how to build your own token step by step, and how to fix common errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Compact
&lt;/h2&gt;

&lt;p&gt;Compact does not support inheritance like Solidity.&lt;/p&gt;

&lt;p&gt;Instead of writing:&lt;br&gt;
contract MyToken is ERC20&lt;/p&gt;

&lt;p&gt;Compact uses modules and composition. This means you import functionality and explicitly use it. There is no hidden behavior.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding the FungibleToken Module
&lt;/h2&gt;

&lt;p&gt;The FungibleToken module provides core token functionality such as balances tracking, allowances, transfers, minting and burning, and metadata like name, symbol, and decimals.&lt;/p&gt;

&lt;p&gt;There are a few differences compared to ERC20:&lt;br&gt;
It uses Uint&amp;lt;128&amp;gt; instead of uint256&lt;br&gt;
There are no events&lt;br&gt;
Contract to contract transfers are not supported yet&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Import the Module
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./token/FungibleToken.compact" prefix FT_;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 2: Create Your Token Contract
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.21.0;

import "./token/FungibleToken.compact" prefix FT_;

contract CustomFungibleToken {

  circuit init(): [] {
    FT_.initialize("Nikku Token", "NIK", 18);

    const owner = left&amp;lt;ZswapCoinPublicKey, ContractAddress&amp;gt;(ownPublicKey());
    FT_._mint(owner, 1000000);
  }

  circuit transfer(
    to: Either&amp;lt;ZswapCoinPublicKey, ContractAddress&amp;gt;,
    amount: Uint&amp;lt;128&amp;gt;
  ): Boolean {
    return FT_.transfer(to, amount);
  }

  circuit balanceOf(
    account: Either&amp;lt;ZswapCoinPublicKey, ContractAddress&amp;gt;
  ): Uint&amp;lt;128&amp;gt; {
    return FT_.balanceOf(account);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 3: Compile the Contract
&lt;/h2&gt;

&lt;p&gt;Run 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;npm run compile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Concepts to Remember
&lt;/h2&gt;

&lt;p&gt;Compact does not support inheritance.&lt;br&gt;
You must use circuit instead of function definitions.&lt;br&gt;
Modules manage their own storage.&lt;br&gt;
Initialization is required and must not be skipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Limitations
&lt;/h2&gt;

&lt;p&gt;Contract to contract calls are not supported.&lt;br&gt;
Events are not available.&lt;br&gt;
Only 128 bit integers are supported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mental Model
&lt;/h2&gt;

&lt;p&gt;Instead of thinking that your contract extends ERC20, think of it as using a token module and calling its functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Can Build Next
&lt;/h2&gt;

&lt;p&gt;You can extend this basic token to add mint restrictions, implement fees, or build more advanced applications on Midnight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Compact encourages explicit and predictable contract design. While it may take some time to adjust, it leads to better security and modularity.&lt;/p&gt;

&lt;p&gt;Once you understand this pattern, building on Midnight becomes much easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  About Author ?
&lt;/h2&gt;

&lt;p&gt;Hi, I’m Nikku.Dev, a Full Stack Blockchain Developer and builder. I work on smart contracts, DeFi systems, and Web3 applications, focusing on building real, scalable products.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://nikkudotdev.vercel.app/" rel="noopener noreferrer"&gt;https://nikkudotdev.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>midnightchallenge</category>
      <category>compact</category>
      <category>blockchain</category>
      <category>privacy</category>
    </item>
    <item>
      <title>DUST vs NIGHT: Rethinking How Blockchains Handle Value and Fees</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Tue, 31 Mar 2026 12:34:28 +0000</pubDate>
      <link>https://dev.to/midnight-aliit/dust-vs-night-rethinking-how-blockchains-handle-value-and-fees-586l</link>
      <guid>https://dev.to/midnight-aliit/dust-vs-night-rethinking-how-blockchains-handle-value-and-fees-586l</guid>
      <description>&lt;p&gt;In most blockchains, one token does everything it stores value and pays for transactions. For example, on Ethereum you use ETH for both holding value and paying gas fees, and on Bitcoin BTC serves a similar dual purpose.&lt;/p&gt;

&lt;p&gt;But Midnight takes a radically different approach.&lt;/p&gt;

&lt;p&gt;Instead of one token doing everything, Midnight splits responsibilities between NIGHT and DUST and that small design decision unlocks huge advantages for developers, users, and businesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NIGHT?
&lt;/h2&gt;

&lt;p&gt;NIGHT is the main token of Midnight the one that holds value and powers the ecosystem.&lt;br&gt;
Key Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed supply (24 billion)&lt;/li&gt;
&lt;li&gt;Public (unshielded)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Governance &amp;amp; voting&lt;/li&gt;
&lt;li&gt;Staking &amp;amp; consensus&lt;/li&gt;
&lt;li&gt;Block rewards&lt;/li&gt;
&lt;li&gt;Exchange trading
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👉 Think of NIGHT as your asset layer — the token you own, hold, and invest in.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  What is DUST?
&lt;/h2&gt;

&lt;p&gt;DUST is not a traditional token — it’s a resource generated by NIGHT.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t buy it.&lt;/li&gt;
&lt;li&gt;You don’t trade it.&lt;/li&gt;
&lt;li&gt;You earn it automatically by holding NIGHT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You register NIGHT to a DUST address&lt;/li&gt;
&lt;li&gt;Over time, it generates DUST&lt;/li&gt;
&lt;li&gt;You use DUST to pay transaction fees
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👉 Think of NIGHT as solar panels and DUST as electricity.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Properties of DUST
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shielded (Private)

DUST transactions are hidden — meaning:

- No public fee tracking
- No visible activity graph

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Non-transferable

You can’t send DUST to others It’s only used to pay fees
Leftover DUST returns to you .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decaying Mechanism

If you stop backing DUST with NIGHT, it decays to zero
Prevents hoarding and speculation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dynamic Balance

Unlike normal tokens: Your DUST increases over time
Depends on how much NIGHT you hold .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Shielded vs Unshielded Tokens
&lt;/h2&gt;

&lt;p&gt;Midnight goes further by letting developers choose:&lt;/p&gt;

&lt;p&gt;Token Privacy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unshielded → public (like ETH)&lt;/li&gt;
&lt;li&gt;Shielded → private via ZK proofs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Token Location:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ledger-based → high performance&lt;/li&gt;
&lt;li&gt;Contract-based → programmable
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👉 This flexibility is unique in blockchain design.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Viewing Keys: Selective Transparency
&lt;/h2&gt;

&lt;p&gt;Need compliance or auditing?&lt;/p&gt;

&lt;p&gt;Share a viewing key&lt;br&gt;
Others can see your private transactions&lt;br&gt;
But nothing becomes publicly visible&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⚠️ Important: Viewing keys are irreversible once shared.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The **DUST vs NIGHT **model is more than a token split it’s a fundamental redesign of blockchain economics.&lt;/p&gt;

&lt;p&gt;What Midnight achieves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stable and predictable fees&lt;/li&gt;
&lt;li&gt;Strong privacy guarantees&lt;/li&gt;
&lt;li&gt;Protection from MEV attacks&lt;/li&gt;
&lt;li&gt;Better onboarding experience&lt;/li&gt;
&lt;li&gt;Flexible identity and token systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About Author ?
&lt;/h2&gt;

&lt;p&gt;Hi, I’m Nikku.Dev, a Full Stack Blockchain Developer and builder. I work on smart contracts, DeFi systems, and Web3 applications, focusing on building real, scalable products.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://nikkudotdev.vercel.app/" rel="noopener noreferrer"&gt;https://nikkudotdev.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>midnightchallenge</category>
      <category>midnight</category>
      <category>blockchain</category>
      <category>compact</category>
    </item>
    <item>
      <title>Running a Validator on Push Chain: A Builder’s Guide</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Fri, 27 Mar 2026 01:33:14 +0000</pubDate>
      <link>https://dev.to/kalidecoder/running-a-validator-on-push-chain-a-builders-guide-201l</link>
      <guid>https://dev.to/kalidecoder/running-a-validator-on-push-chain-a-builders-guide-201l</guid>
      <description>&lt;p&gt;The future of decentralized infrastructure isn’t just about building apps it’s about &lt;strong&gt;running the network itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you’ve ever wanted to go deeper than smart contracts and actually &lt;strong&gt;participate in consensus&lt;/strong&gt;, running a validator on Push Chain is one of the easiest ways to get started.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll break down what a validator is, why it matters, and how you can spin one up in minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Validator?
&lt;/h2&gt;

&lt;p&gt;A validator is a node that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifies transactions&lt;/li&gt;
&lt;li&gt;Produces new blocks&lt;/li&gt;
&lt;li&gt;Secures the blockchain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Push Chain uses a &lt;strong&gt;Proof-of-Stake (PoS)&lt;/strong&gt; model, meaning validators stake tokens to participate in the network and earn rewards.&lt;/p&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instead of just building on the blockchain, you’re helping &lt;em&gt;run&lt;/em&gt; it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Run a Validator on Push Chain?
&lt;/h2&gt;

&lt;p&gt;Push Chain makes validator setup extremely developer friendly. Here’s why it stands out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple CLI-based setup&lt;/strong&gt; — no complex configs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast sync using snapshots&lt;/strong&gt; — no need to download full history&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-upgrades with Cosmovisor&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in dashboard for monitoring&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Earn rewards + participate in governance&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're a builder, DevRel, or infra enthusiast this is a great way to level up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Linux/macOS machine (or VPS)&lt;/li&gt;
&lt;li&gt;Basic terminal knowledge&lt;/li&gt;
&lt;li&gt;Testnet tokens (PC tokens)&lt;/li&gt;
&lt;li&gt;Stable internet connection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Install &amp;amp; Start the Node
&lt;/h2&gt;

&lt;p&gt;Run 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;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.push.network/node/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script does everything for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installs dependencies&lt;/li&gt;
&lt;li&gt;Sets up the node&lt;/li&gt;
&lt;li&gt;Starts syncing using snapshots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⏱️ You’ll be up and running in about &lt;strong&gt;5–20 minutes&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Check Sync Status
&lt;/h2&gt;

&lt;p&gt;To check if your node is fully synced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;push-validator status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’re good to go when you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Catching Up: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Register as a Validator
&lt;/h2&gt;

&lt;p&gt;Now comes the important part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;push-validator register-validator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted to configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wallet (create/import)&lt;/li&gt;
&lt;li&gt;Validator name (moniker)&lt;/li&gt;
&lt;li&gt;Commission rate&lt;/li&gt;
&lt;li&gt;Stake amount (~1.5 PC minimum)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once done 🎉 &lt;strong&gt;you’re officially a validator!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Monitor Your Node
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;push-validator dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens a real-time CLI dashboard showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node health&lt;/li&gt;
&lt;li&gt;Sync status&lt;/li&gt;
&lt;li&gt;Validator performance&lt;/li&gt;
&lt;li&gt;Logs and peers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s like having a lightweight DevOps panel in your terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful Commands
&lt;/h2&gt;

&lt;p&gt;Here are some commands you’ll frequently use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;push-validator start
push-validator stop
push-validator logs
push-validator withdraw-rewards
push-validator restake-rewards
push-validator unjail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These help you manage, debug, and optimize your validator.&lt;/p&gt;




&lt;h2&gt;
  
  
  💸 How Do You Earn?
&lt;/h2&gt;

&lt;p&gt;Validators earn rewards by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validating blocks&lt;/li&gt;
&lt;li&gt;Receiving delegations from others&lt;/li&gt;
&lt;li&gt;Charging commission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more stake you have (self + delegated), the higher your rewards.&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep your &lt;strong&gt;seed phrase safe&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ensure &lt;strong&gt;uptime (avoid downtime penalties)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set a reasonable commission&lt;/li&gt;
&lt;li&gt;Monitor performance regularly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Running a validator isn’t just about earning rewards it’s about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supporting decentralization&lt;/li&gt;
&lt;li&gt;Gaining deeper infra knowledge&lt;/li&gt;
&lt;li&gt;Becoming a core part of the ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Push Chain removes the usual complexity and makes validator operations &lt;strong&gt;accessible to every builder&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’re already building in Web3, running a validator is your next power move.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Try running a validator on testnet&lt;/li&gt;
&lt;li&gt;Experiment with staking strategies&lt;/li&gt;
&lt;li&gt;Explore Push Chain’s universal apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly &lt;strong&gt;don’t just build on the network, help run it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About Author ?
&lt;/h2&gt;

&lt;p&gt;Hi, I’m NikkuDotDev, a Full Stack Blockchain Developer and builder. I work on smart contracts, DeFi systems, and Web3 applications, focusing on building real, scalable products.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://nikkudotdev.vercel.app/" rel="noopener noreferrer"&gt;https://nikkudotdev.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pushchain</category>
      <category>solidity</category>
      <category>blockchain</category>
      <category>validators</category>
    </item>
    <item>
      <title>Midnight Blockchain Architecture ( Layman Explanation )</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Tue, 24 Mar 2026 20:22:33 +0000</pubDate>
      <link>https://dev.to/midnight-aliit/midnight-blockchain-architecture-layman-explanation--4idb</link>
      <guid>https://dev.to/midnight-aliit/midnight-blockchain-architecture-layman-explanation--4idb</guid>
      <description>&lt;p&gt;Midnight is a special type of blockchain that focuses on privacy and trust together. Most blockchains are fully transparent, but Midnight allows you to keep important data private while still proving that everything is correct.&lt;/p&gt;

&lt;p&gt;To understand Midnight, think of it as three main parts working together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Partner Chain (network and security)&lt;/li&gt;
&lt;li&gt;Kachina (private smart contracts)&lt;/li&gt;
&lt;li&gt;Compact (developer layer)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break this down in a simple way.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Main Problem Midnight Solves
&lt;/h2&gt;

&lt;p&gt;In normal blockchains:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Everyone can see all data&lt;br&gt;
Smart contracts run publicly&lt;br&gt;
No privacy for users&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a problem called private shared state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
A company wants to store employee salaries on blockchain&lt;br&gt;
But salaries should be private&lt;/p&gt;

&lt;p&gt;So how do you:&lt;br&gt;
&lt;code&gt;Keep data private Still trust the system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Midnight solves this by separating:&lt;br&gt;
&lt;code&gt;Verification from Visibility&lt;/code&gt;&lt;br&gt;
This means the network checks if something is correct without seeing the actual data .&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Partner Chain Architecture (Security Layer)
&lt;/h2&gt;

&lt;p&gt;Midnight is connected to Cardano using something called a Partner Chain.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
Simple meaning:&lt;br&gt;
Midnight runs its own network&lt;br&gt;
But uses Cardano’s ecosystem for security .&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;How it works&lt;/strong&gt;&lt;br&gt;
Validators (block producers) can be Cardano stake pool operators&lt;br&gt;
The system uses:&lt;br&gt;
AURA for block production GRANDPA for finality&lt;/p&gt;

&lt;p&gt;Midnight nodes also track data from Cardano using tools like database sync systems .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Real Life Example
Think of Midnight like a startup company
And Cardano like a trusted parent company
Midnight builds new features (privacy apps)
Cardano provides trust and reliability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Kachina Model (Privacy Layer)
&lt;/h2&gt;

&lt;p&gt;Kachina is the core idea that makes privacy possible.&lt;br&gt;
It splits data into two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Public State&lt;/li&gt;
&lt;li&gt;Stored on blockchain&lt;/li&gt;
&lt;li&gt;Visible to everyone&lt;/li&gt;
&lt;li&gt;Private State&lt;/li&gt;
&lt;li&gt;Stored on user device&lt;/li&gt;
&lt;li&gt;Never shared publicly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These two are connected using zero knowledge proofs&lt;br&gt;
Meaning:&lt;br&gt;
You can prove something is correct without showing the data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Real Life Example
Imagine online voting:
Your vote stays on your device (private)
The system proves you voted correctly
Blockchain only stores final count
No one knows your vote
But everyone trusts the result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Compact (Developer Layer)
&lt;/h2&gt;

&lt;p&gt;Compact is the language used to write smart contracts on Midnight.&lt;/p&gt;

&lt;p&gt;But unlike normal blockchains:&lt;br&gt;
You are not writing code that runs directly on chain&lt;/p&gt;

&lt;p&gt;Instead, you are writing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A circuit&lt;/li&gt;
&lt;li&gt;That generates a proof&lt;/li&gt;
&lt;li&gt;Then the blockchain verifies that proof&lt;/li&gt;
&lt;li&gt;Three Parts of a Contract&lt;/li&gt;
&lt;li&gt;Public part (on blockchain)&lt;/li&gt;
&lt;li&gt;Private logic (runs locally)&lt;/li&gt;
&lt;li&gt;Proof generation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This design ensures:&lt;/p&gt;

&lt;p&gt;Private data never goes to blockchain&lt;br&gt;
Only proofs are shared&lt;/p&gt;
&lt;h2&gt;
  
  
  5. How a Transaction Works (Simple Flow)
&lt;/h2&gt;

&lt;p&gt;Here is what happens step by step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User runs contract locally&lt;/li&gt;
&lt;li&gt;Private data is used (not shared)&lt;/li&gt;
&lt;li&gt;A proof is generated&lt;/li&gt;
&lt;li&gt;Proof is sent to blockchain&lt;/li&gt;
&lt;li&gt;Blockchain verifies proof&lt;/li&gt;
&lt;li&gt;Public state updates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;If proof is wrong → transaction fails !!!!&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Real Life End to End Example
&lt;/h2&gt;

&lt;p&gt;Example: Loan Approval System&lt;/p&gt;

&lt;p&gt;A user wants a loan but does not want to share full financial data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional system:
Upload salary, bank details
Data is exposed

Midnight system:
User keeps data locally

Contract checks:
income &amp;gt; required limit
Generates proof
Blockchain verifies proof
Loan approved

Result:

Bank trusts the decision
User data stays private

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fgqpwzi5rx4borugx4x0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgqpwzi5rx4borugx4x0s.png" alt=" " width="720" height="1290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About Author :
&lt;/h2&gt;

&lt;p&gt;I'm builder and founder focused on Web3 infrastructure, smart contracts, and developer tools. I specialize in turning complex blockchain ideas into scalable, real-world products across DeFi, cross-chain systems, and AI-integrated applications.&lt;/p&gt;

&lt;p&gt;I’ve worked across multiple ecosystems building production-grade dApps, while also contributing to developer communities through hackathons, content, and open-source. My focus is on building products that are not just technically sound, but actually usable and impactful.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://nikkudotdev.vercel.app/" rel="noopener noreferrer"&gt;https://nikkudotdev.vercel.app/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder&lt;/a&gt;&lt;br&gt;
Contribution : &lt;a href="https://github.com/Kali-Decoder/midnight-dapps" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder/midnight-dapps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>midnightchallenge</category>
      <category>blockchain</category>
      <category>compact</category>
      <category>privacy</category>
    </item>
    <item>
      <title>The Builder’s Guide to Tokens : on the Midnight Network</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Tue, 24 Mar 2026 09:14:47 +0000</pubDate>
      <link>https://dev.to/midnight-aliit/the-builders-guide-to-tokens-on-the-midnight-network-15la</link>
      <guid>https://dev.to/midnight-aliit/the-builders-guide-to-tokens-on-the-midnight-network-15la</guid>
      <description>&lt;p&gt;Blockchain is powerful because it is open and transparent. But that also creates a problem. Everyone can see everything, which is not always good when dealing with sensitive data. This is called the transparency paradox.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Midnight Network&lt;/strong&gt; solves this problem by bringing privacy into blockchain while still keeping trust and compliance. It is built as a Cardano sidechain and focuses on something called rational privacy. This means users can keep important data private while still proving things when needed.&lt;/p&gt;

&lt;p&gt;As Midnight moves toward its mainnet phase called Kūkolu in 2026, this guide explains how developers can build and manage tokens on the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Token Economy with NIGHT and DUST
&lt;/h2&gt;

&lt;p&gt;Midnight uses two tokens instead of one. Each has a clear role.&lt;/p&gt;

&lt;p&gt;NIGHT is the main token. It is visible on the network and is used for staking, governance, and security. The total supply is fixed at 24 billion.&lt;/p&gt;

&lt;p&gt;DUST is very different. It is private and cannot be transferred between users. It is used to pay for transactions and smart contract execution.&lt;/p&gt;

&lt;p&gt;The interesting part is how DUST is created. When you hold NIGHT, you automatically generate DUST over time. This is often called the battery model.&lt;/p&gt;

&lt;p&gt;This system gives developers a big advantage. Costs become predictable because you are not dependent on changing gas fees like in other blockchains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Stack Made Simple
&lt;/h2&gt;

&lt;p&gt;Midnight is designed so developers do not need deep knowledge of cryptography.&lt;/p&gt;

&lt;p&gt;Smart contracts are written in a language called Compact. It is similar to TypeScript, so it feels familiar if you have done web development.&lt;/p&gt;

&lt;p&gt;There is also a full SDK called Midnight.js. It helps you interact with contracts, manage wallets, and build applications easily.&lt;/p&gt;

&lt;p&gt;For privacy, Midnight uses a Local Proof Server. This runs on the user’s machine and creates zero knowledge proofs. This means private data never leaves the device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step by Step Guide to Build a Token
&lt;/h2&gt;

&lt;p&gt;Here is a simple flow to create and deploy a token on Midnight.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First, set up your environment. Install the Compact compiler, Midnight CLI, and Docker for running a local network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, set up your wallet. Use Lace Wallet and switch to the Midnight Preview Network. You can get test tokens called tDUST from the faucet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then write your smart contract. Create a Compact file where you define how your token works. This includes minting, burning, and transfers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After that, test locally. Use the Local Proof Server to generate proofs and check everything before sending transactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, deploy your contract. Compile it and deploy using the Midnight CLI to the test network. Later you can deploy to mainnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security for Real World Applications
&lt;/h2&gt;

&lt;p&gt;For production use, security is very important.&lt;/p&gt;

&lt;p&gt;Midnight supports OpenZeppelin Compact Libraries. These are tested and secure building blocks that help you create safe smart contracts.&lt;/p&gt;

&lt;p&gt;You can use them to build tokens, NFTs, identity systems, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Midnight is Important ?
&lt;/h2&gt;

&lt;p&gt;Midnight brings a new approach to blockchain.&lt;/p&gt;

&lt;p&gt;It gives privacy without removing trust. It makes costs predictable. It provides simple tools for developers. It also helps in building applications that follow regulations.&lt;/p&gt;

&lt;p&gt;This makes it useful for finance, identity, enterprise apps, and many other use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Midnight solves one of the biggest problems in blockchain. It allows developers to build applications that are both private and trustworthy.&lt;/p&gt;

&lt;p&gt;With its dual token system, zero knowledge technology, and easy development tools, it is a strong platform for the future of Web3.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Author :
&lt;/h2&gt;

&lt;p&gt;I'm builder and founder focused on Web3 infrastructure, smart contracts, and developer tools. I specialize in turning complex blockchain ideas into scalable, real-world products across DeFi, cross-chain systems, and AI-integrated applications.&lt;/p&gt;

&lt;p&gt;I’ve worked across multiple ecosystems building production-grade dApps, while also contributing to developer communities through hackathons, content, and open-source. My focus is on building products that are not just technically sound, but actually usable and impactful.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://nikkudotdev.vercel.app/" rel="noopener noreferrer"&gt;https://nikkudotdev.vercel.app/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder&lt;/a&gt;&lt;br&gt;
Contribution : &lt;a href="https://github.com/Kali-Decoder/midnight-dapps" rel="noopener noreferrer"&gt;https://github.com/Kali-Decoder/midnight-dapps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>midnight</category>
      <category>privacy</category>
      <category>nighttoken</category>
      <category>guide</category>
    </item>
    <item>
      <title>Somnia On-Chain Reactivity</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Mon, 16 Feb 2026 14:06:10 +0000</pubDate>
      <link>https://dev.to/kalidecoder/somnia-on-chain-reactivity-2a2i</link>
      <guid>https://dev.to/kalidecoder/somnia-on-chain-reactivity-2a2i</guid>
      <description>&lt;p&gt;Building Reactive Smart Contracts on Somnia&lt;br&gt;
A Developer Guide with Real Solidity Examples&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;As Web3 developers, we often build systems that require automatic reactions.&lt;/p&gt;

&lt;p&gt;Examples from real projects like onchain games, PotWar pools, prediction markets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Last player wins when timer ends&lt;/li&gt;
&lt;li&gt;Auto reward after chest open&lt;/li&gt;
&lt;li&gt;Pool auto payout&lt;/li&gt;
&lt;li&gt;NFT level up after XP&lt;/li&gt;
&lt;li&gt;DAO proposal auto execute&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With traditional smart contracts, this requires:&lt;/p&gt;

&lt;p&gt;• Backend server&lt;br&gt;
• Event indexer&lt;br&gt;
• Cron jobs&lt;br&gt;
• Extra user transactions&lt;/p&gt;

&lt;p&gt;This increases complexity, cost, and centralization.&lt;/p&gt;

&lt;p&gt;Somnia On-Chain Reactivity solves this by allowing smart contracts to automatically react to events fully on-chain.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. What is Somnia On-Chain Reactivity?
&lt;/h2&gt;

&lt;p&gt;Somnia lets smart contracts execute logic automatically when subscribed events occur.&lt;/p&gt;

&lt;p&gt;Traditional Flow :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;User Action → Event → Backend Listener → New Tx → State Update&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Somnia Reactive Flow :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;User Action → Event → Validator Detect → _onEvent() → State Update&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No backend.&lt;br&gt;
No extra user gas.&lt;br&gt;
Fully decentralized.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Why This Matters for Web3 Devs
&lt;/h2&gt;

&lt;p&gt;For builders working on gaming, DeFi, or automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No server infra&lt;/li&gt;
&lt;li&gt;Less latency&lt;/li&gt;
&lt;li&gt;Cleaner architecture&lt;/li&gt;
&lt;li&gt;Better UX&lt;/li&gt;
&lt;li&gt;Faster hackathon builds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, in Last Player Standing, we don’t need a backend timer contract logic can react automatically.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Example: Magic Chest Reactive Game
&lt;/h2&gt;

&lt;p&gt;Let’s build a small game.&lt;/p&gt;

&lt;p&gt;Game Rules&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Common chest → +10 coins&lt;/li&gt;
&lt;li&gt;Rare chest → +50 coins&lt;/li&gt;
&lt;li&gt;Legendary chest → NFT sword&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Player opens chest → reward auto given.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Solidity Contract Example
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import { SomniaEventHandler }
from "@somnia-chain/reactivity-contracts/contracts/SomniaEventHandler.sol";

contract MagicChestReactiveGame is SomniaEventHandler {

    event ChestOpened(address indexed player, uint256 chestType);

    mapping(address =&amp;gt; uint256) public coins;
    mapping(address =&amp;gt; bool) public hasSword;

    bytes32 constant CHEST_SIG =
        keccak256("ChestOpened(address,uint256)");

    uint256 constant COMMON = 1;
    uint256 constant RARE = 2;
    uint256 constant LEGENDARY = 3;

    function openChest(uint256 chestType) external {
        emit ChestOpened(msg.sender, chestType);
    }

    function _onEvent(
        address,
        bytes32[] calldata topics,
        bytes calldata data
    ) internal override {

        require(topics[0] == CHEST_SIG, "Wrong event");

        address player =
            address(uint160(uint256(topics[1])));
        uint256 chestType =
            abi.decode(data, (uint256));

        if (chestType == COMMON)
            coins[player] += 10;
        else if (chestType == RARE)
            coins[player] += 50;
        else if (chestType == LEGENDARY)
            hasSword[player] = true;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  6. How Reactivity Works Internally
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Player calls openChest()&lt;/li&gt;
&lt;li&gt;Event emitted&lt;/li&gt;
&lt;li&gt;Somnia validators detect subscription&lt;/li&gt;
&lt;li&gt;_onEvent() executes automatically&lt;/li&gt;
&lt;li&gt;State updated&lt;/li&gt;
&lt;li&gt;No extra transaction required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reactive tx is executed by validator address:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x0000000000000000000000000000000000000100&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  7. Creating a Subscription for the event :
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SDK } from "@somnia-chain/reactivity";
import { privateKeyToAccount } from "viem/accounts";
import { createPublicClient, createWalletClient, http } from "viem";
import { somniaTestnet } from "viem/chains";
import { keccak256, toBytes } from "viem";

const CONTRACT = "0xYourContractAddress";

async function main() {

  const account = privateKeyToAccount(
    process.env.PRIVATE_KEY as `0x${string}`
  );

  const publicClient = createPublicClient({
    chain: somniaTestnet,
    transport: http(),
  });

  const walletClient = createWalletClient({
    account,
    chain: somniaTestnet,
    transport: http(),
  });

  const sdk = new SDK({
    public: publicClient,
    wallet: walletClient
  });

  const EVENT_SIG = keccak256(
    toBytes("ChestOpened(address,uint256)")
  );

  const txHash = await sdk.createSoliditySubscription({
    handlerContractAddress: CONTRACT,
    emitter: CONTRACT,
    eventTopics: [EVENT_SIG],
    gasLimit: 3_000_000n,
  });

  const receipt = await publicClient.waitForTransactionReceipt({
    hash: txHash,
  });

  // 👉 Extract subscriptionId
  const log = receipt.logs[0];
  const subscriptionId = BigInt(log.topics[2]);

  console.log("Subscription ID:", subscriptionId.toString());
}

main();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Important Notes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need 32 STT balance&lt;/li&gt;
&lt;li&gt;Save subscription ID&lt;/li&gt;
&lt;li&gt;Event signature must match exactly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now after subscribing event that we have to trigger from reactivity we need to test this ,&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing Reactivity
&lt;/h2&gt;

&lt;p&gt;After subscription, test contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from "hardhat";

const CONTRACT = "0xYourContractAddress";

async function main() {

  const [user] = await ethers.getSigners();

  const game = await ethers.getContractAt(
    "MagicChestReactiveGame",
    CONTRACT
  );

  const before = await game.coins(user.address);
  console.log("Coins before:", before.toString());

  const tx = await game.openChest(1);
  await tx.wait();

  console.log("Waiting for Somnia reactivity...");
  await new Promise(r =&amp;gt; setTimeout(r,15000));

  const after = await game.coins(user.address);
  console.log("Coins after:", after.toString());

  if(after &amp;gt; before)
    console.log("✅ Reactivity Working");
  else
    console.log("❌ No Reactivity");
}

main();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real Use Cases
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Gaming&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Last Player Standing&lt;/li&gt;
&lt;li&gt;PotWar auto payout&lt;/li&gt;
&lt;li&gt;Loot rewards&lt;/li&gt;
&lt;li&gt;NFT upgrades&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prediction Markets&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prediction auto reward&lt;/li&gt;
&lt;li&gt;Score updates&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DeFi&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Liquidations&lt;/li&gt;
&lt;li&gt;Yield distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DAO&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proposal auto execute&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Somnia On-Chain Reactivity removes backend dependency and enables fully autonomous smart contracts.&lt;/p&gt;

&lt;p&gt;For developers building automated gaming logic, prediction markets, or DeFi automation, this unlocks a new level of scalability and simplicity.&lt;/p&gt;

&lt;p&gt;The future of Web3 apps is reactive.&lt;/p&gt;

&lt;p&gt;Neeraj Choubisa (Nikku.Dev) is a Full-Stack Blockchain Engineer specializing in smart contract development, Web3 integrations, and consumer-focused decentralized applications.&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://twitter.com/itsNikku876" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>somnia</category>
      <category>solidity</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>&lt;&gt;Building a Cross-Chain Swap with LayerZero on Monad &lt;/&gt;</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Mon, 16 Jun 2025 07:20:21 +0000</pubDate>
      <link>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--51h4</link>
      <guid>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--51h4</guid>
      <description>&lt;p&gt;We will build a DApp with LayerZero that allows users to bridge and swap MON tokens from Monad testnet to ETH tokens on Sepolia testnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does Layer Zero Works ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any cross-chain communication protocol requires an off-chain entity to send messages to and from. However, this creates a centralization risk.&lt;/p&gt;

&lt;p&gt;Here's how LayerZero organizes its' infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LayerZero deployed a smart contract as an endpoint on each supported blockchain. This endpoint serves as a point of assembly for all cross-chain messages. Endpoints are to LayerZero what airports are to air travel.&lt;/li&gt;
&lt;li&gt;An off-chain relayer listens to these endpoints and picks up messages as they arrive. LayerZero lets us run our own relayer, lowering the risk of centralization.&lt;/li&gt;
&lt;li&gt;However, LayerZero only partially relies on a relayer to deliver these messages. In practice, a relayer works with an oracle that confirms or denies the validity of a transaction.&lt;/li&gt;
&lt;li&gt;The messages are delivered to their destination only if both independent entities agree on the validity of a transaction.&lt;/li&gt;
&lt;li&gt;A relayer is usually paired with decentralized oracle networks like Chainlink to ensure reliability, although, in theory, we can also develop our own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating a New Hardhat Project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx hardhat init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This LayerZero example repository contains all the interfaces and abstract contracts we need to talk to the on-chain LayerZero endpoints. We also need the Openzeppelin-contracts library to work with access control in our smart contracts.&lt;/p&gt;

&lt;p&gt;To download these repos into our Hardhat project, we run the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install LayerZero-Labs/solidity-examples&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will work with version 0.8.19 of the Solidity compiler. To ensure hardhat uses this exact version to compile all of the Solidity code, we add this line to the hardhat.config.ts file in our project directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const config: HardhatUserConfig = {&lt;br&gt;
  solidity: "0.8.18",&lt;br&gt;
};&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inside the contract directory, delete Lock.sol and create two files new files instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Monad_Swap.sol
- Sepolia_Swap.sol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first will become the endpoint on the Monad testnet and the other on Sepolia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Base Contract&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

contract Monad_Swap is NonblockingLzApp {
  // the implementation will go here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NonblockingLzApp&lt;/code&gt; is an abstract contract built on underlying LayerZero contracts. The purpose of this contract is to make it easier for devs to interact with the on-chain contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding the Variables&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // State variables for the contract    
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;destChainId&lt;/code&gt; variable represents the destination chain's address, not the chain we deploy this contract to. While sending a cross-chain message using LayerZero, we need to specify the address of the intended destination.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: These aren't the Chain IDs you might know. To quote the LayerZero docs: "chainId values are not related to EVM IDs. Since LayerZero will span EVM &amp;amp; non-EVM chains the chainId are proprietary to our Endpoints." Meaning, LayerZero maintains its own set of Chain IDs to identify blockchains that differ from the normally used numbers. We can find the full reference in their &lt;a href="https://docs.layerzero.network/v2/deployments/deployed-contracts" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Payload&lt;/code&gt; holds the message we send as bytes. This variable is an ABI-encoded amalgamation of everything we want to send across the chain.&lt;/p&gt;

&lt;p&gt;We initialize the &lt;code&gt;deployer&lt;/code&gt; variable in the constructor to the contract owner.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;contractAddress&lt;/code&gt; represents the contract address we know after deployment. We also initialize it in the constructor.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;endpoint&lt;/code&gt; variable is an instance of ILayerZeroEndpoint interface; we use it to interact with the on-chain endpoints. For an example, check out their Monad endpoint on &lt;a href="https://monad-testnet.socialscan.io/address/0x6c7ab2202c98c4227c5c46f1417d81144da716ff" rel="noopener noreferrer"&gt;Monad Explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing the Constructor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
    deployer = payable(msg.sender);
    endpoint = ILayerZeroEndpoint(_lzEndpoint);

    // If Source == Sepolia, then Destination Chain = Monad
    if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
    destChainId = 40204;

    // If Source == Monad, then Destination Chain = Sepolia
    if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
    destChainId = 40161;
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We must pass the address of the on-chain endpoint to the NonblockingLzApp contract for a successful initialization.&lt;/p&gt;

&lt;p&gt;In this example, we have written two if-statements that automatically assign the Chain ID based on the address of the endpoint contract. If we deployed the contract on Monad, the destChainId variable will point to Sepolia, and vice-versa.&lt;/p&gt;

&lt;p&gt;Interlude: How do Smart Contracts Interact with the LayerZero Protocol?&lt;br&gt;
We are now ready to write the two main functions we need to use the LayerZero protocol. But before that, let us take a conceptual detour.&lt;/p&gt;

&lt;p&gt;For any smart contract, interacting with the on-chain LayerZero endpoint is a two-part process:&lt;/p&gt;

&lt;p&gt;First, we call the send() function on the endpoint to send a message. To be clear, &lt;strong&gt;this is a function we call on an already deployed contract, not something we define.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Second, we define the _nonblockingLzReceive function in your contract. Any contract that wants to receive cross-chain messages must have this function defined in their contract. The LayerZero endpoint calls this function on our contract to deliver an incoming message. &lt;strong&gt;To be clear: We do not call this function; we just define it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implementing the &lt;code&gt;swapTo_ETH&lt;/code&gt; Function&lt;br&gt;
Let us now define the main swap function. We create a new function named &lt;code&gt;swapTo_ETH&lt;/code&gt; and define it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we ensure the user has sent at least 1 ETH in value while calling the function.&lt;/p&gt;

&lt;p&gt;A function named &lt;code&gt;setTrustedRemoteAddress&lt;/code&gt; inside the contract we inherit allows us to designate trusted contracts. This way, we can ensure our contract only interacts with trusted code. &lt;code&gt;trustedRemoteLookup[destChainId]&lt;/code&gt; returns the endpoint address from the other chain we trust. The &lt;code&gt;_checkPayloadSize&lt;/code&gt; function ensures our payload size is within acceptable limits.&lt;/p&gt;

&lt;p&gt;Next, we pack the data we want to send into a single variable of type bytes using &lt;code&gt;abi.encode()&lt;/code&gt;. In our case, we ask the user to tell us the destination address on the other side.&lt;/p&gt;

&lt;p&gt;Finally, we call the &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;transfer 15 ETH from our own smart contract to pay for the gas&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I can already hear you shouting: "15 ETH! What the hell is going on here?"&lt;br&gt;
We need to pay some gas fees to the endpoint for the execution of our transaction. The actual fee isn't 15 ETH. However, in my experience, transactions that were accompanied by less gas didn't execute.&lt;br&gt;
While we set 15 ETH in this swap implementation, we get back all unused ETH. 15 ETH is just a buffer to ensure the transaction goes through.&lt;br&gt;
LayerZero does have functions like estimateGasFees() that allow us to estimate the amount of gas that needs to be sent, but I found it to be inaccurate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Implementing the _nonblockingLzReceive Function&lt;/strong&gt;&lt;br&gt;
Well, this is how we send a message to the Sepolia testnet, but what if we receive a message from there?&lt;/p&gt;

&lt;p&gt;To make sure our contract is ready to handle incoming messages, we need to implement a function named &lt;code&gt;_nonblockingLzReceive&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {

    (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
    address payable recipient = payable(Receiver);        
    recipient.transfer(Value);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the function that LayerZero calls upon our contract to deliver a message. We know what we encoded on the other end. So, we can decode it into a recipient's address and an integer value representing the amount in Wei that we locked into the contract on the other end.&lt;/p&gt;

&lt;p&gt;Next, we transfer that value to the recipient by calling the transfer() function. Monad and ETH are two very different assets with wildly different values. In any practical implementation of a cross-chain swap, we would use an oracle to coordinate real-time price mediation between the two assets. For this example, we will assume an exchange rate of 1:1.&lt;/p&gt;

&lt;p&gt;Lastly, we will wrap up the contract code with two simple functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Contract for Monad&lt;br&gt;
After adding a few comments, this is what the finished Monad_Swap.sol should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Monad_Swap
 * @dev This contract sends a cross-chain message from Mumbai to Sepolia to transfer ETH in return for deposited Monad.
 */
contract Monad_Swap is NonblockingLzApp {
    // State variables for the contract
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

        // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to ETH.
     * @param Receiver Address of the receiver.
     */
  function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal override {
        (address Receiver, uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Sepolia Contract&lt;br&gt;
The Sepolia counterpart of this contract is almost the same, just the other way around.&lt;/p&gt;

&lt;p&gt;Now, inside Sepolia_Swap.sol, paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Sepolia_Swap
 * @dev This contract sends a cross-chain message from Sepolia to Monad to transfer Monad in return for deposited ETH.
 */
contract Sepolia_Swap is NonblockingLzApp {

    // State variables for the contract
    address payable deployer;    
    uint16 public destChainId;
    bytes payload;    
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

         // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to Monad.
     * @param Receiver Address of the receiver.
     */
    function swapTo_Monad(address Receiver) public payable {
        require(msg.value &amp;gt;= 1 ether, "Please send at least 1 ETH");
        uint value = msg.value;

        bytes memory trustedRemote = trustedRemoteLookup[destChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(destChainId, payload.length);

        // The message is encoded as bytes and stored in the "payload" variable.
        payload = abi.encode(Receiver, value);

        endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
    }

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {
        (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);        
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile the Contracts&lt;br&gt;
&lt;code&gt;npx hardhat compile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command might print some warnings, but we can ignore them.&lt;/p&gt;

&lt;p&gt;Creating the &lt;code&gt;.env&lt;/code&gt; File&lt;br&gt;
We need to add our sensitive information in a .env file to store it securely. So, we create one at the root of our project and fill it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_SEPOLIA_RPC_URL=
MONAD_RPC_URL=
DEPLOYER_ACCOUNT_PRIV_KEY=

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's Go For Scripts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from "hardhat";

async function deployMonadSwap() {
  const CONTRACT_NAME = "Monad_Swap";
  const lzAddressMonad = "0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff";
  const monadSwap = await ethers.deployContract(CONTRACT_NAME, [
    lzAddressMonad,
  ]);
  await monadSwap.waitForDeployment();
  console.log(
    "Deployed Monad Swap Contract Address:",
    await monadSwap.getAddress()
  );
}

async function main() {
  await deployMonadSwap();
}

main().catch((error) =&amp;gt; {
  console.error(error);
  process.exit(1);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run : 
nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_monad_swap.ts --network monad
Deployed Monad Swap Contract Address: 0xf9Ccd4509d3049ceFe62F800a44b3d66943D0308

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Similar for Base Sepolia :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_sepolia_swap.ts --network baseSepolia 

Deployed Sepolia Swap Contract Address: 0xd0eBE4D0E7C6a7786942c3dcD1390a0C8EE84040

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connecting the Two Contracts&lt;/strong&gt;&lt;br&gt;
Remember how we can use the setTrustedRemoteAddress() to designate trusted contracts? We need to tell each endpoint of its counterparts so they can call each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On Base Sepolia, we call the function with the following params:

_remoteChainId = 40204 (LayerZero Chain ID for Monad)
_remoteAddress = Address of our Monad Swap contract


On Monad, call the function with the following params:

_remoteChainId = 40245 (LayerZero Chain ID for Base Sepolia)
_remoteAddress = Address of the Base Sepolia contract


Lastly, we ensure to send MON and ETH to each contract. Remember, the contracts are the ones paying for gas, so we have to send 30 each to both of the contracts. (I know very hectic because of faucets not available right now ) 😂

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
With the robust capabilities of LayerZero, our solution stands ready to facilitate a seamless 1:1 swap between MON and ETH.&lt;/p&gt;

&lt;p&gt;Should any queries or thoughts arise, don't hesitate to get in touch with me on Twitter. I'm always eager to engage and assist.&lt;/p&gt;

&lt;p&gt;Here's to the boundless possibilities of cross-chain innovations!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://twitter.com/itsNikku876" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>layerzero</category>
      <category>crosschain</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>&lt;&gt;Building a Cross-Chain Swap with LayerZero on Monad &lt;/&gt;</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Mon, 17 Mar 2025 16:06:34 +0000</pubDate>
      <link>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--l0d</link>
      <guid>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--l0d</guid>
      <description>&lt;p&gt;We will build a DApp with LayerZero that allows users to bridge and swap MON tokens from Monad testnet to ETH tokens on Sepolia testnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does Layer Zero Works ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any cross-chain communication protocol requires an off-chain entity to send messages to and from. However, this creates a centralization risk.&lt;/p&gt;

&lt;p&gt;Here's how LayerZero organizes its' infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LayerZero deployed a smart contract as an endpoint on each supported blockchain. This endpoint serves as a point of assembly for all cross-chain messages. Endpoints are to LayerZero what airports are to air travel.&lt;/li&gt;
&lt;li&gt;An off-chain relayer listens to these endpoints and picks up messages as they arrive. LayerZero lets us run our own relayer, lowering the risk of centralization.&lt;/li&gt;
&lt;li&gt;However, LayerZero only partially relies on a relayer to deliver these messages. In practice, a relayer works with an oracle that confirms or denies the validity of a transaction.&lt;/li&gt;
&lt;li&gt;The messages are delivered to their destination only if both independent entities agree on the validity of a transaction.&lt;/li&gt;
&lt;li&gt;A relayer is usually paired with decentralized oracle networks like Chainlink to ensure reliability, although, in theory, we can also develop our own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating a New Hardhat Project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat init 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This LayerZero example repository contains all the interfaces and abstract contracts we need to talk to the on-chain LayerZero endpoints. We also need the Openzeppelin-contracts library to work with access control in our smart contracts.&lt;/p&gt;

&lt;p&gt;To download these repos into our Hardhat project, we run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install LayerZero-Labs/solidity-examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will work with version 0.8.19 of the Solidity compiler. To ensure hardhat uses this exact version to compile all of the Solidity code, we add this line to the hardhat.config.ts file in our project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const config: HardhatUserConfig = {
  solidity: "0.8.18",
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the contract directory, delete Lock.sol and create two files new files instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Monad_Swap.sol
- Sepolia_Swap.sol

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first will become the endpoint on the Monad testnet and the other on Sepolia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Base Contract&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

contract Monad_Swap is NonblockingLzApp {
  // the implementation will go here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NonblockingLzApp&lt;/code&gt; is an abstract contract built on underlying LayerZero contracts. The purpose of this contract is to make it easier for devs to interact with the on-chain contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding the Variables&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // State variables for the contract    
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;destChainId&lt;/code&gt; variable represents the destination chain's address, not the chain we deploy this contract to. While sending a cross-chain message using LayerZero, we need to specify the address of the intended destination.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: These aren't the Chain IDs you might know. To quote the LayerZero docs: "chainId values are not related to EVM IDs. Since LayerZero will span EVM &amp;amp; non-EVM chains the chainId are proprietary to our Endpoints." Meaning, LayerZero maintains its own set of Chain IDs to identify blockchains that differ from the normally used numbers. We can find the full reference in their &lt;a href="https://docs.layerzero.network/v2/deployments/deployed-contracts" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Payload&lt;/code&gt; holds the message we send as bytes. This variable is an ABI-encoded amalgamation of everything we want to send across the chain.&lt;/p&gt;

&lt;p&gt;We initialize the &lt;code&gt;deployer&lt;/code&gt; variable in the constructor to the contract owner.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;contractAddress&lt;/code&gt; represents the contract address we know after deployment. We also initialize it in the constructor.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;endpoint&lt;/code&gt; variable is an instance of ILayerZeroEndpoint interface; we use it to interact with the on-chain endpoints. For an example, check out their Monad endpoint on &lt;a href="https://monad-testnet.socialscan.io/address/0x6c7ab2202c98c4227c5c46f1417d81144da716ff" rel="noopener noreferrer"&gt;Monad Explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing the Constructor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
    deployer = payable(msg.sender);
    endpoint = ILayerZeroEndpoint(_lzEndpoint);

    // If Source == Sepolia, then Destination Chain = Monad
    if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
    destChainId = 40204;

    // If Source == Monad, then Destination Chain = Sepolia
    if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
    destChainId = 40161;
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We must pass the address of the on-chain endpoint to the NonblockingLzApp contract for a successful initialization.&lt;/p&gt;

&lt;p&gt;In this example, we have written two if-statements that automatically assign the Chain ID based on the address of the endpoint contract. If we deployed the contract on Monad, the destChainId variable will point to Sepolia, and vice-versa.&lt;/p&gt;

&lt;p&gt;Interlude: How do Smart Contracts Interact with the LayerZero Protocol?&lt;br&gt;
We are now ready to write the two main functions we need to use the LayerZero protocol. But before that, let us take a conceptual detour.&lt;/p&gt;

&lt;p&gt;For any smart contract, interacting with the on-chain LayerZero endpoint is a two-part process:&lt;/p&gt;

&lt;p&gt;First, we call the send() function on the endpoint to send a message. To be clear, &lt;strong&gt;this is a function we call on an already deployed contract, not something we define.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Second, we define the _nonblockingLzReceive function in your contract. Any contract that wants to receive cross-chain messages must have this function defined in their contract. The LayerZero endpoint calls this function on our contract to deliver an incoming message. &lt;strong&gt;To be clear: We do not call this function; we just define it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implementing the &lt;code&gt;swapTo_ETH&lt;/code&gt; Function&lt;br&gt;
Let us now define the main swap function. We create a new function named &lt;code&gt;swapTo_ETH&lt;/code&gt; and define it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we ensure the user has sent at least 1 ETH in value while calling the function.&lt;/p&gt;

&lt;p&gt;A function named &lt;code&gt;setTrustedRemoteAddress&lt;/code&gt; inside the contract we inherit allows us to designate trusted contracts. This way, we can ensure our contract only interacts with trusted code. &lt;code&gt;trustedRemoteLookup[destChainId]&lt;/code&gt; returns the endpoint address from the other chain we trust. The &lt;code&gt;_checkPayloadSize&lt;/code&gt; function ensures our payload size is within acceptable limits.&lt;/p&gt;

&lt;p&gt;Next, we pack the data we want to send into a single variable of type bytes using &lt;code&gt;abi.encode()&lt;/code&gt;. In our case, we ask the user to tell us the destination address on the other side.&lt;/p&gt;

&lt;p&gt;Finally, we call the &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;transfer 15 ETH from our own smart contract to pay for the gas&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I can already hear you shouting: "15 ETH! What the hell is going on here?"&lt;br&gt;
We need to pay some gas fees to the endpoint for the execution of our transaction. The actual fee isn't 15 ETH. However, in my experience, transactions that were accompanied by less gas didn't execute.&lt;br&gt;
While we set 15 ETH in this swap implementation, we get back all unused ETH. 15 ETH is just a buffer to ensure the transaction goes through.&lt;br&gt;
LayerZero does have functions like estimateGasFees() that allow us to estimate the amount of gas that needs to be sent, but I found it to be inaccurate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Implementing the _nonblockingLzReceive Function&lt;/strong&gt;&lt;br&gt;
Well, this is how we send a message to the Sepolia testnet, but what if we receive a message from there?&lt;/p&gt;

&lt;p&gt;To make sure our contract is ready to handle incoming messages, we need to implement a function named &lt;code&gt;_nonblockingLzReceive&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {

    (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
    address payable recipient = payable(Receiver);        
    recipient.transfer(Value);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the function that LayerZero calls upon our contract to deliver a message. We know what we encoded on the other end. So, we can decode it into a recipient's address and an integer value representing the amount in Wei that we locked into the contract on the other end.&lt;/p&gt;

&lt;p&gt;Next, we transfer that value to the recipient by calling the transfer() function. Monad and ETH are two very different assets with wildly different values. In any practical implementation of a cross-chain swap, we would use an oracle to coordinate real-time price mediation between the two assets. For this example, we will assume an exchange rate of 1:1.&lt;/p&gt;

&lt;p&gt;Lastly, we will wrap up the contract code with two simple functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Contract for Monad&lt;br&gt;
After adding a few comments, this is what the finished Monad_Swap.sol should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Monad_Swap
 * @dev This contract sends a cross-chain message from Mumbai to Sepolia to transfer ETH in return for deposited Monad.
 */
contract Monad_Swap is NonblockingLzApp {
    // State variables for the contract
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

        // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to ETH.
     * @param Receiver Address of the receiver.
     */
  function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal override {
        (address Receiver, uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Sepolia Contract&lt;br&gt;
The Sepolia counterpart of this contract is almost the same, just the other way around.&lt;/p&gt;

&lt;p&gt;Now, inside Sepolia_Swap.sol, paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Sepolia_Swap
 * @dev This contract sends a cross-chain message from Sepolia to Monad to transfer Monad in return for deposited ETH.
 */
contract Sepolia_Swap is NonblockingLzApp {

    // State variables for the contract
    address payable deployer;    
    uint16 public destChainId;
    bytes payload;    
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

         // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to Monad.
     * @param Receiver Address of the receiver.
     */
    function swapTo_Monad(address Receiver) public payable {
        require(msg.value &amp;gt;= 1 ether, "Please send at least 1 ETH");
        uint value = msg.value;

        bytes memory trustedRemote = trustedRemoteLookup[destChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(destChainId, payload.length);

        // The message is encoded as bytes and stored in the "payload" variable.
        payload = abi.encode(Receiver, value);

        endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
    }

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {
        (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);        
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile the Contracts&lt;br&gt;
&lt;code&gt;npx hardhat compile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command might print some warnings, but we can ignore them.&lt;/p&gt;

&lt;p&gt;Creating the &lt;code&gt;.env&lt;/code&gt; File&lt;br&gt;
We need to add our sensitive information in a .env file to store it securely. So, we create one at the root of our project and fill it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_SEPOLIA_RPC_URL=
MONAD_RPC_URL=
DEPLOYER_ACCOUNT_PRIV_KEY=

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's Go For Scripts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from "hardhat";

async function deployMonadSwap() {
  const CONTRACT_NAME = "Monad_Swap";
  const lzAddressMonad = "0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff";
  const monadSwap = await ethers.deployContract(CONTRACT_NAME, [
    lzAddressMonad,
  ]);
  await monadSwap.waitForDeployment();
  console.log(
    "Deployed Monad Swap Contract Address:",
    await monadSwap.getAddress()
  );
}

async function main() {
  await deployMonadSwap();
}

main().catch((error) =&amp;gt; {
  console.error(error);
  process.exit(1);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run : 
nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_monad_swap.ts --network monad
Deployed Monad Swap Contract Address: 0xf9Ccd4509d3049ceFe62F800a44b3d66943D0308

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Similar for Base Sepolia :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_sepolia_swap.ts --network baseSepolia 

Deployed Sepolia Swap Contract Address: 0xd0eBE4D0E7C6a7786942c3dcD1390a0C8EE84040

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connecting the Two Contracts&lt;/strong&gt;&lt;br&gt;
Remember how we can use the setTrustedRemoteAddress() to designate trusted contracts? We need to tell each endpoint of its counterparts so they can call each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On Base Sepolia, we call the function with the following params:

_remoteChainId = 40204 (LayerZero Chain ID for Monad)
_remoteAddress = Address of our Monad Swap contract


On Monad, call the function with the following params:

_remoteChainId = 40245 (LayerZero Chain ID for Base Sepolia)
_remoteAddress = Address of the Base Sepolia contract


Lastly, we ensure to send MON and ETH to each contract. Remember, the contracts are the ones paying for gas, so we have to send 30 each to both of the contracts. (I know very hectic because of faucets not available right now ) 😂

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
With the robust capabilities of LayerZero, our solution stands ready to facilitate a seamless 1:1 swap between MON and ETH.&lt;/p&gt;

&lt;p&gt;Should any queries or thoughts arise, don't hesitate to get in touch with me on Twitter. I'm always eager to engage and assist.&lt;/p&gt;

&lt;p&gt;Here's to the boundless possibilities of cross-chain innovations!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxcibpk43kws7gtvr6ao1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxcibpk43kws7gtvr6ao1.jpeg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/itsNikku876" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>layerzero</category>
      <category>crosschain</category>
      <category>blockchain</category>
      <category>solidity</category>
    </item>
    <item>
      <title>&lt;&gt;Building a Cross-Chain Swap with LayerZero on Monad &lt;/&gt;</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Mon, 17 Mar 2025 16:06:34 +0000</pubDate>
      <link>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--33kn</link>
      <guid>https://dev.to/kalidecoder/building-a-cross-chain-swap-with-layerzero-on-monad--33kn</guid>
      <description>&lt;p&gt;We will build a DApp with LayerZero that allows users to bridge and swap MON tokens from Monad testnet to ETH tokens on Sepolia testnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does Layer Zero Works ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any cross-chain communication protocol requires an off-chain entity to send messages to and from. However, this creates a centralization risk.&lt;/p&gt;

&lt;p&gt;Here's how LayerZero organizes its' infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LayerZero deployed a smart contract as an endpoint on each supported blockchain. This endpoint serves as a point of assembly for all cross-chain messages. Endpoints are to LayerZero what airports are to air travel.&lt;/li&gt;
&lt;li&gt;An off-chain relayer listens to these endpoints and picks up messages as they arrive. LayerZero lets us run our own relayer, lowering the risk of centralization.&lt;/li&gt;
&lt;li&gt;However, LayerZero only partially relies on a relayer to deliver these messages. In practice, a relayer works with an oracle that confirms or denies the validity of a transaction.&lt;/li&gt;
&lt;li&gt;The messages are delivered to their destination only if both independent entities agree on the validity of a transaction.&lt;/li&gt;
&lt;li&gt;A relayer is usually paired with decentralized oracle networks like Chainlink to ensure reliability, although, in theory, we can also develop our own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating a New Hardhat Project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx hardhat init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This LayerZero example repository contains all the interfaces and abstract contracts we need to talk to the on-chain LayerZero endpoints. We also need the Openzeppelin-contracts library to work with access control in our smart contracts.&lt;/p&gt;

&lt;p&gt;To download these repos into our Hardhat project, we run the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install LayerZero-Labs/solidity-examples&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will work with version 0.8.19 of the Solidity compiler. To ensure hardhat uses this exact version to compile all of the Solidity code, we add this line to the hardhat.config.ts file in our project directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const config: HardhatUserConfig = {&lt;br&gt;
  solidity: "0.8.18",&lt;br&gt;
};&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inside the contract directory, delete Lock.sol and create two files new files instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Monad_Swap.sol
- Sepolia_Swap.sol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first will become the endpoint on the Monad testnet and the other on Sepolia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Base Contract&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

contract Monad_Swap is NonblockingLzApp {
  // the implementation will go here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NonblockingLzApp&lt;/code&gt; is an abstract contract built on underlying LayerZero contracts. The purpose of this contract is to make it easier for devs to interact with the on-chain contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding the Variables&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // State variables for the contract    
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;destChainId&lt;/code&gt; variable represents the destination chain's address, not the chain we deploy this contract to. While sending a cross-chain message using LayerZero, we need to specify the address of the intended destination.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: These aren't the Chain IDs you might know. To quote the LayerZero docs: "chainId values are not related to EVM IDs. Since LayerZero will span EVM &amp;amp; non-EVM chains the chainId are proprietary to our Endpoints." Meaning, LayerZero maintains its own set of Chain IDs to identify blockchains that differ from the normally used numbers. We can find the full reference in their &lt;a href="https://docs.layerzero.network/v2/deployments/deployed-contracts" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Payload&lt;/code&gt; holds the message we send as bytes. This variable is an ABI-encoded amalgamation of everything we want to send across the chain.&lt;/p&gt;

&lt;p&gt;We initialize the &lt;code&gt;deployer&lt;/code&gt; variable in the constructor to the contract owner.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;contractAddress&lt;/code&gt; represents the contract address we know after deployment. We also initialize it in the constructor.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;endpoint&lt;/code&gt; variable is an instance of ILayerZeroEndpoint interface; we use it to interact with the on-chain endpoints. For an example, check out their Monad endpoint on &lt;a href="https://monad-testnet.socialscan.io/address/0x6c7ab2202c98c4227c5c46f1417d81144da716ff" rel="noopener noreferrer"&gt;Monad Explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing the Constructor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
    deployer = payable(msg.sender);
    endpoint = ILayerZeroEndpoint(_lzEndpoint);

    // If Source == Sepolia, then Destination Chain = Monad
    if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
    destChainId = 40204;

    // If Source == Monad, then Destination Chain = Sepolia
    if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
    destChainId = 40161;
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We must pass the address of the on-chain endpoint to the NonblockingLzApp contract for a successful initialization.&lt;/p&gt;

&lt;p&gt;In this example, we have written two if-statements that automatically assign the Chain ID based on the address of the endpoint contract. If we deployed the contract on Monad, the destChainId variable will point to Sepolia, and vice-versa.&lt;/p&gt;

&lt;p&gt;Interlude: How do Smart Contracts Interact with the LayerZero Protocol?&lt;br&gt;
We are now ready to write the two main functions we need to use the LayerZero protocol. But before that, let us take a conceptual detour.&lt;/p&gt;

&lt;p&gt;For any smart contract, interacting with the on-chain LayerZero endpoint is a two-part process:&lt;/p&gt;

&lt;p&gt;First, we call the send() function on the endpoint to send a message. To be clear, &lt;strong&gt;this is a function we call on an already deployed contract, not something we define.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Second, we define the _nonblockingLzReceive function in your contract. Any contract that wants to receive cross-chain messages must have this function defined in their contract. The LayerZero endpoint calls this function on our contract to deliver an incoming message. &lt;strong&gt;To be clear: We do not call this function; we just define it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implementing the &lt;code&gt;swapTo_ETH&lt;/code&gt; Function&lt;br&gt;
Let us now define the main swap function. We create a new function named &lt;code&gt;swapTo_ETH&lt;/code&gt; and define it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we ensure the user has sent at least 1 ETH in value while calling the function.&lt;/p&gt;

&lt;p&gt;A function named &lt;code&gt;setTrustedRemoteAddress&lt;/code&gt; inside the contract we inherit allows us to designate trusted contracts. This way, we can ensure our contract only interacts with trusted code. &lt;code&gt;trustedRemoteLookup[destChainId]&lt;/code&gt; returns the endpoint address from the other chain we trust. The &lt;code&gt;_checkPayloadSize&lt;/code&gt; function ensures our payload size is within acceptable limits.&lt;/p&gt;

&lt;p&gt;Next, we pack the data we want to send into a single variable of type bytes using &lt;code&gt;abi.encode()&lt;/code&gt;. In our case, we ask the user to tell us the destination address on the other side.&lt;/p&gt;

&lt;p&gt;Finally, we call the &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;transfer 15 ETH from our own smart contract to pay for the gas&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I can already hear you shouting: "15 ETH! What the hell is going on here?"&lt;br&gt;
We need to pay some gas fees to the endpoint for the execution of our transaction. The actual fee isn't 15 ETH. However, in my experience, transactions that were accompanied by less gas didn't execute.&lt;br&gt;
While we set 15 ETH in this swap implementation, we get back all unused ETH. 15 ETH is just a buffer to ensure the transaction goes through.&lt;br&gt;
LayerZero does have functions like estimateGasFees() that allow us to estimate the amount of gas that needs to be sent, but I found it to be inaccurate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Implementing the _nonblockingLzReceive Function&lt;/strong&gt;&lt;br&gt;
Well, this is how we send a message to the Sepolia testnet, but what if we receive a message from there?&lt;/p&gt;

&lt;p&gt;To make sure our contract is ready to handle incoming messages, we need to implement a function named &lt;code&gt;_nonblockingLzReceive&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {

    (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
    address payable recipient = payable(Receiver);        
    recipient.transfer(Value);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the function that LayerZero calls upon our contract to deliver a message. We know what we encoded on the other end. So, we can decode it into a recipient's address and an integer value representing the amount in Wei that we locked into the contract on the other end.&lt;/p&gt;

&lt;p&gt;Next, we transfer that value to the recipient by calling the transfer() function. Monad and ETH are two very different assets with wildly different values. In any practical implementation of a cross-chain swap, we would use an oracle to coordinate real-time price mediation between the two assets. For this example, we will assume an exchange rate of 1:1.&lt;/p&gt;

&lt;p&gt;Lastly, we will wrap up the contract code with two simple functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Contract for Monad&lt;br&gt;
After adding a few comments, this is what the finished Monad_Swap.sol should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Monad_Swap
 * @dev This contract sends a cross-chain message from Mumbai to Sepolia to transfer ETH in return for deposited Monad.
 */
contract Monad_Swap is NonblockingLzApp {
    // State variables for the contract
    uint16 public destChainId;
    bytes payload;
    address payable deployer;
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

        // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to ETH.
     * @param Receiver Address of the receiver.
     */
  function swapTo_ETH(address Receiver) public payable {
    require(msg.value &amp;gt;= 1 ether, "Please send at least 1 Monad");
    uint value = msg.value;

    bytes memory trustedRemote = trustedRemoteLookup[destChainId];
    require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
    _checkPayloadSize(destChainId, payload.length);

    // The message is encoded as bytes and stored in the "payload" variable.
    payload = abi.encode(Receiver, value);

    endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
}

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal override {
        (address Receiver, uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Complete Sepolia Contract&lt;br&gt;
The Sepolia counterpart of this contract is almost the same, just the other way around.&lt;/p&gt;

&lt;p&gt;Now, inside Sepolia_Swap.sol, paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

import "@layerzero-contracts/lzApp/NonblockingLzApp.sol";

/**
 * @title Sepolia_Swap
 * @dev This contract sends a cross-chain message from Sepolia to Monad to transfer Monad in return for deposited ETH.
 */
contract Sepolia_Swap is NonblockingLzApp {

    // State variables for the contract
    address payable deployer;    
    uint16 public destChainId;
    bytes payload;    
    address payable contractAddress = payable(address(this));

    // Instance of the LayerZero endpoint
    ILayerZeroEndpoint public immutable endpoint;

    /**
     * @dev Constructor that initializes the contract with the LayerZero endpoint.
     * @param _lzEndpoint Address of the LayerZero endpoint.
     */
    constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        deployer = payable(msg.sender);
        endpoint = ILayerZeroEndpoint(_lzEndpoint);

         // If Source == Sepolia, then Destination Chain = Monad
        if (_lzEndpoint == 0x6EDCE65403992e310A62460808c4b910D972f10f)
            destChainId = 40204;

        // If Source == Monad, then Destination Chain = Sepolia
        if (_lzEndpoint == 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff)
            destChainId = 40161;
    }

    /**
     * @dev Allows users to swap to Monad.
     * @param Receiver Address of the receiver.
     */
    function swapTo_Monad(address Receiver) public payable {
        require(msg.value &amp;gt;= 1 ether, "Please send at least 1 ETH");
        uint value = msg.value;

        bytes memory trustedRemote = trustedRemoteLookup[destChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(destChainId, payload.length);

        // The message is encoded as bytes and stored in the "payload" variable.
        payload = abi.encode(Receiver, value);

        endpoint.send{value: 15 ether}(destChainId, trustedRemote, payload, contractAddress, address(0x0), bytes(""));
    }

    /**
     * @dev Internal function to handle incoming LayerZero messages.
     */
    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal override {
        (address Receiver , uint Value) = abi.decode(_payload, (address, uint));
        address payable recipient = payable(Receiver);        
        recipient.transfer(Value);
    }

    // Fallback function to receive ether
    receive() external payable {}

    /**
     * @dev Allows the owner to withdraw all funds from the contract.
     */
    function withdrawAll() external onlyOwner {
        deployer.transfer(address(this).balance);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile the Contracts&lt;br&gt;
&lt;code&gt;npx hardhat compile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command might print some warnings, but we can ignore them.&lt;/p&gt;

&lt;p&gt;Creating the &lt;code&gt;.env&lt;/code&gt; File&lt;br&gt;
We need to add our sensitive information in a .env file to store it securely. So, we create one at the root of our project and fill it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_SEPOLIA_RPC_URL=
MONAD_RPC_URL=
DEPLOYER_ACCOUNT_PRIV_KEY=

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's Go For Scripts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from "hardhat";

async function deployMonadSwap() {
  const CONTRACT_NAME = "Monad_Swap";
  const lzAddressMonad = "0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff";
  const monadSwap = await ethers.deployContract(CONTRACT_NAME, [
    lzAddressMonad,
  ]);
  await monadSwap.waitForDeployment();
  console.log(
    "Deployed Monad Swap Contract Address:",
    await monadSwap.getAddress()
  );
}

async function main() {
  await deployMonadSwap();
}

main().catch((error) =&amp;gt; {
  console.error(error);
  process.exit(1);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run : 
nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_monad_swap.ts --network monad
Deployed Monad Swap Contract Address: 0xf9Ccd4509d3049ceFe62F800a44b3d66943D0308

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Similar for Base Sepolia :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nikku.jr.dev@Neerajs-MacBook-Air swap-layerzero % npx hardhat run scripts/deploy_sepolia_swap.ts --network baseSepolia 

Deployed Sepolia Swap Contract Address: 0xd0eBE4D0E7C6a7786942c3dcD1390a0C8EE84040

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connecting the Two Contracts&lt;/strong&gt;&lt;br&gt;
Remember how we can use the setTrustedRemoteAddress() to designate trusted contracts? We need to tell each endpoint of its counterparts so they can call each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On Base Sepolia, we call the function with the following params:

_remoteChainId = 40204 (LayerZero Chain ID for Monad)
_remoteAddress = Address of our Monad Swap contract


On Monad, call the function with the following params:

_remoteChainId = 40245 (LayerZero Chain ID for Base Sepolia)
_remoteAddress = Address of the Base Sepolia contract


Lastly, we ensure to send MON and ETH to each contract. Remember, the contracts are the ones paying for gas, so we have to send 30 each to both of the contracts. (I know very hectic because of faucets not available right now ) 😂

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
With the robust capabilities of LayerZero, our solution stands ready to facilitate a seamless 1:1 swap between MON and ETH.&lt;/p&gt;

&lt;p&gt;Should any queries or thoughts arise, don't hesitate to get in touch with me on Twitter. I'm always eager to engage and assist.&lt;/p&gt;

&lt;p&gt;Here's to the boundless possibilities of cross-chain innovations!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxcibpk43kws7gtvr6ao1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxcibpk43kws7gtvr6ao1.jpeg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/itsNikku876" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>layerzero</category>
      <category>crosschain</category>
      <category>blockchain</category>
      <category>solidity</category>
    </item>
    <item>
      <title>IEO: DComm Success</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Sat, 02 Dec 2023 07:44:03 +0000</pubDate>
      <link>https://dev.to/kalidecoder/ieo-dcomm-success-52j8</link>
      <guid>https://dev.to/kalidecoder/ieo-dcomm-success-52j8</guid>
      <description>&lt;p&gt;Hello Everyone Welcome to another Blog where we learn and see how we can invest and subscribe to this event which is the IEO Initial Exchange Offering. &lt;/p&gt;

&lt;p&gt;I'm &lt;strong&gt;@Dev3Role&lt;/strong&gt; a full-stack Developer and Blogger. Without Any Wasting time let's start the blog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is IEO?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An IEO or initial exchange offering refers to an event where the sale of tokens is conducted through an established mode of exchanging crypto. It is a way start-up organizations raise capital by selling utility tokens that confer preferred status with the organization via a crypto exchange platform. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is IEO Worked?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Firstly, a verification procedure takes place to prevent scams rampant with ICOs.&lt;br&gt;
The exchange platforms carry out several checks before a sale’s commencement to ensure that the new digital currency is what it claims to be.Also, a white paper is necessary. &lt;br&gt;
Here is the link of Paper :- &lt;a href="https://us-ms.gr-cdn.com/getresponse-Mbb8r/documents/1933fc96-428f-4796-bb46-c1119f715d50.pdf" rel="noopener noreferrer"&gt;White Paper&lt;/a&gt;.This is similar to an academic paper and serves to educate and inform investors about the project.&lt;/p&gt;

&lt;p&gt;The paper includes Team Vision , Marketing Strategy , Why developers and Investors are interested in this and Tokonomics Defined very clearly.&lt;/p&gt;

&lt;p&gt;Here is Coinstore where the $DCM exchange is happening.&lt;/p&gt;

&lt;p&gt;These are some points that we have to look at in Project :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unique selling points or claims of the currency&lt;/li&gt;
&lt;li&gt;Demand and tokenomics for it in cryptocurrency&lt;/li&gt;
&lt;li&gt;Background of the team which is behind the project&lt;/li&gt;
&lt;li&gt;Examining the underlying technology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;`Recently DComm launched their IEO which has some impressive results let's look at them and use them as an investing strategy like what we have to look while investing in crypto.&lt;/p&gt;

&lt;p&gt;Spotlight the total amount oversold - &lt;strong&gt;$751,622.04 USD&lt;/strong&gt;, which is an impressive &lt;strong&gt;751.62%&lt;/strong&gt; over our initial target.`&lt;/p&gt;

&lt;p&gt;The company has additional upcoming projects, and it's advisable to explore these initiatives for potential investment or contributions. Projects with a focus on sustainability and community development are particularly appealing, given the expansive growth potential of this community and the recognized influence of the DComm chain. Conducting research on these future endeavors will allow for informed decisions, aligning investments or contributions with the company's commitment to fostering sustainability and community building, leveraging the strengths of the DComm chain.&lt;/p&gt;

&lt;p&gt;Let's Discuss Some Advantages of IEO :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IEO platforms provide investors with an improved user experience in comparison to ICOs. &lt;/li&gt;
&lt;li&gt;There is a lesser risk of fraud, as IEOs are regulated per the exchange’s set rules.&lt;/li&gt;
&lt;li&gt;As IEOs are conducted via third-party exchanges, they run smoothly. Exchange platforms oversee the transactions and can also provide marketing and development support.&lt;/li&gt;
&lt;li&gt;IEOs are not open to the public but only to the exchange platform’s existing members.&lt;/li&gt;
&lt;li&gt;Investors are more confident when token sales occur via a trusted crypto exchange platform. This also offers the project more credibility and legitimacy, attracting further investments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.coinstore.com/#/launchpadDetail?activityId=109&amp;amp;fromPath=%2Flaunchpad" rel="noopener noreferrer"&gt;Go Ahead And invest in Dcomm IEO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;@Dev3Role&lt;/p&gt;

&lt;p&gt;Follow for more Updates :&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;br&gt;
&lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>exchange</category>
      <category>blockchain</category>
      <category>assets</category>
      <category>tokens</category>
    </item>
    <item>
      <title>Crypto Investment Tips</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Mon, 27 Nov 2023 07:46:49 +0000</pubDate>
      <link>https://dev.to/kalidecoder/crypto-investment-127</link>
      <guid>https://dev.to/kalidecoder/crypto-investment-127</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is cryptocurrency?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A digital currency where the creation of units of currency and the verification of transactions for the transfer of funds is controlled by code that is based on encryption. A cryptocurrency is not supported by any nation's government or central bank. The accounting is handled in a dispersed fashion. Consider it like a distributed ledger where transactions cannot be changed in order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the most important factors when deciding to invest in a cryptocurrency project?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whitepaper Analysis&lt;/strong&gt;&lt;br&gt;
Review the project's whitepaper. It should provide comprehensive details about the technology, purpose, team, tokenomics, and roadmap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team and Development&lt;/strong&gt;&lt;br&gt;
Assess the experience and expertise of the development team. A skilled and transparent team is crucial for project success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community&lt;/strong&gt;&lt;br&gt;
A strong and engaged community can indicate a healthy project. Evaluate the project's presence on social media, forums, and community channels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Token Performance and Liquidity&lt;/strong&gt;&lt;br&gt;
Analyze the historical performance of the project's token, considering factors like price volatility and liquidity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One of the main factor : Tokenomics and Economics&lt;/strong&gt;&lt;br&gt;
Understand the tokenomics of the project, including the total supply, distribution, and any mechanisms for controlling inflation or deflation.&lt;/p&gt;

&lt;p&gt;All the factors play an important role so go through each factor while investing in any crypto-related project. Once check their community how they are active and growing on socials. &lt;/p&gt;

&lt;p&gt;@Dev3Role. &lt;/p&gt;

&lt;p&gt;Happy Coding.  &lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>investment</category>
      <category>tokens</category>
      <category>blokchain</category>
    </item>
    <item>
      <title>Impact of Real-World Asset Tokenization</title>
      <dc:creator>Neeraj Choubisa</dc:creator>
      <pubDate>Thu, 23 Nov 2023 16:42:50 +0000</pubDate>
      <link>https://dev.to/kalidecoder/impact-of-real-world-asset-tokenization-58em</link>
      <guid>https://dev.to/kalidecoder/impact-of-real-world-asset-tokenization-58em</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.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%2Fsjebse9ejg4dbsrj4vd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsjebse9ejg4dbsrj4vd2.png" alt="Impact of Real-World Asset Tokenization" width="800" height="451"&gt;&lt;/a&gt;&lt;em&gt;Hey, Welcome Again to &lt;strong&gt;@Dev.Three&lt;/strong&gt; Blogs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's kick off our exploration by asking: What exactly is &lt;strong&gt;Asset Tokenization&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Asset tokenization is a process where real-world assets, like real estate or art, are converted into digital tokens on a blockchain. It can be any blockchain depending on the Speed we choose a particular blockchain. &lt;/p&gt;

&lt;p&gt;These tokens represent ownership or a share in the underlying asset. It's like turning a physical asset into digital pieces that can be bought, sold, and traded more easily. Breaking assets into smaller pieces and selling them one by one. Let's take an example in Collectibles things : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Imagine you have a valuable painting. Through asset tokenization, you can convert ownership of that painting into digital tokens. Now, instead of selling the entire painting, you can sell or trade these tokens, allowing multiple people to own a portion of the artwork.&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;This makes it simpler to invest in and trade assets that might traditionally be less liquid or easily divisible.&lt;/p&gt;

&lt;p&gt;What are the &lt;strong&gt;Advantages of Tokenization of Real World Assets&lt;/strong&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased Liquidity&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;24/7 Market&lt;/li&gt;
&lt;li&gt;Fractional Ownership&lt;/li&gt;
&lt;li&gt;Reduced Costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dcomm is actively engaged&lt;/strong&gt; in the process of &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tokenizing solar energy investments, highlighting the role of decentralized finance (DeFi) in facilitating renewable energy funding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additionally, the company is championing the tokenization of carbon credits as a crucial step toward advancing sustainability. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Furthermore, Dcomm envisions the future of energy grids to be decentralized, tokenized, and blockchain-powered, emphasizing the transformative potential of these technologies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commitment to &lt;strong&gt;sustainability&lt;/strong&gt;, the pursuit of asset &lt;strong&gt;liquidity&lt;/strong&gt;, and the desire for &lt;strong&gt;global market integration&lt;/strong&gt; underscores the importance of asset tokenization in these initiatives.&lt;/p&gt;

&lt;p&gt;Congratulations &amp;amp; Happy Coding !!! 🎊&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dcomm.network/news/the-future-of-energy-grids-decentralized-tokenized-and-powered-by-blockchain/" rel="noopener noreferrer"&gt;Go Ahead And More Learn About Dcomm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;@Dev.Three &lt;/p&gt;

&lt;p&gt;Follow for more Updates :&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/neeraj-choubisa-a4952b202/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;br&gt;
&lt;a href="https://github.com/Kali-Decoder" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://kali-decoder.github.io/Portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>tokenization</category>
      <category>assets</category>
      <category>ownership</category>
    </item>
  </channel>
</rss>
