<?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: Vedant Chainani</title>
    <description>The latest articles on DEV Community by Vedant Chainani (@envoy1084).</description>
    <link>https://dev.to/envoy1084</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%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif</url>
      <title>DEV Community: Vedant Chainani</title>
      <link>https://dev.to/envoy1084</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/envoy1084"/>
    <language>en</language>
    <item>
      <title>Build a Lottery Smart Contract with Chainlink VRF Random Numbers: A Step-by-Step Guide</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Sun, 14 May 2023 22:42:27 +0000</pubDate>
      <link>https://dev.to/envoy1084/build-a-lottery-smart-contract-with-chainlink-vrf-random-numbers-a-step-by-step-guide-4j4i</link>
      <guid>https://dev.to/envoy1084/build-a-lottery-smart-contract-with-chainlink-vrf-random-numbers-a-step-by-step-guide-4j4i</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this article, we will be exploring how to create a lottery smart contract using &lt;a href="https://docs.chain.link/vrf/v2/introduction" rel="noopener noreferrer"&gt;Chainlink VRF&lt;/a&gt; (Verifiable Random Function) random numbers. Chainlink VRF is a secure and reliable way to generate random numbers on the blockchain, making it ideal for use in lotteries and other games of chance.&lt;/p&gt;

&lt;p&gt;By using Chainlink VRF, we can ensure that our lottery is fair and tamper-proof, giving players the confidence to participate and the assurance that the results are unbiased. We will walk through the steps of building a lottery smart contract using Chainlink VRF, and by the end of the tutorial, you will have a fully functional lottery smart contract that you can use as a template for your own projects.&lt;/p&gt;

&lt;p&gt;You can find the entire code for the contract in the &lt;a href="https://github.com/Envoy-VC/Smart-Contracts/blob/main/Intermediate/Simple%20Lottery/Lottery.sol" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/envoy1084" rel="noopener noreferrer"&gt;
        envoy1084
      &lt;/a&gt; / &lt;a href="https://github.com/envoy1084/Smart-Contracts" rel="noopener noreferrer"&gt;
        Smart-Contracts
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Collection of smart contracts to aid you with your web3 projects.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/envoy1084/Smart-Contracts/./assets/banner.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fenvoy1084%2FSmart-Contracts%2F.%2Fassets%2Fbanner.png" alt="readme banner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://github.com/web3astronaut/Smart-Contracts/issues" rel="noopener noreferrer"&gt;
&lt;img alt="GitHub issues" src="https://camo.githubusercontent.com/91e5923fc90aa0afb66825e0cbbbc5f15b50abeabe725a17bba05cc5047eb796/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f77656233617374726f6e6175742f536d6172742d436f6e7472616374733f7374796c653d666f722d7468652d6261646765"&gt;
&lt;/a&gt;
&lt;a href="https://github.com/web3astronaut/Smart-Contracts/graphs/contributors" rel="noopener noreferrer"&gt;
&lt;img alt="GitHub contributors" src="https://camo.githubusercontent.com/6df7ccd20460f34a5728bf28fe1bc0b15d8e2606bf49d48708fdfa94549852c1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f77656233617374726f6e6175742f536d6172742d436f6e7472616374733f7374796c653d666f722d7468652d6261646765"&gt;
&lt;/a&gt;
&lt;a href="https://github.com/web3astronaut/Smart-Contracts/blob/main/LICENSE" rel="noopener noreferrer"&gt;
&lt;img alt="GitHub" src="https://camo.githubusercontent.com/336fe4450397a66b2ef6c676c73710b04537677d44f6d7b3cb91435f0d2d3611/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f77656233617374726f6e6175742f536d6172742d436f6e7472616374733f7374796c653d666f722d7468652d6261646765"&gt;
&lt;/a&gt;
&lt;a href="https://discord.gg/Zec3HQszZM" rel="nofollow noopener noreferrer"&gt;
   &lt;img src="https://camo.githubusercontent.com/8f2fb7c54f8d8e19c1f6cedf97c2ab67fa6afbecc1b388f0a2cfb70dff5eb791/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313033303737383835333134363233343932303f6c6f676f3d646973636f7264267374796c653d666f722d7468652d626164676526636f6c6f72423d353836354632"&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;b&gt;Collection of deployable smart contracts for Ethereum-based chains to hasten development&lt;/b&gt;
&lt;/p&gt;



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📑 About Smart Contracts&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The sole venue for smart contract programmers to display their concepts and work. To get you started on your web3 adventure, this repository will offer a selection of smart contracts ranging in difficulty from beginner to expert.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🗺️ How to Contribute?&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Check out the current &lt;a href="https://github.com/web3astronaut/Smart-Contracts/issues" rel="noopener noreferrer"&gt;issues&lt;/a&gt; or start a &lt;a href="https://github.com/web3astronaut/Smart-Contracts/issues/new/choose" rel="noopener noreferrer"&gt;new&lt;/a&gt; one!&lt;/li&gt;
&lt;li&gt;Create a branch for each problem you are working on, &lt;a href="https://github.com/web3astronaut/Smart-Contracts/fork" rel="noopener noreferrer"&gt;fork&lt;/a&gt; the repository, and then commit your changes.&lt;/li&gt;
&lt;li&gt;Create a Pull Request (&lt;code&gt;PR&lt;/code&gt;), which will be promptly reviewed and given suggestions for improvements by the community.&lt;/li&gt;
&lt;li&gt;Additionally, supply the solidity source files and a descriptive readme on how the smart contract works.&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📝 How to make a Pull Request?&lt;/h2&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make a fork of the Smart-Contracts repository first. In the top right corner, click the fork icon.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clone your new fork of the…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/envoy1084/Smart-Contracts" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



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

&lt;p&gt;Before you begin with this tutorial make sure you are comfortable with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of Solidity and the Ethereum blockchain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Experience with compiling and deploying contracts using Remix IDE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passion for building cool things&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before starting to build the actual Lottery Contract let's take a look at Chainlink VRF and set up the needed stuff to use it in our Contract&lt;/p&gt;


&lt;h2&gt;
  
  
  Create a Chainlink VRF Subscription
&lt;/h2&gt;

&lt;p&gt;Chainlink VRF is a powerful tool for generating random numbers on the blockchain, and it offers two methods for requesting randomness: &lt;strong&gt;subscription&lt;/strong&gt; and &lt;strong&gt;direct funding&lt;/strong&gt;. In this article, we'll focus on the subscription method, which allows you to fund requests for multiple consumer contracts from a single subscription account.&lt;/p&gt;

&lt;p&gt;To create a Chainlink VRF subscription, you'll need to follow a few simple steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 - Creating a Subscription
&lt;/h3&gt;

&lt;p&gt;To create a subscription for Chainlink VRF, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the subscription manager page at &lt;a href="https://vrf.chain.link" rel="noopener noreferrer"&gt;https://vrf.chain.link&lt;/a&gt; and connect your Metamask wallet. Ensure that your wallet is set to the Sepolia testnet.&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%2Fmdjvssugbk0e9x1y60d2.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%2Fmdjvssugbk0e9x1y60d2.png" alt="Create Subscription" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the "&lt;code&gt;Create Subscription&lt;/code&gt;" button and fill in the required details. Once you have entered the necessary information, click on "Create Subscription" again.&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%2F8lmw5e0gy9z4ojcxnz1u.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%2F8lmw5e0gy9z4ojcxnz1u.png" alt="Fill in Subscription Details" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will be prompted to approve the transaction on Metamask. Approve the transaction and wait until it is confirmed on the chain.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2 - Fund your Subscription
&lt;/h3&gt;

&lt;p&gt;To fund your subscription and obtain random numbers, you will need to pay LINK tokens. To obtain testnet LINK tokens, visit &lt;a href="https://faucets.chain.link/sepolia" rel="noopener noreferrer"&gt;https://faucets.chain.link/sepolia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After obtaining LINK tokens, return to your subscription dashboard and click on the "&lt;code&gt;Fund Subscription&lt;/code&gt;" button located under the "&lt;code&gt;Actions&lt;/code&gt;" dropdown in the top right corner of the page. Enter the number of LINK tokens you wish to fund in the input box and click on "&lt;code&gt;Confirm&lt;/code&gt;". You will then be prompted with a Metamask popup. Click on "&lt;code&gt;Approve&lt;/code&gt;" to complete the transaction.&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%2Fxup7ivmhiws07ld4y6fg.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%2Fxup7ivmhiws07ld4y6fg.png" alt="Fund You Subscription with LINK Tokens" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's It. We have successfully created a subscription to get Random Numbers, now we can move to the smart contract.&lt;/p&gt;




&lt;h2&gt;
  
  
  Create Lottery Contract
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initializing Contract
&lt;/h3&gt;

&lt;p&gt;To begin creating the lottery smart contract, we need to specify the license of the contract, and the pragma version, and import the necessary modules.&lt;/p&gt;

&lt;p&gt;We will be using the &lt;em&gt;Strings&lt;/em&gt; module from &lt;code&gt;@openzeppelin/contracts&lt;/code&gt; to provide custom error messages, and the &lt;em&gt;VRFConsumerBaseV2&lt;/em&gt; and &lt;em&gt;VRFCoordinatorV2Interface&lt;/em&gt; modules from &lt;code&gt;@chainlink/contracts&lt;/code&gt; to implement random number functionality.&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.14;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will create a contract called Lottery that will inherit from VRFConsumerBaseV2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract Lottery is VRFConsumerBaseV2 {
    // Code...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  State Variables
&lt;/h3&gt;

&lt;p&gt;To pass on the configuration to the VRFConsumerBaseV2 contract, we need to declare some state variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VRFCoordinatorV2Interface COORDINATOR;
uint64 subscriptionId;
address vrfCoordinator = 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625;
bytes32 keyHash =
    0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
uint32 callbackGasLimit = 100000;
uint16 requestConfirmations = 3;
uint32 numWords = 1;

uint256 public lotteryCount = 0;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each variable does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;COORDINATOR&lt;/code&gt; - This is the contract address that we will use to request randomness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;subscriptionId&lt;/code&gt; - This is the subscription ID that this contract uses for funding requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;vrfCoordinator&lt;/code&gt; - This is the address of the coordinator on the Sepolia testnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;keyHash&lt;/code&gt; - This is the gas lane key hash value, which functions as an ID of the off-chain VRF job that runs in response to requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;callbackGasLimit&lt;/code&gt; - This is the limit for how much gas to use for the callback request to your contract's function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;requestConfirmations&lt;/code&gt; - This is how many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;numWords&lt;/code&gt; - This is how many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lotteryCount&lt;/code&gt; - This is the variable that keeps track of the total lotteries.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To keep track of the data for the lottery, we need to create some structures and mappings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct LotteryData {
        address lotteryOperator;
        uint256 ticketPrice;
        uint256 maxTickets;
        uint256 operatorCommissionPercentage;
        uint256 expiration;
        address lotteryWinner;
        address[] tickets;
}

struct LotteryStatus {
    uint256 lotteryId;
    bool fulfilled;
    bool exists;
    uint256[] randomNumber;
}

mapping(uint256 =&amp;gt; LotteryData) public lottery;
mapping(uint256 =&amp;gt; LotteryStatus) public requests;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each structure and mapping does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;LotteryData&lt;/code&gt; struct - This structure keeps a record of the &lt;code&gt;lotteryOperator&lt;/code&gt;, which is the address that can start and end a lottery, &lt;code&gt;ticketPrice&lt;/code&gt;, which is the price of each ticket, &lt;code&gt;maxTickets&lt;/code&gt;, which is the maximum number of tickets, &lt;code&gt;operatorCommissionPercentage&lt;/code&gt;, which is a percentage of the total pool that is sent to the operator, &lt;code&gt;expiration&lt;/code&gt;, which is the time when the lottery ends, &lt;code&gt;lotteryWinner&lt;/code&gt;, which is the address of the winner, and &lt;code&gt;tickets&lt;/code&gt;, which stores all the tickets for the lottery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;LotteryStatus&lt;/code&gt; struct - This structure keeps track of the request sent to the VRFCoordinator after the lottery is ended. It stores some states like the request fulfilled status and the &lt;code&gt;randomNumber&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lottery&lt;/code&gt; mapping - This mapping maps &lt;code&gt;lotteryCount&lt;/code&gt; to the &lt;code&gt;LotteryData&lt;/code&gt; struct.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;requests&lt;/code&gt; mapping - This mapping maps to &lt;code&gt;LotteryStatus&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Constructor
&lt;/h3&gt;

&lt;p&gt;The constructor function is used to initialize the Lottery contract. It takes in a &lt;code&gt;subscriptionId&lt;/code&gt; as a parameter, which is used to fund requests for random numbers.&lt;/p&gt;

