This module walks you through building a simple decentralized application (dApp) on Rootstock. You'll integrate a deployed smart contract with a frontend using Ethers.js and a wallet provider (MetaMask or Rabby). By the end, you'll have a fully functional dApp where users can read/write data on the Rootstock Testnet.

## Overview

You will build a minimal dApp that:
- Connects to Rootstock Testnet
- Lets users connect their wallet
- Interacts with a simple smart contract (HelloRootstock.sol)
- Reads stored data from the blockchain
- Updates contract state using a transaction

This is the first "real" end-to-end Rootstock project — contract, deployment, and frontend.

## Prerequisites

Before starting, ensure you have:
- A deployed contract on Rootstock Testnet (from the previous module)
- Node.js installed
- Basic familiarity with React or Next.js
- MetaMask or Rabby wallet configured for Rootstock Testnet
- Your contract's:
  - address
  - ABI
  - [Testnet RPC](https://rpc.rootstock.io/)

## Project Setup (Next.js)

Create a fresh project:

```bash
npx create-next-app rootstock-dApp
cd rootstock-dApp
npm install ethers
```

This gives you a clean React/Next environment with zero noise.

## Add Your Contract ABI

Inside your project, create:
```
/src/abi/HelloRootstock.json
```

Paste your contract ABI from the compiled Hardhat/Foundry output:

```json
[
  {
    "inputs": [],
    "name": "message",
    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [{ "internalType": "string", "name": "_msg", "type": "string" }],
    "name": "setMessage",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]
```

## Wallet Connection (Ethers.js)

Create a reusable wallet connection hook:

`/src/hooks/useWallet.js`

```javascript


export default function useWallet() {
  const [account, setAccount] = useState(null);

  async function connect() {
    if (!window.ethereum) return alert("No wallet found");

    const accounts = await window.ethereum.request({
      method: "eth_requestAccounts",
    });

    setAccount(accounts[0]);
  }

  const provider = typeof window !== "undefined" && window.ethereum
    ? new ethers.BrowserProvider(window.ethereum)
    : null;

  return { account, connect, provider };
}
```

## Contract Interaction Code

Create a helper file:

`/src/lib/contract.js`

```javascript


const CONTRACT_ADDRESS = "YOUR_DEPLOYED_CONTRACT_ADDRESS";
const RPC_URL = "https://public-node.testnet.rsk.co";

export function getReadProvider() {
  return new ethers.JsonRpcProvider(RPC_URL);
}

export function getContract(provider) {
  return new ethers.Contract(CONTRACT_ADDRESS, abi, provider);
}
```

## dApp UI (Read + Write)

Modify your homepage:

`/src/app/page.js`

```jsx
"use client";




export default function Home() {
  const { account, connect, provider } = useWallet();

  const [message, setMessage] = useState("");
  const [newMessage, setNewMessage] = useState("");

  async function loadMessage() {
    const readProvider = getReadProvider();
    const contract = getContract(readProvider);

    const msg = await contract.message();
    setMessage(msg);
  }

  async function updateMessage() {
    if (!provider) return alert("Wallet not connected");

    const signer = await provider.getSigner();
    const contract = getContract(signer);

    const tx = await contract.setMessage(newMessage);
    await tx.wait();

    loadMessage();
  }

  useEffect(() => {
    loadMessage();
  }, []);

  return (
    <main style={{ padding: 40 }}>
      <h1>Hello Rootstock dApp</h1>

      {account ? (
        <p>Connected: {account}</p>
      ) : (
        <button onClick={connect}>Connect Wallet</button>
      )}

      <h2>Stored Message:</h2>
      <p>{message}</p>

      <input
        value={newMessage}
        onChange={(e) => setNewMessage(e.target.value)}
        placeholder="Enter new message"
      />

      <button onClick={updateMessage}>Update Message</button>
    </main>
  );
}
```

## Run the dApp

Start the local server:

```bash
npm run dev
```

Open:
```
http://localhost:3000
```

You should now be able to:
- Connect wallet
- Read message from Rootstock Testnet
- Write/update on-chain
- See the value update live

## Troubleshooting

### ❗ Wallet doesn't connect
Ensure Rootstock Testnet is configured in your MetaMask:
- Chain ID: 31
- Currency: trBTC
- RPC: https://public-node.testnet.rsk.co

### ❗ Transaction fails
Check your Testnet balance:
- You must have trBTC from the faucet (covered earlier).

### ❗ Read works but write doesn't
Your wallet may not be connected as signer.
Verify the provider:

```javascript
const signer = await provider.getSigner();
```

For further practice, check out the [dApp Tutorial](https://hackernoon.com/how-to-build-dApp-on-rootstock-with-nextjs-typescript-and-solidity).

## Summary

In this module you learned how to:
- Build a simple Rootstock dApp using Next.js
- Connect a wallet using Ethers.js
- Read contract state from Rootstock Testnet
- Send transactions to update contract data
- Structure frontend + blockchain interactions cleanly

This module transitions a learner from contract developer to full dApp builder — the skillset required for all advanced Rootstock applications.
