diff --git a/ui/app/layout.tsx b/ui/app/layout.tsx index 6f4cede..c794242 100644 --- a/ui/app/layout.tsx +++ b/ui/app/layout.tsx @@ -61,17 +61,20 @@ export default function RootLayout({ return ( - - - - + + + {children} diff --git a/ui/components/providers.tsx b/ui/components/providers.tsx index c7e7d95..f2f85f8 100644 --- a/ui/components/providers.tsx +++ b/ui/components/providers.tsx @@ -7,7 +7,7 @@ import { getDefaultConfig, RainbowKitProvider } from "@rainbow-me/rainbowkit"; import { siteConfig } from "@/lib/site"; const config = getDefaultConfig({ - appName: siteConfig.name, + appName: siteConfig.name, appDescription: siteConfig.description, projectId: process.env.NEXT_PUBLIC_WC_ID!, chains: [ diff --git a/ui/components/shell-history.tsx b/ui/components/shell-history.tsx index 32cf8c2..3405b74 100644 --- a/ui/components/shell-history.tsx +++ b/ui/components/shell-history.tsx @@ -1,15 +1,16 @@ -'use client' -import useShellStore from "@/lib/use-shell-store" +"use client"; +import useShellStore from "@/lib/use-shell-store"; export const ShellHistory = () => { - const history = useShellStore(state => state.history) + const history = useShellStore((state) => state.history); - return ( -
- {history.map((line, i) => ( -
{line}
- ))} + return ( +
+ {history.map((line, i) => ( +
+ {line}
- ) -} - + ))} +
+ ); +}; diff --git a/ui/components/shell.tsx b/ui/components/shell.tsx index 9a20b63..fba4e2b 100644 --- a/ui/components/shell.tsx +++ b/ui/components/shell.tsx @@ -4,6 +4,7 @@ import { Form, FormControl, FormField, FormItem } from "./ui/form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { + serialize, useAccount, useEnsName, usePublicClient, @@ -11,7 +12,13 @@ import { } from "wagmi"; import { IntentsEngineAbi } from "../lib/abi/IntentsEngineAbi"; import { ETH_ADDRESS, IE_ADDRESS } from "../lib/constants"; -import { erc20Abi, isAddress, isAddressEqual, maxUint256, parseEther } from "viem"; +import { + erc20Abi, + isAddress, + isAddressEqual, + maxUint256, + parseEther, +} from "viem"; import { mainnet } from "viem/chains"; import useShellStore from "@/lib/use-shell-store"; import { ShellHistory } from "./shell-history"; @@ -21,18 +28,20 @@ const formSchema = z.object({ }); const createId = (chainId?: number, user?: string) => { - return (

- {chainId ? chainId : }:\ - {!user ? ( - - ) : !isAddress(user) ? ( - user.slice(0, -4) - ) : ( - user - )} - {">"} -

) -} + return ( +

+ {chainId ? chainId : }:\ + {!user ? ( + + ) : !isAddress(user) ? ( + user.slice(0, -4) + ) : ( + user + )} + {">"} +

+ ); +}; export const Shell = () => { const form = useForm>({ @@ -46,20 +55,27 @@ export const Shell = () => { address, chainId: mainnet.id, }); - const { - writeContractAsync, - } = useWriteContract(); + const { writeContractAsync } = useWriteContract(); const client = usePublicClient(); const addLine = useShellStore((state) => state.addLine); - const addCommand = ({ chainId, user, command }: { - chainId?: number - user?: string - command: string + const addCommand = ({ + chainId, + user, + command, + }: { + chainId?: number; + user?: string; + command: string; }) => { - addLine(
{createId(chainId, user)}

{command}

); - } + addLine( +
+ {createId(chainId, user)} +

{command}

+
, + ); + }; const addError = (error: Error) => { addLine(

{error.message}

); @@ -71,18 +87,18 @@ export const Shell = () => { addCommand({ chainId: chain?.id, user: name ?? address, command }); if (!client) throw new Error("No client available"); if (!address) throw new Error("No wallet connected"); - + const regex = /(\d+(\.\d+)?)\s*eth/i; const match = command.match(regex); let value = 0n; // Default value if no match is found - + if (match && match[1]) { // Convert the matched value to a number value = parseEther(match[1]); } - + console.log({ command, value }); - + const preview = await client.readContract({ address: IE_ADDRESS, abi: IntentsEngineAbi, @@ -90,21 +106,8 @@ export const Shell = () => { args: [command], }); - addLine(

- Preview: {JSON.stringify(preview)} -

) - - const confirm = window.confirm( - `Are you sure you want to execute the following command?\n\n${preview}\n\n`, - ); - - console.log({ preview, confirm }); - - if (!confirm) { - addLine(

Command cancelled.

); - return; - } - + addLine(

Preview: {serialize(preview)}

); + if (!isAddressEqual(preview[2], ETH_ADDRESS)) { // consent to spend tokens const allowance = await client.readContract({ @@ -113,9 +116,9 @@ export const Shell = () => { functionName: "allowance", args: [address, IE_ADDRESS], }); - + console.log({ allowance }); - + if (allowance < preview[1]) { // we do a lil approve dance const approveTxHash = await writeContractAsync({ @@ -124,18 +127,18 @@ export const Shell = () => { functionName: "approve", args: [IE_ADDRESS, maxUint256], }); - + addLine(

Approve TX Hash: {approveTxHash}

); - + const allowanceReceipt = await client.waitForTransactionReceipt({ hash: approveTxHash, confirmations: 1, }); - - addLine(

Allowance Set. Receipt: {JSON.stringify(allowanceReceipt)}

); + + addLine(

Allowance Set. Receipt: {serialize(allowanceReceipt)}

); } } - + const commandTxHash = await writeContractAsync({ address: IE_ADDRESS, abi: IntentsEngineAbi, @@ -143,22 +146,26 @@ export const Shell = () => { value, args: [command], }); - + addLine(

Command TX Hash: {commandTxHash}

); - + const commandReceipt = await client.waitForTransactionReceipt({ hash: commandTxHash, confirmations: 1, }); - - addLine(

Command Executed. Receipt: {JSON.stringify(commandReceipt)}

); + + addLine( +

Command Executed. Receipt: {JSON.stringify(commandReceipt)}

, + ); } catch (error) { console.error(error); - error instanceof Error ? addError(error) : addError(new Error("Unknown error")); + error instanceof Error + ? addError(error) + : addError(new Error("Unknown error")); } } - - const id = createId(chain?.id, name ?? address) + + const id = createId(chain?.id, name ?? address); if (!isConnected || !address || !chain) return null;