aavegotchi-cli 0.1.0 → 0.2.1

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/dist/tx-engine.js CHANGED
@@ -72,9 +72,10 @@ async function waitForConfirmation(intent, ctx, txHash) {
72
72
  async function executeTxIntent(intent, chain, customHome) {
73
73
  const idempotencyKey = (0, idempotency_1.resolveIdempotencyKey)(intent);
74
74
  const journal = new journal_1.JournalStore((0, config_1.resolveJournalPath)(customHome));
75
+ const dryRun = Boolean(intent.dryRun);
75
76
  try {
76
77
  const preflight = await (0, rpc_1.runRpcPreflight)(chain, intent.rpcUrl);
77
- const existing = journal.getByIdempotencyKey(idempotencyKey);
78
+ const existing = dryRun ? undefined : journal.getByIdempotencyKey(idempotencyKey);
78
79
  if (existing && existing.status === "confirmed") {
79
80
  return mapJournalToResult(existing);
80
81
  }
@@ -91,7 +92,13 @@ async function executeTxIntent(intent, chain, customHome) {
91
92
  }
92
93
  const viemChain = (0, chains_1.toViemChain)(chain, intent.rpcUrl);
93
94
  const signerRuntime = await (0, signer_1.resolveSignerRuntime)(intent.signer, preflight.client, intent.rpcUrl, viemChain, customHome);
94
- if (!signerRuntime.summary.canSign || !signerRuntime.sendTransaction || !signerRuntime.summary.address) {
95
+ if (!signerRuntime.summary.address) {
96
+ throw new errors_1.CliError("MISSING_SIGNER_ADDRESS", "Signer address is required for simulation and transaction execution.", 2, {
97
+ signerType: signerRuntime.summary.signerType,
98
+ backendStatus: signerRuntime.summary.backendStatus,
99
+ });
100
+ }
101
+ if (!dryRun && (!signerRuntime.summary.canSign || !signerRuntime.sendTransaction)) {
95
102
  throw new errors_1.CliError("READONLY_SIGNER", "Selected signer cannot submit transactions.", 2, {
96
103
  signerType: signerRuntime.summary.signerType,
97
104
  backendStatus: signerRuntime.summary.backendStatus,
@@ -125,7 +132,7 @@ async function executeTxIntent(intent, chain, customHome) {
125
132
  const maxPriorityFeePerGas = feeEstimate.maxPriorityFeePerGas;
126
133
  const balanceWei = await preflight.client.getBalance({ address: fromAddress });
127
134
  const requiredWei = (intent.valueWei || 0n) + gasLimit * (maxFeePerGas || 0n);
128
- if (balanceWei < requiredWei) {
135
+ if (!dryRun && balanceWei < requiredWei) {
129
136
  throw new errors_1.CliError("INSUFFICIENT_FUNDS_PRECHECK", "Account balance is below estimated transaction requirement.", 2, {
130
137
  from: fromAddress,
131
138
  balanceWei: balanceWei.toString(),
@@ -147,6 +154,31 @@ async function executeTxIntent(intent, chain, customHome) {
147
154
  existing,
148
155
  };
149
156
  const nonce = await resolveNonce(intent, ctx, fromAddress);
157
+ if (dryRun) {
158
+ return {
159
+ idempotencyKey,
160
+ from: fromAddress,
161
+ to: toAddress,
162
+ nonce,
163
+ gasLimit: gasLimit.toString(),
164
+ maxFeePerGasWei: maxFeePerGas?.toString(),
165
+ maxPriorityFeePerGasWei: maxPriorityFeePerGas?.toString(),
166
+ status: "simulated",
167
+ dryRun: true,
168
+ simulation: {
169
+ requiredWei: requiredWei.toString(),
170
+ balanceWei: balanceWei.toString(),
171
+ signerCanSign: signerRuntime.summary.canSign,
172
+ noncePolicy: intent.noncePolicy,
173
+ },
174
+ };
175
+ }
176
+ if (!signerRuntime.sendTransaction) {
177
+ throw new errors_1.CliError("READONLY_SIGNER", "Selected signer cannot submit transactions.", 2, {
178
+ signerType: signerRuntime.summary.signerType,
179
+ backendStatus: signerRuntime.summary.backendStatus,
180
+ });
181
+ }
150
182
  journal.upsertPrepared({
151
183
  idempotencyKey,
152
184
  profileName: intent.profileName,
@@ -208,14 +240,18 @@ async function executeTxIntent(intent, chain, customHome) {
208
240
  }
209
241
  catch (error) {
210
242
  if (error instanceof errors_1.CliError) {
211
- journal.markFailed(idempotencyKey, error.code, error.message);
243
+ if (!dryRun) {
244
+ journal.markFailed(idempotencyKey, error.code, error.message);
245
+ }
212
246
  throw error;
213
247
  }
214
248
  const unknown = new errors_1.CliError("TX_EXECUTION_FAILED", "Transaction execution failed.", 1, {
215
249
  correlationId: (0, crypto_1.randomUUID)(),
216
250
  message: error instanceof Error ? error.message : String(error),
217
251
  });
218
- journal.markFailed(idempotencyKey, unknown.code, unknown.message);
252
+ if (!dryRun) {
253
+ journal.markFailed(idempotencyKey, unknown.code, unknown.message);
254
+ }
219
255
  throw unknown;
220
256
  }
221
257
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aavegotchi-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Agent-first CLI for automating Aavegotchi app and onchain workflows",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,7 +11,8 @@
11
11
  "main": "dist/index.js",
12
12
  "files": [
13
13
  "dist",
14
- "README.md"
14
+ "README.md",
15
+ "CHANGELOG.md"
15
16
  ],
16
17
  "bin": {
17
18
  "ag": "dist/index.js",
@@ -29,6 +30,7 @@
29
30
  "test": "vitest run",
30
31
  "test:watch": "vitest",
31
32
  "parity:check": "node scripts/check-parity.mjs",
33
+ "smoke:write-dryrun": "bash scripts/smoke-write-dryrun.sh",
32
34
  "ag": "tsx src/index.ts",
33
35
  "prepack": "npm run build",
34
36
  "bootstrap:smoke": "AGCLI_HOME=/tmp/agcli-smoke tsx src/index.ts bootstrap --mode agent --profile smoke --chain base --signer readonly --json"