This frontend connects to the ApartmentRental smart contract, allowing landlords and tenants to interact with the lease agreement.
Read this first: Smart Contract for Apartment Rental & Payments (Solidity)
1. Setup the Project
bash
npx create-react-app apartment-rental-dapp cd apartment-rental-dapp npm install web3 @metamask/detect-provider @chakra-ui/react ethers
2. Key Components
- Connect Wallet (MetaMask)
- Landlord Dashboard (Create lease, refund deposit)
- Tenant Dashboard (Pay rent, terminate lease)
3. Full Frontend Code
App.js (Main Component)
jsx
import { useState, useEffect } from 'react';
import { ChakraProvider, Button, Box, Heading, Input, Text, VStack, HStack, Alert, AlertIcon } from '@chakra-ui/react';
import Web3 from 'web3';
import ApartmentRentalABI from './ApartmentRentalABI.json'; // Import ABI
function App() {
const [web3, setWeb3] = useState(null);
const [account, setAccount] = useState('');
const [contract, setContract] = useState(null);
const [isLandlord, setIsLandlord] = useState(false);
const [isTenant, setIsTenant] = useState(false);
const [leaseDetails, setLeaseDetails] = useState(null);
// Contract Address (Replace with your deployed address)
const CONTRACT_ADDRESS = "0x123...YourContractAddress";
// Initialize Web3 and Contract
useEffect(() => {
const initWeb3 = async () => {
if (window.ethereum) {
const web3Instance = new Web3(window.ethereum);
setWeb3(web3Instance);
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
setAccount(accounts[0]);
const contractInstance = new web3Instance.eth.Contract(
ApartmentRentalABI,
CONTRACT_ADDRESS
);
setContract(contractInstance);
// Check if user is landlord or tenant
const landlord = await contractInstance.methods.landlord().call();
setIsLandlord(accounts[0].toLowerCase() === landlord.toLowerCase());
const tenant = await contractInstance.methods.tenant().call();
setIsTenant(accounts[0].toLowerCase() === tenant.toLowerCase());
// Load lease details
if (tenant !== "0x0000000000000000000000000000000000000000") {
const details = {
rentAmount: await contractInstance.methods.rentAmount().call(),
securityDeposit: await contractInstance.methods.securityDeposit().call(),
leaseStart: await contractInstance.methods.leaseStart().call(),
leaseEnd: await contractInstance.methods.leaseEnd().call(),
isActive: await contractInstance.methods.isLeaseActive().call(),
};
setLeaseDetails(details);
}
} else {
alert("Please install MetaMask!");
}
};
initWeb3();
}, []);
// Sign Lease (Tenant)
const signLease = async () => {
const value = Web3.utils.toWei(
(leaseDetails.rentAmount + leaseDetails.securityDeposit).toString(),
'ether'
);
await contract.methods.signLease().send({ from: account, value });
alert("Lease signed successfully!");
};
// Pay Rent (ETH)
const payRent = async (month) => {
const value = Web3.utils.toWei(leaseDetails.rentAmount.toString(), 'ether');
await contract.methods.payRent(month).send({ from: account, value });
alert(`Rent for month ${month} paid!`);
};
// Refund Deposit (Landlord)
const refundDeposit = async (deductions) => {
await contract.methods.refundDeposit(deductions).send({ from: account });
alert("Deposit refunded!");
};
// Terminate Lease
const terminateLease = async () => {
await contract.methods.terminateLease().send({ from: account });
alert("Lease terminated!");
};
return (
<ChakraProvider>
<Box p={8}>
<Heading mb={6}>🏠 Decentralized Apartment Rental</Heading>
{!account ? (
<Button onClick={() => window.ethereum.request({ method: 'eth_requestAccounts' })}>
Connect MetaMask
</Button>
) : (
<VStack spacing={6} align="start">
<Text>Connected as: {account}</Text>
{isLandlord && (
<Box borderWidth="1px" p={4} borderRadius="md">
<Heading size="md">👔 Landlord Dashboard</Heading>
{leaseDetails && leaseDetails.isActive ? (
<Button mt={2} onClick={() => terminateLease()}>
Terminate Lease (Penalty: 1 Month Rent)
</Button>
) : (
<Button mt={2} onClick={() => refundDeposit(0)}>
Refund Deposit
</Button>
)}
</Box>
)}
{isTenant && leaseDetails && (
<Box borderWidth="1px" p={4} borderRadius="md">
<Heading size="md">👤 Tenant Dashboard</Heading>
<Text>Rent: {Web3.utils.fromWei(leaseDetails.rentAmount, 'ether')} ETH/month</Text>
<Text>Lease End: {new Date(leaseDetails.leaseEnd * 1000).toLocaleDateString()}</Text>
<Button mt={2} onClick={() => payRent(1)}>Pay Rent (ETH)</Button>
<Button mt={2} onClick={() => terminateLease()}>Terminate Lease (Lose Deposit)</Button>
</Box>
)}
{!isLandlord && !isTenant && (
<Alert status="info">
<AlertIcon />
You are not the landlord or tenant for this lease.
</Alert>
)}
</VStack>
)}
</Box>
</ChakraProvider>
);
}
export default App;
4. Contract ABI (ApartmentRentalABI.json)
Paste the ABI from Remix/your compiled contract:
json
[
{
"inputs": [
{"internalType": "uint256","name": "_rentAmount","type": "uint256"},
{"internalType": "uint256","name": "_securityDeposit","type": "uint256"},
{"internalType": "uint256","name": "_leaseDurationMonths","type": "uint256"}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
// ... (Include ALL ABI functions from your contract)
]
5. Key Features
✅ MetaMask Wallet Integration
✅ Landlord & Tenant Views
✅ ETH Payments (Easy to add USDT with payRentERC20)
✅ Responsive UI with Chakra UI
6. How to Run
bash
npm start
Open http://localhost:3000 and connect MetaMask.

