import React, { createContext, ReactNode, useCallback, useContext, useEffect, useRef, 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' import BossOutcomeModal from '../components/BossOutcomeModal' import styles from "../styles/Background.module.css" 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 LastBossResult { level: BossLevel; variant: BossLevel; battled_at: bigint; reward: bigint; prestigeGained: boolean; } export interface PlayerContextType { isRegistered: boolean, player: null | Player, army: null | Army, boss: null | Boss, lastBossResult: null | LastBossResult, balance: bigint, register: (arg: "ETH" | "RGCVII") => void, raid: () => void, battleWithBoss: () => void; addUnit: (unit: UnitType, amount?: number) => void; } const PlayerContext = createContext({ isRegistered: false, player: null, army: null, boss: null, lastBossResult: 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, () => { }]) const [bossBattledModalOpen, setBossBattlesModalOpen] = useState(false); const hasFetchedLastBossFirstTime = useRef(false); 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 } }); const { data: lastBossResult } = useReadContract({ address: contractAddress, abi, functionName: 'getLastBossResult', 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.00045"), }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) }, onError: () => resetHashAndCallback() }) } else if (arg === "RGCVII") { writeContract({ abi, address: daoTokenAddress, functionName: 'approve', args: [contractAddress, parseEther("400")], }, { onSuccess: (hash) => { setHashAndCallback([ hash, () => writeContract({ abi, address: contractAddress, functionName: 'register_dao', }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) }, onError: () => resetHashAndCallback() }) ]) }, onError: () => resetHashAndCallback() }); } }, [writeContract, resetHashAndCallback]) const raid = useCallback(() => { writeContract({ abi, address: contractAddress, functionName: 'raid', }, { onSuccess: (hash) => { setHashAndCallback([hash, resetHashAndCallback]) }, onError: () => 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', }, { onSuccess: (hash) => { setHashAndCallback([hash, () => resetHashAndCallback()]) }, onError: () => resetHashAndCallback() }) }, [writeContract, resetHashAndCallback]) useEffect(() => { if (lastBossResult != null) { if (hasFetchedLastBossFirstTime.current) { setBossBattlesModalOpen(true); } else { hasFetchedLastBossFirstTime.current = true; } } }, [lastBossResult]) return ( {children}
{txHash && } {bossBattledModalOpen && }
); } export const usePlayer = () => { return useContext(PlayerContext); } export default PlayerProvider