content.tsx
1 'use client'; 2 import {ConnectButton} from '@rainbow-me/rainbowkit'; 3 4 import {useAccount} from 'wagmi'; 5 import { useReadContracts, useConfig } from 'wagmi' 6 7 import abi from "../bloxy-abi.json"; 8 import { useEffect, useState } from 'react'; 9 import { readContract } from '@wagmi/core' 10 11 import { useWriteContract } from 'wagmi' 12 13 14 15 console.log(abi) 16 17 const contractAddr = "0xfF780774c0eE8f3D9C4611e9c221Aedc30503220"; 18 const DOMAIN = "bloxy.one" 19 20 const Content = () => { 21 const [tokenIds, setTokenIds] = useState<number[]>([]) 22 const [paymentToken, setPaymentToken] = useState<number>(0) 23 const [name, setName] = useState<string>() 24 const [domain, setDomain] = useState<string>() 25 const [target, setTarget] = useState<string>() 26 27 28 const config = useConfig() 29 const {isConnected, address} = useAccount(); 30 const { data: balance } = useReadContracts({ contracts: [ 31 { 32 abi, 33 address: contractAddr, 34 functionName: 'balanceOf', 35 args: [address], 36 }, 37 ]}) 38 39 const [entries, setEntries] = useState([]) 40 41 const { writeContract } = useWriteContract() 42 43 44 useEffect(() => { 45 if (!balance) return 46 47 console.log(balance[0].result) 48 const b = parseInt(balance && balance[0].result > 0 && balance[0].result.toString()) 49 for (var i=0; i<b; i++) { 50 console.log("Querying...") 51 readContract(config, { 52 abi, 53 address: contractAddr, 54 functionName: 'tokenOfOwnerByIndex', 55 args: [address, i], 56 }).then((tokenId) => { 57 console.log(tokenId) 58 if (tokenId === null || tokenId === undefined) return 59 readContract(config, { 60 abi, 61 address: contractAddr, 62 functionName: 'entries', 63 args: [tokenId.toString()], 64 }).then(entry => { 65 console.log(entry) 66 67 if (!entry) return 68 const e = {tokenId: parseInt(tokenId.toString()) ,name: entry[0], domain: entry[1], target: entry[2], expiry: parseInt(entry[3].toString())*1000} 69 console.log(e) 70 setEntries(entries => [...entries, e]) 71 }) 72 }) 73 } 74 75 }, [balance]) 76 77 const createEntry = async () => { 78 const entry = {name: name, domain: domain, target: target, expiry: BigInt(0)} 79 var value = BigInt(0) 80 81 console.log(value) 82 83 if (paymentToken == 0) { 84 console.log("Here") 85 const result = await readContract(config, { 86 abi, 87 address: contractAddr, 88 functionName: 'getPriceETH', 89 args: [60*60*24*30], 90 }) 91 92 console.log(result) 93 value = (BigInt(result && result.toString()) * BigInt(150)) / BigInt(100) 94 console.log(value) 95 } 96 97 writeContract({ 98 abi, 99 address: contractAddr, 100 functionName: "newEntry", 101 args: [entry], 102 value: value, 103 }) 104 } 105 106 const deleteEntry = (tokenId: number) => { 107 writeContract({ 108 abi, 109 address: contractAddr, 110 functionName: "removeEntry", 111 args: [tokenId], 112 }) 113 } 114 115 return ( 116 <main className="max-w-4xl m-auto space-y-7 items-center text-center"> 117 <h1 className='text-4xl'>Bloxy Proxy</h1> 118 <div className="m-auto max-w-fit"> 119 120 <ConnectButton /> 121 122 </div> 123 <div> 124 { isConnected && 125 <div className='space-y-7'> 126 <div> 127 <h2 className='text-2xl'>New Entry</h2> 128 <div> 129 Name 130 </div> 131 <div> 132 <input type="text" onChange={(e) => setName(e.target.value)} className="input-md input-primary input" /> 133 </div> 134 <div> 135 Domain 136 </div> 137 <div> 138 <input type="text" onChange={(e) => setDomain(e.target.value)} className="input-md input-primary input" /> 139 </div> 140 <div> 141 Target 142 </div> 143 <div> 144 <input type="text" onChange={(e) => setTarget(e.target.value)} className="input-md input-primary input" /> 145 </div> 146 <div> 147 Pay in 148 </div> 149 <div className='max-w-32 m-auto'> 150 <div> 151 <label className="label cursor-pointer"> 152 <span className="label-text">ETH</span> 153 <input type="radio" name="paymentToken" checked={paymentToken == 0} onClick={() => setPaymentToken(0)} className='radio radio-primary' /> 154 </label> 155 </div> 156 <div> 157 <label className="label cursor-pointer"> 158 <span className="label-text">USDC</span> 159 <input type="radio" name="paymentToken" checked={paymentToken == 1} onClick={() => setPaymentToken(1)} className='radio radio-primary' /> 160 </label> 161 </div> 162 </div> 163 <div> 164 <button className='btn' onClick={() => createEntry()}>Submit</button> 165 </div> 166 </div> 167 <div> 168 <div className='text-2xl'>Your Entries</div> 169 170 {entries.length == 0 ? 171 <div className='loading loading-spinner'></div> 172 : 173 <table className='table table-zebra w-full'> 174 <thead> 175 <tr> 176 <th>Name</th> 177 <th>Domain</th> 178 <th>Target</th> 179 <th>Expiry</th> 180 </tr> 181 </thead> 182 <tbody> 183 {entries.map((entry) => 184 <tr id={entry.name}> 185 <td><a href={`https://${entry.name}.${DOMAIN}`} target='_blank' className='link'>{entry?.name}</a></td> 186 <td>{entry?.domain}</td> 187 <td>{entry?.target}</td> 188 <td>{entry.expiry == 0? "---" : (new Date(entry?.expiry)).toLocaleString()}</td> 189 <td><button className='btn btn-sm btn-disabled btn-primary'>Edit</button></td> 190 <td>{entry.expiry != 0 &&<button className='btn btn-sm btn-primary'>Extend</button>}</td> 191 <td><button className='btn btn-sm btn-secondary' onClick={() => deleteEntry(entry.tokenId)}>Delete</button></td> 192 </tr> 193 )} 194 </tbody> 195 </table> 196 } 197 </div> 198 </div> 199 } 200 </div> 201 </main> 202 ) 203 } 204 205 export default Content