@wagmi/cli
Version:
Manage and generate code from Ethereum ABIs
56 lines • 2.67 kB
JavaScript
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { homedir } from 'node:os';
import { join } from 'pathe';
/** Fetches and parses contract ABIs from network resource with `fetch`. */
export function fetch(config) {
const { cacheDuration = 1_800_000, contracts: contractConfigs, getCacheKey = ({ contract }) => JSON.stringify(contract), name = 'Fetch', parse = ({ response }) => response.json(), request, timeoutDuration = 5_000, } = config;
return {
async contracts() {
const cacheDir = getCacheDir();
await mkdir(cacheDir, { recursive: true });
const timestamp = Date.now() + cacheDuration;
const contracts = [];
for (const contract of contractConfigs) {
const cacheKey = getCacheKey({ contract });
const cacheFilePath = join(cacheDir, `${cacheKey}.json`);
const cachedFile = JSON.parse(await readFile(cacheFilePath, 'utf8').catch(() => 'null'));
let abi;
if (cachedFile?.timestamp > Date.now())
abi = cachedFile.abi;
else {
const controller = new globalThis.AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutDuration);
try {
const { url, init } = await request(contract);
const response = await globalThis.fetch(url, {
...init,
signal: controller.signal,
});
clearTimeout(timeout);
abi = await parse({ response });
await writeFile(cacheFilePath, `${JSON.stringify({ abi, timestamp }, undefined, 2)}\n`);
}
catch (error) {
clearTimeout(timeout);
try {
// Attempt to read from cache if fetch fails.
abi = JSON.parse(await readFile(cacheFilePath, 'utf8')).abi;
}
catch { }
if (!abi)
throw error;
}
}
if (!abi)
throw Error('Failed to fetch ABI for contract.');
contracts.push({ abi, address: contract.address, name: contract.name });
}
return contracts;
},
name,
};
}
export function getCacheDir() {
return join(homedir(), '.wagmi-cli/plugins/fetch/cache');
}
//# sourceMappingURL=fetch.js.map