import React, { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react' import { useAccount, useReadContract, useWriteContract } from 'wagmi' import contractAbi from "../../../out/RaidGeld.sol/RaidGeld.json" import { Hash, parseEther } from 'viem' import contracts from '../../contract_address' import WaitingForTxModal from '../components/WaitingForTxModal' const { contractAddress, daoTokenAddress } = contracts const abi = contractAbi.abi export type UnitType = 0 | 1 | 2 | 3 export type BossLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 export interface Player { created_at: bigint, last_raided_at: bigint, total_minted: bigint total_rewards: bigint, n_runs: number, prestige_level: number, is_registered: boolean, has_active_session: boolean, } export interface Army { anointed: { level: number } apprentice: { level: number } champion: { level: number } moloch_denier: { level: number } profit_per_second: bigint } export interface Boss { level: BossLevel; variants: [BossLevel, BossLevel, BossLevel, BossLevel, BossLevel, BossLevel, BossLevel] } export interface PlayerContextType { isRegistered: boolean, player: null | Player, army: null | Army, boss: null | Boss, balance: bigint, register: (arg: "ETH" | "RGCVII") => void, raid: () => void, battleWithBoss: () => void; addUnit: (unit: UnitType) => void } const PlayerContext = createContext({ isRegistered: false, player: null, army: null, boss: null, balance: BigInt(0), register: () => { }, raid: () => { }, battleWithBoss: () => { }, addUnit: () => { } }); const PlayerProvider = ({ children }: { children: ReactNode }) => { const { address, isConnected } = useAccount(); const { writeContract, error } = useWriteContract(); const [[txHash, callbackFn], setHashAndCallback] = useState<[Hash | null, () => void]>([null, () => { }]) useEffect(() => { console.warn(error) }, [error]) const resetHashAndCallback = useCallback(() => { setHashAndCallback([null, () => { }]) }, []) const { data: isRegistered } = useReadContract({ address: contractAddress, abi, functionName: 'isRegistered', args: [address], query: { enabled: isConnected, refetchInterval: 15, } }); const { data: balance, } = useReadContract({ address: contractAddress, abi, functionName: 'balanceOf', args: [address], query: { refetchInterval: 15, enabled: isConnected } }); const { data: player } = useReadContract({ address: contractAddress, abi, functionName: 'getPlayer', args: [address], query: { enabled: isConnected, refetchInterval: 15 } }); const { data: army } = useReadContract({ address: contractAddress, abi, functionName: 'getArmy', args: [address], query: { enabled: isConnected, refetchInterval: 15 } }); const { data: boss } = useReadContract({ address: contractAddress, abi, functionName: 'getBoss', args: [address], query: { enabled: isConnected, refetchInterval: 15 } }); console.log(balance, player, army, boss) const register = useCallback((arg: "RGCVII" | "ETH") => { if (arg === 'ETH') { writeContract({ abi, address: contractAddress, functionName: 'register_eth', value: parseEther("0.0005"), }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) } }) } else if (arg === "RGCVII") { writeContract({ abi, address: daoTokenAddress, functionName: 'approve', args: [contractAddress, parseEther("500")], }, { onSuccess: (hash) => { setHashAndCallback([ hash, () => writeContract({ abi, address: contractAddress, functionName: 'register_dao', }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) } }) ]) } }); } }, [writeContract, resetHashAndCallback]) const raid = useCallback(() => { writeContract({ abi, address: contractAddress, functionName: 'raid', }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) } }) }, [writeContract, resetHashAndCallback]) const addUnit = useCallback((unit: UnitType) => { writeContract({ abi, address: contractAddress, functionName: 'addUnit', args: [unit, 1] }) }, [writeContract]) const battleWithBoss = useCallback(() => { writeContract({ abi, address: contractAddress, functionName: 'battle_with_boss', }) }, [writeContract]) return ( {children} {txHash && } ); } export const usePlayer = () => { return useContext(PlayerContext); } export default PlayerProvider