<?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: Gabriel Temsten</title>
    <description>The latest articles on DEV Community by Gabriel Temsten (@gabrieltemtsen).</description>
    <link>https://dev.to/gabrieltemtsen</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%2F1041481%2Fe149e780-e44d-4bcb-b066-5b8cdfd6d046.jpeg</url>
      <title>DEV Community: Gabriel Temsten</title>
      <link>https://dev.to/gabrieltemtsen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrieltemtsen"/>
    <language>en</language>
    <item>
      <title>cmdguard-cli: Your Terminal's Safety Net for Risky Commands – Built with GitHub Copilot CLI</title>
      <dc:creator>Gabriel Temsten</dc:creator>
      <pubDate>Sun, 15 Feb 2026 00:28:45 +0000</pubDate>
      <link>https://dev.to/gabrieltemtsen/cmdguard-cli-your-terminals-safety-net-for-risky-commands-built-with-github-copilot-cli-538d</link>
      <guid>https://dev.to/gabrieltemtsen/cmdguard-cli-your-terminals-safety-net-for-risky-commands-built-with-github-copilot-cli-538d</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;cmdguard-cli&lt;/strong&gt; is a lightweight, standalone Node.js CLI tool that acts as a "safety preview" for potentially dangerous shell commands right in your terminal. Before running something scary like &lt;code&gt;rm -rf node_modules&lt;/code&gt;, &lt;code&gt;docker system prune -a --volumes&lt;/code&gt;, &lt;code&gt;git push --force&lt;/code&gt;, or even &lt;code&gt;chmod 777 .&lt;/code&gt;, cmdguard analyzes it for risks (data loss, permission escalation, resource exhaustion, security issues), shows color-coded warnings (red = high risk, yellow = medium, green = low), suggests safer alternatives, and asks for confirmation before executing.&lt;/p&gt;

&lt;p&gt;It's simple but powerful: pattern-matching for common dangerous tools (rm, git, docker, dd, sudo, chmod/chown, piped curl/wget), piped input support, and flags like &lt;code&gt;--simulate&lt;/code&gt; (explain only) and &lt;code&gt;--rewrite&lt;/code&gt; (output safer version). No hooks, no cloud/Slack setup—just install globally and use it inline.&lt;/p&gt;

&lt;p&gt;To me, this project means peace of mind in the terminal. I've nuked directories or force-pushed the wrong branch too many times—cmdguard is the quick guardrail I wish existed, especially when experimenting with Copilot-generated scripts or late-night commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/gabrieltemtsen/cmd-guard" rel="noopener noreferrer"&gt;https://github.com/gabrieltemtsen/cmd-guard&lt;/a&gt;&lt;br&gt;&lt;br&gt;
NPM: &lt;a href="https://www.npmjs.com/package/cmdguard-cli" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/cmdguard-cli&lt;/a&gt; (install with &lt;code&gt;npm i -g cmdguard-cli&lt;/code&gt;)&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/gabrieltemtsen/cmd-guard/feature/readme-walkthrough-video/public/cmd-guard-demo-ezgif.com-optimize.gif" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/gabrieltemtsen/cmd-guard/feature/readme-walkthrough-video/public/cmd-guard-demo-ezgif.com-optimize.gif&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot CLI was the secret weapon that turned this from "cool idea" to shipped MVP in a short sprint. I started with a single descriptive prompt outlining the core idea (CLI structure, commander for args, chalk for colors, child_process for exec, risk patterns), and it generated a solid plan + initial files (package.json, bin/cmdguard.js, analyzer module).Key ways it helped:Rapid scaffolding: One prompt created the CLI parser, stdin handling, and basic execution flow—saved hours of boilerplate.&lt;br&gt;
Smart code generation: Asked it to "implement risk pattern matching for rm/git/docker commands with suggestions" → got clean, modular functions I could iterate on.&lt;br&gt;
Debugging &amp;amp; iteration: When piped input broke or child_process output wasn't captured right, natural language fixes like "add error handling and stdout/stderr streaming" worked instantly.&lt;br&gt;
Testing boost: Prompted for Jest test skeletons → quickly added analyzer.test.js to verify patterns.&lt;br&gt;
Meta-story: Ironically, building a "safety net for commands" (including those Copilot might suggest) using Copilot CLI itself felt poetic—agentic loops for reasoning about risks, then applying them to the tool.&lt;/p&gt;

&lt;p&gt;Without Copilot CLI, this would have taken days of manual grinding. With it, I focused on refining UX (colors, emojis, clear prompts) and adding the challenge's "how it enhances dev process" narrative. The interactive session (plan → approve files → iterate) made building feel collaborative and fast.Thanks to the GitHub team and DEV community for this challenge—excited to see what everyone built!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Unlocking the Power of Trust: Union Finance-Credit Protocol Explained</title>
      <dc:creator>Gabriel Temsten</dc:creator>
      <pubDate>Fri, 25 Aug 2023 10:05:23 +0000</pubDate>
      <link>https://dev.to/gabrieltemtsen/unlocking-the-power-of-trust-union-finance-credit-protocol-explained-32be</link>
      <guid>https://dev.to/gabrieltemtsen/unlocking-the-power-of-trust-union-finance-credit-protocol-explained-32be</guid>
      <description>&lt;p&gt;One protocol stands out as a beacon of confidence in the ever-evolving world of Web3 and DeFi, where creativity knows no bounds: the Union Credit Protocol. Let's set out on a trip to discover Union Credit's magic and how it's transforming credit networks if you're fresh to the world of blockchain and decentralised finance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Essence of Credit
&lt;/h2&gt;

&lt;p&gt;At its core, credit is simply the act of lending money to someone with the expectation that it will be paid back, often with interest. In the realm of DeFi, this concept is taken to a whole new level. Typically, DeFi systems require collateral to secure loans. However, Union Credit Protocol introduces a game-changing concept – unsecured or undercollateralized credit, where trust takes center stage. Here's how it all works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trusting in the Digital Realm
&lt;/h2&gt;

