diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
index 7c1c80b..99e31cc 100644
Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ
diff --git a/packages/nextjs/app/(app)/dashboard/page.tsx b/packages/nextjs/app/(app)/dashboard/page.tsx
index c05762d..c0fc95f 100644
--- a/packages/nextjs/app/(app)/dashboard/page.tsx
+++ b/packages/nextjs/app/(app)/dashboard/page.tsx
@@ -1,5 +1,8 @@
import { Metadata } from "next";
import { ClaimRoleCard } from "~~/components/dashboard/ClaimRoleCard";
+import { DataRegistry } from "~~/components/dashboard/DataRegistry";
+import MineralToken from "~~/components/dashboard/MineralToken";
+import { SupplyChain } from "~~/components/dashboard/SupplyChain";
export const metadata: Metadata = {
title: "Dashboard",
@@ -7,8 +10,12 @@ export const metadata: Metadata = {
export default function DashboardPage() {
return (
-
+
+
+
+
);
}
+
diff --git a/packages/nextjs/components/dashboard/ClaimRoleCard.tsx b/packages/nextjs/components/dashboard/ClaimRoleCard.tsx
index 735d986..56d1652 100644
--- a/packages/nextjs/components/dashboard/ClaimRoleCard.tsx
+++ b/packages/nextjs/components/dashboard/ClaimRoleCard.tsx
@@ -1,8 +1,23 @@
+/* eslint-disable prettier/prettier */
"use client";
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select";
+import { useState } from "react";
+import { ethers } from "ethers";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "../ui/select";
+import ParticipantsABI from "../../contracts/Participants.json"; // Adjust the path as needed
-const roles = [
+type Role = {
+ label: string;
+ role: string;
+};
+
+const roles: Role[] = [
{ label: "Refiner", role: "REFINER" },
{ label: "Miner", role: "MINER" },
{ label: "Transporter", role: "TRANSPORTER" },
@@ -11,25 +26,72 @@ const roles = [
];
export const ClaimRoleCard: React.FC = () => {
+ const [selectedRole, setSelectedRole] = useState
(null);
+
+ const handleRoleChange = (role: string) => {
+ setSelectedRole(role);
+ };
+
+ const handleClaimRole = async (): Promise => {
+ if (!selectedRole) return;
+
+ try {
+ if (!window.ethereum) {
+ alert("Please install MetaMask or any other EVM-wallet");
+ return;
+ }
+
+ const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const signer = provider.getSigner();
+
+ const contractAddress = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512";
+ const contract = new ethers.Contract(
+ contractAddress,
+ ParticipantsABI.abi,
+ signer
+ );
+
+ const roleBytes32 = ethers.utils.formatBytes32String(selectedRole);
+
+ const tx = await contract.registerParticipant(
+ await signer.getAddress(),
+ "Participant's name",
+ "Participant's location",
+ roleBytes32
+ );
+
+ await tx.wait();
+ alert("Role claimed successfully!");
+ } catch (error: any) {
+ console.error("Error claiming role:", error);
+ alert("An error occurred while claiming the role.");
+ }
+ };
+
return (
-
+
Congratulations!
- Claim a role that will be used to identify you in Stoneproof platform.
+ Claim a role that will be used to identify you on the Stoneproof platform.
-
);
};
diff --git a/packages/nextjs/components/dashboard/DataRegistry.tsx b/packages/nextjs/components/dashboard/DataRegistry.tsx
new file mode 100644
index 0000000..4fb8b5c
--- /dev/null
+++ b/packages/nextjs/components/dashboard/DataRegistry.tsx
@@ -0,0 +1,76 @@
+/* eslint-disable prettier/prettier */
+"use client";
+
+import { useState, useEffect } from "react";
+import { ethers } from "ethers";
+import DataRegistryABI from "../../contracts/DataRegistry.json";
+type DataRecord = {
+ id: string;
+ description: string;
+ owner: string;
+};
+
+export const DataRegistry: React.FC = () => {
+ const [records, setRecords] = useState
([]);
+ const [isLoading, setIsLoading] = useState(true);
+
+ const fetchDataRecords = async () => {
+ setIsLoading(true);
+ try {
+ if (!window.ethereum) {
+ alert("Please install MetaMask or any other EVM-wallet");
+ return;
+ }
+
+ const provider = new ethers.providers.Web3Provider(window.ethereum);
+ const signer = provider.getSigner();
+ const contractAddress = "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0";
+ const contract = new ethers.Contract(contractAddress, DataRegistryABI.abi, signer);
+
+ const recordsData = await contract.getAllRecords();
+ const formattedRecords = recordsData.map((record: any) => ({
+ id: record.id,
+ description: record.description,
+ owner: record.owner,
+ }));
+
+ setRecords(formattedRecords);
+ } catch (error) {
+ console.error("Error fetching records:", error);
+ alert("An error occurred while fetching records.");
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchDataRecords();
+ }, []);
+
+ return (
+
+
Data Records
+
+ View and manage data entries on the StoneProof platform.
+
+ {isLoading ? (
+
Loading records...
+ ) : (
+
+ {records.map((record) => (
+ -
+
{record.description}
+ Owned by: {record.owner}
+
+ ))}
+
+ )}
+
+
+ );
+};
diff --git a/packages/nextjs/components/dashboard/MineralToken.tsx b/packages/nextjs/components/dashboard/MineralToken.tsx
new file mode 100644
index 0000000..e38de0b
--- /dev/null
+++ b/packages/nextjs/components/dashboard/MineralToken.tsx
@@ -0,0 +1,99 @@
+"use client";
+
+import React, { ChangeEvent, useState } from "react";
+// Import ABI correctly
+import MineralTokenABI from "../../contracts/MineralToken.json";
+import { ethers, providers } from "ethers";
+
+// Props interface for optional address override
+interface ClaimRoleCardProps {
+ contractAddress?: string;
+}
+
+// Default contract address used if not provided via props
+const DEFAULT_CONTRACT_ADDRESS = "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9";
+
+const ClaimRoleCard: React.FC = ({ contractAddress = DEFAULT_CONTRACT_ADDRESS }) => {
+ // State hooks with proper types
+ const [role, setRole] = useState("");
+ const [account, setAccount] = useState("");
+ const [statusMessage, setStatusMessage] = useState("");
+
+ // Helper function to get the contract instance
+ const getContract = (): Contract => {
+ const provider = new providers.Web3Provider(window.ethereum as any);
+ const signer = provider.getSigner();
+ return new ethers.Contract(contractAddress, MineralTokenABI.abi, signer);
+ };
+
+ // Grant role function
+ const handleGrantRole = async () => {
+ try {
+ const contract = getContract();
+ const tx = await contract.grantRole(ethers.utils.formatBytes32String(role), account);
+ setStatusMessage(`Transaction submitted: ${tx.hash}`);
+ await tx.wait();
+ setStatusMessage(`Transaction confirmed: ${tx.hash}`);
+ } catch (error: any) {
+ setStatusMessage(`Error: ${error.message}`);
+ }
+ };
+
+ // Revoke role function
+ const handleRevokeRole = async () => {
+ try {
+ const contract = getContract();
+ const tx = await contract.revokeRole(ethers.utils.formatBytes32String(role), account);
+ setStatusMessage(`Transaction submitted: ${tx.hash}`);
+ await tx.wait();
+ setStatusMessage(`Transaction confirmed: ${tx.hash}`);
+ } catch (error: any) {
+ setStatusMessage(`Error: ${error.message}`);
+ }
+ };
+
+ // Handle input changes with reusable setter function
+ const handleChange =
+ (setter: React.Dispatch>) => (event: ChangeEvent) => {
+ setter(event.target.value);
+ };
+
+ return (
+
+
Manage Roles
+
+
+
+
+
+
+
+
+ {statusMessage &&
{statusMessage}
}
+
+ );
+};
+
+export default ClaimRoleCard;
diff --git a/packages/nextjs/components/dashboard/SupplyChain.tsx b/packages/nextjs/components/dashboard/SupplyChain.tsx
new file mode 100644
index 0000000..c054423
--- /dev/null
+++ b/packages/nextjs/components/dashboard/SupplyChain.tsx
@@ -0,0 +1,152 @@
+/* eslint-disable prettier/prettier */
+"use client";
+
+import React, { useState, ChangeEvent } from "react";
+import { ethers, Contract, providers } from "ethers";
+import SupplyChainABI from "../../contracts/SupplyChain.json";
+
+const SupplyChainAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
+
+interface BatchDetails {
+ id: ethers.BigNumber;
+ owner: string;
+ location: string;
+ status: string;
+ timestamp: number;
+}
+
+export const SupplyChain: React.FC = () => {
+ const [location, setLocation] = useState('');
+ const [batchId, setBatchId] = useState('');
+ const [newOwner, setNewOwner] = useState('');
+ const [newStatus, setNewStatus] = useState('');
+ const [batchDetails, setBatchDetails] = useState(null);
+
+ const provider = new providers.Web3Provider(window.ethereum as any);
+ const signer = provider.getSigner();
+ const supplyChainContract: Contract = new ethers.Contract(
+ SupplyChainAddress,
+ SupplyChainABI.abi,
+ signer
+ );
+
+ const createBatch = async (): Promise => {
+ try {
+ const tx = await supplyChainContract.createBatch(location);
+ await tx.wait();
+ alert("Batch created!");
+ } catch (error: any) {
+ console.error(error);
+ alert("Error creating batch.");
+ }
+ };
+
+ const getBatch = async (): Promise => {
+ try {
+ const batch = await supplyChainContract.getBatch(parseInt(batchId, 10));
+ setBatchDetails(batch);
+ } catch (error: any) {
+ console.error(error);
+ alert("Error fetching batch details.");
+ }
+ };
+
+ const transferOwnership = async (): Promise => {
+ try {
+ const tx = await supplyChainContract.transferOwnership(parseInt(batchId, 10), newOwner);
+ await tx.wait();
+ alert("Ownership transferred!");
+ } catch (error: any) {
+ console.error(error);
+ alert("Error transferring ownership.");
+ }
+ };
+
+ const updateStatus = async (): Promise => {
+ try {
+ const tx = await supplyChainContract.updateStatus(parseInt(batchId, 10), newStatus);
+ await tx.wait();
+ alert("Status updated!");
+ } catch (error: any) {
+ console.error(error);
+ alert("Error updating status.");
+ }
+ };
+
+ const handleChange = (setter: React.Dispatch>) =>
+ (event: ChangeEvent) => {
+ setter(event.target.value);
+ };
+
+ return (
+
+
Supply Chain Management
+
+
+
+
+
+
+
+ {batchDetails && (
+
+
Batch ID: {batchDetails.id.toString()}
+
Owner: {batchDetails.owner}
+
Location: {batchDetails.location}
+
Status: {batchDetails.status}
+
Timestamp: {new Date(batchDetails.timestamp * 1000).toLocaleString()}
+
+ )}
+
+
+
+
+
+
+
+ );
+};
diff --git a/packages/nextjs/contracts/Partcipants.json b/packages/nextjs/contracts/Participants.json
similarity index 100%
rename from packages/nextjs/contracts/Partcipants.json
rename to packages/nextjs/contracts/Participants.json
diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json
index ed1fae6..bb6d12d 100644
--- a/packages/nextjs/package.json
+++ b/packages/nextjs/package.json
@@ -24,6 +24,7 @@
"blo": "~1.0.1",
"burner-connector": "~0.0.8",
"daisyui": "4.12.10",
+ "dotenv": "^16.4.5",
"ethers": "5.7.2",
"framer-motion": "^11.11.10",
"lucide-react": "^0.453.0",
diff --git a/yarn.lock b/yarn.lock
index 4e141d5..c39944d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2981,6 +2981,7 @@ __metadata:
blo: ~1.0.1
burner-connector: ~0.0.8
daisyui: 4.12.10
+ dotenv: ^16.4.5
eslint: ~8.24.0
eslint-config-next: ~14.0.4
eslint-config-prettier: ~8.5.0