diff --git a/package.json b/package.json index bb91c3a..931972a 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@tanstack/react-query": "^5.45.1", "@uploadthing/react": "^6.6.0", "@web3modal/wagmi": "^5.0.3", + "axios": "^1.7.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.394.0", diff --git a/src/app/api/review/[id]/route.ts b/src/app/api/review/[id]/route.ts new file mode 100644 index 0000000..62ed2fe --- /dev/null +++ b/src/app/api/review/[id]/route.ts @@ -0,0 +1,24 @@ +import { prisma } from '@/utils/connect' +import { NextRequest, NextResponse } from 'next/server' + +export const GET = async ( + req: NextRequest, + { params }: { params: { id: string } } +) => { + // const body = await req.json() + + const { id } = params + + try { + const phygitals = prisma.phygital.findMany() + + return new NextResponse(JSON.stringify(phygitals), { status: 200 }) + } catch (error) { + console.log(error) + + return new NextResponse( + JSON.stringify({ message: 'something went wrong getting phygital' }), + { status: 500 } + ) + } +} diff --git a/src/app/api/uploadthing/core.ts b/src/app/api/uploadthing/core.ts deleted file mode 100644 index 96a113b..0000000 --- a/src/app/api/uploadthing/core.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createUploadthing, type FileRouter } from 'uploadthing/next' - -const f = createUploadthing() - -// const auth = (req: Request) => ({ id: "fakeId" }); // Fake auth function - -// FileRouter for your app, can contain multiple FileRoutes -export const ourFileRouter = { - // Define as many FileRoutes as you like, each with a unique routeSlug - imageUploader: f({ image: { maxFileSize: '4MB', maxFileCount: 10 } }) - // // Set permissions and file types for this FileRoute - // .middleware(async (req) => { - // // This code runs on your server before upload - // const user = await auth(req); - - // // If you throw, the user will not be able to upload - // if (!user) throw new Error("Unauthorized"); - - // // Whatever is returned here is accessible in onUploadComplete as `metadata` - // return { userId: user.id }; - // }) - .onUploadComplete(async ({ metadata, file }) => { - // This code RUNS ON YOUR SERVER after upload - // console.log("Upload complete for userId:", metadata.userId); - - console.log('file url', file.url) - }), - - // Takes a 4 2mb images and/or 1 256mb video - mediaPost: f({ - image: { maxFileSize: '2MB', maxFileCount: 4 }, - video: { maxFileSize: '256MB', maxFileCount: 1 }, - }) - // .middleware((req) => auth(req)) - .onUploadComplete((data) => console.log('file', data)), -} satisfies FileRouter - -export type OurFileRouter = typeof ourFileRouter diff --git a/src/app/api/uploadthing/route.ts b/src/app/api/uploadthing/route.ts deleted file mode 100644 index fca8d73..0000000 --- a/src/app/api/uploadthing/route.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createRouteHandler } from 'uploadthing/next' - -import { ourFileRouter } from './core' - -// Export routes for Next App Router -export const { GET, POST } = createRouteHandler({ - router: ourFileRouter, -}) diff --git a/src/app/page.tsx b/src/app/page.tsx index 5f27bf2..a988147 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,8 +1,160 @@ +'use client' +import { useState, useEffect } from 'react' import { Button, Navbar } from '@/components' import Image from 'next/image' import Link from 'next/link' +import { useWriteContract, useWalletClient, useChainId } from 'wagmi' +import { abi } from '../lib/abi' // Adjust the path to your ABI file +import { bytecode } from '../lib/bytecode' +import { createPublicClient, http, Hex } from 'viem' +import { baseSepolia } from 'viem/chains' +import { useAccount } from 'wagmi' +import Phygital from '../lib/phygital.json' +import SimpleStorage from '../lib/SimpleStorage.json' +import Simplestore from '../lib/Simplestore.json' +import axios from 'axios' + +// const contractAddress = '0xcA1DE631D9Cb2e64C863BF50b83D18249dFb7054' export default function Home() { + const { address: walletAddress } = useAccount() + + const [contractAddress, setContractAddress] = useState< + `0x${string}` | undefined + >() + const [error, setError] = useState(null) + const [isDeployed, setIsDeployed] = useState(false) + + const publicClient = createPublicClient({ + chain: baseSepolia, + transport: http(), + }) + + const chainId = useChainId() + const { data: walletClient } = useWalletClient({ chainId }) + + async function verifyContract( + contractAddress: string, + contractSourceCode: string, + contractName: string, + compilerVersion: string, + constructorArguments: string + ) { + const apiKey = 'RBNWT988E1EQS41KEP1P4GIHP279Y1TU7I' + + const params = new URLSearchParams() + params.append('apikey', apiKey) + params.append('module', 'contract') + params.append('action', 'verifysourcecode') + params.append('contractaddress', contractAddress) + params.append('sourceCode', contractSourceCode) + params.append('codeformat', 'solidity-single-file') + params.append('contractname', contractName) + params.append('compilerversion', compilerVersion) + params.append('optimizationUsed', '0') // Change to '1' if optimization was used + params.append('runs', '200') // Change to the number of runs if optimization was used + params.append('constructorArguments', constructorArguments) + + try { + const response = await axios.post( + 'https://api-sepolia.etherscan.io/api', + params.toString() + ) + console.log(apiKey) + console.log(contractAddress) + console.log(contractSourceCode) + console.log(contractName) + console.log(compilerVersion) + if (response.data.status === '1') { + console.log('Contract verified successfully') + console.log('Verification response:', response) + console.log('Verification Guid:', response.data.result) + } else { + console.log('Failed to verify contract:', response.data.result) + } + } catch (error) { + console.error('Error verifying contract:', error) + } + } + const deployContract = async () => { + if (!walletClient) { + throw new Error('Wallet client not available') + } + + try { + const hash = await walletClient.deployContract({ + abi: Simplestore.abi, + bytecode: Simplestore.bytecode as Hex, + account: walletAddress, + }) + + if (!hash) { + throw new Error('failed to execeute deploy contract transactiopn') + } + + const txn = await publicClient.waitForTransactionReceipt({ hash }) + setContractAddress(txn.contractAddress as `0x${string}`) + setIsDeployed(true) + + return txn.contractAddress + } catch (error) { + console.error('Deployment error:', error) + setError('Error deploying contract: ' + error) + } + } + + const handleDeploy = async ( + event: React.MouseEvent + ) => { + event.preventDefault() + try { + const address = await deployContract() + console.log('Contract deployed at:', address) + } catch (error) { + console.error('Error deploying contract:', error) + setError('Error deploying contract: ' + error) + } + } + + const handleVerify = async ( + event: React.MouseEvent + ) => { + event.preventDefault() + if (!contractAddress) { + setError('No contract address found to verify.') + return + } + const contractSourceCode = `// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SimpleStorage { + // Private state variable to store a number + uint256 private number; + + // Setter function to set the value of the number + function setNumber(uint256 _number) public { + number = _number; + } + + // Getter function to get the value of the number + function getNumber() public view returns (uint256) { + return number; + } +}` + try { + await verifyContract( + contractAddress as string, + contractSourceCode, + 'SimpleStorage', // Contract name + 'v0.8.0+commit.c7dfd78e', // Compiler version + '' + ) + } catch (error) { + setError('Error verifying contract: ' + error) + console.error('Error verifying contract:', error) + } + } + return ( <> @@ -35,6 +187,19 @@ export default function Home() { + + {isDeployed && ( + + )} + {contractAddress && ( +

Contract Address: {contractAddress}

+ )} + {error &&

{error}

} blob { + setActiveButton(buttonLabel) + } + + const isDevelopment = process.env.NODE_ENV === 'development' + + const getData = () => { + if (typeof window !== 'undefined' && localStorage) { + return localStorage.getItem('phygitalData') + } + } + + const storedData = getData() ?? '{}' + const parsedData = JSON.parse(storedData) + + const apiUrl = isDevelopment + ? 'http://localhost:3000' // Local development URL + : 'https://studio.myriadflow.com' // Production URL + + const getPhygital = async () => { + const res = await fetch(`${apiUrl}/api/review/${'Phygital1'}`) + + const result = await res.json() + console.log(result) + } + + useEffect(() => { + getPhygital() + }, []) + return ( <>
- - -
-
-
-

Phygital

-

Chain: Base network

-
-
-
-
- - -
-
- -