create-accessnode
Version:
CLI for setting up AccessNode projects. Clones AccessNode repo, prompts for chains & contracts, creates node.config.ts.
157 lines (152 loc) • 6.15 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// bin/cli.ts
var import_node_fs = __toESM(require("fs"), 1);
var import_node_path = __toESM(require("path"), 1);
var import_prompts = __toESM(require("prompts"), 1);
var import_picocolors = __toESM(require("picocolors"), 1);
var import_prettier = __toESM(require("prettier"), 1);
var import_execa = require("execa");
// src/chain.ts
var CHAINS = [
{
id: "base",
name: "Base",
config: {
chainId: 8453,
transport: "http(process.env.ACCESSNODE_RPC_URL_8453)",
maxRequestsPerSecond: 15
}
},
{
id: "base-sepolia",
name: "Base Sepolia",
config: {
chainId: 84532,
transport: "http(process.env.ACCESSNODE_RPC_URL_84532)",
maxRequestsPerSecond: 15
}
}
];
// bin/cli.ts
var REPO_URL = "https://github.com/accesstimeio/accessnode";
async function main() {
const args = process.argv.slice(2);
const cliProjectName = args.find((arg) => arg.startsWith("--project-name="));
let projectName = cliProjectName?.split("=")[1];
if (!projectName) {
const res = await (0, import_prompts.default)({
type: "text",
name: "name",
message: "Enter your project name:",
initial: "accessnode-app"
});
projectName = res.name.trim();
}
const projectPath = import_node_path.default.resolve(process.cwd(), projectName);
console.log(import_picocolors.default.blue("\u23F3 Cloning repository..."));
await (0, import_execa.execa)("git", ["clone", REPO_URL, projectName]);
const { selectedChains } = await (0, import_prompts.default)({
type: "multiselect",
name: "selectedChains",
message: "Select chains to support:",
choices: CHAINS.map((c) => ({ title: c.name, value: c.id })),
min: 1
});
const contractNetworkConfig = {};
for (const chainId of selectedChains) {
const { addresses } = await (0, import_prompts.default)({
type: "text",
name: "addresses",
message: `Enter contract addresses for ${chainId} (comma-separated):`
});
const addressList = addresses.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean);
const { startBlock } = await (0, import_prompts.default)({
type: "number",
name: "startBlock",
message: `Enter start block for ${chainId}:`
});
contractNetworkConfig[chainId] = {
address: addressList,
startBlock
};
}
const selectedNetworkConfigs = Object.fromEntries(
selectedChains.map((id) => {
const chain = CHAINS.find((c) => c.id === id);
return [id, chain.config];
})
);
const rawConfig = `
import { createNodeConfig } from "./src/types";
import { http } from "viem";
export default createNodeConfig({
networks: ${JSON.stringify(selectedNetworkConfigs, null, 2).replaceAll(
/"http\((.*?)\)"/g,
(_, env) => `http(${env})`
)},
contracts: {
AccessTime: {
network: ${JSON.stringify(contractNetworkConfig, null, 2)}
}
}
});
`;
const formattedConfig = await import_prettier.default.format(rawConfig, {
parser: "typescript"
});
import_node_fs.default.writeFileSync(import_node_path.default.join(projectPath, "node.config.ts"), formattedConfig);
console.log();
console.log(import_picocolors.default.green("\u2705 Project created at:"), import_picocolors.default.bold(projectPath));
console.log(import_picocolors.default.green("\u2705 Configuration written to node.config.ts"));
console.log();
console.log(import_picocolors.default.blue("\u{1F527} Resetting git history..."));
import_node_fs.default.rmSync(import_node_path.default.join(projectPath, ".git"), { recursive: true, force: true });
await (0, import_execa.execa)("git", ["init"], { cwd: projectPath });
await (0, import_execa.execa)("git", ["add", "."], { cwd: projectPath });
await (0, import_execa.execa)("git", ["commit", "-m", "chore: update config"], { cwd: projectPath });
console.log(import_picocolors.default.green("\u2705 Git repository initialized."));
console.log(import_picocolors.default.blue("\u{1F50D} Checking pnpm..."));
let pnpmInstalled = true;
try {
await (0, import_execa.execa)("pnpm", ["--version"]);
} catch {
pnpmInstalled = false;
}
if (!pnpmInstalled) {
console.log(import_picocolors.default.yellow("\u{1F4E6} pnpm not found. Installing..."));
await (0, import_execa.execa)("npm", ["install", "-g", "pnpm"]);
console.log(import_picocolors.default.green("\u2705 pnpm installed globally."));
}
console.log(import_picocolors.default.blue("\u{1F4E6} Installing dependencies with pnpm..."));
await (0, import_execa.execa)("pnpm", ["install"], { cwd: projectPath });
console.log(import_picocolors.default.green("\u2705 Dependencies installed."));
console.log();
console.log(import_picocolors.default.green("\u{1F680} Setup complete! Happy hacking!"));
}
main().catch((err) => {
console.error(import_picocolors.default.red("\u274C Error:"), err.message);
process.exit(1);
});
;