forked from mico/idle_moloch
257 lines
5.8 KiB
TypeScript
257 lines
5.8 KiB
TypeScript
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<PlayerContextType>({
|
|
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 (
|
|
<PlayerContext.Provider
|
|
value={{
|
|
isRegistered: isRegistered as boolean,
|
|
player: player as Player,
|
|
army: army as Army,
|
|
boss: boss as Boss,
|
|
balance: balance as bigint,
|
|
register,
|
|
raid,
|
|
addUnit,
|
|
battleWithBoss,
|
|
}}
|
|
>
|
|
{children}
|
|
{txHash && <WaitingForTxModal hash={txHash} callbackFn={callbackFn} />}
|
|
</PlayerContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const usePlayer = () => {
|
|
return useContext(PlayerContext);
|
|
};
|
|
|
|
export default PlayerProvider;
|