@@ -20,8 +20,9 @@ import { useEthersSigner } from "@/hooks/useEthersSigner";
2020import { getChallengeContract } from "@/service/contract" ;
2121import { XMarkIcon } from "@heroicons/react/24/solid" ;
2222import useAutoSwitchNetwork from "@/hooks/useAutoSwitchNetwork" ;
23- import { EthersError , formatUnits } from ' ethers'
23+ import { EthersError , formatUnits } from " ethers" ;
2424import { useEthersProvider } from "@/hooks/useEthersProvider" ;
25+ import { useFrontendMoveMutation } from "@/hooks/useFrontendMove" ;
2526
2627const xGap = 45 ;
2728const yGap = 50 ;
@@ -32,8 +33,8 @@ type Node = {
3233 claim : string ;
3334 position : string ;
3435 value : string ;
35- parentIndex : number ,
36- isRoot ?: boolean ,
36+ parentIndex : number ;
37+ isRoot ?: boolean ;
3738 itemStyle : {
3839 color : string ;
3940 } ;
@@ -138,9 +139,13 @@ const genNodesAndLinks = (data: ClaimData[]): any => {
138139 } ;
139140} ;
140141
141- const ClaimChart : FC < { claimData : ClaimData [ ] , address : string , resolved : boolean } > = ( { claimData, address, resolved } ) => {
142+ const ClaimChart : FC < {
143+ claimData : ClaimData [ ] ;
144+ address : string ;
145+ resolved : boolean ;
146+ } > = ( { claimData, address, resolved } ) => {
142147 const { nodes, links, maxDepth } = genNodesAndLinks ( claimData ) ;
143- useAutoSwitchNetwork ( )
148+ useAutoSwitchNetwork ( ) ;
144149 const { isMutating, trigger } = useCalculateClaim ( ) ;
145150 const options : EChartOption < EChartOption . SeriesGraph > = {
146151 tooltip : {
@@ -196,111 +201,155 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
196201 ] ,
197202 } ;
198203 const { openConnectModal } = useConnectModal ( ) ;
199- const { isConnected } = useAccount ( )
204+ const { address : addr , isConnected } = useAccount ( ) ;
200205 const [ showModal , setShowModal ] = useState ( false ) ;
201206 const [ modalData , setModalData ] = useState < Node > ( ) ;
202207 const [ val , setVal ] = useState ( "" ) ;
203- const [ recommendAttackClaim , setAttackClaim ] = useState ( "" )
208+ const [ recommendAttackClaim , setAttackClaim ] = useState ( "" ) ;
204209 const [ attackLoading , setAttackLoading ] = useState ( false ) ;
205210 const [ defendLoading , setDefendLoading ] = useState ( false ) ;
206- const signer = useEthersSigner ( )
207- const provider = useEthersProvider ( )
211+ const signer = useEthersSigner ( ) ;
212+ const provider = useEthersProvider ( ) ;
208213 const [ gas , setGas ] = useState ( {
209- attackGas : '' ,
210- defendGas : ''
211- } )
214+ attackGas : "" ,
215+ defendGas : "" ,
216+ } ) ;
217+
218+ const { trigger : frontMove } = useFrontendMoveMutation ( ) ;
212219
213220 const attackPosition = useMemo ( ( ) => {
214221 if ( modalData ) {
215- return 2 * Number ( modalData . position )
222+ return 2 * Number ( modalData . position ) ;
216223 }
217- } , [ modalData ] )
224+ } , [ modalData ] ) ;
218225 const defendPosition = useMemo ( ( ) => {
219226 if ( modalData ) {
220- return 2 * ( Number ( modalData . position ) + 1 )
227+ return 2 * ( Number ( modalData . position ) + 1 ) ;
221228 }
222- } , [ modalData ] )
229+ } , [ modalData ] ) ;
223230
224231 const handleClick = ( e : any ) => {
225232 if ( ! isConnected ) {
226- openConnectModal && openConnectModal ( )
227- return
233+ openConnectModal && openConnectModal ( ) ;
234+ return ;
228235 }
229236 if ( resolved ) {
230- toast . warning ( ' This game has already resolved!' )
231- return
237+ toast . warning ( " This game has already resolved!" ) ;
238+ return ;
232239 }
233240 setShowModal ( true ) ;
234241 setModalData ( e . data ) ;
235242 } ;
236243
237244 useEffect ( ( ) => {
238245 if ( attackPosition ) {
239- trigger ( { disputeGame : address , position : attackPosition } ) . then ( ( res ) => {
240- setAttackClaim ( res . claims )
241- } )
246+ trigger ( { disputeGame : address , position : attackPosition } ) . then (
247+ ( res ) => {
248+ setAttackClaim ( res . claims ) ;
249+ }
250+ ) ;
242251 }
243- } , [ attackPosition ] )
252+ } , [ attackPosition ] ) ;
244253
245254 useEffect ( ( ) => {
246255 const getGas = async ( ) => {
247256 if ( attackPosition && defendPosition && provider ) {
248- const contract = getChallengeContract ( address , provider )
249- const attackGas = await contract . getRequiredBond ( attackPosition )
250- const defendGas = await contract . getRequiredBond ( defendPosition )
257+ const contract = getChallengeContract ( address , provider ) ;
258+ const attackGas = await contract . getRequiredBond ( attackPosition ) ;
259+ const defendGas = await contract . getRequiredBond ( defendPosition ) ;
251260 setGas ( {
252261 attackGas : formatUnits ( attackGas , 18 ) ,
253- defendGas : formatUnits ( defendGas , 18 )
254- } )
262+ defendGas : formatUnits ( defendGas , 18 ) ,
263+ } ) ;
255264 }
256- }
257- getGas ( )
258- } , [ attackPosition , defendPosition , provider ] )
259-
265+ } ;
266+ getGas ( ) ;
267+ } , [ attackPosition , defendPosition , provider ] ) ;
260268
261269 const handleAttack = async ( ) => {
262270 if ( ! signer ) return ;
263271 if ( ! val ) {
264- toast . error ( 'Challenge claim required!' )
265- return
266- } ;
267- const contract = getChallengeContract ( address , signer )
272+ toast . error ( "Challenge claim required!" ) ;
273+ return ;
274+ }
275+ const contract = getChallengeContract ( address , signer ) ;
276+ const game_contract = contract . getAddress ;
268277 try {
269- setAttackLoading ( true )
270- const gas = await contract . getRequiredBond ( attackPosition )
271- const tx = await contract . attack ( '0x' + modalData ?. claim , modalData ?. parentIndex , val , { value : gas } )
272- const res = await tx . wait ( )
273- setAttackLoading ( false )
278+ setAttackLoading ( true ) ;
279+ const gas = await contract . getRequiredBond ( attackPosition ) ;
280+ const tx = await contract . attack (
281+ "0x" + modalData ?. claim ,
282+ modalData ?. parentIndex ,
283+ val ,
284+ { value : gas }
285+ ) ;
286+ const res = await tx . wait ( ) ;
287+ setAttackLoading ( false ) ;
274288 if ( res . status === 1 ) {
275- toast . success ( 'Transaction receipt!' )
289+ toast . success ( "Transaction receipt!" ) ;
290+ const data = {
291+ game_contract : game_contract ,
292+ tx_hash : tx . hash ,
293+ claimant : addr ,
294+ parent_index : modalData ?. parentIndex ,
295+ challenge_index : modalData ?. position ,
296+ disputed_claim : modalData ?. claim ,
297+ claim : val ,
298+ is_attack : true ,
299+ } ;
300+ await frontMove ( data ) ;
276301 }
277302 } catch ( error : any ) {
278- setAttackLoading ( false )
279- toast . error ( error ?. shortMessage || error ?. reason || ' Transaction error!' )
303+ setAttackLoading ( false ) ;
304+ toast . error ( error ?. shortMessage || error ?. reason || " Transaction error!" ) ;
280305 }
281306 } ;
282307
283308 const handleDefend = async ( ) => {
284309 if ( ! val ) {
285- toast . error ( ' Challenge claim required!' )
286- return
287- } ;
310+ toast . error ( " Challenge claim required!" ) ;
311+ return ;
312+ }
288313 if ( ! signer ) return ;
289- const contract = getChallengeContract ( address , signer )
314+ const contract = getChallengeContract ( address , signer ) ;
315+ const game_contract = contract . getAddress ;
290316 try {
291- setDefendLoading ( true )
292- const gas = await contract . getRequiredBond ( defendPosition )
293- const tx = await contract . defend ( '0x' + modalData ?. claim , modalData ?. parentIndex , val , { value : gas } )
294- const res = await tx . wait ( )
317+ setDefendLoading ( true ) ;
318+ const gas = await contract . getRequiredBond ( defendPosition ) ;
319+ const tx = await contract . defend (
320+ "0x" + modalData ?. claim ,
321+ modalData ?. parentIndex ,
322+ val ,
323+ { value : gas }
324+ ) ;
325+ const res = await tx . wait ( ) ;
295326 if ( res . status === 1 ) {
296- toast . success ( 'Transaction receipt!' )
327+ toast . success ( "Transaction receipt!" ) ;
328+ const data = {
329+ game_contract : game_contract ,
330+ tx_hash : tx . hash ,
331+ claimant : addr ,
332+ parent_index : modalData ?. parentIndex ,
333+ challenge_index : modalData ?. position ,
334+ disputed_claim : modalData ?. claim ,
335+ claim : val ,
336+ is_attack : false ,
337+ } ;
338+ await frontMove ( data ) ;
297339 }
298- setDefendLoading ( false )
340+ setDefendLoading ( false ) ;
299341 } catch ( error : any ) {
300- setDefendLoading ( false )
301- toast . error ( error ?. shortMessage || error ?. reason || error ?. msg || error ?. data || error ?. message || 'Transaction error!' )
342+ setDefendLoading ( false ) ;
343+ toast . error (
344+ error ?. shortMessage ||
345+ error ?. reason ||
346+ error ?. msg ||
347+ error ?. data ||
348+ error ?. message ||
349+ "Transaction error!"
350+ ) ;
302351 }
303- }
352+ } ;
304353
305354 return (
306355 < >
@@ -309,8 +358,8 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
309358 as = "div"
310359 className = "relative z-10 focus:outline-none"
311360 onClose = { ( ) => {
312- setShowModal ( false )
313- setVal ( '' )
361+ setShowModal ( false ) ;
362+ setVal ( "" ) ;
314363 } }
315364 >
316365 < DialogBackdrop
@@ -323,17 +372,23 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
323372 transition
324373 className = "w-full max-w-md rounded-xl dark:bg-surface-dark bg-white p-6 backdrop-blur-2xl duration-300 ease-out data-[closed]:transform-[scale(95%)] data-[closed]:opacity-0"
325374 >
326- < DialogTitle as = "h3" className = "text-base/7 font-medium flex justify-between" >
375+ < DialogTitle
376+ as = "h3"
377+ className = "text-base/7 font-medium flex justify-between"
378+ >
327379 Challenge
328- < XMarkIcon onClick = { ( ) => setShowModal ( false ) } className = "w-6 cursor-pointer" />
380+ < XMarkIcon
381+ onClick = { ( ) => setShowModal ( false ) }
382+ className = "w-6 cursor-pointer"
383+ />
329384 </ DialogTitle >
330385 < div className = "mt-4 text-sm/6 text-white/50" >
331386 < div >
332387 < div className = "text-sm font-semibold text-contentSecondary-light dark:text-warmGray-300 mb-1" >
333388 Claim:
334389 </ div >
335390 < div className = "text-sm text-contentSecondary-light dark:text-warmGray-300 mb-2 break-all" >
336- { '0x' + modalData ?. claim }
391+ { "0x" + modalData ?. claim }
337392 </ div >
338393 </ div >
339394 < div >
@@ -345,16 +400,16 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
345400 </ div >
346401 </ div >
347402
348- {
349- ! modalData ?. isRoot && < div >
403+ { ! modalData ?. isRoot && (
404+ < div >
350405 < div className = "text-sm font-semibold text-contentSecondary-light dark:text-warmGray-300 mb-1" >
351406 Defend Required Bond
352407 </ div >
353408 < div className = "text-sm text-contentSecondary-light dark:text-warmGray-300 mb-2 break-all" >
354409 { gas . defendGas } ETH
355410 </ div >
356411 </ div >
357- }
412+ ) }
358413 < div >
359414 < div className = "text-sm font-semibold text-contentSecondary-light dark:text-warmGray-300 mb-1" >
360415 Attack Required Bond
@@ -373,20 +428,22 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
373428 id = "search"
374429 value = { val }
375430 onChange = { ( e ) => setVal ( e . target . value ) }
376- className = { "rounded-none rounded-l-md text-black dark:text-warmGray-300 h-10 " }
431+ className = {
432+ "rounded-none rounded-l-md text-black dark:text-warmGray-300 h-10 "
433+ }
377434 placeholder = { "challenge string" }
378435 />
379436 </ div >
380437 </ div >
381438 < div className = "mt-4 flex justify-end gap-4" >
382- {
383- ! modalData ?. isRoot && < Button
439+ { ! modalData ?. isRoot && (
440+ < Button
384441 label = "defend"
385442 variant = "outline"
386443 icon = { defendLoading ? < Spinner /> : undefined }
387444 onClick = { handleDefend }
388445 > </ Button >
389- }
446+ ) }
390447 < Button
391448 icon = { attackLoading ? < Spinner /> : undefined }
392449 label = "attack"
@@ -402,7 +459,7 @@ const ClaimChart: FC<{ claimData: ClaimData[], address: string, resolved: boolea
402459 title = {
403460 < div className = "flex items-center gap-10" >
404461 < div > Fault Dispute Game Graph</ div >
405- < ConnectButton chainStatus = { ' none' } showBalance = { false } />
462+ < ConnectButton chainStatus = { " none" } showBalance = { false } />
406463 </ div >
407464 }
408465 handleClick = { handleClick }
0 commit comments