forked from mico/idle_moloch
268 lines
6.8 KiB
TypeScript
268 lines
6.8 KiB
TypeScript
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) => void
|
|
}
|
|
|
|
const PlayerContext = createContext<PlayerContextType>({
|
|
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.00005"),
|
|
}, {
|
|
onSuccess: (hash) => {
|
|
setHashAndCallback([hash, resetHashAndCallback])
|
|
},
|
|
onError: () => 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])
|
|
},
|
|
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 (
|
|
<PlayerContext.Provider value={{
|
|
isRegistered: isRegistered as boolean,
|
|
player: player as Player,
|
|
army: army as Army,
|
|
boss: boss as Boss,
|
|
balance: balance as bigint,
|
|
lastBossResult: lastBossResult as LastBossResult,
|
|
register,
|
|
raid,
|
|
addUnit,
|
|
battleWithBoss
|
|
}}>
|
|
{children}
|
|
<div className={`${(txHash || bossBattledModalOpen) ? styles.leaderboardOverlay : ""}`}>
|
|
{txHash && <WaitingForTxModal hash={txHash} callbackFn={callbackFn} />}
|
|
{bossBattledModalOpen && <BossOutcomeModal setIsOpen={setBossBattlesModalOpen} />}
|
|
</div>
|
|
</PlayerContext.Provider>
|
|
);
|
|
}
|
|
|
|
export const usePlayer = () => {
|
|
return useContext(PlayerContext);
|
|
}
|
|
|
|
export default PlayerProvider
|
|
|