Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 30022f4

Browse files
authored
Merge pull request #28 from Keyrxng/improved-constants
2 parents d5b3446 + edd481c commit 30022f4

23 files changed

+31815
-1279
lines changed

.cspell.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
33
"version": "0.2",
4-
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log", "lib", "dist"],
4+
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log", "lib", "dist", "types/dynamic.ts"],
55
"useGitignore": true,
66
"language": "en",
77
"words": ["dataurl", "devpool", "outdir", "servedir"],
88
"dictionaries": ["typescript", "node", "software-terms"],
99
"import": ["@cspell/dict-typescript/cspell-ext.json", "@cspell/dict-node/cspell-ext.json", "@cspell/dict-software-terms"],
1010
"ignoreRegExpList": ["[0-9a-fA-F]{6}"],
11-
"ignoreWords": ["Rpcs", "ethersproject", "publicnode", "WXDAI", "XDAI", "chainlist", "Knip", "LOCALSTORAGE"]
11+
"ignoreWords": ["Rpcs", "ethersproject", "publicnode", "WXDAI", "XDAI", "chainlist", "Knip", "LOCALSTORAGE", "sonarjs", "cronos", "Cronos", "gochain"]
1212
}

.github/workflows/jest-testing.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ jobs:
2828
- name: Install dependencies
2929
run: yarn install
3030

31+
- name: Setup tests
32+
run: yarn pretest
33+
3134
- name: Build & Run test suite
3235
run: |
3336
yarn test | tee ./coverage.txt && exit ${PIPESTATUS[0]}
34-
37+
3538
- name: Jest Coverage Comment
3639
# Ensures this step is run even on previous step failure (e.g. test failed)
3740
if: always()

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ yarn test
6767
```
6868

6969
- This below will only work after `yarn build` has been run and will fail under test conditions
70+
7071
```bash
7172
npx tsx tests/script-test.ts
72-
```
73+
```

build/dynamic-types.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { appendFile, writeFile } from "fs/promises";
2+
import { BlockExplorer, NativeToken } from "../types/handler";
3+
import { generateChainData } from "../lib/chainlist/utils/fetch";
4+
5+
/**
6+
* This produces dynamic types and constants for:
7+
* - CHAINS_IDS
8+
* - NETWORKS
9+
* - NETWORK_FAUCETS
10+
* - NETWORK_EXPLORERS
11+
* - NETWORK_CURRENCIES
12+
* - EXTRA_RPCS
13+
*/
14+
15+
export async function createDynamicTypes() {
16+
const data = await generateChainData();
17+
const idToNetwork: Record<string, string> = {};
18+
const networkToId: Record<string, number> = {};
19+
const idToRpc: Record<string, string[]> = {};
20+
const idToFaucet: Record<string, string[]> = {};
21+
const idToExplorers = {} as Record<string, BlockExplorer[]>;
22+
const idToNativeCurrency: Record<string, NativeToken> = {};
23+
const extraRpcs: Record<string, string[]> = {};
24+
25+
for (const chain of data) {
26+
let { name, chainId, networkId, rpc, faucets, explorers, nativeCurrency } = chain;
27+
name = name.toLowerCase().replace(/\s/g, "-");
28+
idToNetwork[chainId] = name;
29+
networkToId[name] = networkId;
30+
idToRpc[chainId] = rpc;
31+
idToFaucet[chainId] = faucets;
32+
33+
if (explorers && explorers.length > 0) {
34+
idToExplorers[chainId] = explorers;
35+
}
36+
37+
if (rpc && rpc.length > 0) {
38+
const rpcs = rpc.filter((rpc: { url: string }) => rpc.url);
39+
extraRpcs[chainId] = rpcs.map((rpc: { url: string }) => rpc.url);
40+
}
41+
42+
idToNativeCurrency[chainId] = nativeCurrency;
43+
}
44+
45+
const filename = "types/dynamic.ts";
46+
47+
// Clear the file
48+
await writeFile(filename, "/* eslint-disable sonarjs/no-duplicate-string */\n\n");
49+
50+
appendFile(filename, `\nexport const CHAINS_IDS = ${JSON.stringify(idToNetwork, null, 2)} as const;\n`);
51+
appendFile(filename, `\nexport const NETWORKS = ${JSON.stringify(networkToId, null, 2)} as const;\n`);
52+
appendFile(filename, `\nexport const NETWORK_FAUCETS = ${JSON.stringify(idToFaucet, null, 2)};\n`);
53+
appendFile(filename, `\nexport const NETWORK_EXPLORERS = ${JSON.stringify(idToExplorers, null, 2)};\n`);
54+
appendFile(filename, `\nexport const NETWORK_CURRENCIES = ${JSON.stringify(idToNativeCurrency, null, 2)};\n`);
55+
appendFile(filename, `\nexport const EXTRA_RPCS = ${JSON.stringify(extraRpcs, null, 2)};\n`);
56+
}

