create-mud 2.2.15-7482a5ae322f26278722081838b6103ce6d264e6 → 2.2.15-7fa68f6717ecd3fc2c734ca31c842c1242175cbe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/templates/react/gitignore +5 -14
- package/dist/templates/react/mprocs.yaml +1 -9
- package/dist/templates/react/package.json +4 -28
- package/dist/templates/react/packages/client/gitignore +2 -0
- package/dist/templates/react/packages/client/package.json +12 -21
- package/dist/templates/react/packages/client/src/App.tsx +100 -38
- package/dist/templates/react/packages/client/src/MUDContext.tsx +21 -0
- package/dist/templates/react/packages/client/src/index.tsx +31 -17
- package/dist/templates/react/packages/client/src/mud/createSystemCalls.ts +56 -0
- package/dist/templates/react/packages/client/src/mud/getNetworkConfig.ts +76 -0
- package/dist/templates/react/packages/client/src/mud/setup.ts +18 -0
- package/dist/templates/react/packages/client/src/mud/setupNetwork.ts +101 -0
- package/dist/templates/react/packages/client/src/mud/supportedChains.ts +20 -0
- package/dist/templates/react/packages/client/vite.config.ts +6 -0
- package/dist/templates/react/packages/contracts/gitignore +8 -12
- package/dist/templates/react/packages/contracts/mud.config.ts +8 -13
- package/dist/templates/react/packages/contracts/package.json +7 -8
- package/dist/templates/react/packages/contracts/script/PostDeploy.s.sol +9 -1
- package/dist/templates/react/packages/contracts/src/codegen/index.sol +1 -1
- package/dist/templates/react/packages/contracts/src/codegen/tables/Tasks.sol +522 -0
- package/dist/templates/react/packages/contracts/src/codegen/world/{IMoveSystem.sol → ITasksSystem.sol} +9 -5
- package/dist/templates/react/packages/contracts/src/codegen/world/IWorld.sol +2 -2
- package/dist/templates/react/packages/contracts/src/systems/TasksSystem.sol +24 -0
- package/dist/templates/react/packages/contracts/test/TasksTest.t.sol +30 -0
- package/dist/templates/react/packages/contracts/worlds.json +1 -1
- package/package.json +1 -1
- package/dist/templates/react/packages/client/postcss.config.cjs +0 -6
- package/dist/templates/react/packages/client/src/GameMap.tsx +0 -78
- package/dist/templates/react/packages/client/src/Providers.tsx +0 -44
- package/dist/templates/react/packages/client/src/common.ts +0 -6
- package/dist/templates/react/packages/client/src/mud/Explorer.tsx +0 -32
- package/dist/templates/react/packages/client/src/mud/getWorldDeploy.ts +0 -23
- package/dist/templates/react/packages/client/src/mud/stash.ts +0 -4
- package/dist/templates/react/packages/client/src/mud/useSyncProgress.ts +0 -21
- package/dist/templates/react/packages/client/src/mud/useWorldContract.ts +0 -45
- package/dist/templates/react/packages/client/src/ui/icons/ArrowDownIcon.tsx +0 -22
- package/dist/templates/react/packages/client/src/ui/icons/MUDIcon.tsx +0 -25
- package/dist/templates/react/packages/client/src/useKeyboardMovement.ts +0 -26
- package/dist/templates/react/packages/client/src/wagmiConfig.ts +0 -49
- package/dist/templates/react/packages/client/tailwind.config.ts +0 -10
- package/dist/templates/react/packages/contracts/out/IWorld.sol/IWorld.abi.json +0 -2021
- package/dist/templates/react/packages/contracts/src/MoveSystem.sol +0 -26
- package/dist/templates/react/packages/contracts/src/codegen/common.sol +0 -11
- package/dist/templates/react/packages/contracts/src/codegen/tables/Position.sol +0 -318
|
@@ -4,7 +4,7 @@ pragma solidity >=0.8.24;
|
|
|
4
4
|
/* Autogenerated file. Do not edit manually. */
|
|
5
5
|
|
|
6
6
|
import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol";
|
|
7
|
-
import {
|
|
7
|
+
import { ITasksSystem } from "./ITasksSystem.sol";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @title IWorld
|
|
@@ -13,4 +13,4 @@ import { IMoveSystem } from "./IMoveSystem.sol";
|
|
|
13
13
|
* that are dynamically registered in the World during deployment.
|
|
14
14
|
* @dev This is an autogenerated file; do not edit manually.
|
|
15
15
|
*/
|
|
16
|
-
interface IWorld is IBaseWorld,
|
|
16
|
+
interface IWorld is IBaseWorld, ITasksSystem {}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.8.24;
|
|
3
|
+
|
|
4
|
+
import { System } from "@latticexyz/world/src/System.sol";
|
|
5
|
+
import { Tasks, TasksData } from "../codegen/index.sol";
|
|
6
|
+
|
|
7
|
+
contract TasksSystem is System {
|
|
8
|
+
function addTask(string memory description) public returns (bytes32 id) {
|
|
9
|
+
id = keccak256(abi.encode(block.prevrandao, _msgSender(), description));
|
|
10
|
+
Tasks.set(id, TasksData({ description: description, createdAt: block.timestamp, completedAt: 0 }));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function completeTask(bytes32 id) public {
|
|
14
|
+
Tasks.setCompletedAt(id, block.timestamp);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resetTask(bytes32 id) public {
|
|
18
|
+
Tasks.setCompletedAt(id, 0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function deleteTask(bytes32 id) public {
|
|
22
|
+
Tasks.deleteRecord(id);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.8.24;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Test.sol";
|
|
5
|
+
import { MudTest } from "@latticexyz/world/test/MudTest.t.sol";
|
|
6
|
+
|
|
7
|
+
import { IWorld } from "../src/codegen/world/IWorld.sol";
|
|
8
|
+
import { Tasks, TasksData } from "../src/codegen/index.sol";
|
|
9
|
+
|
|
10
|
+
contract TasksTest is MudTest {
|
|
11
|
+
function testWorldExists() public {
|
|
12
|
+
uint256 codeSize;
|
|
13
|
+
address addr = worldAddress;
|
|
14
|
+
assembly {
|
|
15
|
+
codeSize := extcodesize(addr)
|
|
16
|
+
}
|
|
17
|
+
assertTrue(codeSize > 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function testTasks() public {
|
|
21
|
+
// Expect task to exist that we created during PostDeploy script
|
|
22
|
+
TasksData memory task = Tasks.get("1");
|
|
23
|
+
assertEq(task.description, "Walk the dog");
|
|
24
|
+
assertEq(task.completedAt, 0);
|
|
25
|
+
|
|
26
|
+
// Expect the task to be completed after calling completeTask from our TasksSystem
|
|
27
|
+
IWorld(worldAddress).app__completeTask("1");
|
|
28
|
+
assertEq(Tasks.getCompletedAt("1"), block.timestamp);
|
|
29
|
+
}
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { serialize, useAccount } from "wagmi";
|
|
2
|
-
import { useKeyboardMovement } from "./useKeyboardMovement";
|
|
3
|
-
import { Address, Hex, hexToBigInt, keccak256 } from "viem";
|
|
4
|
-
import { ArrowDownIcon } from "./ui/icons/ArrowDownIcon";
|
|
5
|
-
import { twMerge } from "tailwind-merge";
|
|
6
|
-
import { Direction } from "./common";
|
|
7
|
-
import mudConfig from "contracts/mud.config";
|
|
8
|
-
|
|
9
|
-
export type Props = {
|
|
10
|
-
readonly players?: readonly {
|
|
11
|
-
readonly player: Address;
|
|
12
|
-
readonly x: number;
|
|
13
|
-
readonly y: number;
|
|
14
|
-
}[];
|
|
15
|
-
|
|
16
|
-
readonly onMove?: (direction: Direction) => void;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const size = 40;
|
|
20
|
-
const scale = 100 / size;
|
|
21
|
-
|
|
22
|
-
function getColorAngle(seed: Hex) {
|
|
23
|
-
return Number(hexToBigInt(keccak256(seed)) % 360n);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const rotateClassName = {
|
|
27
|
-
North: "rotate-0",
|
|
28
|
-
East: "rotate-90",
|
|
29
|
-
South: "rotate-180",
|
|
30
|
-
West: "-rotate-90",
|
|
31
|
-
} as const satisfies Record<Direction, `${"" | "-"}rotate-${number}`>;
|
|
32
|
-
|
|
33
|
-
export function GameMap({ players = [], onMove }: Props) {
|
|
34
|
-
const { address: userAddress } = useAccount();
|
|
35
|
-
useKeyboardMovement(onMove);
|
|
36
|
-
return (
|
|
37
|
-
<div className="aspect-square w-full max-w-[40rem]">
|
|
38
|
-
<div className="relative w-full h-full border-8 border-black/10">
|
|
39
|
-
{onMove
|
|
40
|
-
? mudConfig.enums.Direction.map((direction) => (
|
|
41
|
-
<button
|
|
42
|
-
key={direction}
|
|
43
|
-
title={`Move ${direction.toLowerCase()}`}
|
|
44
|
-
className={twMerge(
|
|
45
|
-
"outline-0 absolute inset-0 cursor-pointer grid p-4",
|
|
46
|
-
rotateClassName[direction],
|
|
47
|
-
"transition bg-gradient-to-t from-transparent via-transparent to-blue-50 text-blue-400 opacity-0 hover:opacity-40 active:opacity-100",
|
|
48
|
-
)}
|
|
49
|
-
style={{ clipPath: "polygon(0% 0%, 100% 0%, 50% 50%)" }}
|
|
50
|
-
onClick={() => onMove(direction)}
|
|
51
|
-
>
|
|
52
|
-
<ArrowDownIcon className="rotate-180 text-4xl self-start justify-self-center" />
|
|
53
|
-
</button>
|
|
54
|
-
))
|
|
55
|
-
: null}
|
|
56
|
-
|
|
57
|
-
{players.map((player) => (
|
|
58
|
-
<div
|
|
59
|
-
key={player.player}
|
|
60
|
-
className="absolute bg-current"
|
|
61
|
-
style={{
|
|
62
|
-
color: `hwb(${getColorAngle(player.player)} 40% 20%)`,
|
|
63
|
-
width: `${scale}%`,
|
|
64
|
-
height: `${scale}%`,
|
|
65
|
-
left: `${((((player.x + size / 2) % size) + size) % size) * scale}%`,
|
|
66
|
-
top: `${((size - ((player.y + size / 2) % size)) % size) * scale}%`,
|
|
67
|
-
}}
|
|
68
|
-
title={serialize(player, null, 2)}
|
|
69
|
-
>
|
|
70
|
-
{player.player.toLowerCase() === userAddress?.toLowerCase() ? (
|
|
71
|
-
<div className="w-full h-full bg-current animate-ping opacity-50" />
|
|
72
|
-
) : null}
|
|
73
|
-
</div>
|
|
74
|
-
))}
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { WagmiProvider } from "wagmi";
|
|
2
|
-
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
|
3
|
-
import { ReactNode } from "react";
|
|
4
|
-
import { createSyncAdapter } from "@latticexyz/store-sync/internal";
|
|
5
|
-
import { SyncProvider } from "@latticexyz/store-sync/react";
|
|
6
|
-
import { stash } from "./mud/stash";
|
|
7
|
-
import { Address } from "viem";
|
|
8
|
-
import { defineConfig, EntryKitProvider } from "@latticexyz/entrykit/internal";
|
|
9
|
-
import { wagmiConfig } from "./wagmiConfig";
|
|
10
|
-
import { chainId } from "./common";
|
|
11
|
-
|
|
12
|
-
const queryClient = new QueryClient();
|
|
13
|
-
|
|
14
|
-
export type Props = {
|
|
15
|
-
worldDeploy: {
|
|
16
|
-
address: Address;
|
|
17
|
-
blockNumber: bigint | null;
|
|
18
|
-
};
|
|
19
|
-
children: ReactNode;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export function Providers({ worldDeploy, children }: Props) {
|
|
23
|
-
return (
|
|
24
|
-
<WagmiProvider config={wagmiConfig}>
|
|
25
|
-
<QueryClientProvider client={queryClient}>
|
|
26
|
-
<EntryKitProvider
|
|
27
|
-
config={defineConfig({
|
|
28
|
-
chainId,
|
|
29
|
-
worldAddress: worldDeploy.address,
|
|
30
|
-
})}
|
|
31
|
-
>
|
|
32
|
-
<SyncProvider
|
|
33
|
-
chainId={chainId}
|
|
34
|
-
address={worldDeploy.address}
|
|
35
|
-
startBlock={worldDeploy.blockNumber ?? undefined}
|
|
36
|
-
adapter={createSyncAdapter({ stash })}
|
|
37
|
-
>
|
|
38
|
-
{children}
|
|
39
|
-
</SyncProvider>
|
|
40
|
-
</EntryKitProvider>
|
|
41
|
-
</QueryClientProvider>
|
|
42
|
-
</WagmiProvider>
|
|
43
|
-
);
|
|
44
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
-
import { useEntryKitConfig } from "@latticexyz/entrykit/internal";
|
|
4
|
-
import { MUDIcon } from "../ui/icons/MUDIcon";
|
|
5
|
-
|
|
6
|
-
export function Explorer() {
|
|
7
|
-
const [open, setOpen] = useState(false);
|
|
8
|
-
const { chain, worldAddress } = useEntryKitConfig();
|
|
9
|
-
const explorerUrl = chain.blockExplorers?.worldsExplorer?.url;
|
|
10
|
-
if (!explorerUrl) return null;
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="fixed bottom-0 inset-x-0 flex flex-col opacity-80 transition hover:opacity-100">
|
|
14
|
-
<button
|
|
15
|
-
type="button"
|
|
16
|
-
onClick={() => setOpen(!open)}
|
|
17
|
-
className="outline-none flex justify-end gap-2 p-2 font-medium leading-none text-black"
|
|
18
|
-
>
|
|
19
|
-
{open ? (
|
|
20
|
-
<>Close</>
|
|
21
|
-
) : (
|
|
22
|
-
<>
|
|
23
|
-
Explore <MUDIcon className="text-orange-500" />
|
|
24
|
-
</>
|
|
25
|
-
)}
|
|
26
|
-
</button>
|
|
27
|
-
{open ? (
|
|
28
|
-
<iframe src={`${explorerUrl}/${worldAddress}`} className={twMerge("bg-black", open ? "h-[50vh]" : "h-0")} />
|
|
29
|
-
) : null}
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Address } from "viem";
|
|
2
|
-
|
|
3
|
-
export async function getWorldDeploy(chainId: number): Promise<{
|
|
4
|
-
chainId: number;
|
|
5
|
-
address: Address;
|
|
6
|
-
blockNumber: bigint | null;
|
|
7
|
-
}> {
|
|
8
|
-
// TODO: figure out how to catch vite:import-analysis error when this file is missing
|
|
9
|
-
const { default: worlds } = await import("contracts/worlds.json").catch((error) => {
|
|
10
|
-
console.debug("Could not import worlds.json", error);
|
|
11
|
-
return { default: null };
|
|
12
|
-
});
|
|
13
|
-
const deploy = worlds?.[`${chainId}`];
|
|
14
|
-
if (!deploy) {
|
|
15
|
-
throw new Error(`No world deploy found for chain ${chainId} in "worlds.json".`);
|
|
16
|
-
}
|
|
17
|
-
console.log("chain:", chainId, "world:", deploy);
|
|
18
|
-
return {
|
|
19
|
-
chainId,
|
|
20
|
-
address: deploy.address,
|
|
21
|
-
blockNumber: deploy.blockNumber != null ? BigInt(deploy.blockNumber) : null,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { stash } from "./stash";
|
|
2
|
-
import { initialProgress, SyncProgress } from "@latticexyz/store-sync/internal";
|
|
3
|
-
import { SyncStep } from "@latticexyz/store-sync";
|
|
4
|
-
import { useMemo } from "react";
|
|
5
|
-
import { useRecord } from "@latticexyz/stash/react";
|
|
6
|
-
|
|
7
|
-
export function useSyncProgress() {
|
|
8
|
-
const progress = useRecord({
|
|
9
|
-
stash,
|
|
10
|
-
table: SyncProgress,
|
|
11
|
-
key: {},
|
|
12
|
-
defaultValue: initialProgress,
|
|
13
|
-
});
|
|
14
|
-
return useMemo(
|
|
15
|
-
() => ({
|
|
16
|
-
...progress,
|
|
17
|
-
isLive: progress.step === SyncStep.LIVE,
|
|
18
|
-
}),
|
|
19
|
-
[progress],
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useClient } from "wagmi";
|
|
2
|
-
import { chainId } from "../common";
|
|
3
|
-
import { Account, Chain, Client, GetContractReturnType, Transport, getContract } from "viem";
|
|
4
|
-
import { useQuery } from "@tanstack/react-query";
|
|
5
|
-
import { useSessionClient, useEntryKitConfig } from "@latticexyz/entrykit/internal";
|
|
6
|
-
import { observer } from "@latticexyz/explorer/observer";
|
|
7
|
-
import worldAbi from "contracts/out/IWorld.sol/IWorld.abi.json";
|
|
8
|
-
|
|
9
|
-
export function useWorldContract():
|
|
10
|
-
| GetContractReturnType<
|
|
11
|
-
typeof worldAbi,
|
|
12
|
-
{
|
|
13
|
-
public: Client<Transport, Chain>;
|
|
14
|
-
wallet: Client<Transport, Chain, Account>;
|
|
15
|
-
}
|
|
16
|
-
>
|
|
17
|
-
| undefined {
|
|
18
|
-
const { worldAddress } = useEntryKitConfig();
|
|
19
|
-
const client = useClient({ chainId });
|
|
20
|
-
const { data: sessionClient } = useSessionClient();
|
|
21
|
-
|
|
22
|
-
const { data: worldContract } = useQuery({
|
|
23
|
-
queryKey: ["worldContract", worldAddress, client?.uid, sessionClient?.uid],
|
|
24
|
-
queryFn: () => {
|
|
25
|
-
if (!client || !sessionClient) {
|
|
26
|
-
throw new Error("Not connected.");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return getContract({
|
|
30
|
-
abi: worldAbi,
|
|
31
|
-
address: worldAddress,
|
|
32
|
-
client: {
|
|
33
|
-
public: client,
|
|
34
|
-
wallet: sessionClient.extend(observer()),
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
},
|
|
38
|
-
staleTime: Infinity,
|
|
39
|
-
refetchOnMount: false,
|
|
40
|
-
refetchOnReconnect: false,
|
|
41
|
-
refetchOnWindowFocus: false,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
return worldContract;
|
|
45
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { DetailedHTMLProps, SVGAttributes } from "react";
|
|
2
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
-
|
|
4
|
-
export type Props = DetailedHTMLProps<SVGAttributes<SVGSVGElement>, SVGSVGElement>;
|
|
5
|
-
|
|
6
|
-
export function ArrowDownIcon({ className, ...props }: Props) {
|
|
7
|
-
return (
|
|
8
|
-
<svg
|
|
9
|
-
className={twMerge("h-[1em] w-[1em]", className)}
|
|
10
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
-
viewBox="0 0 16 16"
|
|
12
|
-
fill="currentColor"
|
|
13
|
-
{...props}
|
|
14
|
-
>
|
|
15
|
-
<path
|
|
16
|
-
fillRule="evenodd"
|
|
17
|
-
d="M8 2a.75.75 0 0 1 .75.75v8.69l3.22-3.22a.75.75 0 1 1 1.06 1.06l-4.5 4.5a.75.75 0 0 1-1.06 0l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.22 3.22V2.75A.75.75 0 0 1 8 2Z"
|
|
18
|
-
clipRule="evenodd"
|
|
19
|
-
/>
|
|
20
|
-
</svg>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { DetailedHTMLProps, SVGAttributes } from "react";
|
|
2
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
-
|
|
4
|
-
export type Props = DetailedHTMLProps<SVGAttributes<SVGSVGElement>, SVGSVGElement>;
|
|
5
|
-
|
|
6
|
-
export function MUDIcon({ className, ...props }: Props) {
|
|
7
|
-
return (
|
|
8
|
-
<svg
|
|
9
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
10
|
-
viewBox="0 0 8 8"
|
|
11
|
-
fill="currentColor"
|
|
12
|
-
shapeRendering="crispEdges"
|
|
13
|
-
className={twMerge("-my-[0.125em] h-[1.25em] w-[1.25em]", className)}
|
|
14
|
-
{...props}
|
|
15
|
-
>
|
|
16
|
-
{/* eslint-disable-next-line max-len */}
|
|
17
|
-
<path d="M0 0h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm0 1h1v1H0zm1 0h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm2-1h1v1H7zm0 1h1v1H7zM6 7h1v1H6zm1-2h1v1H7zm0-1h1v1H7zm0-1h1v1H7z" />
|
|
18
|
-
<path
|
|
19
|
-
d="M2 2h1v1H2zm0 1h1v1H2zm0 1h1v1H2zm0 1h1v1H2zm1-3h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm0 1h1v1H5zm0 1h1v1H5zm0 1h1v1H5zM4 5h1v1H4zM3 5h1v1H3z"
|
|
20
|
-
opacity=".5"
|
|
21
|
-
/>
|
|
22
|
-
<path d="M7 2h1v1H7zm0-1h1v1H7zM1 0h1v1H1zm1 0h1v1H2zm1 0h1v1H3zm1 0h1v1H4zm1 0h1v1H5zm1 0h1v1H6zm1 0h1v1H7z" />
|
|
23
|
-
</svg>
|
|
24
|
-
);
|
|
25
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { Direction } from "./common";
|
|
3
|
-
|
|
4
|
-
const keys = new Map<KeyboardEvent["key"], Direction>([
|
|
5
|
-
["ArrowUp", "North"],
|
|
6
|
-
["ArrowRight", "East"],
|
|
7
|
-
["ArrowDown", "South"],
|
|
8
|
-
["ArrowLeft", "West"],
|
|
9
|
-
]);
|
|
10
|
-
|
|
11
|
-
export const useKeyboardMovement = (move: undefined | ((direction: Direction) => void)) => {
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
if (!move) return;
|
|
14
|
-
|
|
15
|
-
const listener = (event: KeyboardEvent) => {
|
|
16
|
-
const direction = keys.get(event.key);
|
|
17
|
-
if (direction == null) return;
|
|
18
|
-
|
|
19
|
-
event.preventDefault();
|
|
20
|
-
move(direction);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
window.addEventListener("keydown", listener);
|
|
24
|
-
return () => window.removeEventListener("keydown", listener);
|
|
25
|
-
}, [move]);
|
|
26
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Chain, http, webSocket } from "viem";
|
|
2
|
-
import { anvil } from "viem/chains";
|
|
3
|
-
import { createWagmiConfig } from "@latticexyz/entrykit/internal";
|
|
4
|
-
import { rhodolite, garnet, redstone } from "@latticexyz/common/chains";
|
|
5
|
-
import { chainId } from "./common";
|
|
6
|
-
|
|
7
|
-
const chains = [
|
|
8
|
-
redstone,
|
|
9
|
-
garnet,
|
|
10
|
-
rhodolite,
|
|
11
|
-
{
|
|
12
|
-
...anvil,
|
|
13
|
-
contracts: {
|
|
14
|
-
...anvil.contracts,
|
|
15
|
-
paymaster: {
|
|
16
|
-
address: "0xf03E61E7421c43D9068Ca562882E98d1be0a6b6e",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
blockExplorers: {
|
|
20
|
-
default: {} as never,
|
|
21
|
-
worldsExplorer: {
|
|
22
|
-
name: "MUD Worlds Explorer",
|
|
23
|
-
url: "http://localhost:13690/anvil/worlds",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
] as const satisfies Chain[];
|
|
28
|
-
|
|
29
|
-
const transports = {
|
|
30
|
-
[anvil.id]: webSocket(),
|
|
31
|
-
[garnet.id]: http(),
|
|
32
|
-
[rhodolite.id]: http(),
|
|
33
|
-
[redstone.id]: http(),
|
|
34
|
-
} as const;
|
|
35
|
-
|
|
36
|
-
export const wagmiConfig = createWagmiConfig({
|
|
37
|
-
chainId,
|
|
38
|
-
// TODO: swap this with another default project ID or leave empty
|
|
39
|
-
walletConnectProjectId: "14ce88fdbc0f9c294e26ec9b4d848e44",
|
|
40
|
-
appName: document.title,
|
|
41
|
-
chains,
|
|
42
|
-
transports,
|
|
43
|
-
pollingInterval: {
|
|
44
|
-
[anvil.id]: 2000,
|
|
45
|
-
[garnet.id]: 2000,
|
|
46
|
-
[rhodolite.id]: 2000,
|
|
47
|
-
[redstone.id]: 2000,
|
|
48
|
-
},
|
|
49
|
-
});
|