Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nexus-strict-network-id.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/nexus": patch
---

Reject partially numeric network IDs in Nexus chain ID parsing.
4 changes: 3 additions & 1 deletion packages/nexus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"knip": "5.60.2",
"rimraf": "6.0.1",
"size-limit": "11.2.0",
"typescript": "5.8.3"
"typescript": "5.8.3",
"vitest": "3.2.4"
},
"engines": {
"node": ">=22"
Expand Down Expand Up @@ -69,6 +70,7 @@
"knip": "knip",
"lint": "knip && biome check ./src && tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --noEmit",
"size": "size-limit",
"test": "vitest run",
"typecheck": "tsc --project ./tsconfig.build.json --module nodenext --moduleResolution nodenext --noEmit"
},
"sideEffects": false,
Expand Down
26 changes: 26 additions & 0 deletions packages/nexus/src/schemas.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from "vitest";

import { networkToChainId } from "./schemas.js";

describe("networkToChainId", () => {
it("parses valid numeric network identifiers", () => {
expect(networkToChainId("eip155:1")).toBe(1);
expect(networkToChainId("8453")).toBe(8453);
});

it("rejects partially numeric network identifiers", () => {
expect(() => networkToChainId("eip155:1abc")).toThrow(
"Invalid network: eip155:1abc",
);
expect(() => networkToChainId("1abc")).toThrow("Invalid network: 1abc");
expect(() => networkToChainId("eip155:1.5")).toThrow(
"Invalid network: eip155:1.5",
);
});

it("rejects unsafe integer network identifiers", () => {
expect(() => networkToChainId("9007199254740992")).toThrow(
"Invalid network: 9007199254740992",
);
});
});
22 changes: 18 additions & 4 deletions packages/nexus/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,16 @@ export type FacilitatorSupportedResponse = z.infer<

export function networkToChainId(network: string): number {
if (network.startsWith("eip155:")) {
const chainId = parseInt(network.split(":")[1] ?? "0");
if (!Number.isNaN(chainId) && chainId > 0) {
const chainId = parseChainId(network.split(":")[1] ?? "");
if (chainId) {
return chainId;
} else {
throw new Error(`Invalid network: ${network}`);
}
}
// attempt to parse it as just an integer
const maybeChainId = parseInt(network);
if (!Number.isNaN(maybeChainId) && maybeChainId > 0) {
const maybeChainId = parseChainId(network);
if (maybeChainId) {
return maybeChainId;
}
const mappedChainId = EvmNetworkToChainId.get(network as Network);
Expand All @@ -107,3 +107,17 @@ export function networkToChainId(network: string): number {
}
return mappedChainId;
}

function parseChainId(value: string): number | undefined {
if (!/^[1-9]\d*$/.test(value)) {
return undefined;
}

const chainId = Number(value);

if (!Number.isSafeInteger(chainId)) {
return undefined;
}

return chainId;
}
Loading
Loading