&lt;p&gt;Union Credit Protocol is essentially a trust-based credit network that operates on smart contracts within the Ethereum blockchain. Unlike traditional finance, where collateral is king, Union Credit Protocol extends credit to individuals based on trust&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mechanism Unveiled
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creating Trust:&lt;/strong&gt; Imagine you have an Ethereum address. In the world of Union Credit, you vouch for this address by specifying an amount of trust. This trust forms the basis for credit within the protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Borrowing Against Trust:&lt;/strong&gt; Now, the address you've vouched for can borrow funds within the Union Credit Protocol. No collateral, just trust. This is where the magic begins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Web of Trust:&lt;/strong&gt; Credit within Union Finance is powered by a web of trust. Multiple members vouch for an address by depositing tokens (like DAI) into the protocol. The amount they vouch for directly impacts the credit limit of the address they're endorsing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Let's dive deeper into how this fascinating protocol works.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Union Credit Protocol in Action
&lt;/h2&gt;

&lt;p&gt;The Union Protocol serves as a coordination mechanism that allows any Ethereum address to accumulate a credit line on-chain in a permissionless and crypto-native manner. Here's a breakdown of its key components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Manager:&lt;/strong&gt; This protocol manages user stakes and registers addresses eligible to interact with the system as members.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;uToken:&lt;/strong&gt; uToken governs who can borrow and how much they can borrow. It also keeps tabs on interest rates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking Trust:&lt;/strong&gt; Users stake their tokens (e.g DAI) into the protocol, setting the amount they trust for specific addresses. For instance, you could stake 100 DAI and vouch for Jordan's address with 1 DAI. The vouch amount is the minimum of your stake or the trust you set, ensuring precision and security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credit Dynamics:&lt;/strong&gt; Unlike traditional credit systems, where you default after a certain period, Union Credit considers you in default the moment you borrow. This dynamic approach keeps things transparent and efficient, with ongoing interest rates reflecting real-time borrowing conditions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://union.finance/"&gt;The Union Credit Protocol&lt;/a&gt; is an exciting evolution in DeFi, where trust becomes the new collateral. It's a testament to the innovative spirit of the blockchain world, where conventional financial systems are reimagined, and new possibilities are constantly unlocked. As you delve deeper into the Web3 ecosystem, keep an eye on Union Finance – it's at the forefront of reshaping how we think about credit in the digital age. Trust has found its new home in the Union Credit Protocol, and the future of finance is brighter because of it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>unionfinance</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to create a Lottery Mobile dApp on Celo using react-native(with expo)</title>
      <dc:creator>Gabriel Temsten</dc:creator>
      <pubDate>Tue, 09 May 2023 14:28:38 +0000</pubDate>
      <link>https://dev.to/gabrieltemtsen/how-to-create-a-lottery-mobile-dapp-on-celo-using-react-nativewith-expo-5jn</link>
      <guid>https://dev.to/gabrieltemtsen/how-to-create-a-lottery-mobile-dapp-on-celo-using-react-nativewith-expo-5jn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We now rely heavily on mobile applications in our daily lives. Mobile decentralised applications (dApps) have grown in popularity since the introduction of blockchain technology. A mobile-first strategy is offered by Celo, a blockchain platform that promises to make financial tools available to everyone. In this tutorial, we'll develop a Celo mobile dApp using React Native, Expo, and Hardhat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you will learn how to build a mobile dApp using React Native with Expo and Hardhat, and how to deploy a smart contract to the Celo blockchain network. The tutorial will cover the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install Expo and create a new React Native project (bootstrapped from celo composer) to set up the development environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the necessary dependencies, such as Hardhat and the Celo SDK.&lt;br&gt;
Using Hardhat, create a straightforward smart contract and publish it to the Celo network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build a basic React Native app that interacts with the deployed smart contract to display the user's token balance and play the lottery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test the mobile dApp using Expo.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;Before we dive into building the Celo mobile dApp, here are some prerequisites that you should be familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of React Native and Solidity programming languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the latest version of &lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm"&gt;Node.js and npm&lt;/a&gt; on your computer. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Hardhat, You can install it globally by running &lt;br&gt;
&lt;code&gt;npm install -g hardhat&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the Celo CLI, You can install it globally by running &lt;code&gt;npm install -g @celo/cli&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Expo CLI, You can install it globally by running npm &lt;code&gt;install -g expo-cli&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An understanding of the Celo blockchain network and the Celo SDK. You can find more information in the Celo &lt;a href="https://docs.celo.org/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Initialise your project using Celo CLI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open up your terminal inside a directory of your choice create the project using &lt;code&gt;npx @celo/celo-composer@latest create&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow up the prompt in the image below: &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9K13f_JO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pdtswcs1x7khs89ja2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9K13f_JO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pdtswcs1x7khs89ja2l.png" alt="Initialise project" width="736" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Writing the Lottery smart contract
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;cd into the newly created project, navigate to hardhat:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd celo-mobile-lottery
cd packages
cd hardhat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open the folder in your preferred code editor, open the contracts folder and create a solidity file name it Lottery.sol paste the code below in it.
&lt;/li&gt;
&lt;/ul&gt;

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


