Skip to content

Commit f87a669

Browse files
committed
fix: harden address handling and share arcade formatters
1 parent c8d58b4 commit f87a669

File tree

4 files changed

+107
-82
lines changed

4 files changed

+107
-82
lines changed

client/src/effect/atoms/arcade.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { createEntityQueryWithUpdatesAtom } from "@dojoengine/react/effect";
2-
import { ARCADE_MODELS, mainnetConfig, toriiRuntime } from "../layers/arcade";
2+
import {
3+
ARCADE_MODELS,
4+
arcadeFormatters,
5+
mainnetConfig,
6+
toriiRuntime,
7+
} from "../layers/arcade";
38
import { KeysClause, ToriiQueryBuilder } from "@dojoengine/sdk";
49

510
const clause = KeysClause([], [], "VariableLen").build();
@@ -14,4 +19,5 @@ export const arcadeAtom = createEntityQueryWithUpdatesAtom(
1419
>[1],
1520
clause,
1621
[mainnetConfig.manifest.world.address],
22+
arcadeFormatters,
1723
);

client/src/effect/atoms/users.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,14 @@ export const accountByAddressAtom = Atom.family(
102102
(address: string | undefined) => {
103103
if (!address) return nullResultAtom;
104104

105-
const checksumAddress = getChecksumAddress(address);
105+
const checksumAddress = (() => {
106+
try {
107+
return getChecksumAddress(address);
108+
} catch {
109+
return null;
110+
}
111+
})();
112+
if (!checksumAddress) return nullResultAtom;
106113

107114
return accountsAtom.pipe(
108115
Atom.map((result) =>

client/src/effect/layers/arcade.ts

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -66,90 +66,92 @@ export const ARCADE_MODELS = [
6666
"ARCADE-Follow",
6767
];
6868

69+
export const arcadeFormatters = {
70+
models: {
71+
"ARCADE-Game": (m: any, ctx: any) => ({
72+
type: "game",
73+
identifier: ctx.entityId,
74+
data: GameModel.from(ctx.entityId, m),
75+
}),
76+
"ARCADE-Edition": (m: any, ctx: any) => ({
77+
type: "edition",
78+
identifier: ctx.entityId,
79+
data: EditionModel.from(ctx.entityId, m),
80+
}),
81+
"ARCADE-Access": (m: any, ctx: any) => ({
82+
type: "access",
83+
identifier: ctx.entityId,
84+
data: AccessModel.from(ctx.entityId, m),
85+
}),
86+
"ARCADE-CollectionEdition": (m: any, ctx: any) => ({
87+
type: "collectionEdition",
88+
identifier: ctx.entityId,
89+
data: CollectionEditionModel.from(ctx.entityId, m),
90+
}),
91+
"ARCADE-Order": (m: any, ctx: any) => ({
92+
type: "order",
93+
identifier: ctx.entityId,
94+
data: OrderModel.from(ctx.entityId, m as any),
95+
}),
96+
"ARCADE-Book": (m: any, ctx: any) => ({
97+
type: "book",
98+
identifier: ctx.entityId,
99+
data: BookModel.from(ctx.entityId, m as any),
100+
}),
101+
"ARCADE-Moderator": (m: any, ctx: any) => ({
102+
type: "moderator",
103+
identifier: ctx.entityId,
104+
data: ModeratorModel.from(ctx.entityId, m as any),
105+
}),
106+
"ARCADE-Alliance": (m: any, ctx: any) => ({
107+
type: "alliance",
108+
identifier: ctx.entityId,
109+
data: AllianceModel.from(ctx.entityId, m),
110+
}),
111+
"ARCADE-Guild": (m: any, ctx: any) => ({
112+
type: "guild",
113+
identifier: ctx.entityId,
114+
data: GuildModel.from(ctx.entityId, m),
115+
}),
116+
"ARCADE-Member": (m: any, ctx: any) => ({
117+
type: "member",
118+
identifier: ctx.entityId,
119+
data: MemberModel.from(ctx.entityId, m),
120+
}),
121+
"ARCADE-Listing": (m: any, ctx: any) => ({
122+
type: "listing",
123+
key: ctx.entityId,
124+
data: ListingEvent.from(ctx.entityId, m as any),
125+
}),
126+
"ARCADE-Offer": (m: any, ctx: any) => ({
127+
type: "offer",
128+
key: ctx.entityId,
129+
data: OfferEvent.from(ctx.entityId, m as any),
130+
}),
131+
"ARCADE-Sale": (m: any, ctx: any) => ({
132+
type: "sale",
133+
key: ctx.entityId,
134+
data: SaleEvent.from(ctx.entityId, m as any),
135+
}),
136+
"ARCADE-TrophyPinning": (m: any, ctx: any) => ({
137+
type: "pin",
138+
key: ctx.entityId,
139+
data: PinEvent.from(ctx.entityId, m),
140+
}),
141+
"ARCADE-Follow": (m: any, ctx: any) => ({
142+
type: "follow",
143+
key: ctx.entityId,
144+
data: FollowEvent.from(ctx.entityId, m),
145+
}),
146+
},
147+
} as const;
148+
69149
const toriiLayer = makeToriiLayer(
70150
{ manifest: mainnetConfig.manifest, toriiUrl: getToriiUrl(DEFAULT_PROJECT) },
71151
{
72152
autoReconnect: false,
73153
maxReconnectAttempts: 5,
74-
formatters: {
75-
models: {
76-
"ARCADE-Game": (m, ctx) => ({
77-
type: "game",
78-
identifier: ctx.entityId,
79-
data: GameModel.from(ctx.entityId, m),
80-
}),
81-
"ARCADE-Edition": (m, ctx) => ({
82-
type: "edition",
83-
identifier: ctx.entityId,
84-
data: EditionModel.from(ctx.entityId, m),
85-
}),
86-
"ARCADE-Access": (m, ctx) => ({
87-
type: "access",
88-
identifier: ctx.entityId,
89-
data: AccessModel.from(ctx.entityId, m),
90-
}),
91-
"ARCADE-CollectionEdition": (m, ctx) => ({
92-
type: "collectionEdition",
93-
identifier: ctx.entityId,
94-
data: CollectionEditionModel.from(ctx.entityId, m),
95-
}),
96-
"ARCADE-Order": (m, ctx) => ({
97-
type: "order",
98-
identifier: ctx.entityId,
99-
data: OrderModel.from(ctx.entityId, m as any),
100-
}),
101-
"ARCADE-Book": (m, ctx) => ({
102-
type: "book",
103-
identifier: ctx.entityId,
104-
data: BookModel.from(ctx.entityId, m as any),
105-
}),
106-
"ARCADE-Moderator": (m, ctx) => ({
107-
type: "moderator",
108-
identifier: ctx.entityId,
109-
data: ModeratorModel.from(ctx.entityId, m as any),
110-
}),
111-
"ARCADE-Alliance": (m, ctx) => ({
112-
type: "alliance",
113-
identifier: ctx.entityId,
114-
data: AllianceModel.from(ctx.entityId, m),
115-
}),
116-
"ARCADE-Guild": (m, ctx) => ({
117-
type: "guild",
118-
identifier: ctx.entityId,
119-
data: GuildModel.from(ctx.entityId, m),
120-
}),
121-
"ARCADE-Member": (m, ctx) => ({
122-
type: "member",
123-
identifier: ctx.entityId,
124-
data: MemberModel.from(ctx.entityId, m),
125-
}),
126-
"ARCADE-Listing": (m, ctx) => ({
127-
type: "listing",
128-
key: ctx.entityId,
129-
data: ListingEvent.from(ctx.entityId, m as any),
130-
}),
131-
"ARCADE-Offer": (m, ctx) => ({
132-
type: "offer",
133-
key: ctx.entityId,
134-
data: OfferEvent.from(ctx.entityId, m as any),
135-
}),
136-
"ARCADE-Sale": (m, ctx) => ({
137-
type: "sale",
138-
key: ctx.entityId,
139-
data: SaleEvent.from(ctx.entityId, m as any),
140-
}),
141-
"ARCADE-TrophyPinning": (m, ctx) => ({
142-
type: "pin",
143-
key: ctx.entityId,
144-
data: PinEvent.from(ctx.entityId, m),
145-
}),
146-
"ARCADE-Follow": (m, ctx) => ({
147-
type: "follow",
148-
key: ctx.entityId,
149-
data: FollowEvent.from(ctx.entityId, m),
150-
}),
151-
},
152-
},
154+
formatters: arcadeFormatters,
153155
},
154156
);
155157

client/src/routes/__root.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useEffect, useMemo } from "react";
22
import { Outlet, createRootRoute, useMatches } from "@tanstack/react-router";
3+
import { getChecksumAddress } from "starknet";
34
import { Template } from "@/components/template";
45
import { ControllerToaster } from "@cartridge/ui";
56
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
@@ -22,7 +23,16 @@ function RootComponent() {
2223
if (data) {
2324
setPlayer((p) => (p !== data.address ? data.address : p));
2425
} else {
25-
setPlayer(manager.getParams().player || undefined);
26+
const param = manager.getParams().player;
27+
if (param?.match(/^0x[0-9a-fA-F]+$/)) {
28+
try {
29+
setPlayer(getChecksumAddress(param));
30+
} catch {
31+
setPlayer(undefined);
32+
}
33+
} else {
34+
setPlayer(undefined);
35+
}
2636
}
2737
}, [data, manager, setPlayer]);
2838

0 commit comments

Comments
 (0)