-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.ts
99 lines (83 loc) · 2.59 KB
/
lib.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import * as wagmiChains from "viem/chains";
import { join } from "path";
import { homedir } from "os";
import fs from "fs";
import fsPromises from "fs/promises";
export const configDirectoryPrefix = ".chains";
export const configDirectory = join(homedir(), configDirectoryPrefix);
const existsAsync = (path: string) => {
// wrap fs.stat to check if file exists, and return a promise indicating true/false:
return new Promise((resolve) => {
fs.stat(path, (err) => {
resolve(!err);
});
});
};
async function readConfigFile(path: string) {
const fullPath = join(configDirectory, path);
if (await existsAsync(fullPath)) {
try {
return JSON.parse(await fsPromises.readFile(fullPath, "utf-8"));
} catch (e) {
console.error(e);
return {};
}
}
return {};
}
const getGlobalConfig = () => readConfigFile("config.json");
async function updateChainConfig(
config: wagmiChains.Chain
): Promise<ChainConfig> {
let rpcUrl = config.rpcUrls.default?.http[0];
const globalConfig = await getGlobalConfig();
if (globalConfig.alchemyApiKey && config.rpcUrls.alchemy) {
rpcUrl = `${config.rpcUrls.alchemy.http[0]}/${globalConfig.alchemyApiKey}`;
}
if (rpcUrl?.includes("$alchemyApiKey")) {
rpcUrl = rpcUrl.replace("$alchemyApiKey", globalConfig.alchemyApiKey);
}
return {
id: config.id,
rpcUrl,
blockExplorer: config.blockExplorers?.default?.url,
etherscanUrl: config.blockExplorers?.etherscan?.url,
};
}
type WagmiKnownChains = Record<string, ChainConfig>;
export type ChainConfig = {
id: number;
rpcUrl: string | undefined;
blockExplorer: string | undefined;
etherscanUrl: string | undefined;
etherscanApiKey?: string;
verifierUrl?: string;
};
const kebabize = (str: string) =>
str.replace(
/[A-Z]+(?![a-z])|[A-Z]/g,
($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
);
export async function buildWagmiKnownChains(): Promise<WagmiKnownChains> {
const wagmiKnownChains: Record<string, ChainConfig> = {};
for (const chain of Object.keys(wagmiChains)) {
wagmiKnownChains[kebabize(chain)] = await updateChainConfig(
wagmiChains[chain as keyof typeof wagmiChains]
);
}
return wagmiKnownChains;
}
const combineWithWagmiKnownChain = async (
chain: string,
configFileOverrides: any
) => {
const wagmiKnownChains = await buildWagmiKnownChains();
return {
...wagmiKnownChains[chain],
...configFileOverrides,
};
};
export const getChain = async (chain: string) => {
const configFileOverrides = await readConfigFile(`${chain}.json`);
return combineWithWagmiKnownChain(chain, configFileOverrides);
};