Get Message
diff --git a/frontend/src/routes/pad-token.lazy.tsx b/frontend/src/routes/pad-token.lazy.tsx
new file mode 100644
index 0000000..e1dc3f4
--- /dev/null
+++ b/frontend/src/routes/pad-token.lazy.tsx
@@ -0,0 +1,123 @@
+import { createLazyFileRoute } from "@tanstack/react-router";
+import { useState } from "react";
+import type { Numbers } from "web3";
+import { useStore } from "../store";
+import { getFormInputValue, toastError, tryWithToast } from "../utils";
+import { padToken, web3 } from "../web3";
+
+export const Route = createLazyFileRoute("/pad-token")({
+ component: PadTokenPage,
+});
+
+function PadTokenPage() {
+ const connectedAccount = useStore((state) => state.connectedAccount);
+ const [balance, setBalance] = useState("(nothingness)");
+
+ const onBalanceOfFormSubmit: React.FormEventHandler
= async (
+ event
+ ) => {
+ event.preventDefault();
+
+ const address = getFormInputValue(
+ event.target as HTMLFormElement,
+ "address"
+ ).trim();
+ if (!address) {
+ toastError("Balance Of", "Enter an address.");
+ return;
+ }
+
+ await tryWithToast("Balance Of", async () => {
+ const balanceBN: Numbers = await padToken.methods
+ .balanceOf(address)
+ .call();
+ setBalance(web3.utils.fromWei(balanceBN, "ether"));
+ });
+ };
+
+ const onMintFormSubmit: React.FormEventHandler = async (
+ event
+ ) => {
+ event.preventDefault();
+
+ if (!connectedAccount) {
+ toastError("Mint", "Connect your wallet first.");
+ return;
+ }
+
+ const to = getFormInputValue(event.target as HTMLFormElement, "to").trim();
+ if (!to) {
+ toastError("Mint", "Enter a target address.");
+ return;
+ }
+
+ const amount = getFormInputValue(
+ event.target as HTMLFormElement,
+ "amount"
+ ).trim();
+ if (!amount) {
+ toastError("Mint", "Enter an amount.");
+ return;
+ }
+
+ await tryWithToast("Mint", async () => {
+ await padToken.methods
+ .mint(to, web3.utils.toWei(amount, "ether"))
+ .send({ from: connectedAccount });
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/frontend/src/store.tsx b/frontend/src/store.tsx
new file mode 100644
index 0000000..92adf15
--- /dev/null
+++ b/frontend/src/store.tsx
@@ -0,0 +1,13 @@
+import { create } from "zustand";
+
+interface State {
+ connectedAccount: string | null;
+ setConnectedAccount: (newAccount: string) => void;
+ unsetConnectedAccount: () => void;
+}
+
+export const useStore = create()((set) => ({
+ connectedAccount: null,
+ setConnectedAccount: (newAccount) => set({ connectedAccount: newAccount }),
+ unsetConnectedAccount: () => set({ connectedAccount: null }),
+}));
diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts
index dc3bec0..197e78b 100644
--- a/frontend/src/utils.ts
+++ b/frontend/src/utils.ts
@@ -1,21 +1,41 @@
import { toast } from "sonner";
+export function toastSuccess(taskName: string) {
+ toast.success(`${taskName}: Success`, {
+ className: "border-none bg-green-100",
+ });
+}
+
+export function toastError(taskName: string, errorMessage: string) {
+ toast.error(`${taskName}: Error`, {
+ description: errorMessage,
+ className: "border-none bg-red-100",
+ });
+}
+
export async function tryWithToast(
taskName: string,
taskFn: () => Promise
) {
try {
await taskFn();
- toast.success(`${taskName}: Success`, {
- className: "border-none bg-green-100",
- });
+ toastSuccess(taskName);
} catch (error: any) {
console.error(error);
- toast.error(`${taskName}: Error`, {
- description:
- error.message ||
- "No error message. Check the DevTools console for details.",
- className: "border-none bg-red-100",
- });
+ toastError(
+ taskName,
+ error.message ||
+ "No error message. Check the DevTools console for details."
+ );
}
}
+
+export function shortenAddress(address: string) {
+ return address.slice(0, 6) + "..." + address.slice(-4);
+}
+
+export function getFormInputValue(form: HTMLFormElement, name: string) {
+ // @ts-expect-error
+ const input = form.elements[name] as HTMLInputElement;
+ return input.value;
+}
diff --git a/frontend/src/web3.ts b/frontend/src/web3.ts
index 76a08ef..de57eeb 100644
--- a/frontend/src/web3.ts
+++ b/frontend/src/web3.ts
@@ -1,5 +1,6 @@
import { Web3 } from "web3";
import messageBoxArtifacts from "./evm-output/MessageBox.artifacts.json";
+import padTokenArtifacts from "./evm-output/PADToken.artifacts.json";
import deployedAddresses from "./evm-output/deployed_addresses.json";
export let web3: Web3;
@@ -17,3 +18,8 @@ export const messageBox = new web3!.eth.Contract(
messageBoxArtifacts.abi,
deployedAddresses["MessageBoxModule#MessageBox"]
);
+
+export const padToken = new web3!.eth.Contract(
+ padTokenArtifacts.abi,
+ deployedAddresses["MainModule#PADToken"]
+);