diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx index fa30e208c24..c07e9ca6e7a 100644 --- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx +++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx @@ -1,7 +1,14 @@ "use client"; -import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; import { Table, TableBody, @@ -12,6 +19,8 @@ import { TableRow, } from "@/components/ui/table"; import { getThirdwebClient } from "@/constants/thirdweb.server"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useMutation } from "@tanstack/react-query"; import { type ColumnDef, flexRender, @@ -32,13 +41,16 @@ import { } from "components/contract-components/contract-deploy-form/modular-contract-default-modules-fieldset"; import { useTxNotifications } from "hooks/useTxNotifications"; import Link from "next/link"; +import { useForm } from "react-hook-form"; import { ZERO_ADDRESS, defineChain, eth_getTransactionCount, getContract, getRpcClient, + prepareContractCall, readContract, + sendAndConfirmTransaction, sendTransaction, waitForReceipt, } from "thirdweb"; @@ -55,6 +67,7 @@ import { encodeAbiParameters, padHex, } from "thirdweb/utils"; +import { z } from "zod"; type CrossChain = { id: number; @@ -63,6 +76,22 @@ type CrossChain = { status: "DEPLOYED" | "NOT_DEPLOYED"; }; +type ChainId = "84532" | "11155420" | "919" | "111557560" | "999999999"; + +const formSchema = z.object({ + amounts: z.object({ + "84532": z.string(), + "11155420": z.string(), + "919": z.string(), + "111557560": z.string(), + "999999999": z.string(), + }), +}); +type FormSchema = z.output; + +const positiveIntegerRegex = /^[0-9]\d*$/; +const superchainBridgeAddress = "0x4200000000000000000000000000000000000028"; + export function DataTable({ data, coreMetadata, @@ -84,6 +113,64 @@ export function DataTable({ "Failed to deploy contract", ); + const form = useForm({ + resolver: zodResolver(formSchema), + values: { + amounts: { + "84532": "", // Base + "11155420": "", // OP testnet + "919": "", // Mode Network + "111557560": "", // Cyber + "999999999": "", // Zora + }, + }, + }); + + const crossChainTransfer = async (chainId: ChainId) => { + if (!activeAccount) { + throw new Error("Account not connected"); + } + const amount = form.getValues().amounts[chainId]; + if (!positiveIntegerRegex.test(amount)) { + form.setError(`amounts.${chainId}`, { message: "Invalid Amount" }); + return; + } + + const superChainBridge = getContract({ + address: superchainBridgeAddress, + chain: coreContract.chain, + client: coreContract.client, + }); + + const sendErc20Tx = prepareContractCall({ + contract: superChainBridge, + method: + "function sendERC20(address _token, address _to, uint256 _amount, uint256 _chainId)", + params: [ + coreContract.address, + activeAccount.address, + BigInt(amount), + BigInt(chainId), + ], + }); + + await sendAndConfirmTransaction({ + account: activeAccount, + transaction: sendErc20Tx, + }); + }; + + const crossChainTransferNotifications = useTxNotifications( + "Successfully submitted cross chain transfer", + "Failed to submit cross chain transfer", + ); + + const crossChainTransferMutation = useMutation({ + mutationFn: crossChainTransfer, + onSuccess: crossChainTransferNotifications.onSuccess, + onError: crossChainTransferNotifications.onError, + }); + const columns: ColumnDef[] = [ { accessorKey: "network", @@ -112,10 +199,40 @@ export function DataTable({ header: "Status", cell: ({ row }) => { if (row.getValue("status") === "DEPLOYED") { - return Deployed; + return ( + ( + + +
+ + +
+
+ +
+ )} + /> + ); } return ( - ); @@ -250,8 +367,6 @@ export function DataTable({ ); } - console.log("nonce used: ", currentNonce + i); - const installTransaction = installPublishedModule({ contract, account: activeAccount, @@ -285,42 +400,49 @@ export function DataTable({ }; return ( - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - +
+ + +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + ))} - - ))} - -
- -
+ + + + + + ); }