Skip to content

Commit

Permalink
Support for WEI vs ETH
Browse files Browse the repository at this point in the history
  • Loading branch information
RohanNero committed Jan 15, 2024
1 parent f5b5403 commit 6e2ace3
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 37 deletions.
25 changes: 17 additions & 8 deletions packages/nextjs/components/EIPs/Token/DataDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import tokenAbi from "../../../abi/eips/Token";
import { chainData } from "../../../utils/scaffold-eth/networks";
import { createPublicClient, createWalletClient, custom, encodeFunctionData } from "viem";
import { createPublicClient, createWalletClient, custom, encodeFunctionData, formatEther } from "viem";
import { useNetwork } from "wagmi";

interface TokenReturnDataType {
Expand Down Expand Up @@ -99,8 +99,12 @@ const DataDisplay: React.FC<DataDisplayProps> = ({ returnData, setReturnData, di
data: totalSupplyCallData,
to: goldContract,
});
console.log("silver supply:", silverSupply);
console.log("gold supply:", goldSupply);
if (!silverSupply?.data || !goldSupply?.data) {
displayError("Silver or Gold supply is undefined!");
return;
}
console.log("silver supply:", parseInt(silverSupply.data.toString()));
console.log("gold supply:", parseInt(goldSupply.data.toString()));

setReturnData(prevData => ({
...prevData,
Expand Down Expand Up @@ -149,21 +153,21 @@ const DataDisplay: React.FC<DataDisplayProps> = ({ returnData, setReturnData, di
<div className="text-gray-400">
{" "}
<span className="text-gray-500">Silver balance: </span>
{returnData.silverBalance}
{formatEther(BigInt(returnData.silverBalance))}
</div>
<div className="text-gray-400">
{" "}
<span className="text-gray-500">Total supply: </span>
{returnData.silverSupply}
{formatEther(BigInt(returnData.silverSupply))}
</div>
<div className="text-gray-400">
{" "}
<span className="text-gray-500">Gold balance: </span>
{returnData.goldBalance}
{formatEther(BigInt(returnData.goldBalance))}
</div>
<div className="text-gray-400">
<span className="text-gray-500">Total supply: </span>
{returnData.goldSupply}
{formatEther(BigInt(returnData.goldSupply))}
</div>
</div>
{chain && chain?.id && (
Expand All @@ -176,7 +180,12 @@ const DataDisplay: React.FC<DataDisplayProps> = ({ returnData, setReturnData, di
)}
{returnData.hash !== "" && (
<div className="mb-4 text-center text-gray-400 text-2xl">
<button className="hover:text-gray-500" title="Click to copy!" onClick={() => copyHexString(true)}>
<button
className="hover:text-gray-500"
disabled={returnData.hash === "Loading..."}
title={returnData.hash === "Loading..." ? undefined : "Click to copy!"}
onClick={() => copyHexString(true)}
>
{returnData.hash === "Loading..." ? (
returnData.hash
) : (
Expand Down
85 changes: 57 additions & 28 deletions packages/nextjs/components/EIPs/Token/InputForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { ChangeEvent, ChangeEventHandler, FormEvent, useState } from "react";
import tokenAbi from "../../../abi/eips/Token";
import { chainData } from "../../../utils/scaffold-eth/networks";
import { createPublicClient, createWalletClient, custom, encodeFunctionData } from "viem";
import { createPublicClient, createWalletClient, custom, encodeFunctionData, parseEther } from "viem";
import { useNetwork } from "wagmi";

interface TokenReturnDataType {
Expand All @@ -13,12 +13,14 @@ interface TokenReturnDataType {
}

interface DataDisplayProps {
useWei: boolean;
setUseWei: React.Dispatch<React.SetStateAction<boolean>>;
returnData: TokenReturnDataType;
displayError: (errorMessage: string) => void;
setReturnData: React.Dispatch<React.SetStateAction<TokenReturnDataType>>;
}

const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, displayError }) => {
const InputForm: React.FC<DataDisplayProps> = ({ useWei, setUseWei, returnData, setReturnData, displayError }) => {
// Get current chain info
const { chain } = useNetwork();

Expand All @@ -38,11 +40,11 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
console.log("name:", name);
console.log("value:", value);

// Check if the input for x value is a valid integer
if (name == "amount" && !/^\d*$/.test(value)) {
console.log(`Invalid input character: ${value} `);
return;
}
// // Check if the input for x value is a valid integer
// if (name == "amount" && !/^\d*$/.test(value)) {
// console.log(`Invalid input character: ${value} `);
// return;
// }

// Update the state only if it's a valid integer
setFormData({
Expand All @@ -66,9 +68,9 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp

// Update the state only if it's a valid integer
setFormData({
...formData,
from: "",
to: "",
amount: undefined,
function: value,
});
};
Expand Down Expand Up @@ -161,12 +163,13 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
}

// Simulate transactions and get the result
const result = getSimulationResult(toAddress, address, publicClient);
const result = await getSimulationResult(toAddress, address, publicClient);
console.log("Simulaton result:", result);

// Ensure simulated transaction result is defined
if (!result) {
console.log("Simulation result is undefined!");
return;
}

// Send the transaction and get the hash
Expand Down Expand Up @@ -206,42 +209,48 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
const getSimulationResult = async (toAddress: string, address: string, publicClient: any) => {
// Ensure the function name is valid
const currentFunction = formData.function as "mint" | "approve" | "burn" | "transfer" | "transferFrom" | "swap";
const formattedAmount = useWei ? formData.amount : formData.amount ? parseEther(formData.amount) : formData.amount;

if (currentFunction == "mint" || currentFunction == "burn" || currentFunction == "swap") {
if (!formData.amount) {
if (!formattedAmount) {
displayError("Amount is undefined!");
return;
}
const { result } = await publicClient.simulateContract({
address: toAddress,
abi: tokenAbi,
args: [BigInt(formData.amount)] as readonly [bigint],
functionName: currentFunction,
account: address,
});
return result;
try {
const { result } = await publicClient.simulateContract({
address: toAddress,
abi: tokenAbi,
args: [BigInt(formattedAmount)] as readonly [bigint],
functionName: currentFunction,
account: address,
});
return result;
} catch (e: any) {
displayError(e.message);
return;
}
} else if (currentFunction == "approve" || currentFunction == "transfer") {
if (!formData.to || !formData.amount) {
if (!formData.to || !formattedAmount) {
displayError("To address or amount is undefined!");
return;
}
const { result } = await publicClient.simulateContract({
address: toAddress,
abi: tokenAbi,
args: [formData.to, BigInt(formData.amount)] as readonly [string, bigint],
args: [formData.to, BigInt(formattedAmount)] as readonly [string, bigint],
functionName: currentFunction,
account: address,
});
return result;
} else if (currentFunction == "transferFrom") {
if (!formData.from || !formData.to || !formData.amount) {
if (!formData.from || !formData.to || !formattedAmount) {
displayError("From/To address or amount is undefined!");
return;
}
const { result } = await publicClient.simulateContract({
address: toAddress,
abi: tokenAbi,
args: [formData.from, formData.to, BigInt(formData.amount)] as readonly [string, string, bigint],
args: [formData.from, formData.to, BigInt(formattedAmount)] as readonly [string, string, bigint],
functionName: currentFunction,
account: address,
});
Expand All @@ -262,16 +271,17 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
| "transfer"
| "transferFrom"
| "swap";
const formattedAmount = useWei ? formData.amount : formData.amount ? parseEther(formData.amount) : formData.amount;
if (currentFunction == "mint" || currentFunction == "burn" || currentFunction == "swap") {
if (!formData.amount) {
if (!formattedAmount) {
displayError("Amount is undefined!");
return;
}
console.log("code reached");
const callData = encodeFunctionData({
abi: tokenAbi,
functionName: currentFunction,
args: [BigInt(formData.amount)] as readonly [bigint],
args: [BigInt(formattedAmount)] as readonly [bigint],
});
return callData;
} else if (currentFunction == "allowance") {
Expand All @@ -286,25 +296,25 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
});
return callData;
} else if (currentFunction == "approve" || currentFunction == "transfer") {
if (!formData.to || !formData.amount) {
if (!formData.to || !formattedAmount) {
displayError("To address or amount is undefined!");
return;
}
const callData = encodeFunctionData({
abi: tokenAbi,
functionName: currentFunction,
args: [formData.to, BigInt(formData.amount)] as readonly [string, bigint],
args: [formData.to, BigInt(formattedAmount)] as readonly [string, bigint],
});
return callData;
} else if (currentFunction == "transferFrom") {
if (!formData.from || !formData.to || !formData.amount) {
if (!formData.from || !formData.to || !formattedAmount) {
displayError("From/To address or amount is undefined!");
return;
}
const callData = encodeFunctionData({
abi: tokenAbi,
functionName: currentFunction,
args: [formData.from, formData.to, BigInt(formData.amount)] as readonly [string, string, bigint],
args: [formData.from, formData.to, BigInt(formattedAmount)] as readonly [string, string, bigint],
});
return callData;
} else {
Expand Down Expand Up @@ -459,6 +469,13 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
}
};

// Update simulateOnly state value depending on checkbox status
const handleCheckboxChange = () => {
// Toggle the state when the checkbox is clicked
setUseWei(!useWei);
console.log("useWei value:", useWei);
};

return (
<div className="mb-4 text-center text-xl">
Input Form
Expand Down Expand Up @@ -493,6 +510,18 @@ const InputForm: React.FC<DataDisplayProps> = ({ returnData, setReturnData, disp
>
Execute
</button>
{/* Checkbox input */}
<div className="flex flex-col">
<input
className="bg-gray-500 mt-2 toggle"
type="checkbox"
id="theme-toggle"
checked={useWei}
onChange={handleCheckboxChange}
title="Toggle between using WEI or ETH"
/>
{useWei ? "WEI" : "ETH"}
</div>
</div>
</form>
</div>
Expand Down
11 changes: 10 additions & 1 deletion packages/nextjs/pages/book/EIPs/20_Token/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const Home: NextPage = () => {
hash: "",
});

// Handle the state of tx interaction, if false the transaction will actually be submitted
const [useWei, setUseWei] = useState<boolean>(true);

// State variable for storing error messages
const [errorMessage, setErrorMessage] = useState("");

Expand Down Expand Up @@ -43,7 +46,13 @@ const Home: NextPage = () => {
<div className="flex-col mx-auto max-w-screen-xl p-4 font-fantasy text-gray-500">
<Text />
<DataDisplay displayError={displayError} returnData={returnData} setReturnData={setReturnData} />
<InputForm displayError={displayError} returnData={returnData} setReturnData={setReturnData} />
<InputForm
useWei={useWei}
setUseWei={setUseWei}
displayError={displayError}
returnData={returnData}
setReturnData={setReturnData}
/>
<ExtraCodeBlocks />
{/* Conditionally render the custom error popup */}
{showErrorPopup && <Error errorMessage={errorMessage} onClose={closeError} />}
Expand Down

0 comments on commit 6e2ace3

Please sign in to comment.