UNPKG

@msquared/etherbase-client

Version:

React hooks for interacting with Etherbase smart contracts

116 lines (115 loc) 5.07 kB
"use client"; import { useCallback, useState } from "react"; import { parseEther } from "viem"; import { useEtherbaseContext } from "../EtherbaseProvider"; import { EtherbaseSourceAbi } from "../abi/EtherbaseSource"; import useWebThree from "./useWebThree"; export default function useEtherbasePermissions({ sourceAddress, }) { useEtherbaseContext(); const { publicClient, getWalletClient } = useWebThree(); const [canGrantRoles, setCanGrantRoles] = useState({}); const getWalletClientInternal = useCallback(async () => { const walletClient = await getWalletClient(); if (!walletClient) { throw new Error("Wallet client not found"); } return walletClient; }, [getWalletClient]); const executeWriteBrowser = useCallback(async (writeFunctionName, args) => { if (!publicClient) { throw new Error("Public client not found"); } const walletClient = await getWalletClientInternal(); // check the function name is valid if (!Array.from(EtherbaseSourceAbi).find((f) => f.type === "function" && f.name === writeFunctionName)) { throw new Error(`Invalid function name: ${writeFunctionName}`); } const hash = await walletClient.writeContract({ address: sourceAddress, abi: EtherbaseSourceAbi, // @ts-ignore functionName: writeFunctionName, // @ts-ignore args, gas: 7920027n, }); const receipt = await publicClient.waitForTransactionReceipt({ hash }); console.log("Execute write receipt:", receipt); }, [sourceAddress, publicClient, getWalletClientInternal]); const grantRoles = useCallback(async (walletAddress, roles) => { await executeWriteBrowser("createWalletIdentity", [walletAddress, roles]); }, [executeWriteBrowser]); const revokeIdentity = useCallback(async (walletAddress) => { await executeWriteBrowser("deleteIdentity", [walletAddress]); }, [executeWriteBrowser]); const grantRole = useCallback(async (walletAddress, role) => { await executeWriteBrowser("grantRole", [walletAddress, role]); }, [executeWriteBrowser]); const revokeRole = useCallback(async (walletAddress, role) => { await executeWriteBrowser("revokeRole", [walletAddress, role]); }, [executeWriteBrowser]); const deposit = useCallback(async (targetAddress, amount) => { const walletClient = await getWalletClientInternal(); if (!walletClient.account) { throw new Error("No account connected"); } const hash = await walletClient.sendTransaction({ to: targetAddress, value: parseEther(amount.toString()), // Convert amount to SOM account: walletClient.account, chain: walletClient.chain, }); await publicClient?.waitForTransactionReceipt({ hash }); }, [publicClient, getWalletClientInternal]); const fetchPermissions = useCallback(async () => { if (!publicClient) { throw new Error("Public client not found"); } // Get owner address const owner = await publicClient.readContract({ address: sourceAddress, abi: EtherbaseSourceAbi, functionName: "owner", }); // Fetch all identities with roles const identityViews = (await publicClient.readContract({ address: sourceAddress, abi: EtherbaseSourceAbi, functionName: "getAllIdentities", })); // Fetch balances for all addresses const balancePromises = identityViews.map((identity) => publicClient.getBalance({ address: identity.walletAddress, })); const balances = await Promise.all(balancePromises); // Get current user's wallet to check permissions const accounts = (await window.ethereum?.request({ method: "eth_requestAccounts", })); const userWallet = accounts[0]; const userIdentity = identityViews.find((identity) => identity.walletAddress.toLowerCase() === userWallet.toLowerCase()); // For this example, we assume that only an identity with role 2 ("Grant") can grant permissions. const roleChecks = Array.from({ length: 4 }, (_, i) => [ i, userIdentity ? userIdentity.roles.includes(2) : false, ]); setCanGrantRoles(Object.fromEntries(roleChecks)); const permissionsList = identityViews.map((identity, index) => ({ walletAddress: identity.walletAddress, roles: identity.roles, isOwner: identity.walletAddress.toLowerCase() === owner.toLowerCase(), balance: balances[index], })); return permissionsList; }, [publicClient, sourceAddress]); return { grantRoles, revokeIdentity, grantRole, revokeRole, deposit, fetchPermissions, canGrantRoles, }; }