@ethernauta/cli
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"execute-DKX5w-or.js","names":[],"sources":["../src/execute.ts"],"sourcesContent":["import {\n readdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport {\n type Description,\n DescriptionSchema,\n to_selector,\n} from \"@ethernauta/abi\"\nimport {\n emit_file_basename_for,\n emit_name_for,\n generate,\n} from \"@ethernauta/abi/generator\"\nimport { array, parse } from \"valibot\"\n\nfunction selector_hex(signature: string): `0x${string}` {\n const bytes = to_selector(signature)\n let hex = \"0x\"\n for (const b of bytes) {\n hex += b.toString(16).padStart(2, \"0\")\n }\n return hex as `0x${string}`\n}\n\nfunction parse_flags(args: string[]) {\n let in_path: string | undefined\n let out_dir: string | undefined\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === \"--in\") {\n in_path = args[++i]\n } else if (arg === \"--out\") {\n out_dir = args[++i]\n }\n }\n if (!in_path || !out_dir) {\n throw new Error(\n \"usage: ethernauta abi --in <path> --out <dir>\",\n )\n }\n return {\n in_path: resolve(process.cwd(), in_path),\n out_dir: resolve(process.cwd(), out_dir),\n }\n}\n\nfunction load_abi(path: string): unknown[] {\n const raw = JSON.parse(readFileSync(path, \"utf8\"))\n if (Array.isArray(raw)) return raw\n if (Array.isArray(raw.abi)) return raw.abi\n throw new Error(\n `expected an ABI JSON array or a foundry artifact with an \\`abi\\` array at ${path}`,\n )\n}\n\nfunction signature_key(d: Description): string {\n if (d.type !== \"function\") return d.type\n const param_types = d.inputs\n .map((i) => i.type)\n .join(\",\")\n return `${d.name}(${param_types})`\n}\n\nfunction snake_or_kebab(name: string): string {\n if (name.includes(\"_\")) return name\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n}\n\nfunction dedupe_by_signature(\n descriptions: Description[],\n): Description[] {\n const seen = new Set<string>()\n const out: Description[] = []\n for (const d of descriptions) {\n const key = signature_key(d)\n if (seen.has(key)) continue\n seen.add(key)\n out.push(d)\n }\n return out\n}\n\nfunction write_barrel(\n out_dir: string,\n functions: Description[],\n): void {\n const seen = new Set<string>()\n const lines: string[] = []\n for (const f of functions) {\n if (f.type !== \"function\") continue\n const js_name = emit_name_for(f, functions)\n if (seen.has(js_name)) continue\n seen.add(js_name)\n const basename = emit_file_basename_for(f, functions)\n lines.push(\n `export { ${js_name} } from \"./${basename}\"`,\n )\n }\n writeFileSync(\n join(out_dir, \"methods\", \"index.ts\"),\n `${lines.join(\"\\n\")}\\n`,\n )\n}\n\nfunction is_generatable(d: Description): boolean {\n if (d.type !== \"function\") return false\n const is_readable =\n d.stateMutability === \"view\" ||\n d.stateMutability === \"pure\"\n if (is_readable && d.outputs.length > 1) return false\n return true\n}\n\nexport function execute_abi(args: string[]): void {\n const { in_path, out_dir } = parse_flags(args)\n const raw = load_abi(in_path)\n const descriptions = parse(\n array(DescriptionSchema),\n raw,\n )\n const functions = dedupe_by_signature(\n descriptions.filter((d) => d.type === \"function\"),\n )\n const generatable = functions.filter(is_generatable)\n generate(generatable, out_dir)\n write_barrel(out_dir, generatable)\n console.log(\n `regenerated ${generatable.length} methods into ${out_dir}/methods/`,\n )\n}\n\nfunction parse_registry_flags(args: string[]) {\n let in_dir: string | undefined\n let out_file: string | undefined\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === \"--in\") {\n in_dir = args[++i]\n } else if (arg === \"--out\") {\n out_file = args[++i]\n }\n }\n if (!in_dir || !out_file) {\n throw new Error(\n \"usage: ethernauta registry --in <dir> --out <file>\",\n )\n }\n return {\n in_dir: resolve(process.cwd(), in_dir),\n out_file: resolve(process.cwd(), out_file),\n }\n}\n\nfunction walk_abi_jsons(root: string): string[] {\n const found: string[] = []\n const stack = [root]\n while (stack.length > 0) {\n const dir = stack.pop() as string\n for (const entry of readdirSync(dir, {\n withFileTypes: true,\n })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n stack.push(full)\n } else if (entry.name.endsWith(\".abi.json\")) {\n found.push(full)\n }\n }\n }\n return found.sort()\n}\n\ntype RegistryEntry = {\n signature: string\n name: string\n types: string[]\n param_names: string[]\n source: string\n}\n\nfunction collect_entries(\n files: string[],\n root: string,\n): Map<`0x${string}`, RegistryEntry> {\n const out = new Map<`0x${string}`, RegistryEntry>()\n for (const file of files) {\n const raw = load_abi(file)\n const descriptions = parse(\n array(DescriptionSchema),\n raw,\n )\n for (const d of descriptions) {\n if (d.type !== \"function\") continue\n const types = d.inputs.map((i) => i.type)\n const param_names = d.inputs.map((i) => i.name)\n const signature = `${d.name}(${types.join(\",\")})`\n const selector = selector_hex(signature)\n const relative = file.startsWith(`${root}/`)\n ? file.slice(root.length + 1)\n : file\n const existing = out.get(selector)\n if (existing) {\n if (existing.signature !== signature) {\n throw new Error(\n `selector collision ${selector}: '${existing.signature}' (${existing.source}) vs '${signature}' (${relative})`,\n )\n }\n continue\n }\n out.set(selector, {\n signature,\n name: d.name,\n types,\n param_names,\n source: relative,\n })\n }\n }\n return out\n}\n\nfunction format_registry(\n entries: Map<`0x${string}`, RegistryEntry>,\n): string {\n const sorted = Array.from(entries.entries()).sort(\n ([a], [b]) => (a < b ? -1 : a > b ? 1 : 0),\n )\n const rows = sorted.map(([selector, entry]) => {\n const types = entry.types\n .map((t) => JSON.stringify(t))\n .join(\", \")\n const names = entry.param_names\n .map((n) => JSON.stringify(n))\n .join(\", \")\n return ` ${JSON.stringify(selector)}: { name: ${JSON.stringify(entry.name)}, signature: ${JSON.stringify(entry.signature)}, types: [${types}], param_names: [${names}] },`\n })\n return `// AUTO-GENERATED — do not edit. Run \\`pnpm --filter @ethernauta/erc generate\\`.\n\nexport const REGISTRY = {\n${rows.join(\"\\n\")}\n} as const\n\nexport type RegistrySelector = keyof typeof REGISTRY\nexport type RegistryEntry = (typeof REGISTRY)[RegistrySelector]\n`\n}\n\nexport function execute_registry(args: string[]): void {\n const { in_dir, out_file } = parse_registry_flags(args)\n const files = walk_abi_jsons(in_dir)\n const entries = collect_entries(files, in_dir)\n writeFileSync(out_file, format_registry(entries))\n console.log(\n `wrote ${entries.size} registry entries from ${files.length} ABI JSONs to ${out_file}`,\n )\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"execute-DKX5w-or.js","names":[],"sources":["../src/execute.ts"],"sourcesContent":["import {\n readdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport {\n type Description,\n DescriptionSchema,\n to_selector,\n} from \"@ethernauta/abi\"\nimport {\n emit_file_basename_for,\n emit_name_for,\n generate,\n} from \"@ethernauta/abi/generator\"\nimport { array, parse } from \"valibot\"\n\nfunction selector_hex(signature: string): `0x${string}` {\n const bytes = to_selector(signature)\n let hex = \"0x\"\n for (const b of bytes) {\n hex += b.toString(16).padStart(2, \"0\")\n }\n return hex as `0x${string}`\n}\n\nfunction parse_flags(args: string[]) {\n let in_path: string | undefined\n let out_dir: string | undefined\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === \"--in\") {\n in_path = args[++i]\n } else if (arg === \"--out\") {\n out_dir = args[++i]\n }\n }\n if (!in_path || !out_dir) {\n throw new Error(\n \"usage: ethernauta abi --in <path> --out <dir>\",\n )\n }\n return {\n in_path: resolve(process.cwd(), in_path),\n out_dir: resolve(process.cwd(), out_dir),\n }\n}\n\nfunction load_abi(path: string): unknown[] {\n const raw = JSON.parse(readFileSync(path, \"utf8\"))\n if (Array.isArray(raw)) return raw\n if (Array.isArray(raw.abi)) return raw.abi\n throw new Error(\n `expected an ABI JSON array or a foundry artifact with an \\`abi\\` array at ${path}`,\n )\n}\n\nfunction signature_key(d: Description): string {\n if (d.type !== \"function\") return d.type\n const param_types = d.inputs.map((i) => i.type).join(\",\")\n return `${d.name}(${param_types})`\n}\n\nfunction snake_or_kebab(name: string): string {\n if (name.includes(\"_\")) return name\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n}\n\nfunction dedupe_by_signature(\n descriptions: Description[],\n): Description[] {\n const seen = new Set<string>()\n const out: Description[] = []\n for (const d of descriptions) {\n const key = signature_key(d)\n if (seen.has(key)) continue\n seen.add(key)\n out.push(d)\n }\n return out\n}\n\nfunction write_barrel(\n out_dir: string,\n functions: Description[],\n): void {\n const seen = new Set<string>()\n const lines: string[] = []\n for (const f of functions) {\n if (f.type !== \"function\") continue\n const js_name = emit_name_for(f, functions)\n if (seen.has(js_name)) continue\n seen.add(js_name)\n const basename = emit_file_basename_for(f, functions)\n lines.push(`export { ${js_name} } from \"./${basename}\"`)\n }\n writeFileSync(\n join(out_dir, \"methods\", \"index.ts\"),\n `${lines.join(\"\\n\")}\\n`,\n )\n}\n\nfunction is_generatable(d: Description): boolean {\n if (d.type !== \"function\") return false\n const is_readable =\n d.stateMutability === \"view\" ||\n d.stateMutability === \"pure\"\n if (is_readable && d.outputs.length > 1) return false\n return true\n}\n\nexport function execute_abi(args: string[]): void {\n const { in_path, out_dir } = parse_flags(args)\n const raw = load_abi(in_path)\n const descriptions = parse(array(DescriptionSchema), raw)\n const functions = dedupe_by_signature(\n descriptions.filter((d) => d.type === \"function\"),\n )\n const generatable = functions.filter(is_generatable)\n generate(generatable, out_dir)\n write_barrel(out_dir, generatable)\n console.log(\n `regenerated ${generatable.length} methods into ${out_dir}/methods/`,\n )\n}\n\nfunction parse_registry_flags(args: string[]) {\n let in_dir: string | undefined\n let out_file: string | undefined\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] as string\n if (arg === \"--in\") {\n in_dir = args[++i]\n } else if (arg === \"--out\") {\n out_file = args[++i]\n }\n }\n if (!in_dir || !out_file) {\n throw new Error(\n \"usage: ethernauta registry --in <dir> --out <file>\",\n )\n }\n return {\n in_dir: resolve(process.cwd(), in_dir),\n out_file: resolve(process.cwd(), out_file),\n }\n}\n\nfunction walk_abi_jsons(root: string): string[] {\n const found: string[] = []\n const stack = [root]\n while (stack.length > 0) {\n const dir = stack.pop() as string\n for (const entry of readdirSync(dir, {\n withFileTypes: true,\n })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n stack.push(full)\n } else if (entry.name.endsWith(\".abi.json\")) {\n found.push(full)\n }\n }\n }\n return found.sort()\n}\n\ntype RegistryEntry = {\n signature: string\n name: string\n types: string[]\n param_names: string[]\n source: string\n}\n\nfunction collect_entries(\n files: string[],\n root: string,\n): Map<`0x${string}`, RegistryEntry> {\n const out = new Map<`0x${string}`, RegistryEntry>()\n for (const file of files) {\n const raw = load_abi(file)\n const descriptions = parse(\n array(DescriptionSchema),\n raw,\n )\n for (const d of descriptions) {\n if (d.type !== \"function\") continue\n const types = d.inputs.map((i) => i.type)\n const param_names = d.inputs.map((i) => i.name)\n const signature = `${d.name}(${types.join(\",\")})`\n const selector = selector_hex(signature)\n const relative = file.startsWith(`${root}/`)\n ? file.slice(root.length + 1)\n : file\n const existing = out.get(selector)\n if (existing) {\n if (existing.signature !== signature) {\n throw new Error(\n `selector collision ${selector}: '${existing.signature}' (${existing.source}) vs '${signature}' (${relative})`,\n )\n }\n continue\n }\n out.set(selector, {\n signature,\n name: d.name,\n types,\n param_names,\n source: relative,\n })\n }\n }\n return out\n}\n\nfunction format_registry(\n entries: Map<`0x${string}`, RegistryEntry>,\n): string {\n const sorted = Array.from(entries.entries()).sort(\n ([a], [b]) => (a < b ? -1 : a > b ? 1 : 0),\n )\n const rows = sorted.map(([selector, entry]) => {\n const types = entry.types\n .map((t) => JSON.stringify(t))\n .join(\", \")\n const names = entry.param_names\n .map((n) => JSON.stringify(n))\n .join(\", \")\n return ` ${JSON.stringify(selector)}: { name: ${JSON.stringify(entry.name)}, signature: ${JSON.stringify(entry.signature)}, types: [${types}], param_names: [${names}] },`\n })\n return `// AUTO-GENERATED — do not edit. Run \\`pnpm --filter @ethernauta/erc generate\\`.\n\nexport const REGISTRY = {\n${rows.join(\"\\n\")}\n} as const\n\nexport type RegistrySelector = keyof typeof REGISTRY\nexport type RegistryEntry = (typeof REGISTRY)[RegistrySelector]\n`\n}\n\nexport function execute_registry(args: string[]): void {\n const { in_dir, out_file } = parse_registry_flags(args)\n const files = walk_abi_jsons(in_dir)\n const entries = collect_entries(files, in_dir)\n writeFileSync(out_file, format_registry(entries))\n console.log(\n `wrote ${entries.size} registry entries from ${files.length} ABI JSONs to ${out_file}`,\n )\n}\n"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index-BUis45IC.d.ts","names":[],"sources":["../src/execute.ts"],"mappings":";iBAsHgB,WAAA;AAAA,iBAsIA,gBAAA,CAtIW,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA"} | ||
| {"version":3,"file":"index-BUis45IC.d.ts","names":[],"sources":["../src/execute.ts"],"mappings":";iBAkHgB,WAAA;AAAA,iBAmIA,gBAAA,CAnIW,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA"} |
+2
-2
@@ -5,3 +5,3 @@ { | ||
| "type": "module", | ||
| "version": "0.0.42", | ||
| "version": "0.0.43", | ||
| "publishConfig": { | ||
@@ -23,3 +23,3 @@ "access": "public" | ||
| "dependencies": { | ||
| "@ethernauta/abi": "0.0.42" | ||
| "@ethernauta/abi": "0.0.43" | ||
| }, | ||
@@ -26,0 +26,0 @@ "peerDependencies": { |
+39
-16
@@ -1,30 +0,53 @@ | ||
| [](https://deno.bundlejs.com/badge?q=@ethernauta/eth@0.0.10&treeshake=[*]) | ||
| [](https://deno.bundlejs.com/?q=@ethernauta/cli&treeshake=[*]) | ||
| ## Philosophy | ||
| This module aims to be an un-opinionated representation of the defined: | ||
| This module ships a CLI for working with ABIs in an Ethernauta codebase. Two subcommands: | ||
| - [abi-spec](https://docs.soliditylang.org/en/latest/abi-spec.html) | ||
| - `ethernauta abi` — generate ready-to-use TypeScript methods from an ABI JSON or a Foundry artifact | ||
| - `ethernauta registry` — walk a directory of ABI JSONs and emit a 4-byte selector → method-metadata map (used by the wallet to surface human-readable function names) | ||
| ## Modules | ||
| - [abi](https://github.com/niconiahi/ethernauta/blob/main/packages/abi) [[NPM](https://www.npmjs.com/package/@ethernauta/abi)] | ||
| - [chain](https://github.com/niconiahi/ethernauta/blob/main/packages/chain) [[NPM](https://www.npmjs.com/package/@ethernauta/chain)] | ||
| - [cli](https://github.com/niconiahi/ethernauta/blob/main/packages/cli) [[NPM](https://www.npmjs.com/package/@ethernauta/cli)] | ||
| - [erc](https://github.com/niconiahi/ethernauta/blob/main/packages/erc) [[NPM](https://www.npmjs.com/package/@ethernauta/erc)] | ||
| - [eth](https://github.com/niconiahi/ethernauta/blob/main/packages/eth) [[NPM](https://www.npmjs.com/package/@ethernauta/eth)] | ||
| - [transaction](https://github.com/niconiahi/ethernauta/blob/main/packages/transaction) [[NPM](https://www.npmjs.com/package/@ethernauta/transaction)] | ||
| - [utils](https://github.com/niconiahi/ethernauta/blob/main/packages/utils) [[NPM](https://www.npmjs.com/package/@ethernauta/utils)] | ||
| - [wallet](https://github.com/niconiahi/ethernauta/blob/main/packages/wallet) | ||
| - [abi](https://github.com/niconiahi/ethernauta/tree/main/packages/abi) [[NPM](https://www.npmjs.com/package/@ethernauta/abi)] | ||
| - [chain](https://github.com/niconiahi/ethernauta/tree/main/packages/chain) [[NPM](https://www.npmjs.com/package/@ethernauta/chain)] | ||
| - [cli](https://github.com/niconiahi/ethernauta/tree/main/packages/cli) [[NPM](https://www.npmjs.com/package/@ethernauta/cli)] | ||
| - [eip](https://github.com/niconiahi/ethernauta/tree/main/packages/eip) [[NPM](https://www.npmjs.com/package/@ethernauta/eip)] | ||
| - [erc](https://github.com/niconiahi/ethernauta/tree/main/packages/erc) [[NPM](https://www.npmjs.com/package/@ethernauta/erc)] | ||
| - [eth](https://github.com/niconiahi/ethernauta/tree/main/packages/eth) [[NPM](https://www.npmjs.com/package/@ethernauta/eth)] | ||
| - [transaction](https://github.com/niconiahi/ethernauta/tree/main/packages/transaction) [[NPM](https://www.npmjs.com/package/@ethernauta/transaction)] | ||
| - [transport](https://github.com/niconiahi/ethernauta/tree/main/packages/transport) [[NPM](https://www.npmjs.com/package/@ethernauta/transport)] | ||
| - [utils](https://github.com/niconiahi/ethernauta/tree/main/packages/utils) [[NPM](https://www.npmjs.com/package/@ethernauta/utils)] | ||
| - [wallet](https://github.com/niconiahi/ethernauta/tree/main/packages/wallet) | ||
| ## Table of contents | ||
| ## API | ||
| 1. [API](#api) | ||
| ### `ethernauta abi` | ||
| ## API | ||
| Regenerate contract method TypeScript files from an ABI JSON or a Foundry artifact. | ||
| ### Generate ABI functions with CLI | ||
| ```bash | ||
| npx ethernauta abi --in abis/IERC20.abi.json --out app/methods | ||
| ``` | ||
| Each function in the ABI emits one file under `<out>/methods/`. View / pure functions emit `Callable<T>`; state-changing functions emit `Signable<Bytes>`. A barrel file at `<out>/methods/index.ts` re-exports everything. | ||
| A typical setup wires this into a `package.json` script so generated methods stay in sync with the contract: | ||
| ```json | ||
| { | ||
| "scripts": { | ||
| "regen:methods": "ethernauta abi --in contracts/out/MyContract.sol/MyContract.json --out app/generated/my-contract" | ||
| } | ||
| } | ||
| ``` | ||
| ### `ethernauta registry` | ||
| Walk a directory for `*.abi.json` files and emit a single `REGISTRY` mapping 4-byte selectors to method metadata. | ||
| ```bash | ||
| npx ethernauta generate --abi abis/IERC20.abi.json --out app | ||
| npx ethernauta registry --in src --out src/registry/registry.generated.ts | ||
| ``` | ||
| The registry is used by the wallet to verify and display function names for transactions whose call data carries an unknown selector. |
+3
-10
@@ -61,5 +61,3 @@ import { | ||
| if (d.type !== "function") return d.type | ||
| const param_types = d.inputs | ||
| .map((i) => i.type) | ||
| .join(",") | ||
| const param_types = d.inputs.map((i) => i.type).join(",") | ||
| return `${d.name}(${param_types})` | ||
@@ -101,5 +99,3 @@ } | ||
| const basename = emit_file_basename_for(f, functions) | ||
| lines.push( | ||
| `export { ${js_name} } from "./${basename}"`, | ||
| ) | ||
| lines.push(`export { ${js_name} } from "./${basename}"`) | ||
| } | ||
@@ -124,6 +120,3 @@ writeFileSync( | ||
| const raw = load_abi(in_path) | ||
| const descriptions = parse( | ||
| array(DescriptionSchema), | ||
| raw, | ||
| ) | ||
| const descriptions = parse(array(DescriptionSchema), raw) | ||
| const functions = dedupe_by_signature( | ||
@@ -130,0 +123,0 @@ descriptions.filter((d) => d.type === "function"), |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
31714
4.21%54
74.19%0
-100%527
-1.31%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated