Skip to content

Commit

Permalink
update react template with stash/entrykit
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Jan 10, 2025
1 parent ff8a065 commit d890131
Show file tree
Hide file tree
Showing 51 changed files with 4,730 additions and 2,345 deletions.
2 changes: 1 addition & 1 deletion packages/entrykit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@rainbow-me/rainbowkit": "2.1.7",
"debug": "^4.3.4",
"dotenv": "^16.0.3",
"permissionless": "^0.2.3",
"permissionless": "0.2.25",
"react-error-boundary": "^4.0.13",
"react-merge-refs": "^2.1.1",
"tailwind-merge": "^1.12.0",
Expand Down
9 changes: 5 additions & 4 deletions packages/entrykit/src/getSessionClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ export async function getSessionClient<chain extends Chain>({
worldAddress: Address;
}): Promise<SessionClient<chain>> {
const bundlerTransport = getBundlerTransport(client.chain);

const sessionClient = createBundlerClient({
const bundlerClient = createBundlerClient({
transport: bundlerTransport,
client,
account: sessionAccount,
})
.extend(smartAccountActions())
});

const sessionClient = bundlerClient
.extend(smartAccountActions)
.extend(callFrom({ worldAddress, delegatorAddress: userAddress, publicClient: client }))
// TODO: add observer once we conditionally fetch receipts while bridge is open
.extend(() => ({ userAddress }));
Expand Down
12 changes: 6 additions & 6 deletions packages/entrykit/src/onboarding/Session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type Props = {
};

export function Session({ isActive, isExpanded, userClient, registerSpender, registerDelegation }: Props) {
const { data: sessionClient } = useSessionClient(userClient.account.address);
const sessionClient = useSessionClient(userClient.account.address);
const setup = useSetupSession({ userClient });
const hasSession = !registerDelegation && !registerDelegation;

Expand All @@ -23,9 +23,9 @@ export function Session({ isActive, isExpanded, userClient, registerSpender, reg
// individual mutations, even though the keys match. And the one we want the status of
// seems to stay pending. This is sorta resolved by triggering this after a timeout.
const timer = setTimeout(() => {
if (isActive && setup.status === "idle" && sessionClient && !hasSession) {
if (isActive && setup.status === "idle" && sessionClient.data && !hasSession) {
setup.mutate({
sessionClient,
sessionClient: sessionClient.data,
registerSpender,
registerDelegation,
});
Expand All @@ -50,12 +50,12 @@ export function Session({ isActive, isExpanded, userClient, registerSpender, reg
variant={isActive ? "primary" : "tertiary"}
className="flex-shrink-0 text-sm p-1 w-28"
autoFocus={isActive}
pending={!sessionClient || setup.status === "pending"}
pending={!sessionClient.data || setup.status === "pending"}
onClick={
sessionClient
sessionClient.data
? () =>
setup.mutate({
sessionClient,
sessionClient: sessionClient.data,
registerSpender,
registerDelegation,
})
Expand Down
2,966 changes: 1,685 additions & 1,281 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

19 changes: 14 additions & 5 deletions templates/react/.gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
.DS_Store
logs
*.log

node_modules

# mud artifacts
.mud
# sqlite indexer data
*.db
*.db-journal
.env.*

# foundry
cache
broadcast
out/*
!out/IWorld.sol
out/IWorld.sol/*
!out/IWorld.sol/IWorld.abi.json
!out/IWorld.sol/IWorld.abi.d.json.ts
10 changes: 9 additions & 1 deletion templates/react/mprocs.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
scrollback: 10000
procs:
client:
cwd: packages/client
Expand All @@ -7,7 +8,14 @@ procs:
shell: pnpm mud dev-contracts --rpc http://127.0.0.1:8545
anvil:
cwd: packages/contracts
shell: anvil --base-fee 0 --block-time 2
shell: anvil --block-time 2
deploy-prereqs:
cwd: packages/contracts
shell: pnpm deploy-local-prereqs
env:
DEBUG: "mud:*"
# Anvil default account (0x70997970C51812dc3A010C7d01b50e0d17dc79C8)
PRIVATE_KEY: "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
explorer:
cwd: packages/contracts
shell: pnpm explorer
24 changes: 24 additions & 0 deletions templates/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,29 @@
"engines": {
"node": "^18",
"pnpm": "^8 || ^9"
},
"pnpm": {
"overrides": {
"@latticexyz/abi-ts": "file:../../packages/abi-ts",
"@latticexyz/block-logs-stream": "file:../../packages/block-logs-stream",
"@latticexyz/cli": "file:../../packages/cli",
"@latticexyz/common": "file:../../packages/common",
"@latticexyz/config": "file:../../packages/config",
"@latticexyz/entrykit": "file:../../packages/entrykit",
"@latticexyz/explorer": "file:../../packages/explorer",
"@latticexyz/gas-report": "file:../../packages/gas-report",
"@latticexyz/paymaster": "file:../../packages/paymaster",
"@latticexyz/protocol-parser": "file:../../packages/protocol-parser",
"@latticexyz/recs": "file:../../packages/recs",
"@latticexyz/schema-type": "file:../../packages/schema-type",
"@latticexyz/stash": "file:../../packages/stash",
"@latticexyz/store": "file:../../packages/store",
"@latticexyz/store-indexer": "file:../../packages/store-indexer",
"@latticexyz/store-sync": "file:../../packages/store-sync",
"@latticexyz/utils": "file:../../packages/utils",
"@latticexyz/world": "file:../../packages/world",
"@latticexyz/world-module-metadata": "file:../../packages/world-module-metadata",
"@latticexyz/world-modules": "file:../../packages/world-modules"
}
}
}
2 changes: 0 additions & 2 deletions templates/react/packages/client/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
node_modules
dist
.DS_Store
13 changes: 11 additions & 2 deletions templates/react/packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,33 @@
},
"dependencies": {
"@latticexyz/common": "link:../../../../packages/common",
"@latticexyz/dev-tools": "link:../../../../packages/dev-tools",
"@latticexyz/entrykit": "link:../../../../packages/entrykit",
"@latticexyz/explorer": "link:../../../../packages/explorer",
"@latticexyz/react": "link:../../../../packages/react",
"@latticexyz/schema-type": "link:../../../../packages/schema-type",
"@latticexyz/stash": "link:../../../../packages/stash",
"@latticexyz/store-sync": "link:../../../../packages/store-sync",
"@latticexyz/utils": "link:../../../../packages/utils",
"@latticexyz/world": "link:../../../../packages/world",
"@tanstack/react-query": "^5.63.0",
"contracts": "workspace:*",
"fast-deep-equal": "^3.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rxjs": "7.5.5",
"viem": "2.21.19"
"tailwind-merge": "^2.6.0",
"viem": "2.21.19",
"wagmi": "2.12.11"
},
"devDependencies": {
"@types/react": "18.2.22",
"@types/react-dom": "18.2.7",
"@vitejs/plugin-react": "^3.1.0",
"autoprefixer": "^10.4.20",
"eslint-plugin-react": "7.31.11",
"eslint-plugin-react-hooks": "4.6.0",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.17",
"vite": "^4.2.1",
"wait-port": "^1.0.4"
}
Expand Down
6 changes: 6 additions & 0 deletions templates/react/packages/client/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
138 changes: 38 additions & 100 deletions templates/react/packages/client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,105 +1,43 @@
import { useMUD } from "./MUDContext";

const styleUnset = { all: "unset" } as const;

export const App = () => {
const {
network: { tables, useStore },
systemCalls: { addTask, toggleTask, deleteTask },
} = useMUD();

const tasks = useStore((state) => {
const records = Object.values(state.getRecords(tables.Tasks));
records.sort((a, b) => Number(a.value.createdAt - b.value.createdAt));
return records;
});
import { stash } from "./mud/stash";
import { useSyncProgress } from "./mud/useSyncProgress";
import { useRecords } from "./mud/useRecords";
import { AccountButton } from "@latticexyz/entrykit/internal";
import { Direction } from "./common";
import mudConfig from "contracts/mud.config";
import { useMemo } from "react";
import { GameMap } from "./GameMap";
import { useWorldContract } from "./mud/useWorldContract";

export function App() {
const { isLive, message, percentage } = useSyncProgress();

const players = useRecords({ stash, table: mudConfig.tables.app__Position });

const worldContract = useWorldContract();
const onMove = useMemo(
() =>
worldContract
? async (direction: Direction) => {
await worldContract.write.app__move([mudConfig.enums.Direction.indexOf(direction)]);
}
: undefined,
[worldContract],
);

return (
<>
<table>
<tbody>
{tasks.map((task) => (
<tr key={task.id}>
<td align="right">
<input
type="checkbox"
checked={task.value.completedAt > 0n}
title={task.value.completedAt === 0n ? "Mark task as completed" : "Mark task as incomplete"}
onChange={async (event) => {
event.preventDefault();
const checkbox = event.currentTarget;

checkbox.disabled = true;
try {
await toggleTask(task.key.id);
} finally {
checkbox.disabled = false;
}
}}
/>
</td>
<td>{task.value.completedAt > 0n ? <s>{task.value.description}</s> : <>{task.value.description}</>}</td>
<td align="right">
<button
type="button"
title="Delete task"
style={styleUnset}
onClick={async (event) => {
event.preventDefault();
if (!window.confirm("Are you sure you want to delete this task?")) return;

const button = event.currentTarget;
button.disabled = true;
try {
await deleteTask(task.key.id);
} finally {
button.disabled = false;
}
}}
>
&times;
</button>
</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<td>
<input type="checkbox" disabled />
</td>
<td colSpan={2}>
<form
onSubmit={async (event) => {
event.preventDefault();
const form = event.currentTarget;
const fieldset = form.querySelector("fieldset");
if (!(fieldset instanceof HTMLFieldSetElement)) return;

const formData = new FormData(form);
const desc = formData.get("description");
if (typeof desc !== "string") return;

fieldset.disabled = true;
try {
await addTask(desc);
form.reset();
} finally {
fieldset.disabled = false;
}
}}
>
<fieldset style={styleUnset}>
<input type="text" name="description" />{" "}
<button type="submit" title="Add task">
Add
</button>
</fieldset>
</form>
</td>
</tr>
</tfoot>
</table>
<div className="fixed inset-0 grid place-items-center p-4">
{isLive ? (
<GameMap players={players} onMove={onMove} />
) : (
<div className="tabular-nums">
{message} ({percentage.toFixed(1)}%)…
</div>
)}
</div>
<div className="fixed top-2 right-2">
<AccountButton />
</div>
</>
);
};
}
Loading

0 comments on commit d890131

Please sign in to comment.