UNPKG

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
#!/usr/bin/env node "use strict"; 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); });