build/esbuild-build-tests.ts

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,15 @@
11
import esbuild from "esbuild";
2-
import chainlist from "../lib/chainlist/constants/extraRpcs";
3-
import chainIDList from "../lib/chainlist/constants/chainIds.json";
42
import path from "path";
53
import * as fs from "fs";
4+
import { createDynamicTypes } from "./dynamic-types";
65

76
const typescriptEntries = ["tests/mocks/rpc-service.ts", "tests/mocks/rpc-handler.ts", "tests/mocks/handler.ts"];
87
export const entries = [...typescriptEntries];
9-
const extraRpcs: Record<string, string[]> = {};
10-
// this flattens all the rpcs into a single object, with key names that match the networkIds. The arrays are just of URLs per network ID.
11-
12-
Object.keys(chainlist).forEach((networkId) => {
13-
const officialUrls = chainlist[networkId].rpcs.filter((rpc) => typeof rpc === "string");
14-
const extraUrls: string[] = chainlist[networkId].rpcs.filter((rpc) => rpc.url !== undefined && rpc.tracking === "none").map((rpc) => rpc.url);
15-
16-
extraRpcs[networkId] = [...officialUrls, ...extraUrls].filter((rpc) => rpc.startsWith("https://"));
17-
});
188

199
export const esBuildContext: esbuild.BuildOptions = {
2010
entryPoints: entries,
2111
bundle: true,
22-
2312
outdir: "dist",
24-
define: createEnvDefines({ extraRpcs, chainIDList }),
2513
};
2614

2715
async function main() {
@@ -34,8 +22,6 @@ async function main() {
3422
}
3523
}
3624

37-
main();
38-
3925
async function buildForEnvironments() {
4026
ensureDistDir();
4127

@@ -62,25 +48,16 @@ async function buildIndex() {
6248
bundle: true,
6349
format: "cjs",
6450
outfile: "dist/index.js",
65-
define: createEnvDefines({ extraRpcs, chainIDList }),
6651
});
6752

6853
console.log("Index build complete.");
6954
}
7055

71-
function createEnvDefines(generatedAtBuild: Record<string, unknown>): Record<string, string> {
72-
const defines: Record<string, string> = {};
73-
74-
Object.keys(generatedAtBuild).forEach((key) => {
75-
defines[key] = JSON.stringify(generatedAtBuild[key]);
76-
});
77-
78-
return defines;
79-
}
80-
8156
function ensureDistDir() {
8257
const distPath = path.resolve(__dirname, "dist");
8358
if (!fs.existsSync(distPath)) {
8459
fs.mkdirSync(distPath, { recursive: true });
8560
}
8661
}
62+
63+
createDynamicTypes().then(main).catch(console.error);

build/esbuild-build.ts

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
import esbuild from "esbuild";
2-
import chainlist from "../lib/chainlist/constants/extraRpcs";
3-
import chainIDList from "../lib/chainlist/constants/chainIds.json";
42
import path from "path";
53
import * as fs from "fs";
4+
import { createDynamicTypes } from "./dynamic-types";
65

