Skip to content

Commit edd4b5b

Browse files
Add generate-abi-json CLI tool
Adds a standalone CLI entry point at src/cli/generate-abi-json.ts that can be invoked via 'npx generate-abi-json' (after installing the SDK) or 'node dist/common/cli/generate-abi-json.js' (after building). Supports: --network (mainnet/testnet/devnet/local) --node-url (custom fullnode endpoint) --address / --module (required) --function (optional, to target a single function) --output (write to file instead of stdout) --pretty (pretty-print JSON) Registered as a bin entry in package.json and added to tsup config. Co-authored-by: Greg Nazario <greg@gnazar.io>
1 parent 66e5e3d commit edd4b5b

File tree

4 files changed

+144
-1
lines changed

4 files changed

+144
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ All notable changes to the Aptos TypeScript SDK will be captured in this file. T
2121

2222
- Add e2e tests for external signer flow (build → getSigningMessage → sign externally → submit) to verify the flow works correctly with the latest SDK version
2323
- Add ABI JSON generation tool: `generateModuleAbiJSON`, `generateEntryFunctionAbiJSON`, `generateViewFunctionAbiJSON` to fetch on-chain module ABIs and produce JSON-serializable output; `parseEntryFunctionAbiJSON` and `parseViewFunctionAbiJSON` to hydrate them back into SDK-native `EntryFunctionABI`/`ViewFunctionABI` types
24+
- Add `generate-abi-json` CLI tool (available via `npx generate-abi-json`) to generate ABI JSON from on-chain state without writing code
2425
- Add MultiKey (K-of-N mixed key types) transfer example (`examples/typescript/multikey_transfer.ts`)
2526
- Add MultiEd25519 (K-of-N Ed25519) transfer example (`examples/typescript/multi_ed25519_transfer.ts`)
2627

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"url": "https://github.com/aptos-labs/aptos-ts-sdk/issues/new/choose"
1111
},
1212
"homepage": "https://aptos-labs.github.io/aptos-ts-sdk/",
13+
"bin": {
14+
"generate-abi-json": "dist/common/cli/generate-abi-json.js"
15+
},
1316
"main": "dist/common/index.js",
1417
"module": "dist/esm/index.mjs",
1518
"exports": {
@@ -47,6 +50,7 @@
4750
"doc": "scripts/generateDocs.sh",
4851
"check-version": "scripts/checkVersion.sh",
4952
"update-version": "scripts/updateVersion.sh && pnpm doc",
53+
"generate-abi-json": "node dist/common/cli/generate-abi-json.js",
5054
"spec": "pnpm build && pnpm _spec",
5155
"_spec": "cucumber-js -p default"
5256
},

