Skip to content

Commit

Permalink
feat(WIP): update rainbowkit + wagmi + ethers
Browse files Browse the repository at this point in the history
  • Loading branch information
PudgyPug authored and mhanson-github committed Aug 20, 2024
1 parent b62e467 commit dd6b5bf
Show file tree
Hide file tree
Showing 8 changed files with 9,812 additions and 3,272 deletions.
47 changes: 19 additions & 28 deletions components/RemoveStakeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import LoadingButton from './LoadingButton';
import { ConfirmModalContext } from './ConfirmModalContextProvider';
import { isMetaMaskError } from '../utils/isMetaMaskError';
import { isEthersError } from '../utils/isEthersError';
import { Address } from 'wagmi';
import { ExternalProvider } from '@ethersproject/providers';
import { NodeStatus } from '../model/node-status'
import {useAccount} from "wagmi";

export default function RemoveStakeButton({nominee, force = false, nodeStatus}: { nominee: string, force?: boolean, nodeStatus: NodeStatus['state'] }) {
const {showTemporarySuccessMessage, showErrorDetails} = useContext(ToastContext);
const { address } = useAccount();
const {writeUnstakeLog} = useTXLogs()
const {openModal} = useContext(ConfirmModalContext);
const ethereum = window.ethereum;
Expand All @@ -33,13 +33,10 @@ export default function RemoveStakeButton({nominee, force = false, nodeStatus}:
throw new Error('MetaMask not found');
}
try {
const provider = new ethers.providers.Web3Provider(ethereum as ExternalProvider);
const signer = provider.getSigner();
const [gasPrice, from, nonce] = await Promise.all([
signer.getGasPrice(),
signer.getAddress(),
signer.getTransactionCount()
]);
const provider = new ethers.BrowserProvider(window.ethereum!);
const signer = await provider.getSigner();
const from = await signer.getAddress()
const nonce = await provider.getTransactionCount(from, 'latest');

const unstakeData = {
isInternalTx: true,
Expand All @@ -54,9 +51,8 @@ export default function RemoveStakeButton({nominee, force = false, nodeStatus}:
const params = {
from,
to: '0x0000000000000000000000000000000000010000',
gasPrice,
data: ethers.utils.hexlify(
ethers.utils.toUtf8Bytes(JSON.stringify(unstakeData))
data: ethers.hexlify(
ethers.toUtf8Bytes(JSON.stringify(unstakeData))
),
nonce
};
Expand All @@ -75,7 +71,7 @@ export default function RemoveStakeButton({nominee, force = false, nodeStatus}:
let errorMessage = (error as Error)?.message || String(error);

// 4001 is the error code for when a user rejects a transaction
if ((isMetaMaskError(error) && error.code === 4001)
if ((isMetaMaskError(error) && error.code === 4001)
|| (isEthersError(error) && error.code === 'ACTION_REJECTED')) {
errorMessage = 'Transaction rejected by user';
}
Expand All @@ -85,15 +81,15 @@ export default function RemoveStakeButton({nominee, force = false, nodeStatus}:
};

const [haveMetamask, sethaveMetamask] = useState(false);
const [accountAddress, setAccountAddress] = useState("");
const [accountAddress, setAccountAddress] = useState<string>('');

useEffect(() => {
const checkMetamaskAvailability = async () => {
const checkWalletAvailability = async () => {
if (!ethereum) {
sethaveMetamask(false);
} else sethaveMetamask(true);
};
checkMetamaskAvailability();
checkWalletAvailability();
}, [ethereum]);

const connectWallet = async () => {
Expand All @@ -106,26 +102,21 @@ export default function RemoveStakeButton({nominee, force = false, nodeStatus}:
method: "eth_requestAccounts"
});

setAccountAddress(accounts[0]);
if (!address || address.length === 0) {
console.error("No accounts returned from Ethereum provider.");
return;
}

setAccountAddress(accounts[0]!);

console.log("Account2: ", accountAddress);
await sendTransaction(accounts[0], nominee, force);
await sendTransaction(address, nominee, force);
} catch (error) {
setLoading(false);
}
};

const [isLoading, setLoading] = useState(false);
const [data, setData] = useState({
isInternalTx: true,
internalTXType: 7,
nominator: accountAddress,
timestamp: Date.now()
});

ethereum?.on?.("accountsChanged", (accounts: Address[]) => {
setData({...data, nominator: accounts[0]});
});

async function removeStake() {
setLoading(true);
Expand Down
83 changes: 34 additions & 49 deletions components/StakeForm.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { ChangeEvent, useContext, useEffect, useState } from "react";
import React, {ChangeEvent, useContext, useEffect, useState} from "react";
import { ethers } from "ethers";
import { ArrowRightIcon } from "@heroicons/react/20/solid";
import { ToastContext } from "./ToastContextProvider";
import { useTXLogs } from "../hooks/useTXLogs";
import LoadingButton from "./LoadingButton";
import { isMetaMaskError } from "../utils/isMetaMaskError";
import { isEthersError } from "../utils/isEthersError";
import { ExternalProvider } from "@ethersproject/providers";
import { useAccount } from "wagmi";
import {replacer} from "../utils/bigIntReplacer";

interface StakeData {
isInternalTx: boolean;
Expand All @@ -18,31 +19,30 @@ interface StakeData {
}

type StakeFormProps = {
nominator: string;
nominee: string;
stakeAmount: string;
onStake?: () => void;
totalStaked: number;
};

export default function StakeForm({
nominator,
nominee,
stakeAmount,
onStake,
totalStaked,
}: StakeFormProps) {
const { showTemporarySuccessMessage, showErrorDetails } =
useContext(ToastContext);
const requiredStake = ethers.utils.parseEther(stakeAmount).toString();
const requiredStake = ethers.parseEther(stakeAmount).toString() ?? '0';
const ethereum = window.ethereum;
const { writeStakeLog } = useTXLogs();
const [isLoading, setLoading] = useState(false);
const [isStakeOk, setStakeOk] = useState(true);
const { address } = useAccount();
const [data, setData] = useState<StakeData>({
isInternalTx: true,
internalTXType: 6,
nominator: nominator.toLowerCase(),
nominator: address?.toLowerCase() ?? '',
nominee,
stake: requiredStake,
timestamp: Date.now(),
Expand All @@ -61,32 +61,35 @@ export default function StakeForm({
txHash: hash,
};

return JSON.stringify(logData);
return JSON.stringify(logData, replacer);
};

function setDataWithNominator(data: StakeData): void {
return setData({
...data,
nominator: address?.toLowerCase() ?? '',
});
}

async function sendTransaction() {
setLoading(true);
let errorFlag = false;
try {
const blobData: string = JSON.stringify(data);
const provider = new ethers.providers.Web3Provider(
ethereum as ExternalProvider
);
const signer = provider.getSigner();
const [gasPrice, from, nonce] = await Promise.all([
signer.getGasPrice(),
signer.getAddress(),
signer.getTransactionCount(),
]);
const dataWithNominator = {...data, nominator: address}
const blobData: string = JSON.stringify(dataWithNominator);
const provider = new ethers.BrowserProvider(ethereum!);
const signer = await provider.getSigner();
const from = await signer.getAddress()
const nonce = await provider.getTransactionCount(from, 'latest');
console.log("BLOB: ", blobData);
console.log(stakeAmount,totalStaked);
const value = ethers.BigNumber.from(data.stake);
const value = BigInt(data.stake);

const totalStakeBigNumber = ethers.BigNumber.from(totalStaked);
const stakeAmountBigNumber = ethers.utils.parseUnits(stakeAmount, "ether")
const totalStakeBigNumber = BigInt(totalStaked);
const stakeAmountBigNumber = ethers.parseUnits(stakeAmount, "ether")

console.log(totalStakeBigNumber, stakeAmountBigNumber)
if (totalStakeBigNumber.lt(stakeAmountBigNumber) && value.lt(stakeAmountBigNumber)) {
if (totalStakeBigNumber < stakeAmountBigNumber && value < stakeAmountBigNumber) {
errorFlag = true;
throw new Error(
"Stake Amount should be greater than the required stake"
Expand All @@ -95,22 +98,17 @@ export default function StakeForm({
const params = {
from,
to: "0x0000000000000000000000000000000000010000",
gasPrice,
value,
data: ethers.utils.hexlify(ethers.utils.toUtf8Bytes(blobData)),
data: ethers.hexlify(ethers.toUtf8Bytes(blobData)),
nonce,
};
console.log("Params: ", params);

const {
hash,
data: resultData,
wait,
} = await signer.sendTransaction(params);
console.log("TX RECEIPT: ", { hash, resultData });
await writeStakeLog(createStakeLog(blobData, params, hash, from));
const txResponse = await signer.sendTransaction(params);
console.log("TX RECEIPT: ", { hash: txResponse.hash, resultData: txResponse.data });
await writeStakeLog(createStakeLog(blobData, params, txResponse.hash, from));

const txConfirmation = await wait();
const txConfirmation = await txResponse.wait();
console.log("TX CONFRIMED: ", txConfirmation);
showTemporarySuccessMessage("Stake successful!");
} catch (error: unknown) {
Expand All @@ -134,31 +132,18 @@ export default function StakeForm({
onStake?.();
}

useEffect(() => {
ethereum?.on?.("accountsChanged", (accounts: string[]) => {
setData((currentData) => ({
...currentData,
nominator: accounts[0].toLowerCase(),
}));
});
setData((currentData) => ({
...currentData,
stake: "0",
}));
}, [requiredStake, ethereum]);

function handleStakeChange(e: ChangeEvent<HTMLInputElement>) {
try {
const newValue = e.target.value.toString();
const stake = ethers.utils.parseEther(newValue).toString();
setData({
const stake = ethers.parseEther(newValue).toString();
setDataWithNominator({
...data,
stake,
});
setStakeOk(true)
} catch (e) {
console.error(e);
setData({
setDataWithNominator({
...data,
});
setStakeOk(false)
Expand All @@ -172,7 +157,7 @@ export default function StakeForm({
</label>
<input
id="rewardWallet"
value={data.nominator}
value={address}
type="text"
className="bg-white text-black p-3 mt-2 w-full block border border-black"
disabled
Expand All @@ -186,7 +171,7 @@ export default function StakeForm({
placeholder="Nominee Public Key"
value={data.nominee}
onChange={(e) =>
setData({ ...data, nominee: e.target.value.toLowerCase() })
setDataWithNominator({ ...data, nominee: e.target.value.toLowerCase() })
}
/>
<label className="block mt-4">Stake Amount (SHM)</label>
Expand Down
Loading

0 comments on commit dd6b5bf

Please sign in to comment.