76
const typescriptEntries = ["index.ts"];
87
export const entries = [...typescriptEntries];
9-
const extraRpcs: Record<string, string[]> = {};
10-
11-
// this flattens all the rpcs into a single object, with key names that match the networkIds. The arrays are just of URLs per network ID.
12-
Object.keys(chainlist).forEach((networkId) => {
13-
const officialUrls = chainlist[networkId].rpcs.filter((rpc) => typeof rpc === "string");
14-
const extraUrls: string[] = chainlist[networkId].rpcs.filter((rpc) => rpc.url !== undefined && rpc.tracking === "none").map((rpc) => rpc.url);
15-
extraRpcs[networkId] = [...officialUrls, ...extraUrls].filter((rpc) => rpc.startsWith("https://"));
16-
});
178

189
export const esBuildContext: esbuild.BuildOptions = {
1910
entryPoints: entries,
2011
bundle: true,
21-
2212
outdir: "dist",
23-
define: createEnvDefines({ extraRpcs, chainIDList }),
2413
};
2514

2615
async function main() {
@@ -33,8 +22,6 @@ async function main() {
3322
}
3423
}
3524

36-
main();
37-
3825
async function buildForEnvironments() {
3926
ensureDistDir();
4027

@@ -76,24 +63,16 @@ async function buildIndex() {
7663
bundle: true,
7764
format: "cjs",
7865
outfile: "dist/index.js",
79-
define: createEnvDefines({ extraRpcs, chainIDList }),
8066
});
8167

8268
console.log("Index build complete.");
8369
}
8470

85-
function createEnvDefines(generatedAtBuild: Record<string, unknown>): Record<string, string> {
86-
const defines: Record<string, string> = {};
87-
Object.keys(generatedAtBuild).forEach((key) => {
88-
defines[key] = JSON.stringify(generatedAtBuild[key]);
89-
});
90-
91-
return defines;
92-
}
93-
9471
function ensureDistDir() {
9572
const distPath = path.resolve(__dirname, "dist");
9673
if (!fs.existsSync(distPath)) {
9774
fs.mkdirSync(distPath, { recursive: true });
9875
}
9976
}
77+
78+
createDynamicTypes().then(main).catch(console.error);

index.ts

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,20 @@ export default async function getRPCHandler() {
1212
}
1313

1414
import {
15-
ChainId,
16-
ChainNames,
15+
NetworkId,
16+
NetworkName,
1717
HandlerConstructorConfig,
1818
HandlerInterface,
1919
NativeToken,
2020
NetworkCurrencies,
2121
NetworkExplorers,
22-
NetworkIds,
23-
NetworkNames,
2422
NetworkRPCs,
2523
Token,
26-
Tokens,
2724
ValidBlockData,
2825
} from "./types/handler";
2926