contract Lottery {
    address public manager;
    uint256 public ticketPrice;
    bool public isOpened;
    address public winner;

    address[] public players;

    constructor () {
        manager = msg.sender;
        ticketPrice = 1 ether;
        isOpened = true;
    }

    function playLottery() public payable returns(bool) {
        require(msg.value == ticketPrice, "Invalid Bet Price");
        players.push(msg.sender);        
        return true;

    }
    function getRandomNumber() internal view returns(uint256 randomNumber) {
        randomNumber = block.timestamp;
    }
    function openLottery() public  returns(bool) {
        isOpened = true;
        return isOpened;
    }
    function CloseLottery() public returns(bool){
        require(isOpened == true, "Already closed!");
         uint256 winnerIndex = getRandomNumber() % players.length;
         address lotteryWinner = players[winnerIndex];
         winner = lotteryWinner;
         uint256 pool = address(this).balance;
        payable(lotteryWinner).transfer(pool);
        isOpened = false;
        return true;


    }
    function getNumberOfPlayers() public view returns(uint){
        return players.length;
    }

   function getLotteryBalance() public view returns(uint256) {
       return address(this).balance;
   }

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Here’s an overview of what’s happening in the code above&lt;/em&gt; : &lt;br&gt;
&lt;strong&gt;Contract&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The contract represents a lottery system where users can place bets and a winner is selected randomly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The state variables&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manager: Stores the address of the contract manager or the address that deploys the contract.&lt;/li&gt;
&lt;li&gt;ticketPrice: Represents the price of a single ticket in ether(cUSD).&lt;/li&gt;
&lt;li&gt;isOpened: Indicates whether the lottery is currently open for participation.&lt;/li&gt;
&lt;li&gt;winner: Stores the address of the winner of the lottery.&lt;/li&gt;
&lt;li&gt;players: An array that keeps track of all the participants in the lottery.
&lt;strong&gt;Constructor&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;The constructor function is executed when the contract is deployed.&lt;/li&gt;
&lt;li&gt;It initializes the manager variable with the address of the contract deployer.&lt;/li&gt;
&lt;li&gt;Sets the ticketPrice to 1 ether.&lt;/li&gt;
&lt;li&gt;Sets the isOpened variable to true.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Functions ()&lt;/strong&gt; :&lt;br&gt;
The &lt;strong&gt;&lt;em&gt;playLottery()&lt;/em&gt;&lt;/strong&gt; function allows users to participate in the lottery by sending the required ticket price in Ether. The &lt;strong&gt;&lt;em&gt;getRandomNumber()&lt;/em&gt;&lt;/strong&gt; function generates a random number based on the current timestamp. The &lt;strong&gt;&lt;em&gt;openLottery()&lt;/em&gt;&lt;/strong&gt; function opens the lottery for participation. The &lt;strong&gt;&lt;em&gt;CloseLottery()&lt;/em&gt;&lt;/strong&gt; function closes the lottery, selects a random winner, transfers the contract balance to the winner, and marks the lottery as closed. The &lt;strong&gt;&lt;em&gt;getNumberOfPlayers()&lt;/em&gt;&lt;/strong&gt; function returns the number of participants in the lottery. The &lt;strong&gt;&lt;em&gt;getLotteryBalance()&lt;/em&gt;&lt;/strong&gt; function retrieves the current balance of the lottery contract. These functions collectively facilitate the operation of the lottery system, including ticket purchase, winner selection, and retrieving relevant information such as the number of participants and the contract balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Deploy the smart contract on celo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a .env file in the hardhat root directory, get your private key from your metamask wallet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Declare a variable PRIVATE_KEY and initialise it with the private key gotten from your metamask wallet.&lt;br&gt;
&lt;strong&gt;NB&lt;/strong&gt;: Before you proceed make sure to get some Alfajores Testnet in your metamask from the Celo Testnet &lt;a href="https://faucet.celo.org/alfajores"&gt;Faucets&lt;/a&gt;. To connect your metamask to the testnet you can check &lt;a href="https://developers.celo.org/3-simple-steps-to-connect-your-metamask-wallet-to-celo-732d4a139587"&gt;Here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your terminal in the hardhat directory compile the lottery contract using &lt;code&gt;npx hardhat compile&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To deploy the contract to the alfajores Celo Testnet : &lt;br&gt;
&lt;code&gt;npx hardhat deploy --network alfajores&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Expected Output:&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vtp7zxmn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68dkqueis5pl2o7ndgu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vtp7zxmn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68dkqueis5pl2o7ndgu5.png" alt="Image description" width="800" height="277"&gt;&lt;/a&gt;&lt;br&gt;
Welldone! we have our lottery contract deployed on the celo testnet. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From your file structure you'd notice there is a deployments folder created after we deployed our contract, navigate to the folder deployments/alfajores/ then copy the the Lottery.json file. Go back to the root directory of our project (outside the hardhat folder). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the react-native folder, create a folder contracts and paste our copied file there.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4: Editing the lottery User interface
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Within the react-native folder, go to screens and rename the Docs.tsx file to Home.tsx and replace the code with the code below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SafeAreaView } from "react-native-safe-area-context";
import Container from "../components/Container";
import { H1, H2, H3, H4, H5, H6 } from "../components/Headings";
import MonoText from "../components/MonoText";
import { Text, View } from "../components/Themed";
import Colors from "../constants/Colors";
import { Button } from "react-native";
import * as LotteryContract from "../contracts/Lottery.json"
import { useWalletConnect } from "@walletconnect/react-native-dapp";
import { useEffect, useState } from "react";
import Web3 from "web3";

const web3 = new Web3("https://alfajores-forno.celo-testnet.org");

