diff --git a/NOTES.md b/NOTES.md
new file mode 100644
index 0000000..3ad5d59
--- /dev/null
+++ b/NOTES.md
@@ -0,0 +1,33 @@
+PayrollFactory deployed to: 0xfe44aB0B966E57F126130BE6401546c7351484ad --mumbai
+TokenTransferor deployed to: 0x21d762ab159676d3bd05e12A95699C1d0b043A48 --mumbai
+Payroll deployed to: 0xDBAbe75848c608bDA3382f0D68219542032B3fEa --mumbai
+All deployed from 0x9768818565ED5968fAACC6F66ca02CBf2785dB84
+
+https://api-testnet.polygonscan.com/IEWN9BX92EIKVXR22UKQQ9A4UWEF5J9IRG
+
+There is no log out / wallet modal on Register Deploy
+Need a rundown of how to log in with wallet and connect to mumbai chain without AA
+
+I shouldnt need to change the web3auth client id correct?
+
+deploy contract in register flow is stuck at getting account address...
+
+## 12/7
+Funkornaut@gmail -- 0xBB65877a1207572321dE0ad64A2e196545904a09
+trevfost503@gmail -- 0xfd330177602f092b72a3b65893602067Ab69cE2c
+sign in with funkornaut through gmail -- 0x1aD394b0c57dbC57f16A5A54b4ccee436b678287
+
+deployed new payroll 0xAB34603b0A8c54f9F9Fe9207b98da8ac354dB68e
+- added function isOwner returns bool, owner() func on ownable works but since we then needed to look for bool on front end thought that would simplify from end logic / routing
+- think that the LogIn flow is a little better
+
+Login.tsx
+Web3 modal pops up when you hit login button - should only pop up if there is a contract address in the form
+
+Now logOut if funky
+Cant log in with Metamask
+
+DeployForm
+- just using useContractWrite was able to click button and make action got this error in browser console
+ next-dev.js:20 ConnectorNotFoundError: Connector not found at writeContract (chunk-TSH6VVF4.js:2348:1)
+
diff --git a/package.json b/package.json
index c4d4ea4..7b46570 100644
--- a/package.json
+++ b/package.json
@@ -36,5 +36,8 @@
},
"resolutions": {
"usehooks-ts@^2.7.2": "patch:usehooks-ts@npm:^2.7.2#./.yarn/patches/usehooks-ts-npm-2.7.2-fceffe0e43.patch"
+ },
+ "dependencies": {
+ "@web3auth/web3auth-wagmi-connector": "^5.0.1"
}
}
diff --git a/packages/hardhat/contracts/Payroll.sol b/packages/hardhat/contracts/Payroll.sol
index a09a1f8..b4df6d1 100644
--- a/packages/hardhat/contracts/Payroll.sol
+++ b/packages/hardhat/contracts/Payroll.sol
@@ -527,8 +527,8 @@ ITokenTransferor public ccip;
}
}
- function getOwner() public view returns (address){
- return owner();
+ function isOwner(address _address) public view returns (bool){
+ return _address == owner();
}
function getEmployeePaymentSplits(address _employeeAddress) public view returns (PaymentSplit memory){
diff --git a/packages/hardhat/deploy/03_deploy_payroll.ts b/packages/hardhat/deploy/03_deploy_payroll.ts
index a0980ad..ca1c6a2 100644
--- a/packages/hardhat/deploy/03_deploy_payroll.ts
+++ b/packages/hardhat/deploy/03_deploy_payroll.ts
@@ -6,7 +6,7 @@ async function main() {
console.log("Deploying contracts with the account:", deployer.address);
// Add the addresses of the dependencies of your Payroll contract
- const ccipTokenTransferorAddress = "0xFFc15127eB60C4Ab1a2e5e0319615ca0982952f2"; // deployed via script
+ const ccipTokenTransferorAddress = "0x21d762ab159676d3bd05e12A95699C1d0b043A48"; // deployed via script
const bnmTokenAddress = "0xf1E3A5842EeEF51F2967b3F05D45DD4f4205FF40"; //BnM Mumbai
// Deploy the Payroll contract
diff --git a/packages/nextjs/.env.example b/packages/nextjs/.env.example
index 6769588..47c95bd 100644
--- a/packages/nextjs/.env.example
+++ b/packages/nextjs/.env.example
@@ -12,7 +12,8 @@
NEXT_PUBLIC_ALCHEMY_API_KEY=
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
-NEXT_PUBLIC_FACTORY_CONTRACT_ADDRESS="" # Polygon Mumbai
-NEXT_PUBLIC_PAYROLL_CONTRACT_ADDRESS="" # Polygon Mumbai
+NEXT_PUBLIC_FACTORY_CONTRACT_ADDRESS= # Polygon Mumbai
+NEXT_PUBLIC_PAYROLL_CONTRACT_ADDRESS= # Polygon Mumbai
+NEXT_PUBLIC_TOKEN_TRANSFEROR_CONTRACT_ADDRESS= # Polygon Mumbai
NEXT_PUBLIC_LOCAL_CHAIN_ID=0 # REPLACE WITH LOCAL DEV CHAIN
NEXT_PUBLIC_TESTNET_CHAIN_ID=80001 # Polygon Mumbai
diff --git a/packages/nextjs/.gitignore b/packages/nextjs/.gitignore
index 6985d55..16dad0e 100644
--- a/packages/nextjs/.gitignore
+++ b/packages/nextjs/.gitignore
@@ -26,6 +26,7 @@ yarn-error.log*
.pnpm-debug.log*
# local env files
+.env
.env.local
.env.development.local
.env.test.local
diff --git a/packages/nextjs/auth/web3auth.ts b/packages/nextjs/auth/web3auth.ts
index f6da7db..b6713f3 100644
--- a/packages/nextjs/auth/web3auth.ts
+++ b/packages/nextjs/auth/web3auth.ts
@@ -1,11 +1,28 @@
// import { useEffect, useState } from "react";
import { Web3Auth } from "@web3auth/modal";
+//import { Web3AuthConnector } from "@web3auth/web3auth-wagmi-connector";
+
// import { createWalletClient, custom } from "viem";
// import { polygonMumbai } from "viem/chains";
// import { AuthProvider, setAuthProvider, setIsConnected } from "~~/auth/authSlice";
// import { MyState, useMyDispatch, useMySelector } from "~~/components/dash-wind/app/store";
+// set up your web3auth instance with all the features you want
+// const web3AuthInstance = new Web3Auth({
+// clientId: "BM0SLNkhMCfIygw0Xi79dG6qbWGMN0o0mEeDjRT0dxlP3BEok9pnu5aqxCNfj2TZ9XT7sQaXm0ltuWbCQ1tsRNI",
+// chainConfig: {
+// chainNamespace: "eip155",
+// chainId: "0x13881", // Mumbai
+// rpcTarget: "https://rpc.ankr.com/polygon_mumbai",
+// displayName: "Mumbai Testnet",
+// blockExplorer: "https://mumbai.polygonscan.com/",
+// ticker: "MATIC",
+// tickerName: "Polygon",
+// },
+// web3AuthNetwork: "sapphire_mainnet",
+// });
+
export const web3auth = new Web3Auth({
clientId: "BM0SLNkhMCfIygw0Xi79dG6qbWGMN0o0mEeDjRT0dxlP3BEok9pnu5aqxCNfj2TZ9XT7sQaXm0ltuWbCQ1tsRNI", // Get your Client ID from the Web3Auth Dashboard
web3AuthNetwork: "sapphire_devnet", // Web3Auth Network
diff --git a/packages/nextjs/components/dash-wind/containers/Header.tsx b/packages/nextjs/components/dash-wind/containers/Header.tsx
index 20d32ac..8ea2c1d 100644
--- a/packages/nextjs/components/dash-wind/containers/Header.tsx
+++ b/packages/nextjs/components/dash-wind/containers/Header.tsx
@@ -5,6 +5,8 @@ import { useRouter } from "next/router";
import { openRightDrawer } from "../features/common/rightDrawerSlice";
import { RIGHT_DRAWER_TYPES } from "../utils/globalConstantUtil";
import { themeChange } from "theme-change";
+import { Address, createWalletClient, custom } from "viem";
+import { polygonMumbai } from "viem/chains";
import Bars3Icon from "@heroicons/react/24/outline/Bars3Icon";
import BellIcon from "@heroicons/react/24/outline/BellIcon";
import MoonIcon from "@heroicons/react/24/outline/MoonIcon";
@@ -13,7 +15,7 @@ import { setIsAdmin, setIsConnected } from "~~/auth/authSlice";
import { web3auth } from "~~/auth/web3auth";
// import UserIcon from "@heroicons/react/24/outline/UserIcon";
import { MyState, useMyDispatch, useMySelector } from "~~/components/dash-wind/app/store";
-import { Address } from "~~/components/web-3-crew/Address";
+import { Address as AddressDisplay } from "~~/components/web-3-crew/Address";
function Header() {
const dispatch = useMyDispatch();
@@ -22,8 +24,19 @@ function Header() {
const [currentTheme, setCurrentTheme] = useState(
typeof window !== "undefined" ? localStorage.getItem("theme") : null,
);
+ const [address, setAddress] = useState
(null);
const router = useRouter();
+ useEffect(() => {
+ async function getAddress() {
+ const address = await getAccounts();
+ if (address) {
+ setAddress(address);
+ }
+ }
+ getAddress();
+ }, []);
+
useEffect(() => {
themeChange(false);
if (currentTheme === null) {
@@ -36,6 +49,23 @@ function Header() {
// 👆 false parameter is required for react project
}, [currentTheme]);
+ async function getAccounts() {
+ if (!web3auth.provider) {
+ console.log("from login - getAccounts: provider not defined");
+ return;
+ }
+ const client = createWalletClient({
+ // account: privateKeyToAccount('0x...'); // from viem
+ chain: polygonMumbai,
+ transport: custom(web3auth.provider),
+ });
+
+ // Get user's public address
+ const [address] = await client.getAddresses();
+ //console.log("user address: ", address);
+ return address as Address;
+ }
+
// Opening right sidebar for notification
const openNotification = () => {
dispatch(openRightDrawer({ header: "Notifications", bodyType: RIGHT_DRAWER_TYPES.NOTIFICATION }));
@@ -107,12 +137,7 @@ function Header() {
state.auth);
-
const router = useRouter();
const dispatch = useMyDispatch();
+ //const userAddress = getAccounts();
+ // state to store user address once it is fetched
+ const [userAddress, setUserAddress] = useState(null);
+
+ useEffect(() => {
+ async function fetchAddress() {
+ const address = await getAccounts();
+ if (address) {
+ // not sure what this issue is with this
+ setUserAddress(address);
+ }
+ }
+ fetchAddress();
+ }, []);
+
+ const payrollABI = Payroll.abi;
/*-------------------------------------*/
// Kaz & Trevor
// getOwner address to test against user's address
// need to see what shape `owner` will be on return
+ // contract interaction calls isOwner()
const {
- data: owner,
+ data: isOwner,
// isError,
// isLoading,
} = useContractRead({
address: process.env.NEXT_PUBLIC_PAYROLL_CONTRACT_ADDRESS,
- // abi: payrollContractAbi,
- functionName: "getOwner",
+ abi: payrollABI,
+ functionName: "isOwner",
+ args: userAddress ? [userAddress] : [],
chainId: Number(chainId),
- });
+ }) as { data: boolean | undefined };
+
+ console.log("is owner: ", isOwner);
+ console.log("user address contract read: ", [getAccounts()]);
+
+ useEffect(() => {
+ if (typeof isOwner !== "undefined") {
+ // Ensure the value is not undefined
+ if (isOwner) {
+ // Redirect to owner's dashboard
+ router.push("/dapp/dashboard");
+ } else {
+ // Redirect to employee or general user dashboard
+ router.push("/dapp/dashboard");
+ }
+ }
+ }, [isOwner, router]);
+
/*-------------------------------------*/
/*-------------------------------------*/
// Kaz & Trevor
//
- const {
- data: isEmployee,
- // isError,
- // isLoading,
- } = useContractRead({
- address: process.env.NEXT_PUBLIC_PAYROLL_CONTRACT_ADDRESS,
- // abi: payrollContractAbi,
- functionName: "doesEmployeeExist",
- args: [
- /* problem: figure out how to getAccount() address here */
- ],
- chainId: Number(chainId),
- });
+ // const {
+ // data: isEmployee,
+ // // isError,
+ // // isLoading,
+ // } = useContractRead({
+ // address: process.env.NEXT_PUBLIC_PAYROLL_CONTRACT_ADDRESS,
+ // abi: payrollABI,
+ // functionName: "doesEmployeeExist",
+ // args: [
+ // /* problem: figure out how to getAccount() address here */
+ // userAddress
+ // ],
+ // chainId: Number(chainId),
+ // });
/*-------------------------------------*/
+ // // Web3Auth
+ // async function login() {
+ // if (isConnected) {
+ // // await determineIfAccountIsAdmin();
+ // // if (!isEmployee) {
+ // // //until the hook is working, this is going to prevent us from being directed to the dashboard
+ // // return;
+ // // }
+ // router.push("/dapp/dashboard");
+ // return;
+ // }
+
+ // try {
+ // await web3auth.connect();
+ // if (web3auth.connected) {
+ // dispatch(setIsConnected({ isConnected: true }));
+ // //const userAddress = await getAccounts(); // Retrieve user's address
+
+ // await determineIfAccountIsAdmin();
+ // if (!isEmployee) {
+ // // until the hook is working, this is going to prevent us from being directed to the dashboard
+ // return;
+ // }
+ // router.push("/dapp/dashboard");
+ // }
+ // } catch (error) {
+ // console.error(error);
+ // }
+ // }
+
// Web3Auth
async function login() {
if (isConnected) {
- await determineIfAccountIsAdmin();
- if (!isEmployee) {
- // until the hook is working, this is going to prevent us from being directed to the dashboard
+ // await determineIfAccountIsAdmin();
+ if (!isOwner) {
+ //until the hook is working, this is going to prevent us from being directed to the dashboard
+ router.push("/dapp/dashboard");
+
return;
}
- router.push("/dapp/dashboard");
return;
}
@@ -83,61 +155,72 @@ function Login() {
await web3auth.connect();
if (web3auth.connected) {
dispatch(setIsConnected({ isConnected: true }));
+
+ //const userAddress = await getAccounts(); // Retrieve user's address
+
// await determineIfAccountIsAdmin();
- // if (!isEmployee) {
- // // until the hook is working, this is going to prevent us from being directed to the dashboard
- // return;
- // }
- router.push("/dapp/dashboard");
+ if (!isOwner) {
+ // until the hook is working, this is going to prevent us from being directed to the dashboard
+ router.push("/dapp/dashboard");
+
+ return;
+ }
+
}
} catch (error) {
console.error(error);
}
}
- async function determineIfAccountIsAdmin() {
- // set loading === true ???
- // const address = await getAccounts();
- // if (!address) {
- // console.error("from determineIfAccountIsAdmin - address is undefined");
- // return;
- // }
- if (!owner) {
- console.error("From determineIfAccountIsAdmin: ownerData from Payroll Contract is undefined");
- return;
- }
+ // async function determineIfAccountIsAdmin() {
+ // // set loading === true ???
+ // const userAddress = getAccounts();
+ // if (!userAddress) {
+ // console.error("from determineIfAccountIsAdmin - address is undefined");
+ // return;
+ // }
- /*-------------------------------------*/
- // Kaz & Trevor
- // need to see what shape `owner` will be on return
- // const isAdmin = address === owner ? true : false;
- // dispatch(setIsAdmin({ isAdmin: isAdmin }));
- /*-------------------------------------*/
- // set loading === false ???
- }
- // async function getAccounts() {
- // if (!web3auth.provider) {
- // console.log("from login - getAccounts: provider not defined");
+ // if (!owner) {
+ // console.error("From determineIfAccountIsAdmin: ownerData from Payroll Contract is undefined");
// return;
// }
- // const client = createWalletClient({
- // // account: privateKeyToAccount('0x...'); // from viem
- // chain: polygonMumbai,
- // transport: custom(web3auth.provider),
- // });
-
- // // Get user's public address
- // const [address] = await client.getAddresses();
- // return address as Address;
+
+ // /*-------------------------------------*/
+ // // Kaz & Trevor
+ // // need to see what shape `owner` will be on return
+ // const isAdmin = userAddress === owner ? true : false;
+ // dispatch(setIsAdmin({ isAdmin: isAdmin }));
+ // /*-------------------------------------*/
+ // // set loading === false ???
// }
+ // func to grab the connected wallet address
+ async function getAccounts() {
+ if (!web3auth.provider) {
+ console.log("from login - getAccounts: provider not defined");
+ return;
+ }
+ const client = createWalletClient({
+ // account: privateKeyToAccount('0x...'); // from viem
+ chain: polygonMumbai,
+ transport: custom(web3auth.provider),
+ });
+
+ //console.log("web3auth provider: ", web3auth.provider);
+ // Get user's public address
+ const [userAddress] = await client.getAddresses();
+ console.log("user address: ", userAddress);
+ return userAddress as Address;
+ }
+
+
const submitForm = (e: React.FormEvent) => {
e.preventDefault();
setErrorMessage("");
- if (loginObj.emailId.trim() === "") return setErrorMessage("Email is required!");
+ // if (loginObj.emailId.trim() === "") return setErrorMessage("Email is required!");
if (loginObj.contractAddress.trim() === "") return setErrorMessage("Contract Address is required!");
};
@@ -165,14 +248,14 @@ function Login() {
updateFormValue={updateFormValue}
/>
-
+ /> */}
{errorMessage}
diff --git a/packages/nextjs/components/dash-wind/features/user/Register.tsx b/packages/nextjs/components/dash-wind/features/user/Register.tsx
index 035ba0d..9629106 100644
--- a/packages/nextjs/components/dash-wind/features/user/Register.tsx
+++ b/packages/nextjs/components/dash-wind/features/user/Register.tsx
@@ -24,7 +24,7 @@ function Register() {
const [walletAddress, setWalletAddress] = useState(null);
const dispatch = useMyDispatch();
-
+ //@note is this working? working for register page?
async function login() {
try {
await web3auth.connect();
@@ -49,6 +49,8 @@ function Register() {
// Get user's public address
const [address] = await client.getAddresses();
+ console.log("user address: ", address);
+
return address;
}
@@ -61,9 +63,12 @@ function Register() {
setRegisterState("loading");
console.log("logging in company...");
await login();
- // Account Abstraction goes here...?
- console.log("getting account address...");
+ // Account Abstraction goes here...? -- kinda is with login
+ // grab account address
const address = await getAccounts();
+ console.log("connected address: ", address);
+
+ console.log("getting account address...");
if (address) {
// Prompt user to fund wallet?
setWalletAddress(address);
diff --git a/packages/nextjs/components/web-3-crew/register-page/DeployForm.tsx b/packages/nextjs/components/web-3-crew/register-page/DeployForm.tsx
index acbef6f..84d8ad7 100644
--- a/packages/nextjs/components/web-3-crew/register-page/DeployForm.tsx
+++ b/packages/nextjs/components/web-3-crew/register-page/DeployForm.tsx
@@ -1,36 +1,66 @@
import React from "react";
import Link from "next/link";
-import { Abi, Address, parseEther } from "viem";
-import { useContractWrite, usePrepareContractWrite } from "wagmi";
+import PayrollFactory from "../../../../hardhat/artifacts/contracts/PayrollFactory.sol/PayrollFactory.json";
+import { Address, parseEther } from "viem";
+import { useContractWrite } from "wagmi";
+import { web3auth } from "~~/auth/web3auth";
import ErrorText from "~~/components/dash-wind/components/Typography/ErrorText";
import { Address as AddressDisplay } from "~~/components/scaffold-eth/Address";
+//import { useDeployedContractInfo } from "~~/hooks/scaffold-eth";
+
interface props {
ownerAddress: Address | null;
}
-
-const payrollFactoryAddress = "";
-const payrollFactoryABI: Abi = [];
+// Check if the user is connected
+const isConnected = web3auth.connected;
+const payrollFactoryAddress = "0xfe44aB0B966E57F126130BE6401546c7351484ad";
+const payrollFactoryABI = PayrollFactory.abi;
export default function DeployForm({ ownerAddress }: props) {
+ //const { data: contractData } = useDeployedContractInfo("PayrollFactory");
+
/*-------------------------------------*/
- // Kaz & Trevor
+ // Kaz & Trevor -- think this is the right way to do it
+ // but running in browser it seems to always be looking for the connected address
+ // see no action in the terminal when the button is clicked
// deploy company contract after registration of account
- const { config } = usePrepareContractWrite({
+ // const { config } = usePrepareContractWrite({
+ // address: payrollFactoryAddress,
+ // // abi: contractData?.abi,
+ // abi: payrollFactoryABI,
+ // functionName: "deployPayrollAndTokenTransferor",
+ // value: parseEther("1", "wei"),
+ // onSuccess(data) {
+ // console.log("contract deployed! Data: ", data); //will data be the contract addresses?
+ // },
+ // onError(error) {
+ // console.error("contract deploy error!", error); //error message
+ // },
+ // });
+
+ //console.log("config: ", config);
+
+ const { data, isLoading, isSuccess, write } = useContractWrite({
address: payrollFactoryAddress,
abi: payrollFactoryABI,
functionName: "deployPayrollAndTokenTransferor",
- value: parseEther("1", "wei"),
- onSuccess(data) {
- console.log("contract deployed! Data: ", data);
- },
- onError(error) {
- console.error("contract deploy error!", error);
- },
});
+ console.log("write: ", write);
+ console.log("data: ", data);
- const { data, isLoading, isSuccess, write } = useContractWrite(config);
- /*-------------------------------------*/
+ // Function to handle button click
+ const handleDeployClick = () => {
+ if (isConnected) {
+ write({
+ args: [],
+ //from: ownerAddress,
+ value: parseEther("1", "wei"),
+ });
+ } else {
+ console.log("Wallet not connected");
+ }
+ };
return (