src/cli/generate-abi-json.ts

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/env node
2+
3+
// Copyright © Aptos Foundation
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
import { parseArgs } from "node:util";
7+
import { writeFileSync } from "node:fs";
8+
9+
import { AptosConfig } from "../api/aptosConfig";
10+
import { Network } from "../utils/apiEndpoints";
11+
import {
12+
generateModuleAbiJSON,
13+
generateEntryFunctionAbiJSON,
14+
generateViewFunctionAbiJSON,
15+
} from "../transactions/transactionBuilder/abiJson";
16+
17+
const USAGE = `
18+
Usage: generate-abi-json [options]
19+
20+
Fetches on-chain Move module ABIs and outputs JSON-serializable entry/view
21+
function ABI definitions that can be embedded in application source code.
22+
23+
Options:
24+
--network <network> Network to connect to: mainnet, testnet, devnet, local
25+
(default: mainnet)
26+
--node-url <url> Custom fullnode URL (overrides --network)
27+
--address <address> Account address of the module (required)
28+
--module <name> Module name (required)
29+
--function <name> Specific function name (omit to output all functions)
30+
--output <file> Write JSON to a file instead of stdout
31+
--pretty Pretty-print JSON with 2-space indentation
32+
--help Show this help message
33+
34+
Examples:
35+
# All entry/view ABIs for the coin module on mainnet
36+
generate-abi-json --address 0x1 --module coin --pretty
37+
38+
# Single entry function, written to a file
39+
generate-abi-json --address 0x1 --module coin --function transfer --output coin_transfer.json
40+
41+
# Use a custom node URL (include /v1 path)
42+
generate-abi-json --node-url http://localhost:8080/v1 --address 0x1 --module coin
43+
`.trim();
44+
45+
const NETWORK_MAP: Record<string, Network> = {
46+
mainnet: Network.MAINNET,
47+
testnet: Network.TESTNET,
48+
devnet: Network.DEVNET,
49+
local: Network.LOCAL,
50+
};
51+
52+
async function main() {
53+
const { values } = parseArgs({
54+
options: {
55+
network: { type: "string", default: "mainnet" },
56+
"node-url": { type: "string" },
57+
address: { type: "string" },
58+
module: { type: "string" },
59+
function: { type: "string" },
60+
output: { type: "string" },
61+
pretty: { type: "boolean", default: false },
62+
help: { type: "boolean", default: false },
63+
},
64+
strict: true,
65+
});
66+
67+
if (values.help) {
68+
console.log(USAGE);
69+
process.exit(0);
70+
}
71+
72+
if (!values.address) {
73+
console.error("Error: --address is required\n");
74+
console.error(USAGE);
75+
process.exit(1);
76+
}
77+
if (!values.module) {
78+
console.error("Error: --module is required\n");
79+
console.error(USAGE);
80+
process.exit(1);
81+
}
82+
83+
const networkKey = values.network!.toLowerCase();
84+
const network = NETWORK_MAP[networkKey];
85+
if (!network && !values["node-url"]) {
86+
console.error(`Error: unknown network '${values.network}'. Use one of: mainnet, testnet, devnet, local\n`);
87+
console.error("Or provide --node-url for a custom endpoint.");
88+
process.exit(1);
89+
}
90+
91+
const aptosConfig = values["node-url"]
92+
? new AptosConfig({ fullnode: values["node-url"], network: Network.CUSTOM })
93+
: new AptosConfig({ network });
94+
95+
try {
96+
let result: unknown;
97+
98+
if (values.function) {
99+
// Try entry function first, then view function
100+
try {
101+
result = await generateEntryFunctionAbiJSON({
102+
aptosConfig,
103+
accountAddress: values.address,
104+
moduleName: values.module,
105+
functionName: values.function,
106+
});
107+
} catch {
108+
result = await generateViewFunctionAbiJSON({
109+
aptosConfig,
110+
accountAddress: values.address,
111+
moduleName: values.module,
112+
functionName: values.function,
113+
});
114+
}
115+
} else {
116+
result = await generateModuleAbiJSON({
117+
aptosConfig,
118+
accountAddress: values.address,
119+
moduleName: values.module,
120+
});
121+
}
122+
123+
const jsonStr = values.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
124+
125+
if (values.output) {
126+
writeFileSync(values.output, `${jsonStr}\n`, "utf-8");
127+
console.error(`Wrote ABI JSON to ${values.output}`);
128+
} else {
129+
console.log(jsonStr);
130+
}
131+
} catch (err: unknown) {
132+
const message = err instanceof Error ? err.message : String(err);
133+
console.error(`Error: ${message}`);
134+
process.exit(1);
135+
}
136+
}
137+
138+
main();

tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const DEFAULT_CONFIG: Options = {
3131
// Common.js config
3232
const COMMON_CONFIG: MandatoryOptions = {
3333
...DEFAULT_CONFIG,
34-
entry: ["src/index.ts", "src/cli/index.ts"],
34+
entry: ["src/index.ts", "src/cli/index.ts", "src/cli/generate-abi-json.ts"],
3535
format: "cjs",
3636
outDir: "dist/common",
3737
};

0 commit comments

Comments
 (0)