const Home = () =&amp;gt; {

    const abi = LotteryContract.abi;
    const lotteryAddress = LotteryContract.address;

    const connector = useWalletConnect();
    const [lotteryPool, setLotteryPool] = useState('');
    const [winner, setWinner] = useState("Naan");
    const [lotteryBets, setLotteryBets] = useState('');
    const [lotteryStatus, setLotteryStatus] = useState(true);
    const contract = LotteryContract
    ? new web3.eth.Contract(abi, lotteryAddress)
    : null;

    const placeBets = async () =&amp;gt; {

        try {
            let txData = await contract?.methods
                .playLottery()
                .encodeABI();

            await connector.sendTransaction({
                from: connector.accounts[0],
                to: lotteryAddress,
                data: txData,
                value: web3.utils.toWei('1', 'ether'),
            });
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };

    const openLottery = async () =&amp;gt; {

        try {
            let txData = await contract?.methods
                .openLottery()
                .encodeABI();

            await connector.sendTransaction({
                from: connector.accounts[0],
                to: lotteryAddress,
                data: txData,
            });
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };

    const closeLottery = async () =&amp;gt; {

        try {
            let txData = await contract?.methods
                .CloseLottery()
                .encodeABI();

            await connector.sendTransaction({
                from: connector.accounts[0],
                to: lotteryAddress,
                data: txData,
            });
            getLotteryStatus();
            alert('Lottery closed! winner selected')
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };

    const getLotteryPool = async () =&amp;gt; {

        try {
            const result = (await contract?.methods.getLotteryBalance().call());
           const pool =  web3.utils.fromWei(result, 'ether');
            setLotteryPool(pool);
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };
    const getLotteryBets = async () =&amp;gt; {

        try {
            const result = (await contract?.methods.getNumberOfPlayers().call()) as string;

            setLotteryBets(result);
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };
    const getLotteryWiner = async () =&amp;gt; {

        try {
            const result = (await contract?.methods.winner().call()) as string;

            setWinner(result);
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };
    const getLotteryStatus = async () =&amp;gt; {

        try {
            const result = (await contract?.methods.isOpened().call()) as boolean;

            setLotteryStatus(result);
        } catch (e) {
            console.log(e);
        } finally {
            return
        }
    };
    useEffect(() =&amp;gt; {
        getLotteryPool();
        getLotteryBets();
        getLotteryStatus();
        if(!lotteryStatus) {
            getLotteryWiner();
        }
    }, [lotteryPool, lotteryBets, lotteryStatus]);



    return (
        &amp;lt;View
            style={{
                height: "100%",
                padding: 10,
            }}
        &amp;gt;
            &amp;lt;View
                style={{
                    flex: 1,
                    margin: 1,
                    alignItems: "center",
                    justifyContent: "center",
                    borderRadius: 10,
                }}
            &amp;gt;
                &amp;lt;H4
                    additionalStyles={{
                        marginTop: -90,
                        fontFamily: "Inter-Medium",
                    }}
                &amp;gt;
                   Play and Win Lottery on Celo
                &amp;lt;/H4&amp;gt;
                &amp;lt;Container style={{ marginTop: 15 }}&amp;gt;
                    &amp;lt;MonoText
                        additionalStyles={{
                            textAlign: "center",
                            color: Colors.brand.brown,
                            fontSize: 13,
                        }}
                    &amp;gt;
                        {
                            `Lottery Pool: ${lotteryPool} cUSD\n`
                        }

                        {
                            "Lottery Price: 1 cUSD "
                        }
                    &amp;lt;/MonoText&amp;gt;
                &amp;lt;/Container&amp;gt;

                &amp;lt;Container style={{ marginBottom: 215 }}&amp;gt;
                    &amp;lt;MonoText
                        additionalStyles={{
                            textAlign: "center",
                            color: Colors.brand.brown,
                            fontSize: 13,
                        }}
                    &amp;gt;
                        {
                            `Lottery Bets:  ${lotteryBets} \n`
                        }

                        {
                          ` Latest Lottery Winner: ${winner} \n`
                        }
                         {
                            `Lottery Status: ${lotteryStatus ? 'Inprogress': 'Closed'} `
                        }
                    &amp;lt;/MonoText&amp;gt;
                    &amp;lt;Container style={{ marginTop: 15 }}&amp;gt;
                    &amp;lt;Button onPress={placeBets}   title={`Place Bets (1 cUSD)`}&amp;gt;&amp;lt;/Button&amp;gt;

                    &amp;lt;/Container&amp;gt;
                &amp;lt;/Container&amp;gt;

                &amp;lt;View style={{backgroundColor: 'yellow', marginTop: 1}}&amp;gt;
                    &amp;lt;Button onPress={closeLottery}  color={'red'} title={`close lottery`}&amp;gt;&amp;lt;/Button&amp;gt;

                &amp;lt;/View&amp;gt;
                &amp;lt;View  style={{marginTop: 5}}&amp;gt;
                    &amp;lt;Button onPress={openLottery}   title={`Open Lottery`}&amp;gt;&amp;lt;/Button&amp;gt;
                &amp;lt;/View&amp;gt;





            &amp;lt;/View&amp;gt;
        &amp;lt;/View&amp;gt;
    );
};

export default Home;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Here’s an overview of what’s happening in the code above&lt;/em&gt; : &lt;/p&gt;

&lt;p&gt;It is a component of a React Native application that communicates with our lottery smart contract, which is running on the Celo blockchain. It has a number of hooks and functions that handle contract interaction and control application state.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We import several React Native components along with custom ones like Container, Headings, and MonoText.&lt;/li&gt;
&lt;li&gt;In order to communicate with the Celo blockchain, we additionally import the LotteryContract and set up a web3 instance.&lt;/li&gt;
&lt;li&gt;The primary screen of the application is represented by the Home functional component, which is defined.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A few functions inside the Home component communicate with the smart contract such as:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;placeBets&lt;/em&gt;&lt;/strong&gt;: Calls the playLottery method while &lt;br&gt;
   passing the necessary information and value to send a &lt;br&gt;
   transaction to the smart contract to take part in the &lt;br&gt;
   lottery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invoking the &lt;strong&gt;&lt;em&gt;openLottery&lt;/em&gt;&lt;/strong&gt; method sends a &lt;br&gt;
   transaction to the smart contract to start the &lt;br&gt;
   lottery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invoking the &lt;strong&gt;&lt;em&gt;CloseLottery&lt;/em&gt;&lt;/strong&gt; method sends a &lt;br&gt;
   transaction to the smart contract to halt the lottery. &lt;br&gt;
   Additionally,when the lottery is closed, a warning is &lt;br&gt;
   displayed and the application status is updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These functions, &lt;strong&gt;&lt;em&gt;getLotteryPool&lt;/em&gt;&lt;/strong&gt;, &lt;br&gt;
  &lt;strong&gt;&lt;em&gt;getLotteryBets&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;getLotteryWinner&lt;/em&gt;&lt;/strong&gt;, and &lt;br&gt;
  &lt;strong&gt;&lt;em&gt;getLotteryStatus&lt;/em&gt;&lt;/strong&gt;, obtain data from the smart &lt;br&gt;
  contract, including the balance of the lottery pool, &lt;br&gt;
  the number of bets, the lottery winner, and the &lt;br&gt;
   lottery's status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The lottery pool balance, total number of bets, and lottery status are automatically fetched when the component mounts using the useEffect hook. It also retrieves the winner if the lottery is closed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To show and interact with the lottery data, the Home component creates a view with a variety of elements, including headings, text, and buttons.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, it functions as the user interface for a lottery application, enabling users to take part, examine lottery data, and conduct operations like placing bets, launching the lottery, and shutting it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sure you'd be seeing some errors already, don't panic- it's because we renamed the Docs file, next we'd have to change all instances where Docs was initiated / declared.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Adding React-Navigation Screen for the lottery
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Head over to the Navigation folder open the index.tsx folder and replace the code with the below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * If you are not familiar with React Navigation, refer to the "Fundamentals" guide:
 * https://reactnavigation.org/docs/getting-started
 *
 */
import { SafeAreaProvider } from "react-native-safe-area-context";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import {
    NavigationContainer,
    DefaultTheme,
    DarkTheme,
} from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import * as React from "react";
import { ColorSchemeName, Button } from "react-native";
import { useWalletConnect } from "@walletconnect/react-native-dapp";
import Colors from "../constants/Colors";
import useColorScheme from "../hooks/useColorScheme";
import ModalScreen from "../screens/ModalScreen";
import NotFoundScreen from "../screens/NotFoundScreen";
import { RootStackParamList, RootTabParamList } from "../types";
import LinkingConfiguration from "./LinkingConfiguration";
import LoginScreen from "../screens/LoginScreen";
// import deployedContracts from "@celo-composer/hardhat/deployments/hardhat_contracts.json";
import Account from "../screens/Account";
import Home from "../screens/Home";

export default function Navigation({
    colorScheme,
}: {
    colorScheme: ColorSchemeName;
}) {
    return (
        &amp;lt;NavigationContainer
            linking={LinkingConfiguration}
            theme={colorScheme === "dark" ? DarkTheme : DefaultTheme}
        &amp;gt;
            &amp;lt;RootNavigator /&amp;gt;
        &amp;lt;/NavigationContainer&amp;gt;
    );
}

/**
 * A root stack navigator is often used for displaying modals on top of all other content.
 * https://reactnavigation.org/docs/modal
 */
const Stack = createNativeStackNavigator&amp;lt;RootStackParamList&amp;gt;();

function RootNavigator() {
    const connector = useWalletConnect();
    return (
        &amp;lt;Stack.Navigator&amp;gt;
            {connector.connected ? (
                &amp;lt;Stack.Screen
                    name="Root"
                    // the Root path renders the component mentioned below.
                    component={BottomTabNavigator}
                    options={{ headerShown: false }}
                /&amp;gt;
            ) : (
                &amp;lt;Stack.Screen
                    name="Root"
                    component={LoginScreen}
                    options={{ headerShown: false }}
                /&amp;gt;
            )}
            &amp;lt;Stack.Screen
                name="NotFound"
                component={NotFoundScreen}
                options={{ title: "Oops!" }}
            /&amp;gt;
            &amp;lt;Stack.Group screenOptions={{ presentation: "modal" }}&amp;gt;
                &amp;lt;Stack.Screen name="Modal" component={ModalScreen} /&amp;gt;
            &amp;lt;/Stack.Group&amp;gt;
        &amp;lt;/Stack.Navigator&amp;gt;
    );
}

/**
 * A bottom tab navigator displays tab buttons on the bottom of the display to switch screens.
 * https://reactnavigation.org/docs/bottom-tab-navigator
 */
const BottomTab = createBottomTabNavigator&amp;lt;RootTabParamList&amp;gt;();

function BottomTabNavigator() {
    const theme = useColorScheme();

    // const contracts = deployedContracts["44787"]?.["alfajores"]?.contracts;

    return (
        &amp;lt;SafeAreaProvider&amp;gt;
            &amp;lt;BottomTab.Navigator
                // first screen visible after login
                initialRouteName="Docs"
                screenOptions={{
                    headerShown: false,
                    tabBarActiveTintColor: Colors["brand"].light.text,
                    tabBarActiveBackgroundColor:
                        Colors["brand"][theme].background,
                    tabBarLabelPosition: "beside-icon",
                    tabBarIconStyle: { display: "none" },
                    tabBarLabelStyle: { textAlign: "center" },
                }}
            &amp;gt;
                {/* &amp;lt;BottomTab.Screen
                    name="Greeter"
                    children={(props) =&amp;gt; (
                        &amp;lt;Greeter contractData={contracts.Greeter} {...props} /&amp;gt;
                    )}
                    options={() =&amp;gt; ({
                        title: "Greeter Contract",
                        headerShown: false,
                        // render icons if any
                        tabBarIcon: ({
                            focused: boolean,
                            color: string,
                            size: number,
                        }) =&amp;gt; {
                            return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
                        },
                        tabBarLabelPosition: "beside-icon",
                    })}
                /&amp;gt;
                &amp;lt;BottomTab.Screen
                    name="Storage"
                    children={(props) =&amp;gt; (
                        &amp;lt;Storage contractData={contracts.Storage} {...props} /&amp;gt;
                    )}
                    options={{
                        title: "Storage Contract",
                        headerShown: false,
                        tabBarIcon: ({
                            focused: boolean,
                            color: string,
                            size: number,
                        }) =&amp;gt; {
                            return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
                        },
                        tabBarLabelPosition: "beside-icon",
                    }}
                /&amp;gt; */}
                &amp;lt;BottomTab.Screen name="Home" component={Home} /&amp;gt;
                &amp;lt;BottomTab.Screen
                    name="Account"
                    component={Account}
                    options={() =&amp;gt; ({
                        title: "Account",
                        headerShown: false,
                        tabBarIcon: ({
                            focused: boolean,
                            color: string,
                            size: number,
                        }) =&amp;gt; {
                            return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
                        },
                        tabBarLabelPosition: "beside-icon",
                    })}
                /&amp;gt;
            &amp;lt;/BottomTab.Navigator&amp;gt;
        &amp;lt;/SafeAreaProvider&amp;gt;
    );
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;code overview&lt;/strong&gt;: We are setting the Navigation and the screens to be displayed on our mobile lottery dApp (remember we edited the Docs file to =&amp;gt; Home file).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We import necessary dependencies, components, and screens from various modules.&lt;/li&gt;
&lt;li&gt;The Navigation component is the entry point that wraps the entire app's navigation logic. It uses NavigationContainer from React Navigation and determines the theme based on the provided color scheme.&lt;/li&gt;
&lt;li&gt;Inside the Navigation component, there is a RootNavigator component defined as a stack navigator. It checks if the user is connected via WalletConnect. If connected, it renders the BottomTabNavigator component; otherwise, it renders the LoginScreen component.&lt;/li&gt;
&lt;li&gt;The RootNavigator also includes a NotFoundScreen component for handling routes not found in the navigation stack and a ModalScreen component for rendering modal screens.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The BottomTabNavigator component represents the bottom tab navigation within the app. It uses the createBottomTabNavigator function to create the navigator.It includes screens like Home and Account to display the main functionality of the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each screen within the BottomTabNavigator has options for customizing its appearance, such as the title, icon, and label position.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, the code sets up the navigation structure for the app, allowing users to navigate between screens using a bottom tab navigation pattern and handle different scenarios such as authentication and error handling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Also open the linkConfigurations.ts file and replace it with the code below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Learn more about deep linking with React Navigation
 * https://reactnavigation.org/docs/deep-linking
 * https://reactnavigation.org/docs/configuring-links
 */

import { LinkingOptions } from "@react-navigation/native";
import * as Linking from "expo-linking";

import { RootStackParamList } from "../types";

const linking: LinkingOptions&amp;lt;RootStackParamList&amp;gt; = {
    prefixes: [Linking.makeUrl("/")],
    config: {
        screens: {
            Root: {
                screens: {
                    Docs: {
                        screens: {
                            Home: "home",
                        },
                    },
                    Account: {
                        screens: {
                            Account: "account",
                        },
                    },
                },
            },
            Modal: "modal",
            NotFound: "*",
        },
    },
};

export default linking;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Testing our Celo Lottery Mobile DApp
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make sure you have the &lt;a href="https://play.google.com/store/apps/details?id=org.celo.mobile.alfajores&amp;amp;hl=en_IN&amp;amp;pli=1"&gt;Alfajores app &lt;/a&gt;installed in your mobile device. and also create a wallet and collect Testnet funds from the &lt;a href="https://faucet.celo.org/alfajores"&gt;faucet&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have the &lt;a href="https://play.google.com/store/apps/details?id=host.exp.exponent&amp;amp;hl=en&amp;amp;gl=US"&gt;Expo Go app&lt;/a&gt; installed on your mobile device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your terminal and enter the following command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx expo start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Scan the QR code using your Expo Go application to test the mobile app. &lt;br&gt;
&lt;strong&gt;NB&lt;/strong&gt;: Make sure your pc and mobile device are connected to one Network.&lt;br&gt;
&lt;strong&gt;Expected output&lt;/strong&gt;: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_3g8TG-s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ptgqz1a9tkbumpmif3l.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_3g8TG-s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ptgqz1a9tkbumpmif3l.jpeg" alt="Image description" width="484" height="955"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go ahead and Test our Lottery app: &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Connect Your wallet&lt;/li&gt;
&lt;li&gt;Place Lottery Bet as many times as you want as far as you have enough Testnet funds, you could also use multiple devices to make the lottery competitive.&lt;/li&gt;
&lt;li&gt;Close Lottery- To select a winner and send funds to the winner from the Prize Pool.&lt;/li&gt;
&lt;li&gt;reOpend the Lottery.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Have any Question reply to this post or DM me on &lt;a href="https://twitter.com/gabe_temtsen"&gt;Twitter&lt;/a&gt; for support&lt;/em&gt;&lt;/p&gt;

</description>
      <category>web3</category>
      <category>celo</category>
      <category>gabrieltemtsen</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a Basic Smart Contract and dApp on Celo</title>
      <dc:creator>Gabriel Temsten</dc:creator>
      <pubDate>Fri, 10 Mar 2023 07:28:59 +0000</pubDate>
      <link>https://dev.to/gabrieltemtsen/building-a-basic-smart-contract-and-dapp-on-celo-3leo</link>
      <guid>https://dev.to/gabrieltemtsen/building-a-basic-smart-contract-and-dapp-on-celo-3leo</guid>
      <description>&lt;p&gt;Writing a smart contract can be a daunting task for beginners, but with the right tools and guidance, it can be made simple. In this tutorial, we will walk through how to write a basic smart contract, deploy it on the Celo testnet, and create a decentralized application (dApp) to interact with the contract.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A82FmmLn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oqv6sg0dqiwf6lnbt5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A82FmmLn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oqv6sg0dqiwf6lnbt5w.png" alt="Image description" width="880" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Basic programming concepts and JavaScript proficiency&lt;br&gt;
Node.js installed on your computer&lt;br&gt;
Command line experience&lt;br&gt;
Celo wallet set up to obtain testnet tokens&lt;br&gt;
Familiarity with Vue.js and TypeScript&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Initialize and Install Hardhat Project&lt;/p&gt;

&lt;p&gt;The first step is to initialize and install a Hardhat project, which is a development environment for building and testing smart contracts on Ethereum and other EVM-compatible blockchains. To do this, you can follow the official Hardhat documentation to install it on your machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Write the Smart Contract Once you have set up your Hardhat project, you can start writing your smart contract. For this tutorial, we will create a basic contract called "HelloWorld.sol" that has two public variables: text and name. The user can set the text they want and also set their name on the contract.&lt;/p&gt;

&lt;p&gt;To create the contract, you can create a new file called "HelloWorld.sol" in the contracts folder of your Hardhat project and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity ^0.8.0;

contract HelloWorld {
  string public text;
  string public name;

  function setText(string memory _text) public {
    text = _text;
  }

  function setName(string memory _name) public {
    name = _name;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This contract has two public variables, text and name, and two public functions, setText and setName, which allow the user to set the values of the variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Deploy the Contract on the Celo Testnet&lt;/p&gt;

&lt;p&gt;After writing the smart contract, the next step is to deploy it on the Celo testnet. To do this, you can follow the official Celo &lt;a href="https://docs.celo.org/developer/deploy/hardhat"&gt;documentation&lt;/a&gt; to set up your Celo account and connect it to your Hardhat project: &lt;br&gt;
hardhatconfig.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mport { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import * as dotenv from 'dotenv'
dotenv.config();

const PRIVATE_KEY = process.env.PRIVATE_KEY

const config: HardhatUserConfig = {
  solidity: "0.8.17",
  networks:{
    alfajores: {
      url: `https://alfajores-forno.celo-testnet.org`,
      accounts: [PRIVATE_KEY]
    },
  }
};

export default config;

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

&lt;/div&gt;



&lt;p&gt;Once you have connected your Celo account to your Hardhat project, you can deploy your contract to the Alfojores Celo network by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run --network alfajores scripts/deploy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will deploy your contract to the Alfojores Celo network and give you the address of the deployed contract(make sure to copy and save the contract address).&lt;/p&gt;

&lt;p&gt;**Step 4: **Create the dApp for Contract Interaction&lt;/p&gt;

&lt;p&gt;The final step is to create a dApp for interacting with the deployed smart contract. For this tutorial, we will create a simple dApp using Vue 3 and TypeScript.&lt;/p&gt;

&lt;p&gt;To create the dApp, you can follow the official Vue &lt;a href="https://vuejs.org/guide/quick-start.html#creating-a-vue-application"&gt;documentation&lt;/a&gt; to set up a new Vue project with TypeScript. &lt;br&gt;
Use this command to Quick start a Vue 3 Appliction&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vue@latest
//select Typescript--useRouter--piniaStore--Eslint--Preetier
npm install bootstrap ethers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the source code h&lt;a href="https://github.com/gabrieltemtsen/celo-dApp/tree/main/my-dapp"&gt;&lt;/a&gt;ere&lt;/p&gt;

&lt;p&gt;After Initiating you Vue application, navigate to src/main.ts to add bootstrap&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'bootstrap/dist/css/bootstrap.min.css'

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

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Step 5: *&lt;/em&gt; Navigate to src/views/HomeView.vue replace the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup lang="ts"&amp;gt;
import { onMounted, reactive, ref, watchEffect } from 'vue'
import { ethers } from 'ethers'
import * as HelloWorldABI from '../contract/HelloWorld.json'

const { ethereum } = window
const contractAddress = '0xF112ba99A3586Ac4b5dA4148c0a03ADD2C6BFA0a'

const setAddress = reactive({
  address: ''
})
const setTexts = reactive({
  setText: '',
  setName: ''
})

const getTexts = reactive({
  getText: '',
  getName: ''
})

const networName = reactive({
  network: ''
})

let connected = ref(false)
onMounted(() =&amp;gt; {
  if (!ethereum) {
    connected.value = false
    alert('Make sure you have MetaMask Connected!')
    return
  }
  watchEffect(() =&amp;gt; {
    getCurrentText()
    getCurrentName()
  })
})

//connect your Metamask wallet on connect button click
const connectWallet = async () =&amp;gt; {
  try {
    // Check if MetaMask is installed
    if (!ethereum) {
      alert('Make sure you have MetaMask Connected!')
      return
    }

    // Get user Metamask Ethereum wallet address
    const accounts = await ethereum.request({
      method: 'eth_requestAccounts'
    })
    setAddress.address = accounts[0]
    const provider = new ethers.providers.Web3Provider(ethereum)
    const network = await provider.getNetwork()
    networName.network = network.name

    console.log(accounts[0])
    connected.value = true
  } catch (error) {
    console.log(error)
  }
}
const getCurrentText = async () =&amp;gt; {
  try {
    // Check if User already connected a wallet
    if (ethereum) {
      const provider = new ethers.providers.Web3Provider(ethereum)
      const signer = provider.getSigner()

      // Create a contract object
      const contractInstance = new ethers.Contract(contractAddress, HelloWorldABI.abi, signer)

      let text = await contractInstance.getText()
      getTexts.getText = text
    }
  } catch (error) {
    console.log(error)
  }
}
const getCurrentName = async () =&amp;gt; {
  try {
    // Check if User already connected a wallet
    if (ethereum) {
      const provider = new ethers.providers.Web3Provider(ethereum)
      const signer = provider.getSigner()
      // Create a contract object
      const contractInstance = new ethers.Contract(contractAddress, HelloWorldABI.abi, signer)
      let text = await contractInstance.getName()
      getTexts.getName = text
    }
  } catch (error) {
    console.log(error)
  }
}
const setText = async () =&amp;gt; {
  try {
    // Check if User already connected a wallet
    if (ethereum) {
      const provider = new ethers.providers.Web3Provider(ethereum)
      const signer = provider.getSigner()

      // Create a contract object
      const contractInstance = new ethers.Contract(contractAddress, HelloWorldABI.abi, signer)

      const setText = await contractInstance.setText(setTexts.setText)
      // Wait for the transaction to be mined
      await setText.wait()
      watchEffect(() =&amp;gt; {
        getCurrentText()
        getCurrentName()
      })
      // Display a success message to the user
      alert('Txn successful!')
    }
  } catch (error) {
    console.log(error)
  }
}

const setName = async () =&amp;gt; {
  try {
    // Check if User already connected a wallet
    if (ethereum) {
      const provider = new ethers.providers.Web3Provider(ethereum)
      const signer = provider.getSigner()

      // Create a contract object
      const contractInstance = new ethers.Contract(contractAddress, HelloWorldABI.abi, signer)

      const setName = await contractInstance.setName(setTexts.setName)
      // Wait for the transaction to be mined
      await setName.wait()
      // Display a success message to the user
      alert('Txn successful!')
      watchEffect(() =&amp;gt; {
        getCurrentText()
        getCurrentName()
      })
    }
  } catch (error) {
    console.log(error)
  }
}
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
  &amp;lt;main&amp;gt;
    &amp;lt;div class="text-center"&amp;gt;
      &amp;lt;img class="text-center img-thumbnail" src="../assets/celo.png" alt="" /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="text-success textcenter"&amp;gt;
      NetWork: &amp;lt;strong&amp;gt;{{ networName.network }}&amp;lt;/strong&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;nav class="navbar navbar-expand-lg navbar-dark bg-dark mt-5 pt-1 mb-1"&amp;gt;
      &amp;lt;div class="container-fluid"&amp;gt;
        &amp;lt;a class="navbar-brand" href="#"&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        &amp;gt;
          &amp;lt;span class="navbar-toggler-icon"&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;/button&amp;gt;
        &amp;lt;div class="collapse navbar-collapse" id="navbarSupportedContent"&amp;gt;
          &amp;lt;ul class="navbar-nav me-auto mb-2 mb-lg-0"&amp;gt;
            &amp;lt;li class="nav-item"&amp;gt;
              &amp;lt;a class="nav-link active" aria-current="page" href="#"&amp;gt;Home&amp;lt;/a&amp;gt;
            &amp;lt;/li&amp;gt;
          &amp;lt;/ul&amp;gt;

          &amp;lt;button v-if="!connected" @click="connectWallet" class="btn btn-outline-success"&amp;gt;
            Connect Wallet
          &amp;lt;/button&amp;gt;
          &amp;lt;button v-else class="btn btn-success"&amp;gt;{{ setAddress.address }}&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/nav&amp;gt;
  &amp;lt;/main&amp;gt;

  &amp;lt;div class="py-5"&amp;gt;
    &amp;lt;div class="card"&amp;gt;
      &amp;lt;label class="card-body" for=""&amp;gt;BLOCKCHAIN-DATA: &amp;lt;/label&amp;gt;
      &amp;lt;p class="card-body"&amp;gt;
        Current Text: &amp;lt;strong&amp;gt; {{ getTexts.getText }}&amp;lt;/strong&amp;gt;
      &amp;lt;/p&amp;gt;
      &amp;lt;p class="card-body"&amp;gt;
        Current Name: &amp;lt;strong&amp;gt; {{ getTexts.getName }}&amp;lt;/strong&amp;gt;
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="py-5 global-container"&amp;gt;
      &amp;lt;div class="card login-form"&amp;gt;
        &amp;lt;div class="card-body"&amp;gt;
          &amp;lt;h3 class="card-title text-center"&amp;gt;Contract Interaction&amp;lt;/h3&amp;gt;
          &amp;lt;div class="card-text"&amp;gt;
            &amp;lt;form&amp;gt;
              &amp;lt;div class="form-group"&amp;gt;
                &amp;lt;label for="exampleInputEmail1"&amp;gt;Set Text&amp;lt;/label&amp;gt;
                &amp;lt;input
                  v-model="setTexts.setText"
                  type="text"
                  class="form-control form-control-sm"
                /&amp;gt;
                &amp;lt;button @click.prevent="setText" class="btn btn-dark py-1 mt-2"&amp;gt;Call&amp;lt;/button&amp;gt;
              &amp;lt;/div&amp;gt;
              &amp;lt;div class="form-group"&amp;gt;
                &amp;lt;label for="exampleInputEmail1"&amp;gt;Set Name&amp;lt;/label&amp;gt;
                &amp;lt;input
                  v-model="setTexts.setName"
                  type="text"
                  class="form-control form-control-sm"
                /&amp;gt;
                &amp;lt;button @click.prevent="setName" class="btn btn-dark py-1 mt-2"&amp;gt;Call&amp;lt;/button&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/form&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;style&amp;gt;
.global-container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #141313;
}

.form {
  padding-top: 10px;
  font-size: 14px;
  margin-top: 30px;
}

.card-title {
  font-weight: 300;
}

.login-form {
  width: 330px;
  margin: 20px;
}

.sign-up {
  text-align: center;
  padding: 20px 0 0;
}

.alert {
  margin-bottom: -30px;
  font-size: 13px;
  margin-top: 20px;
}
&amp;lt;/style&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Edit the styling to the best of your Taste(src/assets/main.ts).&lt;/em&gt;&lt;br&gt;
*&lt;em&gt;Note: *&lt;/em&gt; &lt;br&gt;
Change the smartContract address in src/views/HomeView.vue with the contract address you got from deploying the HelloWorld contract.&lt;/p&gt;

&lt;p&gt;Copy the contract ABI(helloWorld.json) from the contract folder in step 1. then create a folder in your vue application(src/) named contract then paste the json file so you can import it to HomeView.vue for contract interaction.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Summary of the functions: *&lt;/em&gt;&lt;br&gt;
&lt;em&gt;OnMounted()&lt;/em&gt; : To initiate a function call when the page reloads.&lt;br&gt;
&lt;em&gt;connectWallet()&lt;/em&gt;: To connect a user, using MetaMask.&lt;br&gt;
&lt;em&gt;getCurrentText()&lt;/em&gt;: To get the updated text from the contract we deployed earlier.&lt;br&gt;
&lt;em&gt;getCurrentName()&lt;/em&gt;: To get the name from the contract earlier deployed.&lt;br&gt;
&lt;em&gt;setText()&lt;/em&gt;: To send the transaction to the blockchain(celo Alfajores network) containing the text gotten from the form as an argument.&lt;br&gt;
&lt;em&gt;setName()&lt;/em&gt;: To send the transaction to the blockchain(celo Alfajores network) containig the name gotten from the form as an argument.&lt;br&gt;
View the live project &lt;a href="https://celo-dapp.netlify.app/"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>celo</category>
      <category>solidity</category>
      <category>web3</category>
      <category>vue</category>
    </item>
  </channel>
</rss>