3027
import {
3128
LOCAL_HOST,
32-
chainIDList,
33-
extraRpcs,
3429
getNetworkName,
3530
networkCurrencies,
3631
networkExplorers,
@@ -39,39 +34,23 @@ import {
3934
networkRpcs,
4035
nftAddress,
4136
permit2Address,
42-
tokens,
37+
getNetworkId,
4338
} from "./types/constants";
4439

4540
import { RPCHandler } from "./types/rpc-handler";
4641

47-
export {
48-
LOCAL_HOST,
49-
chainIDList,
50-
extraRpcs,
51-
getNetworkName,
52-
networkCurrencies,
53-
networkExplorers,
54-
networkIds,
55-
networkNames,
56-
networkRpcs,
57-
nftAddress,
58-
permit2Address,
59-
tokens,
60-
};
42+
export { LOCAL_HOST, getNetworkName, getNetworkId, networkCurrencies, networkExplorers, networkIds, networkNames, networkRpcs, nftAddress, permit2Address };
6143

6244
export type {
63-
ChainId,
64-
ChainNames,
45+
NetworkId,
46+
NetworkName,
6547
HandlerConstructorConfig,
6648
HandlerInterface,
6749
NativeToken,
6850
NetworkCurrencies,
6951
NetworkExplorers,
70-
NetworkIds,
71-
NetworkNames,
7252
NetworkRPCs,
7353
Token,
74-
Tokens,
7554
ValidBlockData,
7655
};
7756
export { RPCHandler };

package.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,21 @@
1414
"node": ">=20.10.0"
1515
},
1616
"scripts": {
17-
"format": "run-s format:lint format:prettier format:cspell",
17+
"format": "run-p format:*",
1818
"format:lint": "eslint --fix .",
1919
"format:prettier": "prettier --write .",
2020
"format:cspell": "cspell **/*",
2121
"knip": "knip",
2222
"knip-ci": "knip --no-exit-code --reporter json",
2323
"prepare": "husky install",
24-
"build:types": "tsc --emitDeclarationOnly --declaration --outDir dist && rm -rf dist/src",
25-
"build:tests": "tsx build/esbuild-build-tests.ts && tsc --emitDeclarationOnly --declaration --project tsconfig.tests.json",
26-
"build": "rm -rf dist && tsx build/esbuild-build.ts",
27-
"postbuild": "yarn build:types",
2824
"postinstall": "git submodule update --init --recursive",
29-
"test": "rm -rf dist && yarn build:tests && jest"
25+
"build": "run-s clean build:types",
26+
"build:types": "tsx build/esbuild-build.ts && tsc --emitDeclarationOnly --declaration --outDir dist",
27+
"build:tests": "tsx build/esbuild-build-tests.ts && tsc --emitDeclarationOnly --declaration --project tsconfig.tests.json",
28+
"postbuild": "rm -rf dist/src",
29+
"pretest": "run-s clean build:tests",
30+
"test": "jest",
31+
"clean": "rm -rf dist"
3032
},
3133
"keywords": [
3234
"typescript",
@@ -87,4 +89,4 @@
8789
]
8890
},
8991
"packageManager": "yarn@4.2.2"
90-
}
92+
}

src/services/rpc-service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { ValidBlockData } from "../../types/handler";
1+
import { NetworkId, ValidBlockData } from "../../types/handler";
22
import axios from "axios";
33
type PromiseResult = { success: boolean; rpcUrl: string; duration: number };
44

55
export class RPCService {
66
static async testRpcPerformance(
7-
networkId: number,
7+
networkId: NetworkId,
88
latencies: Record<string, number>,
99
runtimeRpcs: string[],
1010
rpcHeader: object,
@@ -58,7 +58,7 @@ export class RPCService {
5858

5959
return { latencies, runtimeRpcs };
6060
}
61-
static async findFastestRpc(latencies: Record<string, number>, networkId: number): Promise<string | null> {
61+
static async findFastestRpc(latencies: Record<string, number>, networkId: NetworkId): Promise<string | null> {
6262
try {
6363
const validLatencies: Record<string, number> = Object.entries(latencies)
6464
.filter(([key]) => key.startsWith(`${networkId}__`))

src/services/storage-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { NetworkId } from "types/handler";
2+
13
export class StorageService {
2-
static getLatencies(env: string, networkId: number): Record<string | number, number> {
4+
static getLatencies(env: string, networkId: NetworkId): Record<string | number, number> {
35
if (env === "browser") {
46
if (this.bypassForTests()) return {};
57
const latencies: Record<string, number> = JSON.parse(localStorage.getItem("rpcLatencies") || "{}");

tests/benchmark.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { JsonRpcProvider } from "@ethersproject/providers";
22
import { RPCHandler, HandlerConstructorConfig } from "../dist";
33

44
export const testConfig: HandlerConstructorConfig = {
5-
networkId: 1,
5+
networkId: "1",
66
autoStorage: false,
77
cacheRefreshCycles: 3,
88
networkName: null,

0 commit comments

Comments
 (0)