&lt;p&gt;Inside the constructor function, the COORDINATOR variable is set to an instance of the VRFCoordinatorV2Interface contract using the &lt;code&gt;vrfCoordinator&lt;/code&gt; address. The &lt;code&gt;subscriptionId&lt;/code&gt; variable is set to the &lt;code&gt;_subscriptionId&lt;/code&gt; parameter passed to the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(uint64 _subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
    COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
    subscriptionId = _subscriptionId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Events
&lt;/h3&gt;

&lt;p&gt;The Lottery contract has several events that are emitted during different stages of the lottery process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event LotteryCreated(
    address lotteryOperator,
    uint256 ticketPrice,
    uint256 maxTickets,
    uint256 operatorCommissionPercentage,
    uint256 expiration
);

event LogTicketCommission(
    uint256 lotteryId,
    address lotteryOperator,
    uint256 amount
);

event TicketsBought(
    address buyer,
    uint256 lotteryId,
    uint256 ticketsBought
);

event LotteryWinnerRequestSent(
    uint256 lotteryId,
    uint256 requestId,
    uint32 numWords
);

event RequestFulfilled(uint256 requestId, uint256[] randomWords);

event LotteryWinnerDrawn(uint256 lotteryId, address lotteryWinner);

event LotteryClaimed(
    uint256 lotteryId,
    address lotteryWinner,
    uint256 amount
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each event does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LotteryCreated&lt;/strong&gt; - This event is emitted when a new lottery is created. It includes information about the &lt;code&gt;lotteryOperator&lt;/code&gt;, &lt;code&gt;ticketPrice&lt;/code&gt;, &lt;code&gt;maxTickets&lt;/code&gt;, &lt;code&gt;operatorCommissionPercentage&lt;/code&gt;, and &lt;code&gt;expiration&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LogTicketCommission&lt;/strong&gt; - This event is emitted when lottery commission is sent to the operator. It includes information about the &lt;code&gt;lotteryId&lt;/code&gt;, &lt;code&gt;lotteryOperator&lt;/code&gt;, and &lt;code&gt;amount&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TicketsBought&lt;/strong&gt; - This event is emitted when a user buys tickets. It includes information about the &lt;code&gt;buyer&lt;/code&gt;, &lt;code&gt;lotteryId&lt;/code&gt;, and &lt;code&gt;ticketsBought&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LotteryWinnerRequestSent&lt;/strong&gt; - This event is emitted when a random number request is sent to Chainlink VRF. It includes information about the &lt;code&gt;lotteryId&lt;/code&gt;, &lt;code&gt;requestId&lt;/code&gt;, and &lt;code&gt;numWords&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RequestFulfilled&lt;/strong&gt; - This event is emitted when a random number request is fulfilled by Chainlink VRF. It includes information about the &lt;code&gt;requestId&lt;/code&gt; and &lt;code&gt;randomWords&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LotteryWinnerDrawn&lt;/strong&gt; - This event is emitted when a lottery winner is drawn. It includes information about the &lt;code&gt;lotteryId&lt;/code&gt; and &lt;code&gt;lotteryWinner&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LotteryClaimed&lt;/strong&gt; - This event is emitted when a lottery winner claims their prize. It includes information about the &lt;code&gt;lotteryId&lt;/code&gt;, &lt;code&gt;lotteryWinner&lt;/code&gt;, and &lt;code&gt;amount&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Modifiers
&lt;/h3&gt;

&lt;p&gt;The Lottery contract has two modifiers that are used to restrict access to certain functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modifier onlyOperator(uint256 _lotteryId) {
    require(
        (msg.sender == lottery[_lotteryId].lotteryOperator),
        "Error: Caller is not the lottery operator"
    );
    _;
}

modifier canClaimLottery(uint256 _lotteryId) {
    require(
        (lottery[_lotteryId].lotteryWinner != address(0x0)),
        "Error: Lottery Winner not yet drawn"
    );
    require(
        (msg.sender == lottery[_lotteryId].lotteryWinner ||
            msg.sender == lottery[_lotteryId].lotteryOperator),
        "Error: Caller is not the lottery winner"
    );
    _;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what each modifier does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;onlyOperator&lt;/strong&gt; - This modifier restricts access to functions that can only be called by the &lt;code&gt;lotteryOperator&lt;/code&gt;. It takes in a &lt;code&gt;_lotteryId&lt;/code&gt; parameter to ensure that the caller is the operator of the specified lottery. If the caller is not the operator, an error message is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;canClaimLottery&lt;/strong&gt; - This modifier restricts access to functions that can only be called by the &lt;code&gt;lotteryWinner&lt;/code&gt; or &lt;code&gt;lotteryOperator&lt;/code&gt; after the winner has been drawn. It takes in a &lt;code&gt;_lotteryId&lt;/code&gt; parameter to ensure that the caller is either the winner or the operator of the specified lottery. If the winner has not been drawn yet or the caller is not the winner or operator, an error message is returned.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Read Functions
&lt;/h3&gt;

&lt;p&gt;The Lottery contract has a read function called &lt;code&gt;getRemainingTickets&lt;/code&gt; that returns the number of remaining tickets for a specified lottery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getRemainingTickets(uint256 _lotteryId) public view returns (uint256) {
    return lottery[_lotteryId].maxTickets - lottery[_lotteryId].tickets.length;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Write Functions
&lt;/h3&gt;

&lt;p&gt;The Lottery contract has a function called &lt;code&gt;createLottery&lt;/code&gt; that is used to create a new lottery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createLottery(
    address _lotteryOperator,
    uint256 _ticketPrice,
    uint256 _maxTickets,
    uint256 _operatorCommissionPercentage,
    uint256 _expiration
) public {
    require(
        _lotteryOperator != address(0),
        "Error: Lottery operator cannot be 0x0"
    );
    require(
        (_operatorCommissionPercentage &amp;gt;= 0 &amp;amp;&amp;amp;
            _operatorCommissionPercentage % 5 == 0),
        "Error: Commission percentage should be greater than zero and multiple of 5"
    );
    require(
        _expiration &amp;gt; block.timestamp,
        "Error: Expiration must be greater than current block timestamp"
    );
    require(_maxTickets &amp;gt; 0, "Error: Max tickets must be greater than 0");
    require(_ticketPrice &amp;gt; 0, "Error: Ticket price must be greater than 0");
    address[] memory ticketsArray;
    lotteryCount++;
    lottery[lotteryCount] = LotteryData({
        lotteryOperator: _lotteryOperator,
        ticketPrice: _ticketPrice,
        maxTickets: _maxTickets,
        operatorCommissionPercentage: _operatorCommissionPercentage,
        expiration: _expiration,
        lotteryWinner: address(0),
        tickets: ticketsArray
    });
    emit LotteryCreated(
        _lotteryOperator,
        _ticketPrice,
        _maxTickets,
        _operatorCommissionPercentage,
        _expiration
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what the function does:&lt;/p&gt;

&lt;p&gt;This function takes in several parameters including the &lt;code&gt;lotteryOperator&lt;/code&gt;, &lt;code&gt;ticketPrice&lt;/code&gt;, &lt;code&gt;maxTickets&lt;/code&gt;, &lt;code&gt;operatorCommissionPercentage&lt;/code&gt;, and &lt;code&gt;expiration&lt;/code&gt;. It first checks that the &lt;code&gt;lotteryOperator&lt;/code&gt; is not the null address, the &lt;code&gt;operatorCommissionPercentage&lt;/code&gt; is greater than or equal to zero and a multiple of 5, and the expiration is greater than the current block timestamp. It also checks that the &lt;code&gt;maxTickets&lt;/code&gt; and &lt;code&gt;ticketPrice&lt;/code&gt; are greater than zero.&lt;/p&gt;

&lt;p&gt;If all of these conditions are met, a new &lt;code&gt;LotteryData&lt;/code&gt; struct is created with the specified parameters and an empty tickets array. The &lt;code&gt;lotteryCount&lt;/code&gt; is incremented and the new LotteryData struct is added to the &lt;code&gt;lottery&lt;/code&gt; mapping with the &lt;code&gt;lotteryCount&lt;/code&gt; as the key. Finally, the &lt;code&gt;LotteryCreated&lt;/code&gt; event is emitted with information about the new lottery.&lt;/p&gt;

&lt;p&gt;Next we have the &lt;code&gt;BuyTickets&lt;/code&gt; Function that is used to buy tickets for a specified lottery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function BuyTickets(uint256 _lotteryId, uint256 _tickets) public payable {
    uint256 amount = msg.value;
    require(
        _tickets &amp;gt; 0,
        "Error: Number of tickets must be greater than 0"
    );
    require(
        _tickets &amp;lt;= getRemainingTickets(_lotteryId),
        "Error: Number of tickets must be less than or equal to remaining tickets"
    );
    require(
        amount &amp;gt;= _tickets * lottery[_lotteryId].ticketPrice,
        "Error: Ether value must be equal to number of tickets times ticket price"
    );
    require(
        block.timestamp &amp;lt; lottery[_lotteryId].expiration,
        "Error: Lottery has expired"
    );

    LotteryData storage currentLottery = lottery[_lotteryId];

    for (uint i = 0; i &amp;lt; _tickets; i++) {
        currentLottery.tickets.push(msg.sender);
    }

    emit TicketsBought(msg.sender, _lotteryId, _tickets);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what the function does:&lt;/p&gt;

&lt;p&gt;This function takes in two parameters including the &lt;code&gt;_lotteryId&lt;/code&gt; and &lt;code&gt;_tickets&lt;/code&gt; to specify which lottery to buy tickets for and how many tickets to buy. It first checks that the &lt;code&gt;_tickets&lt;/code&gt; parameter is greater than zero, that the number of tickets being purchased is less than or equal to the remaining tickets for the specified lottery, and that the amount of ether sent is equal to the number of tickets times the ticket price. It also checks that the specified lottery has not expired.&lt;/p&gt;

&lt;p&gt;If all of these conditions are met, the function adds the buyer's address to the tickets array in the LotteryData struct for the specified lottery &lt;code&gt;_tickets&lt;/code&gt; the number of times. Finally, the &lt;code&gt;TicketsBought&lt;/code&gt; event is emitted with information about the buyer, the lottery, and the number of tickets purchased.&lt;/p&gt;

&lt;p&gt;Next, we have the &lt;code&gt;DrawLotteryWinner&lt;/code&gt; function is used to draw a winner for a specified lottery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function DrawLotteryWinner(
    uint256 _lotteryId
) external onlyOperator(_lotteryId) returns (uint256 requestId) {
    require(
        block.timestamp &amp;gt; lottery[_lotteryId].expiration,
        "Error: Lottery has not yet expired"
    );
    require(
        lottery[_lotteryId].lotteryWinner == address(0),
        "Error: Lottery winner already drawn"
    );
    requestId = COORDINATOR.requestRandomWords(
        keyHash,
        subscriptionId,
        requestConfirmations,
        callbackGasLimit,
        numWords
    );
    requests[requestId] = LotteryStatus({
        lotteryId: _lotteryId,
        randomNumber: new uint256[](0),
        exists: true,
        fulfilled: false
    });
    emit LotteryWinnerRequestSent(_lotteryId, requestId, numWords);
    return requestId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what the function does:&lt;/p&gt;

&lt;p&gt;This function takes in one parameter, &lt;code&gt;_lotteryId&lt;/code&gt;, to specify which lottery to draw a winner for. This function uses &lt;code&gt;onlyOperator&lt;/code&gt; modifier which ensures that only the Lottery Operator can Draw the Lottery Results. Then It checks that the specified lottery has expired and that a winner has not already been drawn.&lt;/p&gt;

&lt;p&gt;If these conditions are met, the function calls the &lt;code&gt;requestRandomWords&lt;/code&gt; function from the VRFConsumerBase contract to generate a random number. The function creates a new &lt;code&gt;LotteryStatus&lt;/code&gt; struct with the specified lottery ID, an empty &lt;code&gt;randomNumber&lt;/code&gt; array, and a flag indicating that the request exists but has not yet been fulfilled. The function then emits a &lt;code&gt;LotteryWinnerRequestSent&lt;/code&gt; event with information about the lottery, the request ID, and the number of words requested. Finally, the function returns the request ID.&lt;/p&gt;

&lt;p&gt;The last write function is called &lt;code&gt;ClaimLottery&lt;/code&gt; that is used to claim the prize for a specified lottery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ClaimLottery(
    uint256 _lotteryId
) public canClaimLottery(_lotteryId) {
    LotteryData storage currentLottery = lottery[_lotteryId];
    uint256 vaultAmount = currentLottery.tickets.length *
        currentLottery.ticketPrice;

    uint256 operatorCommission = vaultAmount /
        (100 / currentLottery.operatorCommissionPercentage);

    (bool sentCommission, ) = payable(currentLottery.lotteryOperator).call{
        value: operatorCommission
    }("");
    require(sentCommission);
    emit LogTicketCommission(
        _lotteryId,
        currentLottery.lotteryOperator,
        operatorCommission
    );

    uint256 winnerAmount = vaultAmount - operatorCommission;

    (bool sentWinner, ) = payable(currentLottery.lotteryWinner).call{
        value: winnerAmount
    }("");
    require(sentWinner);
    emit LotteryClaimed(
        _lotteryId,
        currentLottery.lotteryWinner,
        winnerAmount
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what the function does:&lt;/p&gt;

&lt;p&gt;This function takes in one parameter, &lt;code&gt;_lotteryId&lt;/code&gt;, to specify which lottery to claim the prize for. It has the &lt;code&gt;canClaimLottery&lt;/code&gt; modifier which restricts the Lottery Winner and the Operator to only call the function. Then It checks that the specified lottery has a winner and that the caller is the winner.&lt;/p&gt;

&lt;p&gt;If these conditions are met, the function calculates the total amount of ether in the lottery vault by multiplying the number of tickets sold by the ticket price. It then calculates the operator commission by dividing the vault amount by the operator commission percentage and sends the commission to the lottery operator. The function then calculates the winner amount by subtracting the operator commission from the vault amount and sends the winner amount to the lottery winner. Finally, the function emits a &lt;code&gt;LogTicketCommission&lt;/code&gt; event with information about the operator commission and a &lt;code&gt;LotteryClaimed&lt;/code&gt; event with information about the lottery and the winner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internal Functions
&lt;/h3&gt;

&lt;p&gt;The Lottery contract has an internal function called &lt;code&gt;fulfillRandomWords&lt;/code&gt; which overrides the Chainlink implementation that is used to handle the fulfillment of a randomness request sent in the &lt;code&gt;DrawLottery&lt;/code&gt; Funtion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fulfillRandomWords(
    uint256 _requestId,
    uint256[] memory _randomWords
) internal override {
    require(requests[_requestId].exists, "Error: Request not found");
    uint256 lotteryId = requests[_requestId].lotteryId;
    requests[_requestId].fulfilled = true;
    requests[_requestId].randomNumber = _randomWords;
    uint256 winnerIndex = _randomWords[0] %
        lottery[lotteryId].tickets.length;
    lottery[lotteryId].lotteryWinner = lottery[lotteryId].tickets[
        winnerIndex
    ];
    emit RequestFulfilled(_requestId, _randomWords);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what the function does:&lt;/p&gt;

&lt;p&gt;This function takes in two parameters, &lt;code&gt;_requestId&lt;/code&gt; and &lt;code&gt;_randomWords&lt;/code&gt;, to specify the ID of the request being fulfilled and the random words generated by the VRF coordinator. It first checks that the request exists in the &lt;code&gt;requests&lt;/code&gt; mapping.&lt;/p&gt;

&lt;p&gt;If the request exists, the function retrieves the lottery ID associated with the request and sets the fulfilled flag to true for the request. The function then stores the random words in the &lt;code&gt;randomNumber&lt;/code&gt; array for the request and calculates the index of the winning ticket by taking the modulus of the first random number with the number of tickets sold for the lottery.&lt;/p&gt;

&lt;p&gt;The function then sets the &lt;code&gt;lotteryWinner&lt;/code&gt; address for the specified lottery to the address of the ticket holder at the calculated index. Finally, the function emits a &lt;code&gt;RequestFulfilled&lt;/code&gt; event with information about the request and the random words.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deploying Contract
&lt;/h2&gt;

&lt;p&gt;To deploy the Lottery contract through Remix, you will need to follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open &lt;a href="https://remix.ethereum.org/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; and create a new Solidity file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy and paste the Lottery contract code into the file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile the contract by selecting the appropriate compiler version and clicking on the "&lt;code&gt;Compile&lt;/code&gt;" button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the contract is compiled, click on the "Run" tab and select the "Deploy &amp;amp; Run Transactions" option.Then choose &lt;code&gt;Injected Provider - Metamask&lt;/code&gt; under the Environments Dropdown and make sure you are on Sepolia Testnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the "Deploy" section, select the appropriate account to deploy the contract from and select the Lottery contract from the dropdown menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the constructor arguments for the Lottery contract. One of the constructor arguments is the subscription ID that was generated when creating a VRF subscription. You will need to copy this subscription ID and paste it into the constructor arguments field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the "Transact" button to deploy the contract.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the contract is deployed, we need to whitelist the contract in our Subscription so it can request random numbers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Add Consumer to Subscription Manager
&lt;/h2&gt;

&lt;p&gt;To whitelist our contract in the subscription so that it can request random numbers, go to your subscription dashboard and click on "&lt;code&gt;Add Consumer&lt;/code&gt;" button. then enter the deployed Lottery contract address in the input field and click "&lt;code&gt;Add Consumer&lt;/code&gt;". You will be prompted with a Metamask popup to approve the transaction. That's all, we've added our Lottery Contract to the total and the user can now request random numbers from the VRF.&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%2F7x43b8aikkqbjmff0h4g.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%2F7x43b8aikkqbjmff0h4g.png" alt="Add Consumer to Subscription Manager" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;🎉 Congratulations on successfully deploying the Lottery contract!&lt;/p&gt;

&lt;p&gt;In conclusion, the Lottery contract is a Solidity smart contract that allows for the creation and management of lotteries on the Ethereum blockchain. The contract uses Chainlink's VRF to generate random numbers for selecting lottery winners in a secure and decentralized manner. The contract also includes features such as ticket purchasing, operator commission, and prize claiming.&lt;/p&gt;

&lt;p&gt;To make the Lottery contract even better, one possible improvement would be to add more advanced features such as multi-round lotteries, variable ticket prices, and automatic prize distribution. Additionally, the contract could be audited by a third-party security firm to ensure that it is free from vulnerabilities and exploits.&lt;/p&gt;

&lt;p&gt;Overall, the Lottery contract is a great example of how smart contracts can be used to create decentralized and transparent lotteries on the blockchain.&lt;/p&gt;

&lt;p&gt;👍 If you found this technical writing helpful and would like to see more content like this, please consider following the blog!&lt;/p&gt;

&lt;p&gt;🔍 You can also connect with me on &lt;a href="https://github.com/Envoy-VC" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://twitter.com/Envoy_1084" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more updates and technical discussions. Thank you for reading!&lt;/p&gt;




</description>
      <category>tutorial</category>
      <category>solidity</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Web3 Newsletter Creation Made Easy with Mailchain: A Step-by-Step Guide</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Mon, 17 Apr 2023 22:17:52 +0000</pubDate>
      <link>https://dev.to/envoy1084/web3-newsletter-creation-made-easy-with-mailchain-a-step-by-step-guide-4lj3</link>
      <guid>https://dev.to/envoy1084/web3-newsletter-creation-made-easy-with-mailchain-a-step-by-step-guide-4lj3</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Traditional newsletters often face challenges such as a lack of privacy, security, and user control over data. However, Mailchain provides a solution to these issues. With Mailchain, all messages are secured with end-to-end encryption, giving you full ownership of your keys and ensuring that your data remains private. Messages are also encrypted and stored on decentralized storage, safeguarding your privacy and providing enhanced security.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you will have built a simple yet powerful newsletter service that allows users to join your newsletter using their Ethereum address. You will learn how to keep track of subscribers and send them a joining email using Mailchain.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/52e7d302ee554f1f9f33e3f7b99fd814"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;You can find an example of the final result here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Envoy-VC/mailchain-newsletter" rel="noopener noreferrer"&gt;https://github.com/Envoy-VC/mailchain-newsletter&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/envoy1084" rel="noopener noreferrer"&gt;
        envoy1084
      &lt;/a&gt; / &lt;a href="https://github.com/envoy1084/mailchain-newsletter" rel="noopener noreferrer"&gt;
        mailchain-newsletter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Web3 Newsletter Service built on top of Mailchain
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📰 Mailchain Newsletter&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Mailchain Newsletter is a web3 newsletter service lets users to subscribe to your newsletter and send Welcome E-mails, Newsletters, and more using Mailchain. Mailchain Newsletter is built using Mailchain, GraphQL nnd Next.js.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features ✨&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Encrypted messaging using Mailchain&lt;/li&gt;
&lt;li&gt;Easy to use web interface&lt;/li&gt;
&lt;li&gt;Customizable templates&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Demo 🎥&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;You can find the video demo &lt;a href="https://www.loom.com/share/52e7d302ee554f1f9f33e3f7b99fd814" rel="nofollow noopener noreferrer"&gt;here&lt;/a&gt;:&lt;/p&gt;

  
    
    

    &lt;span class="m-1"&gt;Build.a.Web3.Newsletter.using.Mailchain.mp4&lt;/span&gt;
    
  

  

  



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started 🚀&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;To get started with Mailchain Newsletter, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone the repository to your local machine
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/Envoy-VC/mailchain-newsletter.git&lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Install the necessary dependencies using
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install&lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Configure your Environment Variables in the .env file
&lt;div class="highlight highlight-text-adblock notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;NEXT_PUBLIC_MAILCHAIN_SECRET_KEY='mailchain_recovery_phrase'
NEXT_PUBLIC_HYGRAPH_URL='hygraph_project_url'&lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Start the server using
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm start&lt;/pre&gt;

&lt;/div&gt;
Access the web interface at &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Blog Post 📝&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;For more detailed instructions, please refer to the &lt;a href="https://blog.vedantc.dev/create-a-web3-newsletter-with-mailchain" rel="nofollow noopener noreferrer"&gt;Blog Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/42f17c7c04fefec663bdd918fd4cadf080b57557ed995f7cfa591c5cdf8802fb/68747470733a2f2f63646e2e686173686e6f64652e636f6d2f7265732f686173686e6f64652f696d6167652f75706c6f61642f76313638313938373233343034382f32356233316662642d393730332d343935392d626261362d6333626631333232393163652e706e673f773d3136303026683d383430266669743d63726f702663726f703d656e74726f7079266175746f3d636f6d70726573732c666f726d617426666f726d61743d77656270"&gt;&lt;img src="https://camo.githubusercontent.com/42f17c7c04fefec663bdd918fd4cadf080b57557ed995f7cfa591c5cdf8802fb/68747470733a2f2f63646e2e686173686e6f64652e636f6d2f7265732f686173686e6f64652f696d6167652f75706c6f61642f76313638313938373233343034382f32356233316662642d393730332d343935392d626261362d6333626631333232393163652e706e673f773d3136303026683d383430266669743d63726f702663726f703d656e74726f7079266175746f3d636f6d70726573732c666f726d617426666f726d61743d77656270" alt="Blog Post"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.vedantc.dev/create-a-web3-newsletter-with-mailchain" rel="nofollow noopener noreferrer"&gt;https://blog.vedantc.dev/create-a-web3-newsletter-with-mailchain&lt;/a&gt;&lt;/p&gt;

&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/envoy1084/mailchain-newsletter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;As you work through the tutorial, you'll be using &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; as our frontend framework, &lt;a href="https://www.rainbowkit.com/" rel="noopener noreferrer"&gt;RainbowKit&lt;/a&gt; for wallet authentication and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt; for Styling. Also, we will be using &lt;a href="https://app.hygraph.com" rel="noopener noreferrer"&gt;Hygraph&lt;/a&gt; as our Content Management system(CMS) to keep track of our subscribers. No worries if you're not well-versed in these technologies - we'll provide step-by-step instructions with code snippets throughout the tutorial.&lt;/p&gt;




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

&lt;p&gt;Before you begin with this tutorial, make sure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; installed on your local machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;a href="https://docs.mailchain.com/user/guides/getting-started/create-a-mailchain-account/" rel="noopener noreferrer"&gt;Mailchain account&lt;/a&gt; created for development and testing purposes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An &lt;a href="https://docs.mailchain.com/user/guides/getting-started/register-a-wallet/" rel="noopener noreferrer"&gt;Ethereum address registered in Mailchain&lt;/a&gt; to your development and testing account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An account created on &lt;a href="https://app.hygraph.com/signup" rel="noopener noreferrer"&gt;Hygraph&lt;/a&gt;, a headless CMS that we will use to store the newsletter subscribers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1 - Clone the starter repository
&lt;/h2&gt;

&lt;p&gt;The starter repository contains a basic boilerplate for a Next.js app with Rainbow Kit and Tailwind CSS configured. This starter repository provides a solid foundation for building a web3-based-applications&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open your terminal and navigate to the directory where you want to clone the repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the following command to clone the repository:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Envoy-VC/dapp-kit.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once the cloning is complete, navigate into the cloned directory:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;dapp-kit
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now run &lt;code&gt;npm&lt;/code&gt; in this directory to install all the dependencies.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

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




&lt;h2&gt;
  
  
  Step 2 - Creating our Database
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a New Project in Hygraph&lt;/strong&gt; - Navigate to the Hygraph dashboard and click on "&lt;code&gt;Add Project&lt;/code&gt;" to create a new project. You can give your project any name, provide a description, and select a region that's closest to you. Once done, click on "&lt;code&gt;Add Project&lt;/code&gt;" to create your project.&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%2Fmlakpldbzh4tf78z56at.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%2Fmlakpldbzh4tf78z56at.png" alt="Creating a Hygraph Project" width="735" height="573"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Schema for Your Data Next, let's create a schema, which is a layout for our data. Go to the "&lt;code&gt;Schema&lt;/code&gt;" section in the left sidebar of Hygraph and click on "&lt;code&gt;Add Model&lt;/code&gt;". Fill in the details for the model, as shown in the picture below, and feel free to add any description. Make sure that the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;API IDs&lt;/code&gt; match, as we will be using them to query the data. Click on "&lt;code&gt;Add Model&lt;/code&gt;" to create your schema.&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%2Ffe6kub2fp66ffb6lj9yk.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%2Ffe6kub2fp66ffb6lj9yk.png" alt="Create a new model" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Let's add some fields to our model. In the right sidebar of Hygraph, click on &lt;code&gt;Single Line Text&lt;/code&gt; option, which will add a simple text input to our model. Give it a name, such as "&lt;code&gt;Address&lt;/code&gt;", and provide a description. Under the "&lt;code&gt;Validations&lt;/code&gt;" tab, ensure that the field is set to be unique and required.&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%2Fi9hq0v16er5s4m8ieo2o.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%2Fi9hq0v16er5s4m8ieo2o.png" alt="Address field" width="800" height="670"&gt;&lt;/a&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%2F4s3w01nj279t2ejfpqql.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%2F4s3w01nj279t2ejfpqql.png" alt="Validations" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set Permissions for the API Under the left sidebar, go to "&lt;code&gt;Project Settings&lt;/code&gt;" and navigate to the "&lt;code&gt;Public Content API&lt;/code&gt;" section. Here, we need to set permissions for the API to query and mutate data from our front end. Click on "&lt;code&gt;Add Permissions&lt;/code&gt;" and select all the checkboxes. Then click on "&lt;code&gt;Add&lt;/code&gt;" to set the permissions.&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%2Fv5jpn2pyu5ulpykkqaaj.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%2Fv5jpn2pyu5ulpykkqaaj.png" alt="Set Permissions for Content API" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the Content API Link Scroll to the top of the page until you see a "Content API" link. We will be using this link to communicate with our database. Copy this link and save it somewhere for future reference.&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%2F8hz5dqcwh8ribawi6bug.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%2F8hz5dqcwh8ribawi6bug.png" alt="Content API Link" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we have initialized our Hygraph database and created a schema for our data, we are ready to move on to the next step&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 - Configure environment variables
&lt;/h2&gt;

&lt;p&gt;Now, let's configure our environment variables to set values that will be passed to our code. It's important to avoid storing environment variables in source control, as it can expose sensitive information. In this tutorial, we have a &lt;code&gt;.gitignore&lt;/code&gt; file that tells Git to ignore the existing environment files, preventing any changes to them from being stored in Git. However, make sure to add any new environment files to the &lt;code&gt;.gitignore&lt;/code&gt; as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# env files
.env 
.env.*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a new environment file, go to the root directory of your app and create a file called &lt;code&gt;.env.local&lt;/code&gt;. Open it in your code editor and include the following values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_MAILCHAIN_SECRET_KEY='mailchain-recovery-phrase-here'
NEXT_PUBLIC_HYGRAPH_URL='hygraph-content-url-here'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to replace the placeholder values with your values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;NEXT_PUBLIC_MAILCHAIN_SECRET_KEY&lt;/code&gt; - your secret recovery phrase for your development Mailchain account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;NEXT_PUBLIC_HYGRAPH_URL&lt;/code&gt; - the Content API link that you copied at the end of Step 2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By setting these environment variables, we will be able to securely access our Mailchain account and Hygraph database from our application without exposing any sensitive information in our code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 - Creating an API Route
&lt;/h2&gt;

&lt;p&gt;Now that we have configured our environment variables and installed the Mailchain SDK, we are ready to create an API route for sending emails to users who have joined our newsletter.&lt;/p&gt;

&lt;p&gt;To get started, we need to create an HTML template for the email. Let's create a folder called "&lt;code&gt;constants&lt;/code&gt;" under the root directory of our project, and inside it, we'll create a file called "&lt;code&gt;index.js&lt;/code&gt;" where we can paste the HTML content for the email. This HTML template will be used to generate the content of the email that will be sent to the subscribers of our newsletter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
&amp;lt;div style="max-width: 600px; font-family: Arial, sans-serif; padding: 20px"&amp;gt;
    &amp;lt;div
        style="
            max-width: 600px;
            margin: 0 auto;
            background-color: #ffffff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
        "
    &amp;gt;
        &amp;lt;h1
            style="
                background: linear-gradient(#30cfd0, #c43ad6);
                -webkit-background-clip: text;
                -webkit-text-fill-color: transparent;
                font-size: 36px;
                margin-top: 16px;
                padding-bottom: 16px;
                font-weight: 800;
            "
        &amp;gt;
            GM!
        &amp;lt;/h1&amp;gt;
        &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
            Even if it’s not morning where you are, it’s morning in Web3! 🌞
        &amp;lt;/p&amp;gt;
        &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
            Thank you for being a part of WAGMI Weekly - Your Web3 Fun-dose!
        &amp;lt;/p&amp;gt;
        &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
            Get ready for another exciting edition of our newsletter, packed with fun,
            laughter, and expert analysis of all things Web3!
        &amp;lt;/p&amp;gt;
        &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
            As always, we'll be serving up your weekly dose of Web3 news and
            entertainment, with a touch of coffee ☕️
        &amp;lt;/p&amp;gt;
        &amp;lt;div style="display: inline-block; margin-top: 10px; margin-bottom: 10px"&amp;gt;
            &amp;lt;img
                src="https://i.ibb.co/KNF9zhg/johnny-test-bling-bling-boy.gif"
                alt="Coffee"
                style="max-width: 600px; height: auto"
            /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;p style="color: #999999; font-style: italic"&amp;gt;
            "Web3 without coffee is like a blockchain without blocks!"
        &amp;lt;/p&amp;gt;
        &amp;lt;div style="display: block; margin-top: 20px; text-align: center"&amp;gt;
            &amp;lt;a
                href="https://example.com"
                target="_blank"
                style="
                    display: inline-block;
                    padding: 10px 20px;
                    background-color: #0066cc;
                    color: #ffffff;
                    text-decoration: none;
                    border-radius: 5px;
                "
                &amp;gt;Read Now!&amp;lt;/a
            &amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="footer"&amp;gt;
            &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
                WAGMI Weekly - Your Web3 Fun-dose!
            &amp;lt;/p&amp;gt;
            &amp;lt;p style="color: #333333; line-height: 1.5; padding-bottom: 8px"&amp;gt;
                Questions or comments? Contact us
                &amp;lt;a href="mailto:info@example.com"&amp;gt;here&amp;lt;/a&amp;gt;.
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll create the API route itself. We'll create a new file called "&lt;code&gt;join.js&lt;/code&gt;" inside the "&lt;code&gt;pages/api/&lt;/code&gt;" folder of our project. In this file, we'll import the necessary modules and files that we'll need to send emails using the Mailchain SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Mailchain&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mailchain/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/constants&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretRecoveryPhrase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_MAILCHAIN_SECRET_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the imports are set up, we'll create an exported function called "&lt;code&gt;handler&lt;/code&gt;" which will be the entry point for our API route. This function will be called every time an API call is made to this route. It takes two arguments, "&lt;code&gt;req&lt;/code&gt;" and "&lt;code&gt;res&lt;/code&gt;", which represent the request and response objects respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the "handler" function, we'll first extract the "&lt;code&gt;address&lt;/code&gt;" from the request body. This will be the email address of the subscriber to whom we'll be sending the email. We'll then initialize Mailchain with the recovery phrase that we have set up in our environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mailchain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Mailchain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromSecretRecoveryPhrase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretRecoveryPhrase&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To handle any errors that may occur during the sending of the email, we'll use a try-catch block. If no address is provided in the request body, we'll throw an error indicating that the email address is required. If an address is provided, we'll use the "&lt;code&gt;sendMail&lt;/code&gt;" method from the Mailchain SDK to send the email. This method takes several parameters, such as the sender, receiver, subject, and content of the email, which we'll pass as arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Address not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Send Mail&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mailchain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`envoy1084@lens@lens.mailchain.com`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@ethereum.mailchain.com`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome to WAGMI Weekly!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;It’s official… We’re buddies now!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is it, our API route is configured. Now let's move to the frontend part.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 - Creating Queries for communicating with CMS
&lt;/h2&gt;

&lt;p&gt;Before we dive into building the frontend part of our application, we need to write some queries that will allow us to fetch data from Hygraph CMS. To do this, let's create a folder called "&lt;code&gt;utils&lt;/code&gt;" in the root directory of our project, and inside it, we'll create a file called "&lt;code&gt;query.js&lt;/code&gt;" where we'll define our queries.&lt;/p&gt;

&lt;p&gt;To start, we'll need to install some packages that will help us with querying data. We can do this by running the following command in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;graphql-request graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the packages are installed, we'll need to import some modules and create a Hygraph client that we can use to call our queries. We'll set up our client as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GraphQLClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql-request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hygraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_HYGRAPH_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our client is set up, we can define our queries. We'll create three queries, namely "&lt;code&gt;CHECK_WALLET&lt;/code&gt;", "&lt;code&gt;CREATE_SUBSCRIBER&lt;/code&gt;", and "&lt;code&gt;PUBLISH_SUBSCRIBER&lt;/code&gt;", which will allow us to interact with the CMS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;CHECK_WALLET&lt;/code&gt; query will check if the user is already subscribed to the newsletter by returning the ID of the subscriber if they are subscribed.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CHECK_WALLET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
        {
            subscribers(where: { address: "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" }) {
                id
            }
        }
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The "CREATE_SUBSCRIBER" query will post the address of the subscriber to the CMS, but the data will be in a draft state. We can define this query as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CREATE_SUBSCRIBER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
        mutation CreateSubscriber {
            createSubscriber(
                data: { address: "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"}) {
                id
            }
        }
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;PUBLISH_SUBSCRIBER&lt;/code&gt; query will publish the previously posted data, making it visible to other users. We can define this query as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PUBLISH_SUBSCRIBER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
        mutation PublishSubscriber {
            publishSubscriber(
                where: { address: "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"}) {
                id
            }
        }
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;By defining these queries, we have set up the functionality to interact with the CMS and perform actions such as checking if a user is subscribed, creating a subscriber, and publishing subscriber data. These queries will be used in our frontend application to fetch and manipulate data from Hygraph CMS seamlessly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 - Creating our Newsletter Component
&lt;/h2&gt;

&lt;p&gt;In this step, we'll create a new component called &lt;code&gt;Newsletter.jsx&lt;/code&gt; inside the &lt;code&gt;components&lt;/code&gt; directory, which will serve as our newsletter component. Let's start by importing the necessary modules and files that we'll need for our component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSignMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wagmi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;verifyMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ethers/lib/utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;hygraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;CHECK_WALLET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;CREATE_SUBSCRIBER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PUBLISH_SUBSCRIBER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/utils/query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;newsletter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/newsletter.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll also need to set up some state variables and references to store the loading state and address of the user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recoveredAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll use the &lt;code&gt;signMessage&lt;/code&gt; variable from &lt;code&gt;useSignMessage&lt;/code&gt; to create a function that will allow the user to sign a message. We'll use the &lt;code&gt;onSuccess&lt;/code&gt; method to verify the signature and store the recovered address in the &lt;code&gt;recoveredAddress&lt;/code&gt; variable. Then we'll call the &lt;code&gt;joinNewsletter&lt;/code&gt; function with the &lt;code&gt;userAddress&lt;/code&gt; passed as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSignMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sign this message to subscribe to WAGMI Weekly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verifyMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;recoveredAddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nf"&gt;joinNewsletter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recoveredAddress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// user rejected signature&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll create two functions called &lt;code&gt;isSubscribed&lt;/code&gt; and &lt;code&gt;createSubscriber&lt;/code&gt;, which we'll use to verify if the user is already subscribed and create a new subscriber:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSubscribed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CHECK_WALLET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hygraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSubscriber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subscriberId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hygraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CREATE_SUBSCRIBER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hygraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PUBLISH_SUBSCRIBER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;published&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publishSubscriber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we'll create the &lt;code&gt;joinNewsletter&lt;/code&gt; function, which takes in a &lt;code&gt;userAddress&lt;/code&gt; and checks if the user is an existing subscriber. If not, it adds the address to the subscriber list and calls the join API route to send the user a welcome mail. If the user is already subscribed, it throws an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;joinNewsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;existingSubscriber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;isSubscribed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;existingSubscriber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createSubscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/join&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userAddress&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;savedMessageId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Subscribed successfully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Already subscribed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Already subscribed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll return the HTML content for our component and export the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'my-8 text-black'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'container flex flex-col items-center p-4 mx-auto space-y-6 md:p-8'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;newsletter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'newsletter'&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'px-6 py-2 text-2xl text-gray-700 text-center font-bold sm:text-3xl md:text-4xl lg:max-w-2xl xl:max-w-4xl font-rubik'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;Bored of FOMO? Join WAGMI Weekly and never miss a crypto beat
                    again! Get your weekly dose of fun, laughter, and expert analysis on
                    all things Web3!&lt;span class="ni"&gt;&amp;amp;quot;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
                    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'text-xl text-gray-100  font-sans font-extrabold border-2 py-4 px-8 rounded-3xl semi-transparent-btn transition-all ease-in-out duration-700'&lt;/span&gt;
                    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="nf"&gt;signMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Subscribing...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Join Now&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this newsletter component, we've set up the functionality to allow users to join the newsletter by signing a message, verifying the signature, and adding the user to the subscriber list if they are not already subscribed. This component will be integrated into our frontend application to provide seamless newsletter subscription functionality to our users.&lt;/p&gt;

&lt;p&gt;At last export the component from &lt;code&gt;index.js&lt;/code&gt; file under the &lt;code&gt;components&lt;/code&gt; folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Navbar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Newsletter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then use it in the home page &lt;code&gt;pages/index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Navbar&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7 - Testing
&lt;/h2&gt;

&lt;p&gt;Now that we have implemented the newsletter component, we can test our application. Let's start by running our application in development mode:&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 dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start our application and make it accessible at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000&lt;/code&gt;&lt;/a&gt; in our web browser. We can now click on the "Join" button in our application to initiate the newsletter subscription process.&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%2Fdkuqwzsvheztuozm9907.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%2Fdkuqwzsvheztuozm9907.png" alt="Homepage" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the process is complete, we can check our Mailchain inbox, and we should see a welcome mail for joining the "WAGMI Weekly" newsletter. This will confirm that our newsletter subscription functionality is working as expected.&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%2F8yzsr1gqh2ykorvap8cf.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%2F8yzsr1gqh2ykorvap8cf.png" alt="Mailchain Inbox" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Congratulations 🎉 on successfully building your newsletter service using Mailchain, Next.js, and GraphQL as outlined in this article.&lt;/p&gt;

&lt;p&gt;With the implementation of the newsletter component, you now have a seamless way for users to subscribe to your newsletter and receive welcome emails. You can customize and extend the functionality of this service by visiting the repository&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Some ideas for future enhancements include improving user experience, adding subscription management features, personalizing newsletters, analyzing newsletter performance, and preparing for scalability. By continuing to optimize your newsletter service, you can create a powerful tool for engaging with your audience, promoting your content, and driving traffic to your website.&lt;/p&gt;




</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Create and Deploy Your Own Token on Base Goerli Testnet 🪙</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Thu, 30 Mar 2023 21:18:10 +0000</pubDate>
      <link>https://dev.to/envoy1084/how-to-create-and-deploy-your-own-token-on-base-goerli-testnet-13ni</link>
      <guid>https://dev.to/envoy1084/how-to-create-and-deploy-your-own-token-on-base-goerli-testnet-13ni</guid>
      <description>&lt;h2&gt;
  
  
  What is this article about?
&lt;/h2&gt;

&lt;p&gt;In this article, we will explore the technical process of deploying an ERC-721 token on the &lt;code&gt;Base Blockchain&lt;/code&gt; using &lt;a href="https://thirdweb.com/" rel="noopener noreferrer"&gt;thirdweb&lt;/a&gt;. With this process, you can mint tokens and transfer them to other users. We will also cover the technical aspects of thirdweb and provide detailed instructions on deploying your tokens on more than 700 EVM-compatible blockchains 🚀&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%2Fyad11dc4x7mk1gri4c8n.gif" 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%2Fyad11dc4x7mk1gri4c8n.gif" alt="Let's start building" width="498" height="280"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is an ERC-721 Token
&lt;/h2&gt;

&lt;p&gt;ERC-721 tokens, also known as non-fungible tokens (NFTs), are a unique type of token standard on the Ethereum blockchain that allows for the creation and ownership of completely unique digital assets.&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%2Fgx0k6l1qs8wjptjfi0qt.jpg" 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%2Fgx0k6l1qs8wjptjfi0qt.jpg" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, the most common use case for ERC-721 NFTs is for digital art. Users buy these NFTs for a number of reasons, including supporting artists, investing long-term in hopes that the price will go up, quickly flipping/trading NFTs for a profit, or simply because they like the artwork.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Base Blockchain
&lt;/h2&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%2Fln3fr4vqa1eyfssmxp5n.jpg" 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%2Fln3fr4vqa1eyfssmxp5n.jpg" alt="Base Blockchain" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Base Blockchain is a new Ethereum-based blockchain developed by Coinbase. As a Layer 2 (L2) network, it provides a secure, low-cost, and developer-friendly platform for building decentralized applications (dApps).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the primary goals of Base is to address the scalability issues that plague the Ethereum mainnet. With high gas fees and slow transaction speeds, the mainnet can be a challenging environment for dApp developers to work with. Base is designed to alleviate these problems and offer a more efficient and effective solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is thirdweb
&lt;/h2&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%2Feaarw6kso1w3ypl1ym3m.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%2Feaarw6kso1w3ypl1ym3m.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thirdweb is a powerful development framework designed to help you incorporate web3 functionality into your applications. With Thirdweb, you can easily build and deploy decentralized applications (DApps) that interact with the blockchain, enabling you to leverage the benefits of a decentralized network.&lt;/p&gt;

&lt;p&gt;At its core, Thirdweb provides developers with a variety of tools and workflows to streamline the development process. These include contracts that serve as the foundation for your web3 functionality, software development kits (SDKs) that let you build blockchain applications and dashboards that enable you to manage your contract.&lt;/p&gt;




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

&lt;p&gt;Before you start with the tutorial make sure you have &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; v14 or greater, and the &lt;a href="https://metamask.io/download/" rel="noopener noreferrer"&gt;Metamask&lt;/a&gt; browser extension installed on your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;

&lt;p&gt;Open up your terminal and navigate to the location where you want to create your project directory. Next, we will use the &lt;code&gt;thirdweb Contract Kit&lt;/code&gt; to create a new Smart Contract Project. To get started, create a new Solidity project with 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;npx thirdweb@latest create contract
&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%2Fjuk10h20dhx7g6rz27eo.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%2Fjuk10h20dhx7g6rz27eo.png" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating just fill in the basic things like the name of the project and the contract. In the Starter contract just start with an Empty Contract. We will be using OpenZeppelin Smart Contracts to build our NFT Contract. To install simply 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 &lt;span class="nb"&gt;install&lt;/span&gt; @openzeppelin/contracts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Creating Token
&lt;/h2&gt;

&lt;p&gt;Firstly Navigate to &lt;code&gt;contracts/Token.sol&lt;/code&gt; file and remove any existing code, we will be building our contract from scratch.&lt;/p&gt;

&lt;p&gt;At the top of the file, add the following SPDX license identifier and Solidity version declaration:&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.9;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SPDX license identifier specifies the license under which your code is distributed, while the Solidity version declaration specifies which version of Solidity you're using.&lt;/p&gt;

&lt;p&gt;Next, import the necessary contracts from the OpenZeppelin library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the Overview of all the Files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ERC721.sol&lt;/strong&gt; - Core Implementation on ERC721 Base Contract&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ERC721URIStorage.sol&lt;/strong&gt; - A more Complex and expensive way of storing metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ERC721Burnable.sol&lt;/strong&gt; - A way in which token holders can burn their tokens(transfer to Zero Address)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ownable.sol&lt;/strong&gt; - Method in which an Owner can be assigned to an address, which ensures checks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Counters.sol&lt;/strong&gt; - A simple way to get a counter that can only be incremented, decremented or reset.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Define the contract itself, called Token, and have it inherit from the imported contracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract Token is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line of code specifies that the Token contract is inherited from the &lt;code&gt;ERC721&lt;/code&gt;, &lt;code&gt;ERC721URIStorage&lt;/code&gt;, &lt;code&gt;ERC721Burnable&lt;/code&gt;, and &lt;code&gt;Ownable&lt;/code&gt; contracts.&lt;/p&gt;

&lt;p&gt;Define a variable using Counters from the OpenZeppelin library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow us to keep track of the token IDs for each new token we mint.&lt;/p&gt;

&lt;p&gt;In the constructor, specify the name and symbol for your token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor() ERC721("Token", "TKN") {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line of code sets the name of your token to "&lt;code&gt;Token&lt;/code&gt;" and the symbol to "&lt;code&gt;TKN&lt;/code&gt;". You can customize these to fit your specific needs.&lt;/p&gt;

&lt;p&gt;Now lets define a function called &lt;code&gt;safeMint&lt;/code&gt; that allows the owner of the contract to mint new tokens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function safeMint(address to, string memory uri) public {
    uint256 tokenId = _tokenIdCounter.current();
    _tokenIdCounter.increment();
    _safeMint(to, tokenId);
    _setTokenURI(tokenId, uri);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function takes two arguments: the &lt;strong&gt;address&lt;/strong&gt; that the token will be minted to (to) and the &lt;strong&gt;URI&lt;/strong&gt; for the token's metadata (URI). The function then increments the current token ID counter, mints a new token to the specified address, and sets the token's metadata URI.&lt;/p&gt;

&lt;p&gt;Override two functions required by Solidity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;burn&lt;/strong&gt; - This function allows to burn the tokens, i.e., send to &lt;code&gt;Zero Address&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
    super._burn(tokenId);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;tokenURI&lt;/strong&gt; - It returns the Token URI for the token
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function tokenURI(uint256 tokenId)
    public
    view
    override(ERC721, ERC721URIStorage)
    returns (string memory)
{
    return super.tokenURI(tokenId);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These functions ensure that the Token contract adheres to the ERC721 and ERC721URIStorage standards.&lt;/p&gt;

&lt;p&gt;And that's it! We have completed our smart contract.&lt;/p&gt;

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract Token is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("Token", "TKN") {}

    function safeMint(address to, string memory uri) public {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _burn(
        uint256 tokenId
    ) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(
        uint256 tokenId
    ) public view override(ERC721, ERC721URIStorage) returns (string memory) {
        return super.tokenURI(tokenId);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deploying the Smart Contract
&lt;/h2&gt;

&lt;p&gt;Now that the contract is done, let's deploy it and mint some NFTs! 🚀&lt;/p&gt;

&lt;p&gt;Run the following command to deploy your smart contract using the dashboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx thirdweb@latest deploy
&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%2Fim9liu7xysg16syys9hm.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%2Fim9liu7xysg16syys9hm.png" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, what thirdweb does is firstly compiles your contract and upload your contract to IPFS. After successful compilation and Upload you will be given a link at last from which you can deploy your contract.&lt;/p&gt;

&lt;p&gt;Before Deploying Our Contract, we need to add Base Blockchain Testnet to our Networks. to do that go to &lt;a href="https://thirdweb.com/dashboard" rel="noopener noreferrer"&gt;thirdweb dashboard&lt;/a&gt; and on the top right side of the screen click the Configure Networks gear icon&lt;/p&gt;

&lt;p&gt;then in the add network section search for '&lt;code&gt;Base Goerli Testnet&lt;/code&gt;', select that network and then click on 'Add Network'&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%2Fqphf82s3r9kszjy2vrn4.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%2Fqphf82s3r9kszjy2vrn4.png" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go back to the dashboard and click on the profile icon on the top right of the screen and switch your network. Under the Testnet Section, select the Base Goerli Testnet and click on that. you will be prompted with a Metamask popup where you will be asked to add Base Goerli Testnet to your networks. click on approve.&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%2Fsj7pa31w6mkssgt3apza.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%2Fsj7pa31w6mkssgt3apza.png" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have added Base Testnet to our networks, we need to get some Testnet ETH to deploy our contract. &lt;a href="https://faucet.quicknode.com/drip" rel="noopener noreferrer"&gt;Quicknode&lt;/a&gt; is a multichain faucet that we will use to get some test net eth, go to the Quicknode website and connect your Metamask wallet. now select Base Blockchain with Testnet Config and then click on continue.&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%2F71093ny4ob2r6gwv6px6.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%2F71093ny4ob2r6gwv6px6.png" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now complete the remaining steps and you will receive 0.05 Testnet Ether in your account.&lt;/p&gt;

&lt;p&gt;Now we are ready to deploy our NFT Contract. Go to the link that you got after deploying the contract, and select the '&lt;code&gt;Base Goerli Testnet (ETH)&lt;/code&gt;' under the networks section.&lt;/p&gt;

&lt;p&gt;After that click on the blue deploy button. you will be needed to approve two transactions, the first will be for deploying your contract and the second for adding your contract to the thirdweb's dashboard.&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%2Fjgh78eyligywe0085q7z.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%2Fjgh78eyligywe0085q7z.png" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and that's it you have successfully deployed your contract to &lt;strong&gt;Base Goerli Testnet&lt;/strong&gt;. 🎉&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%2Fp8zc4nlfchv3kzfvmk7g.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%2Fp8zc4nlfchv3kzfvmk7g.png" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the Deployed Contract on the thirdweb Dashboard: &lt;a href="https://thirdweb.com/base-goerli/0xb4Ee5e8ab99425F48bdf2458249F0B81Be3FFFbF" rel="noopener noreferrer"&gt;https://thirdweb.com/base-goerli/0xb4Ee5e8ab99425F48bdf2458249F0B81Be3FFFbF&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Mint an NFT
&lt;/h2&gt;

&lt;p&gt;Now that we've successfully deployed our contract, it's time to mint an NFT!&lt;/p&gt;

&lt;p&gt;To do this, let's head over to the Explorer section under the sidebar. Here, you'll find all the read-and-write methods for your contract. We'll be using the &lt;code&gt;safemint&lt;/code&gt; function located under the write methods.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;safeMint&lt;/code&gt; function requires two arguments: the address to which the NFT will be minted and the metadata URI. The metadata is a JSON file containing the name, image, and attributes of your NFT. It should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Unicorn #2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"black unicorn, a rare and mystical creature. The background should be a moonlit night, with stars twinkling in the sky and a misty forest in the distance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ipfs://bafybeieusozzkp2mt742urqgypwrdyv65uv2jidyspqq5j4lsuipzs2hk4/image.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"display_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"trait_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Date Created"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1679134683&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luckily, I've already uploaded a metadata file for a Unicorn NFT, which you can use! Simply populate the fields with your wallet address and the URI:&lt;/p&gt;

&lt;p&gt;URI - &lt;a href="https://ipfs.io/ipfs/bafybeicb6ytxdp3jbedqejdd3ckbuzjv57tb33bk2ldyd7jw5pg3e52yky/metadata.json" rel="noopener noreferrer"&gt;&lt;code&gt;https://ipfs.io/ipfs/bafybeicb6ytxdp3jbedqejdd3ckbuzjv57tb33bk2ldyd7jw5pg3e52yky/metadata.json&lt;/code&gt;&lt;/a&gt;&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%2Fqcxouwshowq0puy7k7aj.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%2Fqcxouwshowq0puy7k7aj.png" alt="Unicorn NFT" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've filled in the fields, hit that &lt;code&gt;execute&lt;/code&gt; button and approve the transaction in Metamask.&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%2F6vtknvy2l62i6lfsj04y.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%2F6vtknvy2l62i6lfsj04y.png" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 Congratulations! You've successfully minted your NFT on the Base Goerli Testnet!&lt;/p&gt;

&lt;p&gt;🚀 You can also view your transactions on the &lt;a href="https://goerli.basescan.org/" rel="noopener noreferrer"&gt;Basescan Goerli Explorer&lt;/a&gt;.&lt;/p&gt;




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

&lt;p&gt;Congratulations on creating and deploying your own token on the blockchain! 🎉&lt;/p&gt;

&lt;p&gt;But, of course, the journey doesn't stop here. Now that you have a basic understanding of how to create and deploy a token, there are plenty of ways to take your project to the next level. Here are a few ideas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expand your token's functionality:&lt;/strong&gt; You can explore more advanced Solidity programming concepts and add more features to your token, such as staking, voting, or yield farming.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explore different blockchain platforms:&lt;/strong&gt; While we focused on the Ethereum blockchain in this tutorial, there are many other blockchain platforms out there, each with its unique features and use cases. You can explore platforms like Polkadot, Binance Smart Chain, or Solana to see what they have to offer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrate your token into a real-world application:&lt;/strong&gt; With your token deployed, you can integrate it into a real-world application, such as a decentralized marketplace or a gaming platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connect with the blockchain community:&lt;/strong&gt; Finally, don't forget to connect with other developers and enthusiasts in the blockchain community! There are many forums, Discord servers, and social media groups where you can ask questions, share ideas, and collaborate on new projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The possibilities are endless, and we can't wait to see what you'll create next!&lt;/p&gt;




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

&lt;p&gt;I hope you found this article on creating and deploying a token on the blockchain informative and helpful!&lt;/p&gt;

&lt;p&gt;This article is about the Implementation Deep Dive contest by Alchemy University Techwriters Guild. It's an exciting opportunity for tech writers to showcase their skills by explaining complex implementation processes. By participating, writers can gain exposure to new technologies and methodologies while honing their technical writing skills. Join Alchemy University to participate in amazing contests and take your technical writing skills to the next level!&lt;/p&gt;

&lt;p&gt;Of course, I understand that this process can be challenging at times, and you may encounter some roadblocks along the way. But don't worry! If you run into any issues or have any questions, feel free to drop a comment or send me a DM on &lt;a href="https://twitter.com/Envoy_1084" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. I'm always happy to help out a fellow blockchain enthusiast. 🙌&lt;/p&gt;

&lt;p&gt;And if you enjoyed this article and want to see more like it, be sure to follow me for regular updates and engaging content. Let's stay connected on &lt;a href="https://www.linkedin.com/in/vedant-chainani/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://twitter.com/Envoy_1084" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; to share our experiences and insights into the ever-evolving world of blockchain technology. 🔗&lt;/p&gt;

&lt;p&gt;Thanks for reading, and keep on creating! 🚀&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Getting Up to Speed with Soulbound Tokens 👻</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Fri, 10 Feb 2023 18:07:05 +0000</pubDate>
      <link>https://dev.to/envoy_/getting-up-to-speed-with-soulbound-tokens-3jml</link>
      <guid>https://dev.to/envoy_/getting-up-to-speed-with-soulbound-tokens-3jml</guid>
      <description>&lt;h2&gt;
  
  
  Introduction 🚀
&lt;/h2&gt;

&lt;p&gt;Welcome to the exciting world of Soulbound Tokens! Whether you're new to the world of decentralized finance or have a bit of experience under your belt, this article is for you. Let's mark a journey through Soulbound Tokens and help you understand what makes them special.&lt;/p&gt;

&lt;p&gt;It's worth mentioning that Soulbound Tokens are the brainchild of none other than Vitalik Buterin, the creator of Ethereum. This exciting project is set to shake up the world of decentralized finance and has already caught the attention of the crypto community.&lt;/p&gt;

&lt;p&gt;No need to stress about technical jargon or complex financial lingo. The main goal is to make this journey as easy and approachable as possible.&lt;/p&gt;

&lt;p&gt;We'll explore Soulbound Tokens, from their origin story to the many ways they're changing the game in decentralized finance. We'll also share the juicy details on how they work, why they're so beneficial, and what real-world applications they have.&lt;/p&gt;

&lt;p&gt;So, sit back, relax, and let's explore the soulful side of Web3.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are Soulbound Tokens 👻
&lt;/h2&gt;

&lt;p&gt;Soulbound Tokens, also known as SBTs, are unique, non-transferable and non-financialized tokens in the Web3 ecosystem that represent an individual's online identity, commitments, and affiliations.&lt;/p&gt;

&lt;p&gt;Just like a resume or medical records in the non-Web3 world, SBTs are used to showcase a person's credentials and affiliations on the decentralized Web3 networks. These tokens cannot be sold or traded and serve as a permanent record of a person's digital identity.&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%2F4znppsd85ulrv4ctjtk3.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%2F4znppsd85ulrv4ctjtk3.png" alt="Soulbound Tokens" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://academy.binance.com/en/articles/what-are-soulbound-tokens-sbt" rel="noopener noreferrer"&gt;Binance Academy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of Soulbound Tokens as the rebellious cousins of NFTs (Non-Fungible Tokens). While NFTs are all about what you own and what you can show off, Soulbound Tokens are all about who you are.&lt;br&gt;
 That's right, we're talking about a new level of personal expression and identity.&lt;/p&gt;

&lt;p&gt;Ahh! Talking on the topic of reputation the China Social Credit System - it's been a hot topic in the world of decentralized networks and web3 enthusiasts. But while the concept of a government-run credit score system might send shivers down the spine of privacy advocates, the difference between that and Soulbound Tokens (SBTs) is like night and day.&lt;/p&gt;

&lt;p&gt;SBTs are all about you being in control of your own identity and reputation, while still allowing for the formation of trustworthy communities and collaborations. On the other hand, the China Social Credit System is a top-down approach where the government holds all the power and decides your worth.&lt;/p&gt;

&lt;p&gt;Vitalik, the big brain behind this whole thing, says it best:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Making more items in the crypto space &lt;code&gt;Soulbound&lt;/code&gt; can be one path toward an alternative, where NFTs can represent much more of who you are and not just what you can afford."&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Where did Soulbound tokens come from? 🫠
&lt;/h2&gt;

&lt;p&gt;So, let's dive into the history of Soulbound Tokens and see how they've come a long way. It all started back in May 2022 when the brains behind this idea, economist &amp;amp; social technologist E. Glen Weyl, lawyer Puja Ohlhaver, and the one and only Ethereum creator Vitalik Buterin, came together to propose the concept of Soulbound Tokens.&lt;/p&gt;

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

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



&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%2Fcointelegraph.com%2Fmagazine%2Fwp-content%2Fuploads%2F2022%2F06%2Fmagazine-Soulbound-Tokens.jpg" 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%2Fcointelegraph.com%2Fmagazine%2Fwp-content%2Fuploads%2F2022%2F06%2Fmagazine-Soulbound-Tokens.jpg" alt="Soulbound Tokens" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://cointelegraph.com/magazine/soulbound-cryptocurrency-tokens-social-credit-system-spark-next-bull-run/" rel="noopener noreferrer"&gt;Cointelegraph Magazine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They envisioned SBTs as a primitive, or foundational building block, in an emerging Web3 trend known as the Decentralized Society.&lt;/p&gt;

&lt;p&gt;Ok, wait now what is a &lt;em&gt;Decentralized society&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DeSoc&lt;/code&gt;, or the Decentralized Society, is a bottom-up community that aims to augment Web3's trajectory toward hyper-financialization(excessive growth of financial sector, leading to economic domination) and create something more inclusive, democratic, and decentralized.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;So why are SBTs gaining popularity in the Web3 space? It all comes down to their unique capabilities and the potential they hold for a more inclusive, democratic, and decentralized future. With SBTs, individuals and entities can build their own digital identities, represent their commitments and affiliations, and gain access to new opportunities and networks.&lt;/p&gt;

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

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



&lt;/p&gt;




&lt;h2&gt;
  
  
  How do they Work? 🤔
&lt;/h2&gt;

&lt;p&gt;The inner workings of SBTs have yet to be formally specified, but their functioning can be understood through the whitepaper co-authored by Vitalik Buterin and his partners.&lt;/p&gt;

&lt;p&gt;A defining feature of SBTs is their non-transferable nature. Unlike the current NFTs or other token standards like ERC-20 and ERC-721, SBTs are not meant to have monetary value and therefore cannot be bought, sold, or transferred to another wallet. This is because they are linked to "&lt;code&gt;Souls&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;So, what are Souls? Souls are the accounts in which SBTs are stored and issued. They play a role in determining provenance and reputation. Souls can represent individuals, organizations, companies, or any other entity. It's important to note that a single person may have multiple Souls in a decentralized society (DeSoc)&lt;/p&gt;

&lt;p&gt;Let's take a closer look at how Soulbound Tokens (SBTs) operate within the Web3 ecosystem using a decentralized autonomous organization's (DAO) voting system as an example. Conventionally, a DAO's governance model assigns voting power based on the number of tokens a member holds. However, DAOs utilizing SBTs might place a greater emphasis on a member's reputation, which can be verified through their interactions within the community, over the number of tokens they own.&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%2Flh5.googleusercontent.com%2FCzw-5eqDgKBomOOVEPUcLS_jtKnnGXCjpmE0XA7C4zUfVxoC_te_JIr3m-PHfWBy9g0Z7PEzI6GYuTgUbuEIMlSt7pqeaZmixz0mOrb9HoJbnJgsNBXny4kBg-YR5Ugg34fQk1AwfMe40kBVN-o2ritFMsN50VgmOHYdXqX155d_LaG6-BGwezKZEw" 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%2Flh5.googleusercontent.com%2FCzw-5eqDgKBomOOVEPUcLS_jtKnnGXCjpmE0XA7C4zUfVxoC_te_JIr3m-PHfWBy9g0Z7PEzI6GYuTgUbuEIMlSt7pqeaZmixz0mOrb9HoJbnJgsNBXny4kBg-YR5Ugg34fQk1AwfMe40kBVN-o2ritFMsN50VgmOHYdXqX155d_LaG6-BGwezKZEw" alt="SBTs in Governance" width="1600" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://academy.moralis.io/blog/soulbound-tokens-sbts-explained" rel="noopener noreferrer"&gt;Moralis Blog&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why we need Soulbound Tokens
&lt;/h2&gt;

&lt;p&gt;Have you ever stopped to think about why the Web3 ecosystem is mostly focused on financial objects like tokens and currencies? It's like we've only got a bunch of wallets full of assets that can be transferred and sold, but there's no actual person behind them. Just a financial holding account.&lt;/p&gt;

&lt;p&gt;Well, it's time to move beyond just financial objects in the decentralized world. And, believe it or not, even that will help the financial aspects work better and open up a world of possibilities.&lt;/p&gt;

&lt;p&gt;That's where Soulbound Tokens (SBTs) come in. They're not just a financial object, they're a universal aggregation system that represents you and your relationships. But, unlike the top-down China social credit system, SBTs are built from the bottom up by the community and governed by network users. And the best part? You can have multiple Souls, representing different aspects of your life.&lt;/p&gt;

&lt;p&gt;Imagine having a Soul for your health profile, only accessible to doctors. Another for your professional life, like your CV, and another for personal relationships. You get the idea!&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%2Fqmp5y061vbjxy39xgybc.jpg" 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%2Fqmp5y061vbjxy39xgybc.jpg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://mobile.twitter.com/Leo_Glisic/status/1527743746288168961" rel="noopener noreferrer"&gt;@Leo_Glisic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Soulbound Tokens bring the values of decentralization to real human relationships and communities. And here's the good news, decentralized verifiable credentials already exist. So, we're not talking about choosing between Soulbound NFTs and off-chain identifiers. SBTs are simply a subset of verifiable credentials that are part of an NFT on the blockchain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benefits of Soulbound Tokens ✨
&lt;/h2&gt;

&lt;p&gt;Let's dive into some of the benefits they offer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;🎯 &lt;strong&gt;Reduce dependence on centralized services&lt;/strong&gt;: Soulbound Tokens can empower individuals and organizations to take control of their online identity and reputation. With SBTs, there's no need to rely on centralized services that could potentially be compromised, censored or hacked. By decentralizing this important aspect of our online lives, Soulbound Tokens offer a new level of security and privacy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🎭 &lt;strong&gt;Authenticity&lt;/strong&gt;: SBTs allow for verifiable and tamper-proof records of information, such as credentials and achievements. This can help to eliminate the need for trust in central authorities and reduce fraud. Plus, with decentralized authentication, individuals and organizations will be able to access and share their records instantly and without barriers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🤞 &lt;strong&gt;Enhanced Trust&lt;/strong&gt;: The decentralized nature of Soulbound Tokens allows individuals and organizations to interact and transact with one another without having to worry about trust. SBTs help to establish provenance and reputation in a way that's transparent and tamper-proof, leading to a more trustworthy and secure decentralized society.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;⚖️ &lt;strong&gt;Improved Accountability and Transparency&lt;/strong&gt;: The public and immutable nature of SBTs allows for increased accountability and transparency in online transactions and interactions. This can have a positive impact on the reputation and image of individuals, organizations and companies alike, helping to build trust and credibility with stakeholders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🪪 &lt;strong&gt;Personalized Identity Management&lt;/strong&gt;: Soulbound Tokens can provide individuals with a new level of control over their online identity and reputation. By allowing for the creation of multiple Souls, individuals can have distinct digital identities for different aspects of their lives, such as their personal life, professional life, and health profile.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Use Cases of Soulbound Tokens
&lt;/h2&gt;

&lt;p&gt;When it comes to the practical applications of SBTs, the possibilities are endless. Let's dive into a few use cases that showcase the potential of these unique tokens:&lt;/p&gt;

&lt;h3&gt;
  
  
  Verifying Exclusive Membership
&lt;/h3&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%2Fk32hmke0tk9movjcbvcp.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%2Fk32hmke0tk9movjcbvcp.png" alt="Membership SBTs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://rarible.com/blog/9-membership-nfts/" rel="noopener noreferrer"&gt;Rarible&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to join a decentralized community that only allows the cream of the crop? Soulbound tokens could be used to verify exclusive membership, ensuring that only the most deserving individuals get in. For example, a high-end digital country club could use SBTs to grant access to members with a certain reputation or skill set. This would allow the club to maintain its exclusivity while also taking advantage of the benefits of a decentralized network.&lt;/p&gt;




&lt;h3&gt;
  
  
  Decentralized Loans and Digital Country Clubs
&lt;/h3&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%2F6jj7z29ahvi78zig0yvc.jpg" 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%2F6jj7z29ahvi78zig0yvc.jpg" alt="Decentralized Loans" width="752" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://builtin.com/finance/defi-decentralized-finance" rel="noopener noreferrer"&gt;builtin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine being able to take out a loan from a decentralized platform, without the need for a middleman like a bank. Soulbound tokens could be used to secure loans based on an individual's reputation, rather than just their credit score. This opens up new opportunities for those who might have been denied traditional loans due to a lack of credit history. And, on the flip side, investors could use SBTs to identify trustworthy borrowers and provide loans with peace of mind.&lt;/p&gt;




&lt;h3&gt;
  
  
  Storing Verifiable Credentials in Web3
&lt;/h3&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%2Fc08r774dzaoxhvzp9qet.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%2Fc08r774dzaoxhvzp9qet.png" alt="Verifiable Credentials" width="600" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://ec.europa.eu/digital-building-blocks/wikis/display/EBSI/Verifiable+Credentials+Success+Stories" rel="noopener noreferrer"&gt;ebsi - European Blockchain&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to keep your professional credentials in a secure and decentralized location? Soulbound tokens could be used to store and verify professional skills, such as certifications, licenses, and degrees. This would allow individuals to control their personal data while also making it easy to prove their skills and qualifications to potential employers or customers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof of Skills
&lt;/h3&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%2Fpbs.twimg.com%2Fmedia%2FFgEi1FSXkAEsks3%3Fformat%3Djpg" 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%2Fpbs.twimg.com%2Fmedia%2FFgEi1FSXkAEsks3%3Fformat%3Djpg" alt="Proof of Skills" width="1200" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://twitter.com/kleoverse/status/1585586908880666624" rel="noopener noreferrer"&gt;@kleoverse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a world where remote work is becoming the norm, it's more important than ever to be able to prove your skills and experience to potential employers. Soulbound tokens could be used to provide proof of professional skills, allowing individuals to showcase their expertise and set themselves apart from the competition. For example, a freelancer might use SBTs to demonstrate their portfolio of work, making it easier to land new clients.&lt;/p&gt;

&lt;p&gt;These are just a few examples of how SBTs could be used in the real world, but the possibilities are limited only by our imagination. As we continue to push the boundaries of the Web3 ecosystem, it's exciting to think about all the innovative ways that Soulbound tokens might be used in the future.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real word Implementation for Soulbound tokens
&lt;/h2&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%2Fmetaversezeus.com%2Fwp-content%2Fuploads%2F2022%2F05%2Fblog-pic-7-1024x577.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%2Fmetaversezeus.com%2Fwp-content%2Fuploads%2F2022%2F05%2Fblog-pic-7-1024x577.png" alt="Soulbound Tokens in Metaverse" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Source - &lt;a href="https://metaversezeus.com/soulbound-tokens-sbts-explain-it-like-im-ten/" rel="noopener noreferrer"&gt;Metaverse Zeus&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The evolution of Soulbound tokens is well underway, with some of the biggest names in the crypto industry jumping on board. &lt;em&gt;MetaMask&lt;/em&gt;, &lt;em&gt;Cobo&lt;/em&gt;, and &lt;em&gt;Gnosis DAO&lt;/em&gt; have teamed up for a Soulbound token implementation called “Evolution,” where users can create a digital identity for themselves. In a digital-first world, the 'identity' can't afford to be 'physical first,' and Soulbound Tokens provide all the credentials necessary to authenticate a person in the digital realm or the metaverse.&lt;/p&gt;

&lt;p&gt;Binance, one of the world's largest crypto exchanges, has launched &lt;em&gt;Binance Account Bound&lt;/em&gt; (&lt;code&gt;BAB&lt;/code&gt;) token, which is their take on the Soulbound concept, and functions as a unique identifier for Binance customers who want to use decentralized wallets but still trade using their unique KYC-ed identity on Binance.&lt;/p&gt;

&lt;p&gt;Even communities such as &lt;em&gt;Alchemy&lt;/em&gt;, &lt;em&gt;Buildspace&lt;/em&gt;, &lt;em&gt;LearnWeb3DAO&lt;/em&gt; and &lt;em&gt;Moralis&lt;/em&gt; have embraced Soulbound tokens, launching Proofs of Knowledge (PoKs) that identify a skill a person has acquired through completing a project or course. This can be an important aspect to include in resumes and CVs, demonstrating one's expertise and skillset in a verifiable and trustworthy manner.&lt;/p&gt;

&lt;p&gt;These are just a few of the ways Soulbound Tokens are being implemented in the real world, and it's exciting to see how they'll continue to shape and change the landscape of the decentralized society.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges and Concerns with Soulbound Tokens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recovery of Lost Souls
&lt;/h3&gt;

&lt;p&gt;When it comes to Soulbound tokens, one of the biggest worries is how to recover a lost Soul. The famous trio of Vitalik Buterin, Glen Weyl, and Puja Ohlhaver came up with some possible solutions, but they still need to be put to the test.&lt;/p&gt;

&lt;p&gt;One solution is the community recovery model, where a member of Soul's community needs to give the green light to recover their private keys. But let's be real, life can be unpredictable and relationships can change. Entrusting your Soul to a group of people who may not be able to follow through, even unintentionally, is a risky game.&lt;/p&gt;

&lt;p&gt;Another idea is to choose a group of guardians to hold the keys to your Soul. But what if you lose touch with one of them or if things go sour between you two? The idea of entrusting your Soul to a group of people who may not be able to come through for you, even with the best intentions, is a scary thought.&lt;/p&gt;

&lt;p&gt;It's important to remember that these solutions are just suggestions, and the future of Soulbound token recovery is still uncertain. But, we're optimistic that the right solution will come along and make it easier for us to keep our Souls safe and secure.&lt;/p&gt;




&lt;h3&gt;
  
  
  Reputation System
&lt;/h3&gt;

&lt;p&gt;Another potential hiccup on the road to Soulbound token success is the risk of reputation-based communities turning into a social credit system. Picture this: those with higher ratings get all the perks while those with lower ratings get banned, and no second chances are allowed. This raises some serious ethical questions and doesn't give people a fighting chance to improve. It's like being stuck with a permanent grade of 'C' on your report card, no matter how much you try to improve.&lt;/p&gt;




&lt;h3&gt;
  
  
  Technical Complexities
&lt;/h3&gt;

&lt;p&gt;And finally, there's always the chance that the technology simply isn't ready for prime time yet. Just like how we all laughed at the idea of a phone you can carry in your pocket (come on, who needs one of those?!), there's always the possibility that Soulbound tokens may still be a bit too ahead of their time. But hey, if history has taught us anything, it's that we love to prove naysayers wrong and embrace the latest and greatest technology. So bring on the Soulbound tokens!&lt;/p&gt;




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

&lt;p&gt;And there you have it folks! A journey into the fascinating world of 👻 Soulbound tokens, the latest and greatest addition to the web3 ecosystem. We've explored its features, implementation, benefits, some real-world use cases, and a few of the challenges it faces. It was a deep dive and we couldn't cover every single detail, but if you have any questions or want to add something, feel free to drop a comment and I'll be sure to include it in my next update.&lt;/p&gt;

&lt;p&gt;More potential use cases for Soulbound Tokens can be found in the “Decentralized Society: Finding Web3’s Soul” &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763" rel="noopener noreferrer"&gt;paper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So if you're interested in learning about new technologies and concepts in the web3 and blockchain space, make sure to follow me on my socials (Twitter, blog, etc.) 🙌 I'll be sure to keep you in the loop on all the latest and greatest.&lt;/p&gt;

&lt;p&gt;Until next time, farewell friends! 🤠&lt;/p&gt;

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

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



&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__528762"&gt;
    &lt;a href="/envoy_" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy_ image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/envoy_"&gt;Vedant Chainani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/envoy_"&gt;Web3 Technical Writer ✍️ | ⛓️ Blockchain Enthusiast&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://github.com/Envoy-VC" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F65389981%3Fv%3D4%3Fs%3D400" height="460" class="m-0" width="460"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://github.com/Envoy-VC" rel="noopener noreferrer" class="c-link"&gt;
          Envoy-VC (Vedant Chainani) · GitHub
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Developer &amp;amp; Technical Writer | 🛠️ Indie Maker. Envoy-VC has 160 repositories available. Follow their code on GitHub.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.svg" width="32" height="32"&gt;
        github.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>cli</category>
      <category>howto</category>
      <category>tutorial</category>
      <category>documentation</category>
    </item>
    <item>
      <title>⛽ Gasless Meta-Transactions: The Key to Scalable and Accessible Blockchain Adoption</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Fri, 03 Feb 2023 08:03:38 +0000</pubDate>
      <link>https://dev.to/envoy1084/gasless-meta-transactions-the-key-to-scalable-and-accessible-blockchain-adoption-2c3f</link>
      <guid>https://dev.to/envoy1084/gasless-meta-transactions-the-key-to-scalable-and-accessible-blockchain-adoption-2c3f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Blockchain transactions are revolutionizing the way we send and receive value. Ethereum, one of the top blockchain platforms, is handling millions of smart contract executions every day. But, it can be hard for new users to get started, since they need ETH and the process can be complicated. Meta transactions simplify this process by allowing users to interact with the blockchain without holding ETH. &lt;/p&gt;

&lt;p&gt;In this article, we'll uncover the benefits of using these innovative transactions and how they can be easily implemented with the help of OpenZeppelin Defender Services. Plus, we'll explore the wide range of use cases for gasless meta transactions, from decentralized finance to gaming and beyond.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Gasless Meta-Transactions
&lt;/h2&gt;

&lt;p&gt;Gasless Meta-Transactions are a new way to use blockchain technology without having to pay extra fees. Normally, when you want to do a transaction on a blockchain like Ethereum, you need to pay a fee called &lt;code&gt;gas&lt;/code&gt;. But with Gasless Meta-Transactions, you don't have to pay this fee. This makes it easier and cheaper for people to use the blockchain and participate in transactions. Simply put, Gasless Meta-Transactions allow you to use the blockchain without having to pay extra fees, making it more accessible to everyone.&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%2Fnpj04b6e7dx28kt9esab.jpg" 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%2Fnpj04b6e7dx28kt9esab.jpg" alt="High Ethereum Gas Fees" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Gasless Meta-Transactions are Beneficial?
&lt;/h2&gt;

&lt;p&gt;Gasless Meta-Transactions are beneficial since they simplify user transactions on the Ethereum network. Users can send payments to each other quickly and easily without having to worry about gas fees. This simplifies the process of using the Ethereum network, which may assist promote adoption. Furthermore, gasless Meta-Transactions can assist minimize the cost of utilizing the Ethereum network, which is especially essential for low-budget customers.&lt;/p&gt;

&lt;p&gt;Another reason why Gasless Meta-Transactions are required is that they can help in the solving of the Ethereum network's scalability problem. As more people join the Ethereum network, the demand for transactions rises, potentially leading to higher gas fees and slower transaction times. The Ethereum network can handle more transactions without worrying about expensive gas fees or long transaction times by allowing for gasless Meta-Transactions. This can help the network in scaling to meet the increasing demands of its users.&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Terms
&lt;/h2&gt;

&lt;p&gt;Gasless Meta-Transactions work based on the &lt;a href="https://docs.openzeppelin.com/contracts/4.x/api/metatx" rel="noopener noreferrer"&gt;Ethereum Improvement Proposal (EIP) 2771&lt;/a&gt;. This proposal outlines a way to execute transactions on the Ethereum blockchain without the need for the user to pay gas fees.&lt;/p&gt;

&lt;p&gt;Before we get into the specifics of how these transactions function, we must first know a few things.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenZeppelin Defender
&lt;/h3&gt;

&lt;p&gt;OpenZeppelin Defender is an open source and free solution that helps automate smart contract operations to deliver high-quality products with lower risk&lt;/p&gt;

&lt;h3&gt;
  
  
  Relayer
&lt;/h3&gt;

&lt;p&gt;A relayer is a third-party service that helps users execute transactions on the blockchain without having to pay gas fees.&lt;/p&gt;

&lt;p&gt;Think of a relayer as a middleman that helps you send a message or make a transaction without having to pay for it yourself. The relayer pays the gas fees for the transaction and then gets reimbursed by the user. This way, the user doesn't have to hold any Ethereum or pay gas fees to make a transaction on the blockchain.&lt;/p&gt;

&lt;p&gt;A Defender &lt;a href="https://docs.openzeppelin.com/defender/relay" rel="noopener noreferrer"&gt;Relay&lt;/a&gt; allows you to send transactions easily and handles private key storage, transaction signing, nonce management, gas estimation, and automatic resubmissions if necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defender Relay Service
&lt;/h3&gt;

&lt;p&gt;The Defender Relay service handles private key secure storage, transaction signing, nonce management, gas pricing estimation, and resubmissions over a standard HTTP API. This eliminates the need to secure your private keys in your backend scripts or monitor your transactions to guarantee they are mined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autotasks
&lt;/h3&gt;

&lt;p&gt;The Defender Autotasks service allows you to run code snippets on a regular basis, via webhooks, or in response to a transaction.&lt;/p&gt;

&lt;p&gt;An Autotask, similar to a serverless function, is a snippet of javascript code that is invoked at regular intervals. And, in fact, they are implemented using Lambda functions.&lt;/p&gt;

&lt;p&gt;When you create an Autotask, you provide a javascript snippet, select a trigger for it to perform, and optionally connect it to a Relayer. Currently, Defender supports two types of triggers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Schedule&lt;/strong&gt;: Select a frequency for executing your Autotask, and Defender will ensure that your function is invoked at the appropriate interval, you can use &lt;code&gt;cron&lt;/code&gt; expressions to indicate when the Autotask should run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook&lt;/strong&gt;: Defender will generate a secret URL for your Autotask and call it anytime an HTTP POST request is made to that endpoint. This URL can be regenerated at any moment. Defender will inject the HTTP request data into your Autotask and send the Autotask run information along with any data returned from your function.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How do Gasless Transactions Work?
&lt;/h2&gt;

&lt;p&gt;A meta-transaction is a fancy word for a simple concept: a relay server can send a user's transaction while also paying for the gas cost. Instead of signing an Ethereum transaction, which would cost ETH for gas, a user signs and transmits a message containing information about a transaction they want to execute to a relay server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Components of a Meta-transaction&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Client&lt;/em&gt;: signs and sends transactions to the relay server.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Autotasks&lt;/em&gt;: Supply the necessary logic for telling the Relayer to send a transaction to the forwarder contract.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Relay servers&lt;/em&gt;: makes a transaction and pays the Ethereum protocol's gas fees.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Forwarder&lt;/em&gt;: Ensures that the signature matches to the request.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Recipient contract&lt;/em&gt;: Executes the call using the original sender.&lt;/li&gt;
&lt;/ul&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%2F1cqol5nkvggqtfm701qw.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%2F1cqol5nkvggqtfm701qw.png" alt="Flowchart depicting how Gasless Meta-Transactions work?" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Client
&lt;/h3&gt;

&lt;p&gt;A client signs a message with its own private key and sends the request to an Autotasks API-created Webhook URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autotasks
&lt;/h3&gt;

&lt;p&gt;The Autotask's webhook URL is prominently displayed in the frontend of the decentralized application (dApp). Each time the dApp makes a call to the webhook, the Autotask is activated.&lt;/p&gt;

&lt;p&gt;It's important to note that only the Autotask's webhook is accessible from the frontend. The Autotask carries out the transaction based on the specific logic assigned to it.&lt;/p&gt;

&lt;p&gt;For instance, in a non-fungible token (NFT) project, the logic can be set such that a transaction is only sent to the relayer if the user is on the whitelist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relay Server
&lt;/h3&gt;

&lt;p&gt;When the conditions within the Autotask are satisfied, the Autotask code is executed and sends the transaction to the relayer. The relayer then forwards the transaction, including the gas fees, to the Forwarder Contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forwarder
&lt;/h3&gt;

&lt;p&gt;The Forwarder Contract then checks if the signature matches the request sent by the user. If the signature is valid, the transaction is executed.&lt;/p&gt;




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

&lt;p&gt;Gasless Meta-Transactions allow users to make transactions without having to pay gas fees, making them an attractive option for a number of use cases. In this article, we will explore some of the most promising use cases for gasless meta transactions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized Finance (&lt;code&gt;DeFi&lt;/code&gt;)&lt;/strong&gt;: These types of applications often require a large number of transactions to be conducted, many of which can be small and infrequent. The elimination of gas fees can help to reduce the overall cost of conducting these transactions and make DeFi applications more accessible to a wider range of users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaming and NFTs&lt;/strong&gt;: These industries often rely on a large number of transactions to facilitate the exchange of virtual assets and currency. The elimination of gas fees can help to make these transactions more efficient and cost-effective, making it easier for users to engage in these types of activities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microtransactions&lt;/strong&gt;: Microtransactions, or small transactions conducted for a low value, are another use case for gasless meta transactions. The elimination of gas fees through gasless meta transactions can help to make these types of transactions more accessible and cost-effective, encouraging greater use of the blockchain for microtransactions.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;In conclusion, gasless meta transactions have emerged as a game-changer in the world of blockchain technology. By eliminating the need for gas fees, these transactions offer a more user-friendly and cost-effective way of conducting transactions on the blockchain. From decentralized finance applications and gaming to supply chain management and microtransactions, the potential use cases for gasless meta transactions are vast and varied. As the technology continues to evolve and gain wider adoption, it is likely that we will see more and more innovative applications for gasless meta transactions in the future.&lt;/p&gt;




&lt;p&gt;If you found this article informative, be sure to follow me for more in-depth coverage on web3 and the latest blockchain trends. I'll also be publishing guides on implementing gasless transactions using OpenZeppelin Defender and exploring the technical side. If you're interested, leave a comment and let me know.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__528762"&gt;
    &lt;a href="/envoy1084" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/envoy1084"&gt;Vedant Chainani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/envoy1084"&gt;Web3 Technical Writer ✍️ | ⛓️ Blockchain Enthusiast&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Keep Building 🚀&lt;/p&gt;




</description>
      <category>web3</category>
      <category>crypto</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>☕ Coffee and Code: My Developer Journey in 2022</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Fri, 30 Dec 2022 05:41:31 +0000</pubDate>
      <link>https://dev.to/envoy1084/coffee-and-code-my-developer-journey-in-2022-19kg</link>
      <guid>https://dev.to/envoy1084/coffee-and-code-my-developer-journey-in-2022-19kg</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%2Fpdsofvixo7i6h6c2kwmd.jpg" 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%2Fpdsofvixo7i6h6c2kwmd.jpg" alt="Hello" width="626" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to the wild and wacky world of coding! My name is Vedant and I'm here to share with you my developer journey in 2022. It's been a bumpy ride, filled with endless lines of code, late nights at the computer, and plenty of debugging headaches. But through it all, I've learned that with a little perseverance and a lot of caffeine, anything is possible in the world of tech. So grab a coffee ☕ and join me as I take you on a journey through the chaos of code and the triumphs of a developer in 2022.&lt;/p&gt;

&lt;p&gt;The new year started with a lot of expectations and I was eager to explore various fields of computer science, including blockchain technology. My main goal for 2022 was to get into a good college and then use that as a platform to learn more about blockchains and gain new experiences in the field. &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%2Fvipuwh3jjg1goj2a9kob.jpg" 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%2Fvipuwh3jjg1goj2a9kob.jpg" alt="Blockchain" width="626" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Designed by &lt;a href="https://www.freepik.com" rel="noopener noreferrer"&gt;Freepik&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was excited to discover what the year had in store and was determined to make the most of the opportunities that came my way. Whether it was learning new programming languages or delving into the world of cryptocurrency and blockchains, I was ready to take on any challenge and continue growing my skills and knowledge.&lt;/p&gt;

&lt;p&gt;During the first few months of 2022, I was primarily focused on preparing for my college entrance exams and didn't have much time for coding. However, I remained interested in web3 and made an effort to stay up-to-date with the latest news in the cryptocurrency and web3 space. Despite my busy schedule, I was still passionate about learning more about these topics.&lt;/p&gt;

&lt;p&gt;I have a strong memory of my first course on web3 and blockchain technology, which was Alchemy's Road to web3 program. This course is a comprehensive introduction to the world of blockchain and is a popular starting point for many people interested in this field. It spans a total of 10 weeks and covers a wide range of topics related to blockchain, including cryptocurrency, non-fungible tokens (NFTs), decentralized finance (DeFi), and even decentralized social media. As a participant in the course, you received a proof of knowledge non-fungible token (POK) on the Polygon blockchain for completing each week of the program. This was a great way to track your progress and demonstrate your knowledge of the material. I began the Road to web3 course about 4 weeks after it first kicked off, and by the end of the 11th week, I had completed the program. Overall, it was a valuable learning experience that provided me with a solid foundation in blockchain and web3.&lt;/p&gt;

&lt;p&gt;It was during this time that I began writing technical articles. As I worked my way through the Alchemy's Road to web3 program, I wrote blog posts about the projects for each week and shared them on my blog and social media. This was my very first foray into technical writing and it was an exciting and energizing experience.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/envoy1084" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/envoy1084/build-your-first-smart-contract-using-solidity-111p" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;♦️ Build Your First Smart Contract using Solidity&lt;/h2&gt;
      &lt;h3&gt;Vedant Chainani ・ Jun 3 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#blockchain&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#solidity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#web3&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/envoy1084" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/envoy1084/the-ultimate-nft-api-24d5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🎨 Exploring the Alchemy NFT API&lt;/h2&gt;
      &lt;h3&gt;Vedant Chainani ・ Oct 10 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#web3&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#alchemy&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#nft&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#blockchain&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;If you're still reading this, it's probably clear that I am a huge coffee fan and my day never starts without a boost from a cup of coffee. It was like drinking a cup of coffee and getting a burst of energy and focus, just from the act of writing about what I was learning and sharing my thoughts with others. I was excited to share my knowledge and help others learn more about web3 and blockchain technology.&lt;/p&gt;

&lt;p&gt;Completing Alchemy's Road to web3 was a major accomplishment for me and one of my happiest moments in 2022. I was able to earn all 10 PoKs and the Alchemy Early Student pass, which was a huge achievement for me. This was my first foray into the world of web3 and it was an incredibly exciting experience.&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%2Fyypifnn73hxfoabvvpmn.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%2Fyypifnn73hxfoabvvpmn.png" alt="Road to Web3 PoKs" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I continued to grow and learn with Alchemy, I learned about several other companies such as Moralis, buildspace, and LearnWeb3 DAO.&lt;/p&gt;

&lt;p&gt;I stumbled upon Moralis while searching for a web3 software development kit (SDK) for interacting with blockchain technology. As I looked into their company, I learned about their Moralis Hall of Fame, which is a learning track which is majorly focused on building web3 games using their Moralis Unity web3 SDK. While learning from Moralis, I completed a number of projects, including a web3 Airbnb clone, a Spotify clone, a web3 metaverse, building a decentralized autonomous organization (DAO) from scratch, and building a simple game in Unity using the Moralis Unity SDK. These projects allowed me to gain hands-on experience with web3 and the Moralis Unity SDK, and helped me build my skills and knowledge in this exciting field. Overall, it was a valuable learning experience that allowed me to explore the potential of web3 and build a foundation for future projects.&lt;/p&gt;

&lt;p&gt;Here's the Airbnb clone made using Moralis &lt;code&gt;web3uikit&lt;/code&gt;&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%2Ft8k0yp6pairaj12d8i57.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%2Ft8k0yp6pairaj12d8i57.png" alt="Web3 Airbnb Clone" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are all the PoKs earned by completing Moralis Projects&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%2Fq0tiadfsa58f7rfrid9j.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%2Fq0tiadfsa58f7rfrid9j.png" alt="Moralis PoKs" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing a variety of projects with both Alchemy and Moralis, I felt confident in my abilities and decided to take on my first mainchain decentralized application (dApp) project. This involved buying some Matic, a cryptocurrency, and starting to develop a non-fungible token (NFT) drop. It was a thrilling, yet bumpy experience as I navigated the process of creating my first mainchain dApp. The collection I created was called "Stinky Little Monsters" and consisted of 10 ERC-1155 NFTs. You may have seen my profile picture, which is actually the first NFT in the collection. It features a cute monster called Cursefigure. I was really proud of this project and tried to incorporate everything I had learned about NFTs in the process of creating it. Overall, it was an exciting and rewarding experience that allowed me to put my skills to the test and create something unique and meaningful.&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%2Fs57jluduptkpk6ylv3iw.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%2Fs57jluduptkpk6ylv3iw.png" alt="Stinky Little Monsters Website" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I made a bit of a blunder in the smart contract for my NFT drop by forgetting to add a condition to check that users could only mint NFTs from the set of numbers 1 to 10. Oops! While this was a pretty major mistake, it was my first project in web3 and I was still learning the ropes. On the bright side, now that the smart contract is on the blockchain for all to see, I can't deny my mistake and have to live with it forever. But hey, at least now I know what to avoid in the future, right? I guess you could say I learned the hard way, but at least now I'm a little wiser for it.&lt;/p&gt;

&lt;p&gt;If you're interested, you can check out the project here. Just keep in mind that the app isn't functional, but you can still take a look at the smart contract and the app code.&lt;/p&gt;

&lt;p&gt;Smart Contract:&lt;br&gt;
&lt;a href="https://polygonscan.com/address/0xd92b8d06505D334fD92bbE4b97CE299759D92404" rel="noopener noreferrer"&gt;https://polygonscan.com/address/0xd92b8d06505D334fD92bbE4b97CE299759D92404&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Website:&lt;br&gt;
&lt;a href="https://stinky-little-monsters.vercel.app/" rel="noopener noreferrer"&gt;https://stinky-little-monsters.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was finally time for my college entrance exams and I was feeling the pressure. Although the exams were just okay, I was determined to make the most of my post-exam period by taking on a challenge called 30 Days of Solidity. For 30 consecutive days, I posted Solidity tutorials on my GitHub page and Blog, covering every single topic related to smart contract development. This was a major accomplishment for me in 2022, and I'm proud to have successfully completed the challenge. If you're interested, you can check out the 30 Days of Solidity repository on my GitHub profile.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/envoy1084" rel="noopener noreferrer"&gt;
        envoy1084
      &lt;/a&gt; / &lt;a href="https://github.com/envoy1084/30-Days-of-Solidity" rel="noopener noreferrer"&gt;
        30-Days-of-Solidity
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      30 Days of Solidity step-by-step guide to learn Smart Contract Development.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/87b6dc8da97a62c437535fde4090ca5277f0a2f54fc8da0a80b54e01e564dbd7/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d736f6c6964697479266d6573736167653d76302e382e3726636f6c6f723d326561343466266c6f676f3d736f6c6964697479"&gt;&lt;img src="https://camo.githubusercontent.com/87b6dc8da97a62c437535fde4090ca5277f0a2f54fc8da0a80b54e01e564dbd7/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d736f6c6964697479266d6573736167653d76302e382e3726636f6c6f723d326561343466266c6f676f3d736f6c6964697479" alt="Solidity"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: This repository is currently undergoing updates and revisions to incorporate the latest information and advancements in Solidity programming. Please be advised that the content may not be up-to-date or accurate during this time. We expect the updates to be completed within the next 30 days, and appreciate your patience during this process. Thank you for your understanding.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2001%20-%20Licenses%20and%20Pragma/readme.md" rel="noopener noreferrer"&gt;Day 1 - Licenses and Pragma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2002%20-%20Comments/readme.md" rel="noopener noreferrer"&gt;Day 2 - Comments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2003%20-%20Initializing%20Basic%20Contract/readme.md" rel="noopener noreferrer"&gt;Day 3 - Initializing Basic Contract&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2004%20-%20Variables%20and%20Scopes/readme.md" rel="noopener noreferrer"&gt;Day 4 - Variables and Scopes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2005%20-%20Operators/readme.md" rel="noopener noreferrer"&gt;Day 5 - Operators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2006%20-%20Types/readme.md" rel="noopener noreferrer"&gt;Day 6 - Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2007%20-%20Functions/readme.md" rel="noopener noreferrer"&gt;Day 7 - Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2008%20-%20Loops/readme.md" rel="noopener noreferrer"&gt;Day 8 - Loops&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2009%20-%20Decision%20Making/readme.md" rel="noopener noreferrer"&gt;Day 9 - Decision Making&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2010%20-%20Arrays/readme.md" rel="noopener noreferrer"&gt;Day 10 - Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2011%20-%20Array%20Operations/readme.md" rel="noopener noreferrer"&gt;Day 11 - Array Operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2012%20-%20Enums/readme.md" rel="noopener noreferrer"&gt;Day 12 - Enums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2013%20-%20Structs/readme.md" rel="noopener noreferrer"&gt;Day 13 - Structs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2014%20-%20Mappings/readme.md" rel="noopener noreferrer"&gt;Day 14 - Mappings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2015%20-%20Units/readme.md" rel="noopener noreferrer"&gt;Day 15 - Units&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2016%20-%20Require%20Statement/readme.md" rel="noopener noreferrer"&gt;Day 16 - Require Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2017%20-%20Assert%20Statement/readme.md" rel="noopener noreferrer"&gt;Day 17 - Assert Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2018%20-%20Revert%20Statement/readme.md" rel="noopener noreferrer"&gt;Day 18 - Revert Statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2019%20-%20Function%20Modifiers/readme.md" rel="noopener noreferrer"&gt;Day 19 - Function Modifiers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/envoy1084/30-Days-of-Solidity/./Day%2020%20-%20Constructors/readme.md" rel="noopener noreferrer"&gt;Day 20&lt;/a&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/envoy1084/30-Days-of-Solidity" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It was during this time that I stumbled upon Buildspace, a new platform that offered small weekend projects focused on Ethereum and non-fungible tokens (NFTs). I was excited to dive in and get my hands dirty, and the projects I worked on did not disappoint. Some of the projects I built included a Solana NFT Collection, a turn-based NFT game, and a decentralized autonomous organization (DAO) app.&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%2Fjrz9n8xzoz5fe82lb1sd.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%2Fjrz9n8xzoz5fe82lb1sd.png" alt="buildspace PoKs" width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the best part about Buildspace was definitely the instructor, Farza. He was such a cool and knowledgeable person, and I truly believe he was one of the best instructors in the space. He made the projects so much fun and I learned so much from him. Overall, my experience with Buildspace was extremely positive and I'm grateful to have had the opportunity to work on these exciting projects.&lt;/p&gt;

&lt;p&gt;I was thrilled when I received my first ever offer to write articles for a web3 company as a freelancer. It was an amazing opportunity and I couldn't wait to get started. The first article I wrote was focused on the non-technical side of web3, and while it was a bit of a challenge, I was grateful for the opportunity to write for a company and share my knowledge with others.&lt;/p&gt;

&lt;p&gt;Finally, the moment I had been waiting for had arrived: it was time for me to start college. This was a new and exciting, yet also scary, experience. Going away to study was a big step, but I knew it had the potential to be one of the most amazing experiences of my life. I was filled with excitement and anticipation as I packed my bags and prepared to embark on this new journey.&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%2Fa2g1xkihn5h5wdvneluc.jpg" 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%2Fa2g1xkihn5h5wdvneluc.jpg" alt="Long Travel" width="720" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Around the same time I heard about the beta program for Alchemy University in October. For those who may not be familiar, Alchemy University is an incredible resource for learning how to build on the web3 platform. It's essentially a college for web3 developers, offering three tracks: JavaScript Fundamentals, Ethereum Bootcamp, and Road to Web3.&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%2Fwvr1ua7yz0vwucpi798a.jpg" 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%2Fwvr1ua7yz0vwucpi798a.jpg" alt="Alchemy University Acceptance Mail" width="656" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had an amazing time participating in the beta program and learning from some of the best in the field. I spent a lot of time hanging out on Discord townhalls and attending live quizzes on Discord, which was a great experience. I'm especially grateful to Albert and Vitto, who were absolute gems at Alchemy University and really helped me advance my knowledge and skills. Overall, I'm incredibly thankful for the opportunity to be a part of Alchemy University and for all the amazing people I met there.&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%2F89896i0esuase1zoyldj.jpg" 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%2F89896i0esuase1zoyldj.jpg" alt="Alchemy University Townhall" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The year ended on a high note with some exciting news: I had applied for the Ethos Hackathon hosted by IIT Guwahati and I had been shortlisted for the final round, which was scheduled to take place on 7-9 January of the following year. I was absolutely thrilled to have the opportunity to participate in my first ever offline hackathon, and the fact that it was being held at IIT Guwahati only added to the excitement. I couldn't wait to see what this event had in store and to see what I could create and accomplish.&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%2Fpuwjj83qggtbyggerm8u.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%2Fpuwjj83qggtbyggerm8u.png" alt="Ethos Hackathon" width="491" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking back, I can't help but feel grateful for the opportunities and experiences that 2022 brought my way. As a developer and learner, I feel like I really grew and learned a lot this year. From taking on challenges like 30 Days of Solidity to joining the beta program at Alchemy University and participating in my first offline hackathon, 2022 pushed me to explore new areas and step out of my comfort zone. I'm grateful for all the amazing people I met and the experiences I had, and I can't wait to see what 2023 has in store. I hope it will be filled with even more opportunities to learn and grow, and to have new and exciting experiences.&lt;/p&gt;

&lt;p&gt;Thank you to everyone who has made it to the end of this article. I am truly grateful for all of your support and for taking the time to read about my journey. To each and every person who has supported me along the way, thank you from the bottom of my heart. I hope you have a wonderful day and that your own journey is filled with all the learning, growth, and excitement that you desire.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>🖼️ How to use Alchemy NFT API to get Rarity Insights for your NFT</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Mon, 19 Dec 2022 19:58:56 +0000</pubDate>
      <link>https://dev.to/envoy1084/how-to-use-alchemy-nft-api-to-get-rarity-insights-for-your-nft-1ppk</link>
      <guid>https://dev.to/envoy1084/how-to-use-alchemy-nft-api-to-get-rarity-insights-for-your-nft-1ppk</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Discover the excitement of collecting rare NFTs! These unique digital tokens represent ownership of digital art, collectibles, and more, and their rarity adds to their value. But how is NFT rarity calculated? It's all about supply and demand. NFTs with a limited supply are naturally more rare and valuable, as there are fewer of them available for collectors to acquire. On the other hand, NFTs with a higher supply may not be as coveted, and therefore not as valuable.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is NFT Rarity
&lt;/h2&gt;

&lt;p&gt;Rarity is a measure of how scarce or unique an NFT is, and it is an important factor that can affect the value of the NFT.&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%2F6mhnnggi77e8ueu4wj8s.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%2F6mhnnggi77e8ueu4wj8s.png" alt="Bored Ape Yacht Club NFT Traits" width="712" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are several ways to calculate rarity for NFTs, and the specific method used may depend on the type of NFT and the context in which it is being evaluated. Some common methods of calculating rarity include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Total supply: Rarity can be calculated based on the total number of units of an NFT that are available. For example, if an NFT has a total supply of 100 units, it may be considered rarer than an NFT with a total supply of 1,000 units.&lt;/li&gt;
&lt;li&gt; Demand: Rarity can be influenced by the demand for an NFT, which is the extent to which people are interested in acquiring it. An NFT with high demand may be considered rarer than one with low demand.&lt;/li&gt;
&lt;li&gt; Rarity tiers: Some NFT platforms or marketplaces may assign rarity tiers to NFTs, based on a combination of factors such as total supply, edition size, demand, and other criteria. These tiers can be used to classify NFTs as common, rare, very rare, or ultra rare, for example.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🚀 What we will be building
&lt;/h2&gt;

&lt;p&gt;Today, we will create a NFT rank determiner using the newest Alchemy NFT Rarity API. The API provides us with information on the prevalence of NFT traits.&lt;/p&gt;

&lt;p&gt;The prevalence number indicates how many percent of the collection contains certain qualities, so if the prevalence value is high, the NFT is more common, and if the prevalence value is low, the provided trait is less common in the collection, making the NFT containing trait unusual.&lt;/p&gt;

&lt;p&gt;We will use the average approach, which involves taking the average of all trait prevalence data and then multiplying it by the total supply of the collection to calculate the rank of the NFT.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setting up the Environment
&lt;/h2&gt;

&lt;p&gt;To store your scripts, create a new directory named &lt;code&gt;alchemy-rarity-api&lt;/code&gt;. Use the following command to set up the project as a npm project or a yarn project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn init --yes

npm init --yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the directory has been created as a npm project, we need to make a few changes within the &lt;code&gt;package.json&lt;/code&gt; file. Because we will be utilizing the import syntax to load ES6 modules, add the following line to your &lt;code&gt;package.json&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we have to install the Alchemy SDK to easily interact with the Alchemy APIs.&lt;br&gt;
To install &lt;code&gt;alchemy-sdk&lt;/code&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;yarn add alchemy-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to write our NFT rank determiner script. Make a new file in the project root named &lt;code&gt;nft-rarity.js&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Initializing SDK
&lt;/h2&gt;

&lt;p&gt;The first step is to import the module, which we shall accomplish simply by doing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Alchemy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alchemy-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we must define the configuration to use the SDK; we will construct a settings object to contain our API Key and the network from which the data will be collected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;api-key-here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ETH_MAINNET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;last step is to initialize a new instance of the SDK, for this we will use the following line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Alchemy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Calling API for Rarity Details
&lt;/h2&gt;

&lt;p&gt;First, we'll create two variables to store the address and token id of the NFT collection and NFT, respectively, for which we want rarity insights.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Bored Ape Yacht Club&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;7717&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We require the total supply of the collection since we need the rank of the NFT, and we can easily acquire that data using the &lt;code&gt;getContractMetadata&lt;/code&gt; method in the NFT API.&lt;/p&gt;

&lt;p&gt;The total supply will then be saved in a new variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contractMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contractMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use the &lt;code&gt;computeRarity&lt;/code&gt; endpoint with the contract address and token id as inputs to receive the rarity details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;computeRarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rarity endpoints returns an array of objects containing the &lt;code&gt;traitType&lt;/code&gt;, &lt;code&gt;prevalence&lt;/code&gt;, and &lt;code&gt;value&lt;/code&gt; for each NFT attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0626&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Fur'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Tan'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0479&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Eyes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Coins'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0462&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Earring'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Gold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Hoop'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0163&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Clothes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Bandolier'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2272&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Mouth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Bored'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prevalence:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.1266&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;traitType:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Background'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;value:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Aquamarine'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Calculating Rank
&lt;/h2&gt;

&lt;p&gt;We will now calculate the rank of the NFT using the average approach, which involves taking the average of all the prevalence of the NFT attributes and multiplying it by the &lt;code&gt;totalSupply&lt;/code&gt; for the collection to determine the NFT's position in the collection.&lt;/p&gt;

&lt;p&gt;we can construct a function called &lt;code&gt;computeRank&lt;/code&gt; and take in two arguments the rarity array and the overall supply of the collection.&lt;/p&gt;

&lt;p&gt;then we will iterate over the array and take the average of the prevalence and then multiply it with the total supply of the collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;computeRank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;prevalence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we will run the function to determine the nft's rank.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;computeRank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 878&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entire Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Network&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Alchemy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alchemy-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;api-key-here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ETH_MAINNET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Alchemy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Bored Ape Yacht Club&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;7717&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;computeRank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;prevalence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contractMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contractMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rarity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;alchemy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;computeRarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;computeRank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rarity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSupply&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 878&lt;/span&gt;

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

&lt;/div&gt;






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

&lt;p&gt;Congratulations! You have successfully built a NFT rank determiner using the Alchemy NFT Rarity API. By using the basic average method, you were able to determine the rank of an NFT based on its rarity.&lt;/p&gt;

&lt;p&gt;However, it's important to note that the ranks of NFTs can vary greatly depending on people's personal preferences. What one person considers a highly prized NFT might be seen as less valuable to someone else. Therefore, it's important to remember that the rank determiner you have built is just a rough estimate, and the true value of an NFT can only be determined by the market.&lt;/p&gt;

&lt;p&gt;Despite this, your NFT rank determiner can still be a useful tool for getting a general idea of the relative rarity and value of different NFTs. You can use it to compare the ranks of different NFTs and get a sense of which ones might be more sought after by collectors.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>web3</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Applications and Uses of Blockchain</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Thu, 15 Dec 2022 05:00:00 +0000</pubDate>
      <link>https://dev.to/envoy1084/applications-and-uses-of-blockchain-2jp5</link>
      <guid>https://dev.to/envoy1084/applications-and-uses-of-blockchain-2jp5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Blockchain has the potential to revolutionize the way we store, share, and protect data, with applications ranging from secure financial transactions to the management of supply chains and digital identities."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Blockchain technology has revolutionized many industries with its ability to securely record and transfer data. From finance and healthcare to supply chain management and voting systems, the applications of blockchain are vast and varied. With its decentralized and immutable nature, blockchain offers increased transparency, improved security, and enhanced efficiency in various industries. As the world continues to embrace this technology, the possibilities for its use are only limited by our imagination.&lt;/p&gt;

&lt;p&gt;This is &lt;a href="https://dev.to/envoy_/series/20519"&gt;Web3 Trends&lt;/a&gt;, a collection of brief but informative Web3 threads.&lt;/p&gt;

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

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



&lt;/p&gt;




&lt;p&gt;🔰 Cryptocurrencies&lt;/p&gt;

&lt;p&gt;The most well-known application of blockchain is as the underlying technology for digital currencies like Bitcoin and Ethereum. Blockchain allows for the secure and transparent transfer of value between individuals without the need for a central authority or intermediary.&lt;/p&gt;




&lt;p&gt;🔰 Supply chain management&lt;/p&gt;

&lt;p&gt;Blockchain can be used to track the movement of goods and materials through the supply chain, from their origin to their final destination. This can improve transparency and efficiency in the supply chain, and help to prevent fraud and counterfeiting.&lt;/p&gt;




&lt;p&gt;🔰 Voting systems &lt;/p&gt;

&lt;p&gt;Blockchain technology can be used to create secure and transparent voting systems. By using blockchain, it is possible to create a tamper-proof record of votes that can be audited and verified. This could help to improve the integrity of elections and reduce the risk of voter fraud.&lt;/p&gt;




&lt;p&gt;🔰 Identity verification&lt;/p&gt;

&lt;p&gt;Blockchain can be used to create and manage digital identities. This can be helpful in cases where it is necessary to verify someone's identity without revealing personal information. For example, blockchain could be used to verify the identity of someone applying for a loan or other financial product without exposing their personal details.&lt;/p&gt;




&lt;p&gt;🔰 Medical records: &lt;/p&gt;

&lt;p&gt;Blockchain can be used to securely store and manage medical records. This can help to improve the accuracy and accessibility of medical records, and make it easier for patients to share their medical history with healthcare providers.&lt;/p&gt;




&lt;p&gt;For more exciting brief web3 threads, follow me.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__528762"&gt;
    &lt;a href="/envoy1084" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/envoy1084"&gt;Vedant Chainani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/envoy1084"&gt;Web3 Technical Writer ✍️ | ⛓️ Blockchain Enthusiast&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1584856929259913216-448" src="https://platform.twitter.com/embed/Tweet.html?id=1584856929259913216"&gt;
&lt;/iframe&gt;

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








</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>🚀 Axelar: The Future of Cross Chain Communication for Web3</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Sun, 11 Dec 2022 15:00:00 +0000</pubDate>
      <link>https://dev.to/envoy1084/axelar-the-future-of-cross-chain-communication-for-web3-1866</link>
      <guid>https://dev.to/envoy1084/axelar-the-future-of-cross-chain-communication-for-web3-1866</guid>
      <description>&lt;h2&gt;
  
  
  📜 Introduction
&lt;/h2&gt;

&lt;p&gt;Cross-chain communication is an essential part of the Web3 ecosystem, enabling different blockchain networks to interoperate and exchange data and value. By facilitating the seamless transfer of information and assets between different blockchains, cross-chain communication allows for the creation of a more open, connected, and inclusive decentralized world. With the ability to bridge the gap between different blockchains, cross-chain communication is a powerful tool for driving innovation and adoption in the world of decentralized technologies.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Cross-chain Interoperability?
&lt;/h2&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%2Fhkexumkay4eeqftv9o6k.jpg" 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%2Fhkexumkay4eeqftv9o6k.jpg" alt="What is Cross-chain Interoperability?" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cross-chain communication refers to the ability of different blockchain networks to communicate and exchange information with each other. This is important because it allows for the transfer of value and data between different blockchains, which can help to increase the overall interoperability and effectiveness of the broader blockchain ecosystem. &lt;/p&gt;

&lt;p&gt;For example, if two different blockchain networks are able to communicate with each other, it would be possible for a user on one network to send a transaction to another user on the other network, even though the two users are on separate blockchains. This can help to improve the overall usability and utility of blockchain technology.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 What is Axelar
&lt;/h2&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%2Fwi5umi1cap5a9egs6uhl.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%2Fwi5umi1cap5a9egs6uhl.png" alt="Axelar" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Axelar provides Web3 with secure cross-chain communication. Axelar is built on proof-of-stake, the battle-tested method utilised by Ethereum, Cosmos, Avalanche, and others.&lt;/p&gt;

&lt;p&gt;Axelar-based cross-chain apps are really permissionless, which means that their transactions cannot be restricted by any oracle, relayer, or validator. Axelar's security model is similar to that of many of the chains it connects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fundamental functionality
&lt;/h3&gt;

&lt;p&gt;Here are two basic cross-chain functions that Axelar can add to a dApp.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Token transfers&lt;/em&gt;&lt;/strong&gt;: Securely send and receive fungible tokens from one chain to another, including Cosmos-to-EVM and other complex transfers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;General Message Transmission&lt;/em&gt;&lt;/strong&gt;: Call any EVM chain function from within a dApp; construct DeFi functions; move NFTs cross-chain; execute cross-chain calls of any kind that securely sync state between dApps on different ecosystems.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🚀 What we'll be building
&lt;/h2&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%2Fi9c9g3v8zfupa0pv2weo.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%2Fi9c9g3v8zfupa0pv2weo.png" alt="Cross Chain Smart Contract" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we will create a smart contract in which a user can send a token (say, USDC) from one chain to an account on another chain with "payment information." Payment information can include an invoice/description of payment/reason and note to a buddy, among other things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Must be familiar with smart contracts written in solidity.&lt;/li&gt;
&lt;li&gt;You must be familiar with the Metamask wallet.&lt;/li&gt;
&lt;li&gt;Be passionate about creating cool things.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Setting Up Dev Environment
&lt;/h2&gt;

&lt;p&gt;To begin, we must clone the examples GitHub repository so that we may work on the pre-built example to send tokens from the source chain to an account in the destination chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/axelarnetwork/axelar-local-gmp-examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we must perform a clean installation of the essential npm packages for this run.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we'll need our Ethereum wallet private key to deploy contracts to the testnet. Rename &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; then insert your private key into the &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Editing The Smart contract
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;DistributionExecutable.sol&lt;/code&gt; file in the &lt;code&gt;example/call-contract-with-token&lt;/code&gt; directory. The contract will be written by default and used to send tokens from the source chain to numerous addresses on the destination chain. For example, if we send &lt;em&gt;100 aUSDC&lt;/em&gt; from the source chain to five addresses in the destination chain, each will receive around &lt;em&gt;20 aUSDC&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We will be creating a new feature that will include payment information with the transaction. Payment information can include an invoice or the purpose for sending the token.&lt;/p&gt;

&lt;p&gt;In our file, we will create a struct called &lt;code&gt;TransactionInfo&lt;/code&gt; to contain payment information such as the sender's address, the address of the token sent, the amount, and finally the message.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// TransactionInfo struct to store transaction details
struct TransactionInfo {
    address sender;
    address tokenAddress;
    uint256 amount;
    string message;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we'll add two mappings: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;recipientsToTransactions&lt;/code&gt;: which will link the struct to the sender's address.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;recipientsTransactionCounter&lt;/code&gt;: which will hold the number of structures associated with a given address.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Mapping to store transaction details for each recipient
mapping(address =&amp;gt; TransactionInfo[]) public recipientsToTransactions;

// Mapping to store number of transactions for each recipient
mapping(address =&amp;gt; uint256) public recipientsTransactionCounter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we'll modify our &lt;code&gt;sendToMany&lt;/code&gt; method to include message as one of the function parameters. The message will then be included in the payload variable, ensuring that it is included in the transaction.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function sendToMany(
    string memory destinationChain,
    string memory destinationAddress,
    address[] calldata destinationAddresses,
    string memory symbol,
    uint256 amount,
    string memory message // Added message parameter
) external payable {
    address tokenAddress = gateway.tokenAddresses(symbol);
    IERC20(tokenAddress).transferFrom(msg.sender, address(this), amount);
    IERC20(tokenAddress).approve(address(gateway), amount);
    bytes memory payload = abi.encode(destinationAddresses, message, msg.sender); // &amp;lt;-- updated payload to include message
    if (msg.value &amp;gt; 0) {
        gasReceiver.payNativeGasForContractCallWithToken{ value: msg.value }(
            address(this),
            destinationChain,
            destinationAddress,
            payload,
            symbol,
            amount,
            msg.sender
        );
    }
    gateway.callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, in the &lt;code&gt;_executeWithToken&lt;/code&gt; function, we will pass some more variables in the decode function so that we can also store the message and the sender of the tokens.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(address[] memory recipients, string memory message, address sender) = abi.decode(payload, (address[], string, address)); // Decoding payload to get message and sender
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And then, once we have all of the necessary details, we will create a struct in memory and pass the variables in that struct, as well as map the struct to the sender address. Finally, we'll increase the counter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TransactionInfo memory txnInfo = TransactionInfo(sender, tokenAddress, sentAmount, message); // Create TransactionInfo struct
recipientsToTransactions[recipients[i]].push(txnInfo); // Store TransactionInfo struct in mapping
recipientsTransactionCounter[recipients[i]]++; // Increment transaction counter for recipient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Making changes to deploy script
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;code&gt;scripts&lt;/code&gt; directory and open the &lt;code&gt;deploy.js&lt;/code&gt; file. To make the script operate with our smart contract, we need to make a few tweaks.&lt;/p&gt;

&lt;p&gt;To begin, we must modify our &lt;code&gt;test&lt;/code&gt; function to populate certain variables based on the console parameters.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getGasPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getGasPrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Avalanche&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fantom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getDefaultProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distributionExecutable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DistributionExecutable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usdcAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenAddresses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aUSDC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usdcAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IERC20&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;balances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// code ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Following that, we will write two  nested function that will be used to log the balances of the address's aUSDC tokens.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logAccountBalances&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Source : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; aUSDC`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;destinationAccountBal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Destination &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;destinationAccountBal&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; aUSDC`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;balances&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;destinationAccountBal&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;matchandLogAccountBalances&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Source(After Transaction) : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; aUSDC`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\n------------For Account &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;------------`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;destinationAccountBal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Destination(Before Transaction) &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; aUSDC`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Destination(After Transaction) &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;destinationAccountBal&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; aUSDC`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\tDetails of TransactionInfo `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;---------------------------&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recipientsCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recipientsTransactionCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;recipientsCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transactionInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recipientsToTransactions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\tSender\t\t : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transactionInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\tTokenAddress\t : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transactionInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokenAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\tAmount\t\t : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transactionInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\tMessage\t\t : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transactionInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, using the &lt;code&gt;getGasPrice&lt;/code&gt; method, we will obtain the gas price of the, verify the balance of the destination account, and then initiate a transaction to the source account to approve spending a particular quantity of &lt;code&gt;aUSDC&lt;/code&gt; tokens, and wait until the transaction is approved.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gasLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getGasPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AddressZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;approveTx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;approve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;approveTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, using the sendToMany method, we will send the amount of aUSDC from the source account to be shared equally among the destination accounts. We'll wait once the transaction is finished.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendTx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distributionExecutable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aUSDC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gasLimit&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sendTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction Hash : &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sendTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;--- Waiting Period Started ---&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we'll create a loop that checks  to see if the destination address balance has been changed, and if it has, we'll exit the loop and print out the account amount.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;allBalancesMatched&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pendingMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;waitTimeInMin&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\rWaited for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;waitTimeInMin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; minutes`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accountBalance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usdc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountBalance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;balances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;pendingMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;allBalancesMatched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;pendingMatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;--- After ---&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;matchandLogAccountBalances&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Testing on Local chain
&lt;/h2&gt;

&lt;p&gt;To start a local node, open a new terminal window and enter 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;node scripts/createLocal.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we must deploy our smart contract to the local chain. To do so, 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;node scripts/deploy.js examples/call-contract-with-token &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's put our contract to the test. We'll transmit 100 aUSDC tokens from Polygon to the Avalanche chain and distribute them to two users by running 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;node scripts/test examples/call-contract-with-token &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="s2"&gt;"Polygon"&lt;/span&gt; &lt;span class="s2"&gt;"Avalanche"&lt;/span&gt; 100 0x438d67e825D31D4a9910241074025B75b08470e1,0x57E2355F3CD8CB932952e773a5C57b64cE692e76 &lt;span class="s2"&gt;"Here's your Coffee"&lt;/span&gt;
&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/deploy%2520contract" 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/deploy%2520contract" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output after executing the transaction:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- Waiting Period Started ---
Waited for 1 minutes
--- After ---
Source(After Transaction) : 0xBF4979305B43B0eB5Bb6a5C67ffB89408803d3e1 has 999999999900 aUSDC

------------For Account 0x438d67e825D31D4a9910241074025B75b08470e1------------
Destination(Before Transaction) 1 : 0x438d67e825D31D4a9910241074025B75b08470e1 has 0 aUSDC
Destination(After Transaction) 1: 0x438d67e825D31D4a9910241074025B75b08470e1 has 49.5 aUSDC
        Details of TransactionInfo
        ---------------------------
        Sender           : 0xBF4979305B43B0eB5Bb6a5C67ffB89408803d3e1
        TokenAddress     : 0x1d1aD0c677c2Ca7945f0B9D47298ca8eb9e61909
        Amount           : 49.5
        Message          : Here's your Coffee

------------For Account 0x57E2355F3CD8CB932952e773a5C57b64cE692e76------------
Destination(Before Transaction) 2 : 0x57E2355F3CD8CB932952e773a5C57b64cE692e76 has 0 aUSDC
Destination(After Transaction) 2: 0x57E2355F3CD8CB932952e773a5C57b64cE692e76 has 49.5 aUSDC
        Details of TransactionInfo
        ---------------------------
        Sender           : 0xBF4979305B43B0eB5Bb6a5C67ffB89408803d3e1
        TokenAddress     : 0x1d1aD0c677c2Ca7945f0B9D47298ca8eb9e61909
        Amount           : 49.5
        Message          : Here's your Coffee
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Deploying to Testnet
&lt;/h2&gt;

&lt;p&gt;after successfully testing our contract we can deploy to testnet for this we can use the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/deploy.js examples/call-contract-with-token testnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's put our contract to the test. We'll transmit 10 aUSDC tokens from Axelar to the Ethereum chain and distribute them to two users by running 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;node scripts/test examples/call-contract-with-token testnet &lt;span class="s2"&gt;"Axelar"&lt;/span&gt; &lt;span class="s2"&gt;"Ethereum"&lt;/span&gt; 10 0x919d935dca4abc9079cfb9abe01529581c355552 &lt;span class="s2"&gt;"Here's your Coffee"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And with that, you've successfully launched a cross-chain smart contract that shows how to transfer tokens from one chain to another using Axelar.&lt;/p&gt;

&lt;p&gt;Here you may view the finished transaction:&lt;/p&gt;

&lt;p&gt;Transaction Hash: 6B293A9A00D7419FE92698AEA41390D7F3DC25F70B8C155F3FE5C3978515A519&lt;br&gt;
Testnet Transaction: &lt;a href="https://testnet.axelarscan.io/transfer/6B293A9A00D7419FE92698AEA41390D7F3DC25F70B8C155F3FE5C3978515A519" rel="noopener noreferrer"&gt;https://testnet.axelarscan.io/transfer/6B293A9A00D7419FE92698AEA41390D7F3DC25F70B8C155F3FE5C3978515A519&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Make a separate account for testing smart contracts rather than using your main account for testnet transactions.&lt;/p&gt;
&lt;/blockquote&gt;


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

&lt;p&gt;Congratulations 🥳🎉 on making it to the end of this article. I hope you learned something new today. If you enjoy constructing cool projects like this one, be sure to follow me for more amazing web3 and blockchain lessons.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__528762"&gt;
    &lt;a href="/envoy1084" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/envoy1084"&gt;Vedant Chainani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/envoy1084"&gt;Web3 Technical Writer ✍️ | ⛓️ Blockchain Enthusiast&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;iframe class="tweet-embed" id="tweet-1584856929259913216-127" src="https://platform.twitter.com/embed/Tweet.html?id=1584856929259913216"&gt;
&lt;/iframe&gt;

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




&lt;/h2&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Two years of blogging: The ups, downs, and everything in between</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Tue, 06 Dec 2022 15:00:00 +0000</pubDate>
      <link>https://dev.to/envoy1084/two-years-of-blogging-the-ups-downs-and-everything-in-between-1110</link>
      <guid>https://dev.to/envoy1084/two-years-of-blogging-the-ups-downs-and-everything-in-between-1110</guid>
      <description>&lt;p&gt;As a blogger on the dev.to platform, I have had a truly wonderful and fulfilling journey. When I first started out on this platform, I was a complete novice when it came to writing and sharing my thoughts and ideas online. But over time, I have grown as a writer and have been able to connect with a wonderful community of like-minded individuals who share my passion for all things technology.&lt;/p&gt;

&lt;p&gt;Today is a really meaningful day for me because I've been on dev.to for two years and have built a community of 1500 like-minded people.&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%2Fnxxubsbalzfnebyyi0gh.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%2Fnxxubsbalzfnebyyi0gh.png" alt="2 Year Club" width="726" height="595"&gt;&lt;/a&gt;&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%2Finu8pfdj10div1jfko64.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%2Finu8pfdj10div1jfko64.png" alt="1500 like minded people" width="262" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a learner, I have always been passionate about sharing my knowledge and experiences with others in the tech community. When I discovered the Dev.to blogging platform, I knew it was the perfect place for me to share my thoughts and insights on a variety of topics related to technology and programming.&lt;/p&gt;

&lt;p&gt;When I first started blogging on dev.to, I was unsure of what to write about. But I quickly realized that there was no shortage of topics to choose from in the world of technology. I started by blogging about my experiences, offering ideas and methods that I had picked up along the road. This not only helped me to improve my own skills, but it also allowed me to help others who were just starting out in the field.&lt;/p&gt;

&lt;p&gt;As I continued to write, I began to receive a steady stream of feedback and engagement from other members of the dev.to community. This was incredibly motivating, and it encouraged me to continue sharing my thoughts and experiences. I also began to participate in the various discussions and forums on the platform, which allowed me to learn from others and gain new perspectives on various topics.&lt;/p&gt;

&lt;p&gt;Unfortunately, I had to take a break from writing for a while due to college exams. Nonetheless, when I returned, the community was much more supportive than before, which assisted me in getting ideas and continuing to write.&lt;/p&gt;

&lt;p&gt;One of the most rewarding aspects of my journey as a blogger on Dev.to has been the opportunity to connect with and learn from other members of the tech community. I have had the pleasure of engaging in thoughtful discussions with other bloggers and readers, and I have gained a wealth of knowledge and insights from these interactions.&lt;/p&gt;

&lt;p&gt;In addition to the support of the community, the dev.to platform itself has also been a great resource for me. The platform provides a range of tools and features that make it easy to write and share my articles, and it has a clean and intuitive interface that is a pleasure to use.&lt;/p&gt;

&lt;p&gt;One of the things that I love about Dev.to is the variety of topics that are covered on the platform. Whether you're interested in front-end development, machine learning, or anything in between, there's something for everyone on Dev.to. This diversity has allowed me to learn about a wide range of subjects and to engage with a community of like-minded individuals who are passionate about technology and programming.&lt;/p&gt;

&lt;p&gt;There were many people who kept me inspired to write and made me interact in the community; some of them are listed below.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__1"&gt;
    &lt;a href="/ben" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1%2Ff451a206-11c8-4e3d-8936-143d0a7e65bb.png" alt="ben image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ben"&gt;Ben Halpern&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ben"&gt;A Canadian software developer who thinks he’s funny.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Monday meme has been an important part of the community, allowing us to step away from whatever we were doing and enjoy some of the internet's most hilarious memes.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__833086"&gt;
    &lt;a href="/youneslaaroussi" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F833086%2F2f9e14a5-ab79-422a-95bd-c7c267c319e7.png" alt="youneslaaroussi image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/youneslaaroussi"&gt;Younes Laaroussi&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/youneslaaroussi"&gt;serial problem solver&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This guy is a lifesaver for all devs out there; the resources are meticulously curated and have aided me greatly in my front-end journey; my favourite post is &lt;a href="https://dev.to/eludadev/i-made-100-css-buttons-for-your-next-big-project-m55"&gt; I Made 100 CSS Buttons For Your Next Big Project 🚀️&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__820341"&gt;
    &lt;a href="/nevodavid" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F820341%2F5d291561-0d60-40cf-a9d3-959dab08f1ac.png" alt="nevodavid image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/nevodavid"&gt;Nevo David&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/nevodavid"&gt;Founder of Postiz, an open-source social media scheduling tool.
Running Gitroom, the best place to learn how to grow open-source tools.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This was my go-to destination on dev.to for the greatest technical articles; the articles were precise and well described. After reading the post, even the most difficult topics seemed simple.&lt;/p&gt;

&lt;p&gt;Overall, my journey as a writer on Dev.to has been incredibly fulfilling and rewarding. I have had the opportunity to share my knowledge and experiences with others, to learn from and engage with a vibrant and supportive community, and to showcase my skills and abilities. I am grateful for the opportunities that Dev.to has provided me, and I look forward to continuing to share my thoughts and insights on a wide range of topics related to technology and programming.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>🤖 ChatGPT: The Future of Conversational AI</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Sun, 04 Dec 2022 07:40:22 +0000</pubDate>
      <link>https://dev.to/envoy1084/chatgpt-the-future-of-conversational-ai-2nfp</link>
      <guid>https://dev.to/envoy1084/chatgpt-the-future-of-conversational-ai-2nfp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;AI is transforming how we work and live. Routine tasks are automated, massive volumes of data are analyzed, and forecasts are made to aid businesses and organizations in decision-making.&lt;/p&gt;

&lt;p&gt;GPT-3.5 debuted ChatGPT on Wednesday, a fine-tuned version of GPT-3.5 that functions as a general-purpose chatbot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ChatGPT
&lt;/h2&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%2Fqv6rgb1rzy4w52uht0nu.jpg" 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%2Fqv6rgb1rzy4w52uht0nu.jpg" alt="ChatGPT" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ChatGPT is an OpenAI-developed variation of the GPT-3 language model. It is intended for use in chatbots and other conversational systems, and it can generate human-like responses to text inputs. ChatGPT, like other language models, employs machine learning techniques to generate text that is similar to the input it gets, allowing it to have natural and intuitive conversations with users.&lt;/p&gt;

&lt;p&gt;Testers can now visit OpenAI and sample ChatGPT for free.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go to the &lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;OpenAI website&lt;/a&gt; and click on the "Sign up" button located in the top right corner.&lt;/li&gt;
&lt;li&gt; Fill out the registration form with your personal information, such as your name, email, and password.&lt;/li&gt;
&lt;li&gt; Agree to the terms of service and privacy policy by checking the boxes provided.&lt;/li&gt;
&lt;li&gt; Click on the "Create account" button to complete the registration process.&lt;/li&gt;
&lt;li&gt;After that, visit the chat &lt;a href="https://chat.openai.com/chat" rel="noopener noreferrer"&gt;playground&lt;/a&gt; to give it a try.&lt;/li&gt;
&lt;/ol&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%2Fg6bkwl4nubhn62a5dowa.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%2Fg6bkwl4nubhn62a5dowa.png" alt="ChatGPT Playground" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What can ChatGPT do?
&lt;/h2&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%2Flwc2cazpuu78pwj44t9y.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%2Flwc2cazpuu78pwj44t9y.png" alt="Use Cases of ChatGPT" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT is a big language model capable of producing human-like text in response to user input.&lt;/li&gt;
&lt;li&gt;ChatGPT can converse with users and respond in ways that are relevant to the topic and situation.&lt;/li&gt;
&lt;li&gt;ChatGPT can generate text in a variety of formats and styles, such as paragraphs, lists, and bullet points.&lt;/li&gt;
&lt;li&gt;ChatGPT can provide information on a variety of topics such as current affairs, history, science, and more.&lt;/li&gt;
&lt;li&gt;ChatGPT can be embedded in a wide range of applications, including chatbots and virtual assistants, to provide intelligent, natural language responses to user queries.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ChatGPT and Web3
&lt;/h2&gt;

&lt;p&gt;The use of AI in web3 and blockchain technology has various advantages. The capacity to automate challenging and time-consuming processes is one of the key benefits. This can increase productivity and lower the possibility of mistakes.&lt;/p&gt;

&lt;p&gt;Making better decisions is another advantage of employing AI with web3 and blockchain. It is feasible to analyze enormous volumes of data using machine learning algorithms, and then use the results to generate predictions or suggestions. This can assist companies and organizations in improving decisions and operations.&lt;/p&gt;

&lt;p&gt;AI in web3 can also help to increase security. AI can be applied to networks to keep an eye out for potential security risks as well as to spot and stop fraud. This can aid in defending against internet crimes and cyberattacks.&lt;/p&gt;

&lt;p&gt;Additionally, the employment of AI in web3 and blockchain can enhance trust and transparency. Blockchain technology can contribute to the development of trust between parties and the assurance that information is accurate and current by offering a secure and immutable record of transactions.&lt;/p&gt;

&lt;p&gt;Overall, the use of AI in web3 and blockchain technology has the potential to bring significant benefits in terms of automation, decision-making, security, and transparency.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Writing Code
&lt;/h3&gt;

&lt;p&gt;When we ask the chat bot to "code to connect to metamask wallet using javascript and ethers.js and then print the user address" we get this response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import the ethers.js library&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Check if the user has MetaMask installed&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MetaMask is not installed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Request access to the user's MetaMask account&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eth_requestAccounts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Create a provider to connect to the user's MetaMask wallet&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Web3Provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Get the user's address&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Your address is: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error requesting access to account: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to include the ethers.js library in your project before running this code. You can do this by running &lt;code&gt;npm install ethers&lt;/code&gt; or &lt;code&gt;yarn add ethers&lt;/code&gt; in your project directory.&lt;/p&gt;

&lt;p&gt;This code checks if MetaMask is installed and requests access to the user's account. It then creates a Web3Provider using the window.ethereum object, which allows it to connect to the user's MetaMask wallet. Finally, it retrieves the user's address and logs it to the console.&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%2Flnfhwsrok590ub3582ct.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%2Flnfhwsrok590ub3582ct.png" alt="Asking the Bot to write Code" width="671" height="819"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's incredible that an AI can write code that is both functional and includes documentation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Ask for Suggestions
&lt;/h3&gt;

&lt;p&gt;For this, we may ask the chatbot for some current hot web3 subjects, and here is the response.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Decentralized finance (DeFi) and decentralized autonomous organizations (DAOs)&lt;/li&gt;
&lt;li&gt; Blockchain gaming and non-fungible tokens (NFTs)&lt;/li&gt;
&lt;li&gt; Privacy-focused protocols and tools, such as zk-SNARKs and zero-knowledge proofs&lt;/li&gt;
&lt;li&gt; Stablecoins and decentralized exchanges (DEXs)&lt;/li&gt;
&lt;li&gt; Web3 infrastructure and development, including decentralized storage and data management solutions.&lt;/li&gt;
&lt;/ol&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%2F2llzxqzg928sisfy0nm6.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%2F2llzxqzg928sisfy0nm6.png" alt="Asking for Suggestions" width="753" height="348"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Ask for Explanation
&lt;/h3&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%2Fevyfqzcc6c5pdqoy1x06.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%2Fevyfqzcc6c5pdqoy1x06.png" alt="Explain NFTs like I'm 5" width="752" height="292"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Asking follow up questions
&lt;/h3&gt;

&lt;p&gt;You can also ask the Chat Bot follow-up questions about the previous question and its answer.&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%2F8y45lf6fb1oukdemwh7e.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%2F8y45lf6fb1oukdemwh7e.png" alt="Asking follow up questions" width="792" height="758"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Limitations of ChatGPT
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT may not always provide accurate or relevant responses to user input.&lt;/li&gt;
&lt;li&gt;ChatGPT may not have enough knowledge or information on a particular topic to provide a satisfactory response.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to understand and interpret complex or abstract concepts.&lt;/li&gt;
&lt;li&gt;ChatGPT may struggle to understand and respond to natural language, leading to awkward or confusing conversations.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to adapt to changing contexts or new information, leading to inconsistencies in its responses.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to generate original or creative responses, relying instead on pre-programmed responses or templates.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to engage in interactive or dynamic conversations, leading to repetitive or dull exchanges.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to maintain the same level of performance over long periods of time, leading to degradation in its responses.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to handle large volumes of input or multiple concurrent conversations, leading to delays or errors in its responses.&lt;/li&gt;
&lt;li&gt;ChatGPT may not be able to understand or respond to users with different backgrounds, experiences, or language abilities, leading to misunderstandings or bias.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;There are numerous reasons why you should give ChatGPT a try. For starters, it is a huge language model created by OpenAI, which means it has been trained on a large amount of text data and can generate human-like responses to a variety of queries and prompts. Furthermore, ChatGPT is a useful and efficient tool that can help you save time and effort when creating high-quality written material. ChatGPT is a fantastic resource for improving your writing and communication abilities, whether you're a student, a professional, or simply someone who enjoys engaging in intellectual discourse. Try it out today and see how it may improve your discussions and help you express yourself more effectively.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>news</category>
      <category>web3</category>
    </item>
    <item>
      <title>🚀 Building a Decentralized Chat App using GUN.js and Svelte</title>
      <dc:creator>Vedant Chainani</dc:creator>
      <pubDate>Mon, 28 Nov 2022 15:00:00 +0000</pubDate>
      <link>https://dev.to/envoy1084/building-a-decentralized-chat-app-using-gunjs-and-svelte-29h6</link>
      <guid>https://dev.to/envoy1084/building-a-decentralized-chat-app-using-gunjs-and-svelte-29h6</guid>
      <description>&lt;p&gt;The complete code for this tutorial is available here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/envoy1084" rel="noopener noreferrer"&gt;
        envoy1084
      &lt;/a&gt; / &lt;a href="https://github.com/envoy1084/gun-chat" rel="noopener noreferrer"&gt;
        gun-chat
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Decentralized Chat App using GUN.js and Svelte
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;🚀 Live Site: &lt;a href="https://gun-chat-zeta.vercel.app/" rel="nofollow noopener noreferrer"&gt;https://gun-chat-zeta.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is GUN&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;GUN.js a decentralized graph database for freedom fighters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Graph database applications have grown dramatically during the last few years. Graph databases, for example, are already utilized by Facebook for their social media platform, Stripe for fraudulent transactions, Amazon for product recommendation, and companies all over the world for big data analytics in a variety of sectors and challenges.&lt;/p&gt;
&lt;p&gt;Unlike a centralized database that stays on a server maintained by big tech, data in GUN is dispersed between several peers or users using the power of WebRTC. This decentralized database functions exactly like a cloud database from the developer’s perspective; however, it is hosted on a completely peer to peer network. It is not a blockchain, but leverages some of the same cryptographic algorithms, such as Patricia-Merkle trees.&lt;/p&gt;
&lt;p&gt;In this post, we'll utilize GUN to build a decentralized chat software that employs user authentication…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/envoy1084/gun-chat" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🚀 Live Site: &lt;a href="https://gun-chat-zeta.vercel.app/" rel="noopener noreferrer"&gt;https://gun-chat-zeta.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is GUN
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;GUN.js a decentralized graph database for freedom fighters. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Graph database applications have grown dramatically during the last few years. Graph databases, for example, are already utilized by Facebook for their social media platform, Stripe for fraudulent transactions, Amazon for product recommendation, and companies all over the world for big data analytics in a variety of sectors and challenges.&lt;/p&gt;

&lt;p&gt;Unlike a centralized database that stays on a server maintained by big tech, data in GUN is dispersed between several peers or users using the power of WebRTC. This decentralized database functions exactly like a cloud database from the developer’s perspective; however, it is hosted on a completely peer to peer network. It is not a blockchain, but leverages some of the same cryptographic algorithms, such as Patricia-Merkle trees.&lt;/p&gt;

&lt;p&gt;In this post, we'll utilize GUN to build a decentralized chat software that employs user authentication and end-to-end encryption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&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%2F1al4rbdjemh9t5toepi0.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%2F1al4rbdjemh9t5toepi0.png" alt="Login Page" width="800" height="404"&gt;&lt;/a&gt;&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%2Fdd4hky6qqrgv4jkskos5.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%2Fdd4hky6qqrgv4jkskos5.png" alt="Chat Section" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 - Setting up the Environment
&lt;/h2&gt;

&lt;p&gt;We will use slimline as our frontend framework, so create a new project directory called '&lt;code&gt;chat-app&lt;/code&gt;' and run command to initialize npm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;to create a svelte app run&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest chat-app &lt;span class="nt"&gt;--template&lt;/span&gt; svelte
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Following that, we will require a gun for storage and to install run&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 gun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2 - Implementing User Authentication
&lt;/h2&gt;

&lt;p&gt;Create a new file called &lt;code&gt;user.js&lt;/code&gt; in the project's &lt;code&gt;src&lt;/code&gt; subdirectory, where we will implement our user authentication.&lt;/p&gt;

&lt;p&gt;Following that, we will import Gun as well as the side libraries known as &lt;code&gt;sea&lt;/code&gt; and &lt;code&gt;axe&lt;/code&gt;. sea represents security, encryption, and authorization, and it allows for user authentication. axe stands for advanced exchange equation, and it is a different technique to link peers.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GUN&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gun&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gun/sea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gun/axe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Following that, we will initialize our database and make a database reference to the currently authenticated user.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Database&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GUN&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Gun User&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We used &lt;code&gt;sessionStorage: true&lt;/code&gt; to prevent the user from being logged out while closing and reopening tabs.&lt;/p&gt;

&lt;p&gt;Next, we'll need the username, which will be used frequently in the app, so we'll import writable from svelte/store at the start of the file to make the app more responsive.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte/store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To obtain the user's alias, we will use the get method.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Current User's username&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alias&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We will create a on event function that will update the user's username whenever he or she logs in and out.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 3 - Creating Header
&lt;/h2&gt;

&lt;p&gt;Now we'll make a header for our app that will display our username and avatar when we sign up or login in. In the &lt;code&gt;src&lt;/code&gt; directory, create a new file called &lt;code&gt;Header.svelte&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We will import the user database and the username from the user.js file into the script tag. We'll also write a &lt;code&gt;signout&lt;/code&gt; function that logs the user out and sets the username to an empty string.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;signout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the header tag, we will create a conditional block that will display the username along with a unique avatar generated using the &lt;a href="https://avatars.dicebear.com/" rel="noopener noreferrer"&gt;DiceBear API&lt;/a&gt; if the username is not an empty string.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;🔫 Chat App&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  {#if $username}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-bio"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Hello &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;{$username}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;{`https://avatars.dicebear.com/api/human/${$username}.svg`}&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signout-button"&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{signout}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sign Out&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  {/if}
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 - Creating Login form
&lt;/h2&gt;

&lt;p&gt;Now we'll design our login and sign up forms, where users may log in or create new accounts. Make a new file called &lt;code&gt;Login.svelte&lt;/code&gt; for this purpose.&lt;/p&gt;

&lt;p&gt;We will import the user database from the &lt;code&gt;user.js&lt;/code&gt; file into the script tag. In addition, we will create state variables for &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we'll create two functions: &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;signup&lt;/code&gt;. In the login function, we will utilize the &lt;code&gt;auth&lt;/code&gt; method to validate the user. We will also handle errors and notify the user if any input is incorrect.&lt;/p&gt;

&lt;p&gt;We will create a new item in the database using the username and password in the sign up method.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;signup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Following that, we'll add input fields for the username and password, as well as use the &lt;code&gt;bind:value&lt;/code&gt; method in Svelte to update the state variables when the input changes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Username&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{username}&lt;/span&gt; &lt;span class="na"&gt;minlength=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{password}&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{login}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt;  &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{signup}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sign Up&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5 - Building Chat Component
&lt;/h2&gt;

&lt;p&gt;To begin, we will import various modules and global state variables while developing our chat component, so create a new file called &lt;code&gt;Chat. svelte&lt;/code&gt; .&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Login.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ChatMessage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./ChatMessage.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onMount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;debounce&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash.debounce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GUN&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gun&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Now we'll declare some new state variables named &lt;code&gt;newMessage&lt;/code&gt;, which will store the message, the &lt;code&gt;messages&lt;/code&gt; array, and some minor scrolling feature variables.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GUN&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;scrollBottom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lastScrollTop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;canAutoScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;unreadMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then we'll write some scroll methods that will monitor chat and auto-scroll as new messages arrive.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;autoScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;scrollBottom&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;unreadMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;watchScroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;canAutoScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lastScrollTop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;lastScrollTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nl"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;debouncedWatchScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;watchScroll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we'll utilize the &lt;code&gt;onMount&lt;/code&gt; hook, which will be executed when the component is initialized. It contains a match variable, which functions similarly to a RegEx, and will look for any messages that are less than 3 hours old.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// lexical queries are kind of like a limited RegEx or Glob.&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// property selector&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// find any indexed property larger ~3 hours ago&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// filter in reverse&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Following that, we will retrieve the chat by using the get method, map on it once, and if any data is received, we will create a new variable that will store the same key that will aid in decrypting the data.&lt;/p&gt;

&lt;p&gt;Then  we will reformat the data as per our convenience in a new message object with keys - who, what and when. In the &lt;code&gt;who&lt;/code&gt; key we will store the username of the sender, in the &lt;code&gt;what&lt;/code&gt; key we will store the message after decrypting it using the key and in the &lt;code&gt;when&lt;/code&gt; key we will store the timestamp of the message.&lt;/p&gt;

&lt;p&gt;If a new message is received, we will perform an if conditional block that will store it in the messages array.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Key for end-to-end encryption&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// transform the data&lt;/span&gt;
            &lt;span class="na"&gt;who&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alias&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// a user might lie who they are! So let the user system detect whose data it is.&lt;/span&gt;
            &lt;span class="na"&gt;what&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SEA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;what&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// force decrypt as text.&lt;/span&gt;
            &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GUN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;what&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// get the internal timestamp for the what property.&lt;/span&gt;
          &lt;span class="p"&gt;};&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;what&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;when&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canAutoScroll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;autoScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;unreadMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we will construct a new function &lt;code&gt;sendMessage&lt;/code&gt; that will allow users to send messages, and then we will insert the message into the database using the put method.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SEA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;what&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;newMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;canAutoScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;autoScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We will now create the UI for the chat component, which will loop through all of the messages in the messages array based on the timestamp. In addition, we will create a new input field for users to send messages.&lt;/p&gt;

&lt;p&gt;Then we'll add some scrolling elements that will scroll to the bottom when fresh messages arrive.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {#if $username}
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;on:scroll=&lt;/span&gt;&lt;span class="s"&gt;{debouncedWatchScroll}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      {#each messages as message (message.when)}
        &lt;span class="nt"&gt;&amp;lt;ChatMessage&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="na"&gt;sender=&lt;/span&gt;&lt;span class="s"&gt;{$username}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      {/each}

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dummy"&lt;/span&gt; &lt;span class="na"&gt;bind:this=&lt;/span&gt;&lt;span class="s"&gt;{scrollBottom}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;on:submit&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="na"&gt;preventDefault=&lt;/span&gt;&lt;span class="s"&gt;{sendMessage}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Type a message..."&lt;/span&gt; &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{newMessage}&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;disabled=&lt;/span&gt;&lt;span class="s"&gt;{!newMessage}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;💥&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;


    {#if !canAutoScroll}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroll-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{autoScroll}&lt;/span&gt; &lt;span class="na"&gt;class:red=&lt;/span&gt;&lt;span class="s"&gt;{unreadMessages}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {#if unreadMessages}
          💬
        {/if}

        👇
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   {/if}
  {:else}
    &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Login&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  {/if}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5 - Create Message Bubble
&lt;/h2&gt;

&lt;p&gt;Now we'll make a chat message bubble, so make a new file called &lt;code&gt;ChatMessage.svelte&lt;/code&gt; and paste the following code into it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;who&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;received&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;avatar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://avatars.dicebear.com/api/human/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;who&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.svg`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;when&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;{`message&lt;/span&gt; &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="na"&gt;messageClass&lt;/span&gt;&lt;span class="err"&gt;}`}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;{avatar}&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"message-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{message.what}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;time&amp;gt;&lt;/span&gt;{ts.toLocaleTimeString()}&lt;span class="nt"&gt;&amp;lt;/time&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6 - Finalizing
&lt;/h2&gt;

&lt;p&gt;We are nearly finished with our app; simply go to &lt;code&gt;App.svelte&lt;/code&gt; and import the header and chat components into our app component.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Chat&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Chat.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Header.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Header&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Chat&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;First and foremost, congratulations 🎉🎉 on making it this far. You have successfully built a decentralized chat app utilizing GUN.js and svelte as the frontend framework.&lt;/p&gt;

&lt;p&gt;This article was inspired by a &lt;a href="https://www.youtube.com/@Fireship" rel="noopener noreferrer"&gt;Fireship&lt;/a&gt; video:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/J5x3OMXjgMc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This article demonstrates what you can build using GUN.js. Feel free to improve on the project by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding User to User E2E Encryption&lt;/li&gt;
&lt;li&gt;Improving the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete code for this tutorial is available here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/envoy1084" rel="noopener noreferrer"&gt;
        envoy1084
      &lt;/a&gt; / &lt;a href="https://github.com/envoy1084/gun-chat" rel="noopener noreferrer"&gt;
        gun-chat
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Decentralized Chat App using GUN.js and Svelte
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;🚀 Live Site: &lt;a href="https://gun-chat-zeta.vercel.app/" rel="nofollow noopener noreferrer"&gt;https://gun-chat-zeta.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is GUN&lt;/h2&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;GUN.js a decentralized graph database for freedom fighters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Graph database applications have grown dramatically during the last few years. Graph databases, for example, are already utilized by Facebook for their social media platform, Stripe for fraudulent transactions, Amazon for product recommendation, and companies all over the world for big data analytics in a variety of sectors and challenges.&lt;/p&gt;

&lt;p&gt;Unlike a centralized database that stays on a server maintained by big tech, data in GUN is dispersed between several peers or users using the power of WebRTC. This decentralized database functions exactly like a cloud database from the developer’s perspective; however, it is hosted on a completely peer to peer network. It is not a blockchain, but leverages some of the same cryptographic algorithms, such as Patricia-Merkle trees.&lt;/p&gt;

&lt;p&gt;In this post, we'll utilize GUN to build a decentralized chat software that employs user authentication…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/envoy1084/gun-chat" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;If you enjoyed this essay and would like to see more on web3, blockchain, and decentralization, make sure to follow and connect with me.&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__528762"&gt;
    &lt;a href="/envoy1084" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F528762%2Fcd4ce7bd-dd34-40fd-9be9-e22cccfd9e5b.gif" alt="envoy1084 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/envoy1084"&gt;Vedant Chainani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/envoy1084"&gt;Web3 Technical Writer ✍️ | ⛓️ Blockchain Enthusiast&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1584856929259913216-938" src="https://platform.twitter.com/embed/Tweet.html?id=1584856929259913216"&gt;
&lt;/iframe&gt;

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








</description>
      <category>ai</category>
      <category>aws</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
