aavegotchi-cli 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/README.md +69 -0
- package/dist/abi.js +88 -0
- package/dist/command-catalog.js +104 -0
- package/dist/command-runner.js +12 -2
- package/dist/commands/bootstrap.js +9 -0
- package/dist/commands/mapped.js +9 -1
- package/dist/commands/onchain.js +8 -55
- package/dist/commands/stubs.js +9 -1
- package/dist/commands/tx.js +5 -0
- package/dist/index.js +6 -1
- package/dist/output.js +399 -65
- package/dist/schemas.js +6 -0
- package/dist/signer.js +191 -1
- package/dist/tx-engine.js +41 -5
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.2.2 - 2026-02-27
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Command-targeted help:
|
|
10
|
+
- `ag --help`
|
|
11
|
+
- `ag <command> --help`
|
|
12
|
+
- `ag help <command>`
|
|
13
|
+
- Mapped-write help now includes mapped function name, required flags, and dry-run pattern.
|
|
14
|
+
- ABI-derived signature/input introspection for mapped help when `--abi-file` is passed.
|
|
15
|
+
- Unknown command suggestion list in `UNKNOWN_COMMAND` error details.
|
|
16
|
+
- CLI UX audit report: `docs/ux/cli-ux-audit-2026-02-27.md`.
|
|
17
|
+
- Native `bankr` signer backend:
|
|
18
|
+
- signer spec: `bankr[:address|apiKeyEnv|apiUrl]`
|
|
19
|
+
- default auth env var: `BANKR_API_KEY`
|
|
20
|
+
- default API URL: `https://api.bankr.bot`
|
|
21
|
+
- address auto-resolution via `GET /agent/me` when address is not pinned
|
|
22
|
+
- transaction submit via `POST /agent/submit`
|
|
23
|
+
- Bootstrap overrides now support `bankr`:
|
|
24
|
+
- `--signer-address` to pin wallet address
|
|
25
|
+
- `--signer-auth-env-var` to customize Bankr API key env var
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Stub namespace errors now include mapped command options for the requested root.
|
|
30
|
+
|
|
31
|
+
## 0.2.1 - 2026-02-27
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- `--dry-run` mode for write surfaces:
|
|
36
|
+
- `ag tx send --dry-run`
|
|
37
|
+
- `ag onchain send --dry-run`
|
|
38
|
+
- mapped writes (for example `ag token approve --dry-run`)
|
|
39
|
+
- `scripts/smoke-write-dryrun.sh` and npm script `smoke:write-dryrun` for automated write-path smoke checks without broadcasting.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Dry-run execution now returns `status: "simulated"` with simulation details and skips journal mutation and transaction submission.
|
|
44
|
+
- `--dry-run` is explicitly blocked with `--wait` / `--confirm`.
|
|
45
|
+
|
|
3
46
|
## 0.2.0 - 2026-02-27
|
|
4
47
|
|
|
5
48
|
### Added
|
package/README.md
CHANGED
|
@@ -55,6 +55,54 @@ Planned domain namespaces are stubbed for parity tracking:
|
|
|
55
55
|
Many Base-era write flows are already executable as mapped aliases in those namespaces (internally routed through `onchain send`).
|
|
56
56
|
Example: `ag lending create --abi-file ./abis/GotchiLendingFacet.json --address 0x... --args-json '[...]' --json`
|
|
57
57
|
|
|
58
|
+
## Command help and discoverability
|
|
59
|
+
|
|
60
|
+
The CLI supports command-targeted help:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ag --help
|
|
64
|
+
ag tx send --help
|
|
65
|
+
ag help baazaar buy-now
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Mapped write commands now expose their onchain function mapping and required flags:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ag baazaar buy-now --help
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If you provide `--abi-file` with `--help`, the CLI prints ABI-derived function signature and input names for the mapped method:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ag baazaar buy-now --help --abi-file ./abis/BaazaarFacet.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Unknown commands return suggestions:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ag tx snd --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Dry-run writes
|
|
87
|
+
|
|
88
|
+
Use `--dry-run` on write commands to run full preflight without broadcasting:
|
|
89
|
+
|
|
90
|
+
- runs simulation (`eth_call`)
|
|
91
|
+
- runs gas + fee estimation
|
|
92
|
+
- enforces policy checks
|
|
93
|
+
- resolves nonce
|
|
94
|
+
- returns `status: \"simulated\"` with simulation details
|
|
95
|
+
|
|
96
|
+
Supported write surfaces:
|
|
97
|
+
|
|
98
|
+
- `tx send --dry-run`
|
|
99
|
+
- `onchain send --dry-run`
|
|
100
|
+
- mapped write aliases (for example: `token approve --dry-run`)
|
|
101
|
+
|
|
102
|
+
Safety rule:
|
|
103
|
+
|
|
104
|
+
- `--dry-run` cannot be combined with `--wait` / `--confirm`
|
|
105
|
+
|
|
58
106
|
## Subgraph sources and endpoint policy
|
|
59
107
|
|
|
60
108
|
Canonical source aliases:
|
|
@@ -127,12 +175,26 @@ npm run ag -- auction active --first 5 --raw --json
|
|
|
127
175
|
- `keychain:ACCOUNT_ID` (encrypted local key store; requires `AGCLI_KEYCHAIN_PASSPHRASE`)
|
|
128
176
|
- `remote:URL|ADDRESS|AUTH_ENV` (HTTP signer service)
|
|
129
177
|
- `ledger:DERIVATION_PATH|ADDRESS|BRIDGE_ENV` (external bridge command signer)
|
|
178
|
+
- `bankr[:ADDRESS|API_KEY_ENV|API_URL]` (Bankr-native signer via `/agent/me` + `/agent/submit`; defaults: `BANKR_API_KEY`, `https://api.bankr.bot`)
|
|
130
179
|
|
|
131
180
|
Remote signer contract:
|
|
132
181
|
|
|
133
182
|
- `GET /address` -> `{ "address": "0x..." }` (optional if address configured)
|
|
134
183
|
- `POST /sign-transaction` -> `{ "rawTransaction": "0x..." }` or `{ "txHash": "0x..." }`
|
|
135
184
|
|
|
185
|
+
Bankr signer contract:
|
|
186
|
+
|
|
187
|
+
- `GET /agent/me` -> resolves wallet address when signer address is not pinned
|
|
188
|
+
- `POST /agent/submit` -> submits transaction and returns transaction hash
|
|
189
|
+
- auth header: `x-api-key: <BANKR_API_KEY>`
|
|
190
|
+
|
|
191
|
+
Bankr bootstrap example:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
BANKR_API_KEY=... \
|
|
195
|
+
npm run ag -- bootstrap --mode agent --profile bankr --chain base --signer bankr --json
|
|
196
|
+
```
|
|
197
|
+
|
|
136
198
|
Ledger bridge contract:
|
|
137
199
|
|
|
138
200
|
- Set `AGCLI_LEDGER_BRIDGE_CMD` (or custom env var in signer config) to a command that reads tx payload JSON from stdin and outputs JSON containing either `rawTransaction` or `txHash`.
|
|
@@ -186,5 +248,12 @@ npm run typecheck
|
|
|
186
248
|
npm test
|
|
187
249
|
npm run build
|
|
188
250
|
npm run parity:check
|
|
251
|
+
npm run smoke:write-dryrun
|
|
189
252
|
npm run ag -- help
|
|
190
253
|
```
|
|
254
|
+
|
|
255
|
+
Write dry-run smoke test notes:
|
|
256
|
+
|
|
257
|
+
- `npm run smoke:write-dryrun` validates write paths without broadcasting any transaction.
|
|
258
|
+
- To run against an installed binary instead of local source:
|
|
259
|
+
- `AG_BIN=/absolute/path/to/ag npm run smoke:write-dryrun`
|
package/dist/abi.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseAbiFile = parseAbiFile;
|
|
37
|
+
exports.getAbiFunctionEntries = getAbiFunctionEntries;
|
|
38
|
+
exports.formatAbiFunctionSignature = formatAbiFunctionSignature;
|
|
39
|
+
exports.formatAbiFunctionInputs = formatAbiFunctionInputs;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const errors_1 = require("./errors");
|
|
42
|
+
function normalizeTypeName(item) {
|
|
43
|
+
if (!item.type) {
|
|
44
|
+
return "unknown";
|
|
45
|
+
}
|
|
46
|
+
if (!item.type.includes("tuple")) {
|
|
47
|
+
return item.type;
|
|
48
|
+
}
|
|
49
|
+
const components = item.components || [];
|
|
50
|
+
const componentTypes = components.map((component) => component.type).join(",");
|
|
51
|
+
return item.type.replace("tuple", `tuple(${componentTypes})`);
|
|
52
|
+
}
|
|
53
|
+
function parseAbiFile(filePath) {
|
|
54
|
+
if (!fs.existsSync(filePath)) {
|
|
55
|
+
throw new errors_1.CliError("ABI_NOT_FOUND", `ABI file not found: ${filePath}`, 2);
|
|
56
|
+
}
|
|
57
|
+
let parsed;
|
|
58
|
+
try {
|
|
59
|
+
parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw new errors_1.CliError("INVALID_ABI", `ABI file is not valid JSON: ${filePath}`, 2);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(parsed)) {
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
if (typeof parsed === "object" && parsed !== null && "abi" in parsed && Array.isArray(parsed.abi)) {
|
|
68
|
+
return parsed.abi;
|
|
69
|
+
}
|
|
70
|
+
throw new errors_1.CliError("INVALID_ABI", "ABI file must be an array or object containing 'abi'.", 2);
|
|
71
|
+
}
|
|
72
|
+
function getAbiFunctionEntries(abi, functionName) {
|
|
73
|
+
return abi.filter((item) => item.type === "function" && typeof item.name === "string" && item.name === functionName);
|
|
74
|
+
}
|
|
75
|
+
function formatAbiFunctionSignature(item) {
|
|
76
|
+
const inputTypes = (item.inputs || []).map((input) => normalizeTypeName(input));
|
|
77
|
+
return `${item.name}(${inputTypes.join(",")})`;
|
|
78
|
+
}
|
|
79
|
+
function formatAbiFunctionInputs(item) {
|
|
80
|
+
const inputs = item.inputs || [];
|
|
81
|
+
if (inputs.length === 0) {
|
|
82
|
+
return ["(none)"];
|
|
83
|
+
}
|
|
84
|
+
return inputs.map((input, index) => {
|
|
85
|
+
const label = input.name ? input.name : `arg${index}`;
|
|
86
|
+
return `${index}: ${label} (${normalizeTypeName(input)})`;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listKnownCommands = listKnownCommands;
|
|
4
|
+
exports.suggestCommands = suggestCommands;
|
|
5
|
+
const mapped_1 = require("./commands/mapped");
|
|
6
|
+
const stubs_1 = require("./commands/stubs");
|
|
7
|
+
const BUILTIN_COMMANDS = [
|
|
8
|
+
"help",
|
|
9
|
+
"bootstrap",
|
|
10
|
+
"profile list",
|
|
11
|
+
"profile show",
|
|
12
|
+
"profile use",
|
|
13
|
+
"profile export",
|
|
14
|
+
"signer check",
|
|
15
|
+
"signer keychain list",
|
|
16
|
+
"signer keychain import",
|
|
17
|
+
"signer keychain remove",
|
|
18
|
+
"policy list",
|
|
19
|
+
"policy show",
|
|
20
|
+
"policy upsert",
|
|
21
|
+
"rpc check",
|
|
22
|
+
"tx send",
|
|
23
|
+
"tx status",
|
|
24
|
+
"tx resume",
|
|
25
|
+
"tx watch",
|
|
26
|
+
"batch run",
|
|
27
|
+
"onchain call",
|
|
28
|
+
"onchain send",
|
|
29
|
+
"subgraph list",
|
|
30
|
+
"subgraph check",
|
|
31
|
+
"subgraph query",
|
|
32
|
+
"baazaar listing get",
|
|
33
|
+
"baazaar listing active",
|
|
34
|
+
"baazaar listing mine",
|
|
35
|
+
"auction get",
|
|
36
|
+
"auction active",
|
|
37
|
+
"auction mine",
|
|
38
|
+
"auction bids",
|
|
39
|
+
"auction bids-mine",
|
|
40
|
+
];
|
|
41
|
+
function listDomainReadCommands() {
|
|
42
|
+
return (0, stubs_1.listDomainStubRoots)().map((root) => `${root} read`);
|
|
43
|
+
}
|
|
44
|
+
function levenshteinDistance(a, b) {
|
|
45
|
+
if (a === b) {
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
if (a.length === 0) {
|
|
49
|
+
return b.length;
|
|
50
|
+
}
|
|
51
|
+
if (b.length === 0) {
|
|
52
|
+
return a.length;
|
|
53
|
+
}
|
|
54
|
+
const previous = new Array(b.length + 1).fill(0).map((_, index) => index);
|
|
55
|
+
const current = new Array(b.length + 1).fill(0);
|
|
56
|
+
for (let i = 1; i <= a.length; i++) {
|
|
57
|
+
current[0] = i;
|
|
58
|
+
for (let j = 1; j <= b.length; j++) {
|
|
59
|
+
const substitutionCost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
60
|
+
current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + substitutionCost);
|
|
61
|
+
}
|
|
62
|
+
for (let j = 0; j <= b.length; j++) {
|
|
63
|
+
previous[j] = current[j];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return previous[b.length];
|
|
67
|
+
}
|
|
68
|
+
function listKnownCommands() {
|
|
69
|
+
return [
|
|
70
|
+
...BUILTIN_COMMANDS,
|
|
71
|
+
...listDomainReadCommands(),
|
|
72
|
+
...(0, mapped_1.listMappedCommands)(),
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
function suggestCommands(input, max = 5) {
|
|
76
|
+
const query = input.trim().toLowerCase();
|
|
77
|
+
if (!query) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const scored = listKnownCommands().map((command) => {
|
|
81
|
+
const normalized = command.toLowerCase();
|
|
82
|
+
const startsWith = normalized.startsWith(query);
|
|
83
|
+
const includes = normalized.includes(query);
|
|
84
|
+
const distance = levenshteinDistance(query, normalized);
|
|
85
|
+
let score = distance;
|
|
86
|
+
if (startsWith) {
|
|
87
|
+
score = 0;
|
|
88
|
+
}
|
|
89
|
+
else if (includes) {
|
|
90
|
+
score = Math.min(score, 1);
|
|
91
|
+
}
|
|
92
|
+
return { command, score };
|
|
93
|
+
});
|
|
94
|
+
scored.sort((a, b) => {
|
|
95
|
+
if (a.score !== b.score) {
|
|
96
|
+
return a.score - b.score;
|
|
97
|
+
}
|
|
98
|
+
return a.command.localeCompare(b.command);
|
|
99
|
+
});
|
|
100
|
+
const threshold = Math.max(2, Math.floor(query.length / 2) + 1);
|
|
101
|
+
const filtered = scored.filter((entry) => entry.score <= threshold);
|
|
102
|
+
const results = (filtered.length > 0 ? filtered : scored).slice(0, max).map((entry) => entry.command);
|
|
103
|
+
return [...new Set(results)];
|
|
104
|
+
}
|
package/dist/command-runner.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.normalizeCommandPath = normalizeCommandPath;
|
|
4
4
|
exports.executeCommand = executeCommand;
|
|
5
5
|
const errors_1 = require("./errors");
|
|
6
|
+
const command_catalog_1 = require("./command-catalog");
|
|
6
7
|
const batch_1 = require("./commands/batch");
|
|
7
8
|
const bootstrap_1 = require("./commands/bootstrap");
|
|
8
9
|
const mapped_1 = require("./commands/mapped");
|
|
@@ -17,9 +18,12 @@ const stubs_1 = require("./commands/stubs");
|
|
|
17
18
|
const subgraph_1 = require("./commands/subgraph");
|
|
18
19
|
const tx_1 = require("./commands/tx");
|
|
19
20
|
function normalizeCommandPath(positionals) {
|
|
20
|
-
if (positionals.length === 0
|
|
21
|
+
if (positionals.length === 0) {
|
|
21
22
|
return ["help"];
|
|
22
23
|
}
|
|
24
|
+
if (positionals[0] === "help") {
|
|
25
|
+
return positionals;
|
|
26
|
+
}
|
|
23
27
|
return positionals;
|
|
24
28
|
}
|
|
25
29
|
async function executeCommand(ctx) {
|
|
@@ -220,5 +224,11 @@ async function executeCommand(ctx) {
|
|
|
220
224
|
data: await (0, stubs_1.runDomainStubCommand)(ctx),
|
|
221
225
|
};
|
|
222
226
|
}
|
|
223
|
-
|
|
227
|
+
const command = ctx.commandPath.join(" ");
|
|
228
|
+
const suggestions = (0, command_catalog_1.suggestCommands)(command);
|
|
229
|
+
throw new errors_1.CliError("UNKNOWN_COMMAND", `Unknown command '${command}'.`, 2, {
|
|
230
|
+
command,
|
|
231
|
+
suggestions,
|
|
232
|
+
hint: suggestions.length > 0 ? "Try one of the suggested commands with '--help'." : "Run 'ag help'.",
|
|
233
|
+
});
|
|
224
234
|
}
|
|
@@ -26,6 +26,15 @@ function buildSignerConfig(ctx, signerInput) {
|
|
|
26
26
|
...(authEnvVar ? { authEnvVar } : {}),
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
+
if (signer.type === "bankr") {
|
|
30
|
+
const address = (0, args_1.getFlagString)(ctx.args.flags, "signer-address");
|
|
31
|
+
const apiKeyEnvVar = (0, args_1.getFlagString)(ctx.args.flags, "signer-auth-env-var");
|
|
32
|
+
return {
|
|
33
|
+
...signer,
|
|
34
|
+
...(address ? { address: address } : {}),
|
|
35
|
+
...(apiKeyEnvVar ? { apiKeyEnvVar } : {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
29
38
|
if (signer.type === "ledger") {
|
|
30
39
|
const address = (0, args_1.getFlagString)(ctx.args.flags, "signer-address");
|
|
31
40
|
const bridgeCommandEnvVar = (0, args_1.getFlagString)(ctx.args.flags, "signer-bridge-env-var");
|
package/dist/commands/mapped.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findMappedFunction = findMappedFunction;
|
|
4
|
+
exports.listMappedCommands = listMappedCommands;
|
|
4
5
|
exports.listMappedCommandsForRoot = listMappedCommandsForRoot;
|
|
6
|
+
exports.getMappedCommandEntries = getMappedCommandEntries;
|
|
5
7
|
exports.runMappedDomainCommand = runMappedDomainCommand;
|
|
6
8
|
const errors_1 = require("../errors");
|
|
7
9
|
const onchain_1 = require("./onchain");
|
|
@@ -50,8 +52,14 @@ function findMappedFunction(commandPath) {
|
|
|
50
52
|
const key = commandPath.join(" ");
|
|
51
53
|
return MAPPED_WRITE_COMMANDS[key];
|
|
52
54
|
}
|
|
55
|
+
function listMappedCommands() {
|
|
56
|
+
return Object.keys(MAPPED_WRITE_COMMANDS).sort((a, b) => a.localeCompare(b));
|
|
57
|
+
}
|
|
53
58
|
function listMappedCommandsForRoot(root) {
|
|
54
|
-
return
|
|
59
|
+
return listMappedCommands().filter((entry) => entry.startsWith(`${root} `));
|
|
60
|
+
}
|
|
61
|
+
function getMappedCommandEntries() {
|
|
62
|
+
return { ...MAPPED_WRITE_COMMANDS };
|
|
55
63
|
}
|
|
56
64
|
async function runMappedDomainCommand(ctx) {
|
|
57
65
|
const key = ctx.commandPath.join(" ");
|
package/dist/commands/onchain.js
CHANGED
|
@@ -1,44 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.runOnchainCallCommand = runOnchainCallCommand;
|
|
37
4
|
exports.runOnchainSendWithFunction = runOnchainSendWithFunction;
|
|
38
5
|
exports.runOnchainSendCommand = runOnchainSendCommand;
|
|
39
|
-
const fs = __importStar(require("fs"));
|
|
40
6
|
const viem_1 = require("viem");
|
|
41
7
|
const args_1 = require("../args");
|
|
8
|
+
const abi_1 = require("../abi");
|
|
42
9
|
const chains_1 = require("../chains");
|
|
43
10
|
const config_1 = require("../config");
|
|
44
11
|
const errors_1 = require("../errors");
|
|
@@ -66,25 +33,6 @@ function parseArgsJson(value) {
|
|
|
66
33
|
}
|
|
67
34
|
return parsed;
|
|
68
35
|
}
|
|
69
|
-
function parseAbiFile(filePath) {
|
|
70
|
-
if (!fs.existsSync(filePath)) {
|
|
71
|
-
throw new errors_1.CliError("ABI_NOT_FOUND", `ABI file not found: ${filePath}`, 2);
|
|
72
|
-
}
|
|
73
|
-
let parsed;
|
|
74
|
-
try {
|
|
75
|
-
parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
throw new errors_1.CliError("INVALID_ABI", `ABI file is not valid JSON: ${filePath}`, 2);
|
|
79
|
-
}
|
|
80
|
-
if (Array.isArray(parsed)) {
|
|
81
|
-
return parsed;
|
|
82
|
-
}
|
|
83
|
-
if (typeof parsed === "object" && parsed !== null && "abi" in parsed && Array.isArray(parsed.abi)) {
|
|
84
|
-
return parsed.abi;
|
|
85
|
-
}
|
|
86
|
-
throw new errors_1.CliError("INVALID_ABI", `ABI file must be an array or object containing 'abi'.`, 2);
|
|
87
|
-
}
|
|
88
36
|
function parseValueWei(value) {
|
|
89
37
|
if (!value) {
|
|
90
38
|
return undefined;
|
|
@@ -123,7 +71,7 @@ async function runOnchainCallCommand(ctx) {
|
|
|
123
71
|
const chain = (0, chains_1.resolveChain)(profile.chain);
|
|
124
72
|
const rpcUrl = (0, chains_1.resolveRpcUrl)(chain, (0, args_1.getFlagString)(ctx.args.flags, "rpc-url") || profile.rpcUrl);
|
|
125
73
|
const abiFile = requireFlag((0, args_1.getFlagString)(ctx.args.flags, "abi-file"), "--abi-file");
|
|
126
|
-
const abi = parseAbiFile(abiFile);
|
|
74
|
+
const abi = (0, abi_1.parseAbiFile)(abiFile);
|
|
127
75
|
const address = parseAddress((0, args_1.getFlagString)(ctx.args.flags, "address"), "--address");
|
|
128
76
|
const functionName = requireFlag((0, args_1.getFlagString)(ctx.args.flags, "function"), "--function");
|
|
129
77
|
const args = parseArgsJson((0, args_1.getFlagString)(ctx.args.flags, "args-json"));
|
|
@@ -162,7 +110,7 @@ async function runOnchainSendWithFunction(ctx, forcedFunctionName, commandOverri
|
|
|
162
110
|
const chain = (0, chains_1.resolveChain)(profile.chain);
|
|
163
111
|
const rpcUrl = (0, chains_1.resolveRpcUrl)(chain, (0, args_1.getFlagString)(ctx.args.flags, "rpc-url") || profile.rpcUrl);
|
|
164
112
|
const abiFile = requireFlag((0, args_1.getFlagString)(ctx.args.flags, "abi-file"), "--abi-file");
|
|
165
|
-
const abi = parseAbiFile(abiFile);
|
|
113
|
+
const abi = (0, abi_1.parseAbiFile)(abiFile);
|
|
166
114
|
const address = parseAddress((0, args_1.getFlagString)(ctx.args.flags, "address"), "--address");
|
|
167
115
|
const functionName = forcedFunctionName || requireFlag((0, args_1.getFlagString)(ctx.args.flags, "function"), "--function");
|
|
168
116
|
const args = parseArgsJson((0, args_1.getFlagString)(ctx.args.flags, "args-json"));
|
|
@@ -184,6 +132,10 @@ async function runOnchainSendWithFunction(ctx, forcedFunctionName, commandOverri
|
|
|
184
132
|
});
|
|
185
133
|
}
|
|
186
134
|
const waitForReceipt = (0, args_1.getFlagBoolean)(ctx.args.flags, "wait");
|
|
135
|
+
const dryRun = (0, args_1.getFlagBoolean)(ctx.args.flags, "dry-run");
|
|
136
|
+
if (dryRun && waitForReceipt) {
|
|
137
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--dry-run cannot be combined with --wait.", 2);
|
|
138
|
+
}
|
|
187
139
|
const intent = {
|
|
188
140
|
idempotencyKey: (0, args_1.getFlagString)(ctx.args.flags, "idempotency-key"),
|
|
189
141
|
profileName: profile.name,
|
|
@@ -197,6 +149,7 @@ async function runOnchainSendWithFunction(ctx, forcedFunctionName, commandOverri
|
|
|
197
149
|
noncePolicy: noncePolicyRaw,
|
|
198
150
|
nonce,
|
|
199
151
|
waitForReceipt,
|
|
152
|
+
dryRun,
|
|
200
153
|
timeoutMs: parseTimeoutMs((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms")),
|
|
201
154
|
command: commandOverride || `onchain send ${functionName}`,
|
|
202
155
|
};
|
package/dist/commands/stubs.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isDomainStubRoot = isDomainStubRoot;
|
|
4
|
+
exports.listDomainStubRoots = listDomainStubRoots;
|
|
4
5
|
exports.runDomainStubCommand = runDomainStubCommand;
|
|
5
6
|
const errors_1 = require("../errors");
|
|
7
|
+
const mapped_1 = require("./mapped");
|
|
6
8
|
const SUPPORTED_STUB_ROOTS = [
|
|
7
9
|
"gotchi",
|
|
8
10
|
"portal",
|
|
@@ -22,11 +24,17 @@ const SUPPORTED_STUB_ROOTS = [
|
|
|
22
24
|
function isDomainStubRoot(root) {
|
|
23
25
|
return SUPPORTED_STUB_ROOTS.includes(root);
|
|
24
26
|
}
|
|
27
|
+
function listDomainStubRoots() {
|
|
28
|
+
return SUPPORTED_STUB_ROOTS;
|
|
29
|
+
}
|
|
25
30
|
async function runDomainStubCommand(ctx) {
|
|
26
31
|
const command = ctx.commandPath.join(" ");
|
|
32
|
+
const root = ctx.commandPath[0];
|
|
33
|
+
const availableMapped = (0, mapped_1.listMappedCommandsForRoot)(root);
|
|
27
34
|
throw new errors_1.CliError("COMMAND_NOT_IMPLEMENTED", `Command '${command}' is planned but not implemented yet.`, 2, {
|
|
28
35
|
command,
|
|
29
|
-
hint: "
|
|
36
|
+
hint: "Run 'ag help <command>' for usage. Mapped writes require --abi-file/--address/--args-json.",
|
|
37
|
+
availableMapped,
|
|
30
38
|
plannedRoots: SUPPORTED_STUB_ROOTS,
|
|
31
39
|
});
|
|
32
40
|
}
|
package/dist/commands/tx.js
CHANGED
|
@@ -75,10 +75,14 @@ async function runTxSendCommand(ctx) {
|
|
|
75
75
|
const nonceValue = (0, args_1.getFlagString)(ctx.args.flags, "nonce");
|
|
76
76
|
const nonce = nonceValue ? parseNumberFlag(nonceValue, "--nonce", 0) : undefined;
|
|
77
77
|
const waitForReceipt = (0, args_1.getFlagBoolean)(ctx.args.flags, "wait") || (0, args_1.getFlagBoolean)(ctx.args.flags, "confirm");
|
|
78
|
+
const dryRun = (0, args_1.getFlagBoolean)(ctx.args.flags, "dry-run");
|
|
78
79
|
const timeoutMs = parseNumberFlag((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms"), "--timeout-ms", 120000);
|
|
79
80
|
if (noncePolicy === "manual" && nonce === undefined) {
|
|
80
81
|
throw new errors_1.CliError("MISSING_NONCE", "--nonce is required when --nonce-policy=manual.", 2);
|
|
81
82
|
}
|
|
83
|
+
if (dryRun && waitForReceipt) {
|
|
84
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--dry-run cannot be combined with --wait/--confirm.", 2);
|
|
85
|
+
}
|
|
82
86
|
const intent = {
|
|
83
87
|
idempotencyKey,
|
|
84
88
|
profileName: profile.name,
|
|
@@ -92,6 +96,7 @@ async function runTxSendCommand(ctx) {
|
|
|
92
96
|
noncePolicy,
|
|
93
97
|
nonce,
|
|
94
98
|
waitForReceipt,
|
|
99
|
+
dryRun,
|
|
95
100
|
timeoutMs,
|
|
96
101
|
command: "tx send",
|
|
97
102
|
};
|
package/dist/index.js
CHANGED
|
@@ -11,8 +11,13 @@ async function run() {
|
|
|
11
11
|
const globals = (0, args_1.normalizeGlobals)(args);
|
|
12
12
|
(0, logger_1.initializeLogger)(globals);
|
|
13
13
|
const commandPath = (0, command_runner_1.normalizeCommandPath)(args.positionals);
|
|
14
|
+
const helpRequested = (0, args_1.getFlagBoolean)(args.flags, "help", "h");
|
|
14
15
|
if (commandPath[0] === "help") {
|
|
15
|
-
(0, output_1.outputHelp)();
|
|
16
|
+
(0, output_1.outputHelp)(commandPath.slice(1), args.flags);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (helpRequested) {
|
|
20
|
+
(0, output_1.outputHelp)(commandPath, args.flags);
|
|
16
21
|
return;
|
|
17
22
|
}
|
|
18
23
|
const ctx = {
|