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, amount?: number) => 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.error(error?.message); }, [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.00005"), }, { 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, amount: number = 1) => { writeContract({ abi, address: contractAddress, functionName: "addUnit", args: [unit, amount], }); }, [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;