'use client' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' import { useDeployWithWallet } from '@/lib/functions/deploy-contract/wallet-deploy' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useEffect, useState } from 'react' import Link from 'next/link' import { IconExternalLink, IconSpinner } from './ui/icons' import { useGlobalStore } from '@/app/state/global-store' import { useNetwork } from 'wagmi' export function DeployContractButton({ sourceCode }: { sourceCode: string }) { const { deploy: deployWithWallet } = useDeployWithWallet() const [constructorArgs, setConstructorArgs] = useState([]) const [explorerUrl, setExplorerUrl] = useState('') const [ipfsUrl, setIpfsUrl] = useState('') const [isErrorDeploying, setIsErrorDeploying] = useState(false) const { isDeploying, setIsDeploying, isGenerating } = useGlobalStore() const { chain } = useNetwork() const [unsupportedNetwork, setUnsupportedNetwork] = useState(false) // check if the network is supported useEffect(() => { if (chain?.unsupported) { setUnsupportedNetwork(true) } else { setUnsupportedNetwork(false) } }, [chain]) // function to get the contract name from the source code const getContractName = () => { const contractNameRegex = /contract\s+(\w+)\s*(?:is|{)/; const contractNameMatch = contractNameRegex.exec(sourceCode) return contractNameMatch ? contractNameMatch[1] : '' } // function to get the constructor arguments from the source code const getConstructorArgs = () => { // regex match to get the constructor arguments from the source code. // i.e. constructor(uint256 _initialSupply, string memory _name, string memory _symbol) should get uint256 _initialSupply, string memory _name, string memory _symbol const constructorArgsRegex = /constructor\(([^)]+)\)/ const constructorArgsMatch = constructorArgsRegex.exec(sourceCode) if (!constructorArgsMatch) return [] const constructorArgs = constructorArgsMatch[1] // split the constructor arguments into an array const constructorArgsArray = constructorArgs.split(',') // trim the whitespace from each argument const trimmedConstructorArgsArray = constructorArgsArray.map(arg => arg.trim() ) // return the array of constructor arguments return trimmedConstructorArgsArray } function generateInputFields() { const generatedConstructorArgs = getConstructorArgs() const inputFields = generatedConstructorArgs.map((arg, index) => { return (
{ const newConstructorArgs = [...constructorArgs] newConstructorArgs[index] = e.target.value setConstructorArgs(newConstructorArgs) }} className="rounded-md border border-gray-300 p-2" />
) }) return inputFields } // Handler for deploy with wallet const handleDeployWithWallet = async () => { setIsDeploying(true) setIsErrorDeploying(false) try { const { explorerUrl, ipfsUrl } = await deployWithWallet({ contractName: getContractName(), sourceCode, constructorArgs: constructorArgs }) explorerUrl && setExplorerUrl(explorerUrl) setIpfsUrl(ipfsUrl) setIsDeploying(false) } catch (e) { console.log(e) setIsErrorDeploying(true) setIsDeploying(false) } } return (
{ if (!isOpen && !isDeploying) { setExplorerUrl('') setIpfsUrl('') setConstructorArgs([]) setIsErrorDeploying(false) } }} > Manually Deploy Contract Deploy the contract using your wallet. Must be connected to a supported testnet.

Agent Deploy

RECOMMENDED

{`This method does not require wallet connection. Just use the keyword "deploy" in the chat.`}

Deploy with Wallet

ADVANCED

Sign and deploy the contract using your own wallet. Be cautious of risks and network fees.

{getConstructorArgs().length > 0 && (
Constructor Arguments {generateInputFields()}
)}
{isErrorDeploying && (

Error deploying contract.

)} {isDeploying && ( )} {explorerUrl && (
View on Explorer
)} {ipfsUrl && (
View on IPFS
)}
) }