Skip to content

Commit

Permalink
feat: mudExample.tsx
Browse files Browse the repository at this point in the history
  • Loading branch information
singyiu committed Oct 20, 2023
1 parent 5658d96 commit 507c8e1
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 19 deletions.
109 changes: 107 additions & 2 deletions packages/client/src/mud/createSystemCalls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { ethers } from "ethers";
import { ClientComponents } from "./createClientComponents";
import { SetupNetworkResult } from "./setupNetwork";

import IERC20Abi from "contracts/out/IERC20.sol/IERC20.abi.json";
import ILapuVaultAbi from "contracts/out/ILapuVault.sol/ILapuVault.abi.json";

export type SystemCalls = ReturnType<typeof createSystemCalls>;

export function createSystemCalls(
Expand All @@ -31,8 +34,21 @@ export function createSystemCalls(
* through createClientComponents.ts, but it originates in
* syncToRecs (https://github.com/latticexyz/mud/blob/26dabb34321eedff7a43f3fcb46da4f3f5ba3708/templates/react/packages/client/src/mud/setupNetwork.ts#L39).
*/
{ worldContract, waitForTransaction }: SetupNetworkResult,
{ Counter, Position, Orientation, EntityType, OwnedBy }: ClientComponents
{
worldContract,
waitForTransaction,
publicClient,
walletClient,
worldAddress,
}: SetupNetworkResult,
{
Counter,
Position,
Orientation,
EntityType,
OwnedBy,
GameSetting,
}: ClientComponents
) {
const defaultVector3 = new Vector3(1, 0, 3);

Expand Down Expand Up @@ -196,6 +212,88 @@ export function createSystemCalls(
return res;
};

const approveDaiToLapuVaultForTheConnectedPlayer = async (amount) => {
const gameSetting = await getComponentValue(GameSetting, singletonEntity);
const { request } = await publicClient.simulateContract({
address: gameSetting?.daiAddress,
abi: IERC20Abi,
functionName: "approve",
args: [gameSetting?.lapuVaultAddress, amount],
account: walletClient?.account,
});
const res = await walletClient.writeContract(request);
return res;
};

const approveLapuToMudWorldForTheConnectedPlayer = async (amount) => {
const gameSetting = await getComponentValue(GameSetting, singletonEntity);
const { request } = await publicClient.simulateContract({
address: gameSetting?.lapuVaultAddress,
abi: IERC20Abi,
functionName: "approve",
args: [worldAddress, amount],
account: walletClient?.account,
});
const res = await walletClient.writeContract(request);
return res;
};

const depositDaiToLapuVaultForTheConnectedPlayer = async (amount) => {
const gameSetting = await getComponentValue(GameSetting, singletonEntity);
const { request } = await publicClient.simulateContract({
address: gameSetting?.lapuVaultAddress,
abi: ILapuVaultAbi,
functionName: "deposit",
args: [amount, walletClient?.account.address],
account: walletClient?.account,
});
const res = await walletClient.writeContract(request);
return res;
};

const withdrawDaiFromLapuVaultForTheConnectedPlayer = async (amount) => {
const gameSetting = await getComponentValue(GameSetting, singletonEntity);
const { request } = await publicClient.simulateContract({
address: gameSetting?.lapuVaultAddress,
abi: ILapuVaultAbi,
functionName: "withdraw",
args: [
amount,
walletClient?.account.address,
walletClient?.account.address,
],
account: walletClient?.account,
});
const res = await walletClient.writeContract(request);
return res;
};

const mudDefiConsumesLapuFromPlayer = async (amount, playerAddress) => {
const tx = await worldContract.write.defiConsumesLapuFromPlayer([
amount,
playerAddress,
]);
await waitForTransaction(tx);
return tx;
};

const mudMockYieldGenerationFromDeFiPool = async (amount) => {
const tx = await worldContract.write.mockYieldGenerationFromDeFiPool([
amount,
]);
await waitForTransaction(tx);
return tx;
};

const mudMockReleaseRewardToPlayer = async (playerAddress, amount) => {
const tx = await worldContract.write.mockReleaseRewardToPlayer([
playerAddress,
amount,
]);
await waitForTransaction(tx);
return tx;
};

return {
increment,
mudGetEntityType,
Expand All @@ -211,5 +309,12 @@ export function createSystemCalls(
mudDefiDaiBalanceOf,
mudDefiLapuBalanceOf,
mudDefiGetTotalRewardBalance,
approveDaiToLapuVaultForTheConnectedPlayer,
approveLapuToMudWorldForTheConnectedPlayer,
depositDaiToLapuVaultForTheConnectedPlayer,
withdrawDaiFromLapuVaultForTheConnectedPlayer,
mudDefiConsumesLapuFromPlayer,
mudMockYieldGenerationFromDeFiPool,
mudMockReleaseRewardToPlayer,
};
}
1 change: 1 addition & 0 deletions packages/client/src/mud/setupNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,6 @@ export async function setupNetwork() {
waitForTransaction,
worldContract,
write$: write$.asObservable().pipe(share()),
worldAddress: networkConfig.worldAddress as Hex,
};
}
122 changes: 106 additions & 16 deletions packages/client/src/mudExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,100 @@ import { singletonEntity } from "@latticexyz/store-sync/recs";
import { useMUD } from "./useMUD";

import { getState } from "./game/store";
import { useState } from "react";
import { useState, useEffect } from "react";

export const MudExample = () => {
const {
components: { Counter },
systemCalls: {
mudGetAllFacilityEntityMetadatas,
mudBuildFacility,
mudGetEntityMetadataAtPosition,
mudDefiDaiBalanceOf,
mudMockDaiFaucet,
approveDaiToLapuVaultForTheConnectedPlayer,
approveLapuToMudWorldForTheConnectedPlayer,
depositDaiToLapuVaultForTheConnectedPlayer,
withdrawDaiFromLapuVaultForTheConnectedPlayer,
mudDefiLapuBalanceOf,
mudDefiConsumesLapuFromPlayer,
mudDefiGetTotalRewardBalance,
mudMockYieldGenerationFromDeFiPool,
mudMockReleaseRewardToPlayer,
},
} = useMUD();

const defaultTestAmount = 1000;
const defaultConsumeAmount = 100;
const defaultYieldAmount = 50;
const defaultRewardAmount = 30;

const counter = useComponentValue(Counter, singletonEntity);
const playerAddress = getState().player?.playerData?.address;
const [playerDaiBalance, setPlayerDaiBalance] = useState<number | null>(null);
const [playerLapuBalance, setPlayerLapuBalance] = useState<number | null>(
null
);
const [totalRewardBalance, setTotalRewardBalance] = useState<number | null>(
null
);

useEffect(() => {
const refreshData = async () => {
const playerDaiBalance_ = (await mudDefiDaiBalanceOf(
playerAddress
)) as number;
setPlayerDaiBalance(playerDaiBalance_);

const playerLapuBalance_ = (await mudDefiLapuBalanceOf(
playerAddress
)) as number;
setPlayerLapuBalance(playerLapuBalance_);

const totalRewardBalance_ =
(await mudDefiGetTotalRewardBalance()) as number;
setTotalRewardBalance(totalRewardBalance_);
};

const refreshDataIntervalId = setInterval(refreshData, 1000);
return () => {
clearInterval(refreshDataIntervalId);
};
}, [
mudDefiDaiBalanceOf,
mudDefiLapuBalanceOf,
mudDefiGetTotalRewardBalance,
playerAddress,
]);

useEffect(() => {
const generateYieldIntervalId = setInterval(() => {
mudMockYieldGenerationFromDeFiPool(defaultYieldAmount);
}, 10000);
return () => {
clearInterval(generateYieldIntervalId);
};
}, [mudMockYieldGenerationFromDeFiPool]);

useEffect(() => {
const rewardPlayerIntervalId = setInterval(() => {
mudMockReleaseRewardToPlayer(playerAddress, defaultRewardAmount);
}, 15000);
return () => {
clearInterval(rewardPlayerIntervalId);
};
}, [playerAddress, mudMockReleaseRewardToPlayer]);

const delay = async (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};

return (
<div>
<div>
Player Address: <span>{playerAddress ?? "??"}</span>
Player balance: <span>{playerDaiBalance?.toString() ?? "??"} DAI</span>{" "}
<span> {playerLapuBalance?.toString() ?? "??"} LAPU</span>
</div>
<div>
Player DAI balance: <span>{playerDaiBalance ?? "??"}</span>
Reward balance:{" "}
<span>{totalRewardBalance?.toString() ?? "??"} LAPU</span>
</div>
<div>
Counter: <span>{counter?.value ?? "??"}</span>
Expand All @@ -40,51 +109,72 @@ export const MudExample = () => {
event.preventDefault();
console.log(
"mudMockDaiFaucet:",
await mudMockDaiFaucet(playerAddress, 1000)
await mudMockDaiFaucet(playerAddress, defaultTestAmount)
);
const playerDaiBalance_ = (await mudDefiDaiBalanceOf(
playerAddress
)) as number;
console.log("playerDaiBalance_:", playerDaiBalance_);
setPlayerDaiBalance(playerDaiBalance_);
}}
>
mudMockDaiFaucet
getDaiFromFaucet
</button>
<button
type="button"
className="px-100 py-100 rounded-md border border-gray-300 bg-white text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50"
onClick={async (event) => {
event.preventDefault();
console.log("mudBuildFacility:", await mudBuildFacility());
console.log(
"approveDaiToLapuVaultForTheConnectedPlayer:",
await approveDaiToLapuVaultForTheConnectedPlayer(defaultTestAmount)
);
await delay(1000);
console.log(
"depositDaiToLapuVaultForTheConnectedPlayer:",
await depositDaiToLapuVaultForTheConnectedPlayer(defaultTestAmount)
);
}}
>
mudBuildFacility
swapDaiToLapu
</button>
<button
type="button"
className="px-100 py-100 rounded-md border border-gray-300 bg-white text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50"
onClick={async (event) => {
event.preventDefault();
console.log(
"mudGetAllFacilityEntityMetadatas:",
await mudGetAllFacilityEntityMetadatas()
"approveLapuToMudWorldForTheConnectedPlayer:",
await approveLapuToMudWorldForTheConnectedPlayer(
defaultConsumeAmount
)
);
await delay(1000);
console.log(
"mudDefiConsumesLapuFromPlayer:",
await mudDefiConsumesLapuFromPlayer(
defaultConsumeAmount,
playerAddress
)
);
}}
>
mudGetAllFacilityEntityMetadatas
consumeLapu
</button>
<button
type="button"
className="px-100 py-100 rounded-md border border-gray-300 bg-white text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50"
onClick={async (event) => {
event.preventDefault();
console.log(
"mudGetEntityMetadataAtPosition:",
await mudGetEntityMetadataAtPosition()
"withdrawDaiFromLapuVaultForTheConnectedPlayer:",
await withdrawDaiFromLapuVaultForTheConnectedPlayer(
defaultConsumeAmount
)
);
}}
>
mudGetEntityMetadataAtPosition
swapLapuToDai
</button>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/test/DefiSystemtTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract DefiSystemTest is MudTest {
assertEq(world.defiGetTotalRewardBalance(), amount02);
vm.stopPrank();

//5. mock yield generation from DeFi pool (which we can call periodically from client)
//5. mock yield generation from DeFi pool (which we can call periodically call from client)
world.mockYieldGenerationFromDeFiPool(amount03);
assertEq(world.defiGetTotalRewardBalance(), amount02 + amount03);

Expand Down

0 comments on commit 507c8e1

Please sign in to comment.