zk-agent-cli 0.1.0-rc.2 → 0.1.0-rc.4
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/README.md +97 -31
- package/dist/index.js +1298 -137
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command14, CommanderError } from "commander";
|
|
5
5
|
import { config as loadEnv } from "dotenv";
|
|
6
6
|
|
|
7
7
|
// src/commands/operations.ts
|
|
@@ -79,6 +79,9 @@ import fs from "node:fs";
|
|
|
79
79
|
import os from "node:os";
|
|
80
80
|
import path from "node:path";
|
|
81
81
|
|
|
82
|
+
// ../agent-core/src/wallet-session.ts
|
|
83
|
+
import { createHash } from "node:crypto";
|
|
84
|
+
|
|
82
85
|
// ../agent-session-protocol/src/constants.ts
|
|
83
86
|
var PROTOCOL_VERSION = "zk-agent-session-v1";
|
|
84
87
|
|
|
@@ -239,6 +242,10 @@ function buildApprovedSessionPayload(input) {
|
|
|
239
242
|
function isHexPrivateKey(value) {
|
|
240
243
|
return /^0x[a-fA-F0-9]{64}$/.test(value);
|
|
241
244
|
}
|
|
245
|
+
function deriveStableWalletId(wallet) {
|
|
246
|
+
const seed = `${wallet.walletAddress.trim().toLowerCase()}:${wallet.chainId}:${wallet.createdAt.trim()}`;
|
|
247
|
+
return `wal_${createHash("sha256").update(seed).digest("hex").slice(0, 24)}`;
|
|
248
|
+
}
|
|
242
249
|
function deriveLocalExecutionSignerAddress(privateKey) {
|
|
243
250
|
if (!privateKey || !isHexPrivateKey(privateKey)) return void 0;
|
|
244
251
|
try {
|
|
@@ -263,15 +270,25 @@ function resolveLocalExecutionPrivateKey(wallet) {
|
|
|
263
270
|
function migrateWalletSessionRecord(wallet) {
|
|
264
271
|
const legacyPrivateKey = wallet.sessionPayload?.sessionPrivateKey;
|
|
265
272
|
const existingAuthority = wallet.localExecutionAuthority;
|
|
273
|
+
const walletId = wallet.walletId || deriveStableWalletId(wallet);
|
|
266
274
|
if (!existingAuthority && !legacyPrivateKey) {
|
|
267
|
-
return wallet;
|
|
275
|
+
if (wallet.walletId === walletId) return wallet;
|
|
276
|
+
return {
|
|
277
|
+
...wallet,
|
|
278
|
+
walletId
|
|
279
|
+
};
|
|
268
280
|
}
|
|
269
281
|
const privateKey = existingAuthority?.privateKey || legacyPrivateKey;
|
|
270
282
|
if (!privateKey) {
|
|
271
|
-
return wallet;
|
|
283
|
+
if (wallet.walletId === walletId) return wallet;
|
|
284
|
+
return {
|
|
285
|
+
...wallet,
|
|
286
|
+
walletId
|
|
287
|
+
};
|
|
272
288
|
}
|
|
273
289
|
return {
|
|
274
290
|
...wallet,
|
|
291
|
+
walletId,
|
|
275
292
|
localExecutionAuthority: {
|
|
276
293
|
privateKey,
|
|
277
294
|
signerAddress: existingAuthority?.signerAddress || deriveLocalExecutionSignerAddress(privateKey),
|
|
@@ -375,6 +392,33 @@ function readEncryptedJson(filePath) {
|
|
|
375
392
|
function storageDir() {
|
|
376
393
|
return ensureStorageDir();
|
|
377
394
|
}
|
|
395
|
+
function ensureStorageCollectionDir(collectionName) {
|
|
396
|
+
const storageDirectory = ensureStorageDir();
|
|
397
|
+
const collectionDirectory = path.join(storageDirectory, collectionName);
|
|
398
|
+
if (!fs.existsSync(collectionDirectory)) {
|
|
399
|
+
fs.mkdirSync(collectionDirectory, { recursive: true, mode: 448 });
|
|
400
|
+
}
|
|
401
|
+
return collectionDirectory;
|
|
402
|
+
}
|
|
403
|
+
async function saveEncryptedStorageRecord(collectionName, recordId, value) {
|
|
404
|
+
const collectionDirectory = ensureStorageCollectionDir(collectionName);
|
|
405
|
+
writeEncryptedJson(path.join(collectionDirectory, `${recordId}.json`), value);
|
|
406
|
+
}
|
|
407
|
+
async function loadEncryptedStorageRecord(collectionName, recordId) {
|
|
408
|
+
const filePath = storagePath(collectionName, `${recordId}.json`);
|
|
409
|
+
if (!fs.existsSync(filePath)) return null;
|
|
410
|
+
return readEncryptedJson(filePath);
|
|
411
|
+
}
|
|
412
|
+
async function listEncryptedStorageRecordIds(collectionName) {
|
|
413
|
+
const collectionDirectory = ensureStorageCollectionDir(collectionName);
|
|
414
|
+
return fs.readdirSync(collectionDirectory).filter((entry) => entry.endsWith(".json")).map((entry) => entry.replace(/\.json$/, ""));
|
|
415
|
+
}
|
|
416
|
+
async function deleteEncryptedStorageRecord(collectionName, recordId) {
|
|
417
|
+
const filePath = storagePath(collectionName, `${recordId}.json`);
|
|
418
|
+
if (!fs.existsSync(filePath)) return false;
|
|
419
|
+
fs.unlinkSync(filePath);
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
378
422
|
async function saveProjectConfig(config) {
|
|
379
423
|
const storageDirectory = ensureStorageDir();
|
|
380
424
|
writeJson(path.join(storageDirectory, "config.json"), config);
|
|
@@ -385,64 +429,42 @@ async function loadProjectConfig() {
|
|
|
385
429
|
return readJson(filePath);
|
|
386
430
|
}
|
|
387
431
|
async function saveWalletSession(record) {
|
|
388
|
-
|
|
389
|
-
writeEncryptedJson(
|
|
390
|
-
path.join(storageDirectory, "wallets", `${record.walletName}.json`),
|
|
391
|
-
migrateWalletSessionRecord(record)
|
|
392
|
-
);
|
|
432
|
+
await saveEncryptedStorageRecord("wallets", record.walletName, migrateWalletSessionRecord(record));
|
|
393
433
|
}
|
|
394
434
|
async function loadWalletSession(walletName) {
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
return migrateWalletSessionRecord(readEncryptedJson(filePath));
|
|
435
|
+
const record = await loadEncryptedStorageRecord("wallets", walletName);
|
|
436
|
+
return record ? migrateWalletSessionRecord(record) : null;
|
|
398
437
|
}
|
|
399
438
|
async function listWalletNames() {
|
|
400
|
-
|
|
401
|
-
return fs.readdirSync(path.join(storageDirectory, "wallets")).filter((entry) => entry.endsWith(".json")).map((entry) => entry.replace(/\.json$/, ""));
|
|
439
|
+
return listEncryptedStorageRecordIds("wallets");
|
|
402
440
|
}
|
|
403
441
|
async function listWalletRequestIds() {
|
|
404
442
|
const storageDirectory = ensureStorageDir();
|
|
405
443
|
return fs.readdirSync(path.join(storageDirectory, "requests")).filter((entry) => entry.endsWith(".json")).map((entry) => entry.replace(/\.json$/, ""));
|
|
406
444
|
}
|
|
407
445
|
async function deleteWalletSession(walletName) {
|
|
408
|
-
|
|
409
|
-
if (!fs.existsSync(filePath)) return false;
|
|
410
|
-
fs.unlinkSync(filePath);
|
|
411
|
-
return true;
|
|
446
|
+
return deleteEncryptedStorageRecord("wallets", walletName);
|
|
412
447
|
}
|
|
413
448
|
async function saveWalletRequest(record) {
|
|
414
|
-
|
|
415
|
-
writeEncryptedJson(path.join(storageDirectory, "requests", `${record.requestId}.json`), record);
|
|
449
|
+
await saveEncryptedStorageRecord("requests", record.requestId, record);
|
|
416
450
|
}
|
|
417
451
|
async function loadWalletRequest(requestId) {
|
|
418
|
-
|
|
419
|
-
if (!fs.existsSync(filePath)) return null;
|
|
420
|
-
return readEncryptedJson(filePath);
|
|
452
|
+
return loadEncryptedStorageRecord("requests", requestId);
|
|
421
453
|
}
|
|
422
454
|
async function deleteWalletRequest(requestId) {
|
|
423
|
-
|
|
424
|
-
if (!fs.existsSync(filePath)) return false;
|
|
425
|
-
fs.unlinkSync(filePath);
|
|
426
|
-
return true;
|
|
455
|
+
return deleteEncryptedStorageRecord("requests", requestId);
|
|
427
456
|
}
|
|
428
457
|
async function saveWorkflowCheckpoint(record) {
|
|
429
|
-
|
|
430
|
-
writeEncryptedJson(path.join(storageDirectory, "workflows", `${record.requestId}.json`), record);
|
|
458
|
+
await saveEncryptedStorageRecord("workflows", record.requestId, record);
|
|
431
459
|
}
|
|
432
460
|
async function loadWorkflowCheckpoint(requestId) {
|
|
433
|
-
|
|
434
|
-
if (!fs.existsSync(filePath)) return null;
|
|
435
|
-
return readEncryptedJson(filePath);
|
|
461
|
+
return loadEncryptedStorageRecord("workflows", requestId);
|
|
436
462
|
}
|
|
437
463
|
async function listWorkflowCheckpointIds() {
|
|
438
|
-
|
|
439
|
-
return fs.readdirSync(path.join(storageDirectory, "workflows")).filter((entry) => entry.endsWith(".json")).map((entry) => entry.replace(/\.json$/, ""));
|
|
464
|
+
return listEncryptedStorageRecordIds("workflows");
|
|
440
465
|
}
|
|
441
466
|
async function deleteWorkflowCheckpoint(requestId) {
|
|
442
|
-
|
|
443
|
-
if (!fs.existsSync(filePath)) return false;
|
|
444
|
-
fs.unlinkSync(filePath);
|
|
445
|
-
return true;
|
|
467
|
+
return deleteEncryptedStorageRecord("workflows", requestId);
|
|
446
468
|
}
|
|
447
469
|
async function renameWalletSession(walletName, nextWalletName) {
|
|
448
470
|
const storageDirectory = ensureStorageDir();
|
|
@@ -461,7 +483,7 @@ async function renameWalletSession(walletName, nextWalletName) {
|
|
|
461
483
|
if (fs.existsSync(targetFilePath)) {
|
|
462
484
|
throw new Error(`Wallet already exists: ${targetName}`);
|
|
463
485
|
}
|
|
464
|
-
const wallet = readEncryptedJson(currentFilePath);
|
|
486
|
+
const wallet = migrateWalletSessionRecord(readEncryptedJson(currentFilePath));
|
|
465
487
|
wallet.walletName = targetName;
|
|
466
488
|
writeEncryptedJson(targetFilePath, wallet);
|
|
467
489
|
fs.unlinkSync(currentFilePath);
|
|
@@ -7823,7 +7845,7 @@ function appendPaymasterMode(command, paymasterMode) {
|
|
|
7823
7845
|
function buildDefaultsRecommendedCommand() {
|
|
7824
7846
|
return "zk-agent defaults";
|
|
7825
7847
|
}
|
|
7826
|
-
function buildSuiteRecommendedCommand(walletName = "main", chain = "zksync-sepolia") {
|
|
7848
|
+
function buildSuiteRecommendedCommand(walletName = "main", chain = "zksync-sepolia", options = {}) {
|
|
7827
7849
|
const flags = [];
|
|
7828
7850
|
if (walletName !== "main") {
|
|
7829
7851
|
flags.push(`--wallet ${walletName}`);
|
|
@@ -7831,14 +7853,18 @@ function buildSuiteRecommendedCommand(walletName = "main", chain = "zksync-sepol
|
|
|
7831
7853
|
if (chain !== "zksync-sepolia") {
|
|
7832
7854
|
flags.push(`--chain ${chain}`);
|
|
7833
7855
|
}
|
|
7856
|
+
if (options.includeOnboarding) {
|
|
7857
|
+
flags.push("--include-onboarding");
|
|
7858
|
+
}
|
|
7834
7859
|
return flags.length > 0 ? `zk-agent suite ${flags.join(" ")}` : "zk-agent suite";
|
|
7835
7860
|
}
|
|
7836
|
-
function buildTopLevelNextRecommendedCommand(requestId, paymasterMode) {
|
|
7837
|
-
const command = requestId ? `zk-agent next --request-id ${requestId}` : "zk-agent next";
|
|
7861
|
+
function buildTopLevelNextRecommendedCommand(requestId, paymasterMode, walletName = "main") {
|
|
7862
|
+
const command = requestId ? `zk-agent next --request-id ${requestId}` : walletName !== "main" ? `zk-agent next --wallet ${walletName}` : "zk-agent next";
|
|
7838
7863
|
return appendPaymasterMode(command, paymasterMode);
|
|
7839
7864
|
}
|
|
7840
|
-
function buildWalletCreateRecommendedCommand(paymasterMode) {
|
|
7841
|
-
|
|
7865
|
+
function buildWalletCreateRecommendedCommand(paymasterMode, walletName = "main") {
|
|
7866
|
+
const command = walletName !== "main" ? `zk-agent wallet create --name ${walletName} --await-local` : "zk-agent wallet create --await-local";
|
|
7867
|
+
return appendPaymasterMode(command, paymasterMode);
|
|
7842
7868
|
}
|
|
7843
7869
|
function buildRelayInspectRecommendedCommand(relayUrl = "<url>") {
|
|
7844
7870
|
return `zk-agent relay inspect --relay-url ${relayUrl}`;
|
|
@@ -7996,6 +8022,37 @@ function buildWorkflowPayRecommendedCommand(walletName, paymasterMode) {
|
|
|
7996
8022
|
const command = `zk-agent workflow pay --wallet ${walletName} --to <address> --amount <amount>`;
|
|
7997
8023
|
return appendPaymasterMode(command, paymasterMode);
|
|
7998
8024
|
}
|
|
8025
|
+
function buildSendTokenRecommendedCommand(input) {
|
|
8026
|
+
let command = `zk-agent send-token --wallet ${input.walletName}`;
|
|
8027
|
+
command += ` --to ${input.to || "<address>"}`;
|
|
8028
|
+
command += ` --amount ${input.amount || "<amount>"}`;
|
|
8029
|
+
if (input.symbol) {
|
|
8030
|
+
command += ` --symbol ${input.symbol}`;
|
|
8031
|
+
}
|
|
8032
|
+
if (input.tokenAddress) {
|
|
8033
|
+
command += ` --token ${input.tokenAddress}`;
|
|
8034
|
+
}
|
|
8035
|
+
if (input.decimals !== void 0) {
|
|
8036
|
+
command += ` --decimals ${input.decimals}`;
|
|
8037
|
+
}
|
|
8038
|
+
return appendPaymasterMode(command, input.paymasterMode);
|
|
8039
|
+
}
|
|
8040
|
+
function buildPaymentListRecommendedCommand() {
|
|
8041
|
+
return "zk-agent payment list";
|
|
8042
|
+
}
|
|
8043
|
+
function buildPaymentShowRecommendedCommand(requestId) {
|
|
8044
|
+
return `zk-agent payment show --request-id ${requestId}`;
|
|
8045
|
+
}
|
|
8046
|
+
function buildPaymentSetStatusRecommendedCommand(requestId, status, txHash) {
|
|
8047
|
+
let command = `zk-agent payment set-status --request-id ${requestId} --status ${status}`;
|
|
8048
|
+
if (txHash) {
|
|
8049
|
+
command += ` --tx-hash ${txHash}`;
|
|
8050
|
+
}
|
|
8051
|
+
return command;
|
|
8052
|
+
}
|
|
8053
|
+
function buildPaymentRemoveRecommendedCommand(requestId) {
|
|
8054
|
+
return `zk-agent payment remove --request-id ${requestId}`;
|
|
8055
|
+
}
|
|
7999
8056
|
function buildWorkflowFundRecommendedCommand(walletName) {
|
|
8000
8057
|
return `zk-agent workflow fund --wallet ${walletName}`;
|
|
8001
8058
|
}
|
|
@@ -10175,28 +10232,28 @@ function recommendedPathLines(paths) {
|
|
|
10175
10232
|
...paths.remoteBrowser?.length ? [["path (remote-browser)", formatRecommendedPath(paths.remoteBrowser)]] : []
|
|
10176
10233
|
];
|
|
10177
10234
|
}
|
|
10178
|
-
function buildSetupRecommendedPaths(relayUrl = "<url>", paymasterMode) {
|
|
10179
|
-
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
|
|
10235
|
+
function buildSetupRecommendedPaths(relayUrl = "<url>", paymasterMode, walletName = "main") {
|
|
10236
|
+
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode, walletName);
|
|
10180
10237
|
return {
|
|
10181
10238
|
local: [
|
|
10182
10239
|
"zk-agent setup",
|
|
10183
10240
|
next,
|
|
10184
|
-
buildWalletCreateRecommendedCommand(paymasterMode),
|
|
10241
|
+
buildWalletCreateRecommendedCommand(paymasterMode, walletName),
|
|
10185
10242
|
next
|
|
10186
10243
|
],
|
|
10187
10244
|
remoteBrowser: [
|
|
10188
10245
|
"zk-agent setup",
|
|
10189
10246
|
next,
|
|
10190
10247
|
buildRelayInspectRecommendedCommand(relayUrl),
|
|
10191
|
-
buildWalletCreateRemoteRecommendedCommand(relayUrl, paymasterMode),
|
|
10248
|
+
buildWalletCreateRemoteRecommendedCommand(relayUrl, paymasterMode, walletName),
|
|
10192
10249
|
next
|
|
10193
10250
|
]
|
|
10194
10251
|
};
|
|
10195
10252
|
}
|
|
10196
10253
|
function buildWalletBootstrapRecommendedPaths(relayUrl = "<url>", paymasterMode, walletName = "main") {
|
|
10197
|
-
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
|
|
10254
|
+
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode, walletName);
|
|
10198
10255
|
return {
|
|
10199
|
-
local: [buildWalletCreateRecommendedCommand(paymasterMode), next],
|
|
10256
|
+
local: [buildWalletCreateRecommendedCommand(paymasterMode, walletName), next],
|
|
10200
10257
|
remoteBrowser: [
|
|
10201
10258
|
buildRelayInspectRecommendedCommand(relayUrl),
|
|
10202
10259
|
buildWalletCreateRemoteRecommendedCommand(relayUrl, paymasterMode, walletName),
|
|
@@ -10205,7 +10262,7 @@ function buildWalletBootstrapRecommendedPaths(relayUrl = "<url>", paymasterMode,
|
|
|
10205
10262
|
};
|
|
10206
10263
|
}
|
|
10207
10264
|
function buildWalletReapprovalRecommendedPaths(walletName, relayUrl = "<url>", paymasterMode) {
|
|
10208
|
-
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
|
|
10265
|
+
const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode, walletName);
|
|
10209
10266
|
return {
|
|
10210
10267
|
local: [buildWalletReapproveRecommendedCommand(walletName), next],
|
|
10211
10268
|
remoteBrowser: [
|
|
@@ -10219,7 +10276,7 @@ function buildSignerRecoveryRecommendedPaths(walletName, paymasterMode) {
|
|
|
10219
10276
|
return {
|
|
10220
10277
|
local: [
|
|
10221
10278
|
buildWalletSignerAttachRecommendedCommand(walletName),
|
|
10222
|
-
buildTopLevelNextRecommendedCommand(void 0, paymasterMode)
|
|
10279
|
+
buildTopLevelNextRecommendedCommand(void 0, paymasterMode, walletName)
|
|
10223
10280
|
]
|
|
10224
10281
|
};
|
|
10225
10282
|
}
|
|
@@ -10698,11 +10755,139 @@ function agentProfileLines(summary) {
|
|
|
10698
10755
|
return lines;
|
|
10699
10756
|
}
|
|
10700
10757
|
|
|
10758
|
+
// src/lib/product-entry-summary.ts
|
|
10759
|
+
function buildProductEntrySummary(input) {
|
|
10760
|
+
const currentSurface = input.currentSurface ?? "next";
|
|
10761
|
+
switch (input.stage) {
|
|
10762
|
+
case "setup":
|
|
10763
|
+
return {
|
|
10764
|
+
view: "product-entry",
|
|
10765
|
+
currentSurface,
|
|
10766
|
+
stage: input.stage,
|
|
10767
|
+
category: "bootstrap",
|
|
10768
|
+
recommendedMode: "local-first",
|
|
10769
|
+
nextSurface: input.nextSurface ?? "setup",
|
|
10770
|
+
nextAction: input.nextAction ?? null,
|
|
10771
|
+
suiteAvailable: false,
|
|
10772
|
+
note: input.note ?? "Start with setup first. The operator path is still in first-run bootstrap."
|
|
10773
|
+
};
|
|
10774
|
+
case "wallet-bootstrap":
|
|
10775
|
+
return {
|
|
10776
|
+
view: "product-entry",
|
|
10777
|
+
currentSurface,
|
|
10778
|
+
stage: input.stage,
|
|
10779
|
+
category: "bootstrap",
|
|
10780
|
+
recommendedMode: "local-first",
|
|
10781
|
+
nextSurface: input.nextSurface ?? "wallet",
|
|
10782
|
+
nextAction: input.nextAction ?? null,
|
|
10783
|
+
suiteAvailable: false,
|
|
10784
|
+
note: input.note ?? "Local defaults exist, but wallet bootstrap is still the current product question."
|
|
10785
|
+
};
|
|
10786
|
+
case "wallet-recovery":
|
|
10787
|
+
return {
|
|
10788
|
+
view: "product-entry",
|
|
10789
|
+
currentSurface,
|
|
10790
|
+
stage: input.stage,
|
|
10791
|
+
category: "recover",
|
|
10792
|
+
recommendedMode: "local-first",
|
|
10793
|
+
nextSurface: input.nextSurface ?? "wallet",
|
|
10794
|
+
nextAction: input.nextAction ?? null,
|
|
10795
|
+
suiteAvailable: false,
|
|
10796
|
+
note: input.note ?? "Stay on wallet recovery until approval or local signer readiness stops being the blocker."
|
|
10797
|
+
};
|
|
10798
|
+
case "wallet-ready":
|
|
10799
|
+
return {
|
|
10800
|
+
view: "product-entry",
|
|
10801
|
+
currentSurface,
|
|
10802
|
+
stage: input.stage,
|
|
10803
|
+
category: "operate",
|
|
10804
|
+
recommendedMode: "local-first",
|
|
10805
|
+
nextSurface: input.nextSurface ?? (currentSurface === "doctor" ? "next" : "workflow"),
|
|
10806
|
+
nextAction: input.nextAction ?? null,
|
|
10807
|
+
suiteAvailable: input.suiteAvailable === true,
|
|
10808
|
+
note: input.note ?? (currentSurface === "doctor" ? "Local readiness is clear. Return to zk-agent next when you want the live operator path instead of a local-only diagnosis." : "The default product action is now the flagship workflow path. Switch to suite when the question becomes broader than one flagship pay step.")
|
|
10809
|
+
};
|
|
10810
|
+
case "workflow":
|
|
10811
|
+
return {
|
|
10812
|
+
view: "product-entry",
|
|
10813
|
+
currentSurface,
|
|
10814
|
+
stage: input.stage,
|
|
10815
|
+
category: "workflow",
|
|
10816
|
+
recommendedMode: "workflow-followup",
|
|
10817
|
+
nextSurface: input.nextSurface ?? "workflow",
|
|
10818
|
+
nextAction: input.nextAction ?? null,
|
|
10819
|
+
suiteAvailable: input.suiteAvailable === true,
|
|
10820
|
+
note: input.note ?? "A stored workflow checkpoint is now the active product context. Stay on workflow follow-up until the question is no longer workflow-specific."
|
|
10821
|
+
};
|
|
10822
|
+
default: {
|
|
10823
|
+
const exhaustive = input.stage;
|
|
10824
|
+
throw new Error(`Unsupported product entry stage: ${String(exhaustive)}`);
|
|
10825
|
+
}
|
|
10826
|
+
}
|
|
10827
|
+
}
|
|
10828
|
+
function productEntrySummaryLines(summary) {
|
|
10829
|
+
return [
|
|
10830
|
+
["entry view", summary.view],
|
|
10831
|
+
["entry category", summary.category],
|
|
10832
|
+
["recommended mode", summary.recommendedMode],
|
|
10833
|
+
["next surface", summary.nextSurface],
|
|
10834
|
+
["suite available", summary.suiteAvailable ? "yes" : "no"],
|
|
10835
|
+
["entry note", summary.note]
|
|
10836
|
+
];
|
|
10837
|
+
}
|
|
10838
|
+
|
|
10701
10839
|
// src/lib/suite-handoff.ts
|
|
10840
|
+
function buildSuiteHandoffJourney(journeyId, walletName) {
|
|
10841
|
+
switch (journeyId) {
|
|
10842
|
+
case "send-value-now":
|
|
10843
|
+
return {
|
|
10844
|
+
id: journeyId,
|
|
10845
|
+
title: "Send Value Now",
|
|
10846
|
+
command: buildWorkflowPayRecommendedCommand(walletName)
|
|
10847
|
+
};
|
|
10848
|
+
case "inspect-before-acting":
|
|
10849
|
+
return {
|
|
10850
|
+
id: journeyId,
|
|
10851
|
+
title: "Inspect Before Acting",
|
|
10852
|
+
command: buildAssetsRecommendedCommand(walletName)
|
|
10853
|
+
};
|
|
10854
|
+
case "unstick-a-write":
|
|
10855
|
+
return {
|
|
10856
|
+
id: journeyId,
|
|
10857
|
+
title: "Unstick a Write",
|
|
10858
|
+
command: buildWorkflowPayRecommendedCommand(walletName, "approval-based")
|
|
10859
|
+
};
|
|
10860
|
+
case "recover-remote-approval":
|
|
10861
|
+
return {
|
|
10862
|
+
id: journeyId,
|
|
10863
|
+
title: "Recover Remote Approval",
|
|
10864
|
+
command: buildRelayInspectRecommendedCommand("<url>")
|
|
10865
|
+
};
|
|
10866
|
+
case null:
|
|
10867
|
+
case void 0:
|
|
10868
|
+
return null;
|
|
10869
|
+
default: {
|
|
10870
|
+
const exhaustive = journeyId;
|
|
10871
|
+
throw new Error(`Unsupported suite handoff journey: ${String(exhaustive)}`);
|
|
10872
|
+
}
|
|
10873
|
+
}
|
|
10874
|
+
}
|
|
10702
10875
|
function buildSuiteHandoffSummary(input) {
|
|
10876
|
+
const walletName = input.walletName?.trim() || "main";
|
|
10703
10877
|
const command = buildSuiteRecommendedCommand(input.walletName, input.chain);
|
|
10704
|
-
const
|
|
10878
|
+
const recommendedJourney = input.recommendedNow === true ? buildSuiteHandoffJourney(input.recommendedJourneyId ?? null, walletName) : null;
|
|
10879
|
+
const useWhen = "Use suite once wallet approval and local signer readiness are no longer the blocker and you want one packaged surface for flagship pay plus the current post-flagship discovery, paymaster, funding, and hosted recovery slices.";
|
|
10705
10880
|
switch (input.currentSurface) {
|
|
10881
|
+
case "doctor":
|
|
10882
|
+
return {
|
|
10883
|
+
currentSurface: input.currentSurface,
|
|
10884
|
+
recommendedNow: input.recommendedNow,
|
|
10885
|
+
command,
|
|
10886
|
+
useWhen,
|
|
10887
|
+
stayOnCurrentSurfaceWhen: "Stay on doctor when local config, approval metadata, or local signer state is still unclear and you need a local-only diagnosis before choosing the live path.",
|
|
10888
|
+
note: input.recommendedNow ? "Local readiness is clear. Return to zk-agent next for the shortest live path, or start with the suggested suite journey when the operator question is broader than one immediate flagship workflow step." : "Suite is not the current recommendation because doctor is still diagnosing a local setup or wallet-readiness blocker.",
|
|
10889
|
+
recommendedJourney
|
|
10890
|
+
};
|
|
10706
10891
|
case "next":
|
|
10707
10892
|
return {
|
|
10708
10893
|
currentSurface: input.currentSurface,
|
|
@@ -10710,7 +10895,8 @@ function buildSuiteHandoffSummary(input) {
|
|
|
10710
10895
|
command,
|
|
10711
10896
|
useWhen,
|
|
10712
10897
|
stayOnCurrentSurfaceWhen: "Stay on next when you still need the CLI to choose across setup, wallet readiness, and the shortest flagship workflow entry.",
|
|
10713
|
-
note: input.recommendedNow ? "Wallet readiness is no longer the blocker. The default shortest action can still be workflow pay, while suite is the broader packaged follow-up surface." : "Suite is not the current recommendation because next is still steering setup or wallet remediation."
|
|
10898
|
+
note: input.recommendedNow ? "Wallet readiness is no longer the blocker. The default shortest action can still be workflow pay, while suite is the broader packaged follow-up surface. Start with the suggested suite journey when the question is broader than one immediate workflow pay step." : "Suite is not the current recommendation because next is still steering setup or wallet remediation.",
|
|
10899
|
+
recommendedJourney
|
|
10714
10900
|
};
|
|
10715
10901
|
case "wallet":
|
|
10716
10902
|
return {
|
|
@@ -10719,7 +10905,8 @@ function buildSuiteHandoffSummary(input) {
|
|
|
10719
10905
|
command,
|
|
10720
10906
|
useWhen,
|
|
10721
10907
|
stayOnCurrentSurfaceWhen: "Stay on wallet status or wallet next when approval, signer attach, deployment sync, or wallet-specific remediation is still the blocker.",
|
|
10722
|
-
note: input.recommendedNow ? "Wallet readiness is no longer the blocker, so suite is available as the broader packaged surface." : "Suite is not the current recommendation because wallet-specific remediation is still the blocker."
|
|
10908
|
+
note: input.recommendedNow ? "Wallet readiness is no longer the blocker, so suite is available as the broader packaged surface. Start with the suggested suite journey when the operator question is broader than one wallet-status remediation step." : "Suite is not the current recommendation because wallet-specific remediation is still the blocker.",
|
|
10909
|
+
recommendedJourney
|
|
10723
10910
|
};
|
|
10724
10911
|
case "workflow":
|
|
10725
10912
|
return {
|
|
@@ -10728,7 +10915,8 @@ function buildSuiteHandoffSummary(input) {
|
|
|
10728
10915
|
command,
|
|
10729
10916
|
useWhen,
|
|
10730
10917
|
stayOnCurrentSurfaceWhen: "Stay on workflow when you already have an explicit workflow question, checkpoint, or execution state to inspect, continue, or resume.",
|
|
10731
|
-
note: "This workflow surface stays authoritative for the current workflow. Switch to suite only after the question is no longer workflow-specific."
|
|
10918
|
+
note: "This workflow surface stays authoritative for the current workflow. Switch to suite only after the question is no longer workflow-specific.",
|
|
10919
|
+
recommendedJourney
|
|
10732
10920
|
};
|
|
10733
10921
|
default: {
|
|
10734
10922
|
const exhaustive = input.currentSurface;
|
|
@@ -10741,6 +10929,13 @@ function suiteHandoffLines(summary) {
|
|
|
10741
10929
|
["suite", summary.command],
|
|
10742
10930
|
["suite ready", summary.recommendedNow ? "yes" : "no"],
|
|
10743
10931
|
["suite when", summary.useWhen],
|
|
10932
|
+
...summary.recommendedJourney ? [
|
|
10933
|
+
[
|
|
10934
|
+
"suite journey",
|
|
10935
|
+
`${summary.recommendedJourney.id} (${summary.recommendedJourney.title})`
|
|
10936
|
+
],
|
|
10937
|
+
["suite journey start", summary.recommendedJourney.command]
|
|
10938
|
+
] : [],
|
|
10744
10939
|
[`stay on ${summary.currentSurface} when`, summary.stayOnCurrentSurfaceWhen],
|
|
10745
10940
|
["suite note", summary.note]
|
|
10746
10941
|
];
|
|
@@ -10866,8 +11061,8 @@ function resolveNextCommandDeps(deps) {
|
|
|
10866
11061
|
function buildSetupCommand() {
|
|
10867
11062
|
return "zk-agent setup";
|
|
10868
11063
|
}
|
|
10869
|
-
function buildTopLevelNextRecommendedCommand2(requestId) {
|
|
10870
|
-
return requestId ? `zk-agent next --request-id ${requestId}` : "zk-agent next";
|
|
11064
|
+
function buildTopLevelNextRecommendedCommand2(requestId, walletName = "main") {
|
|
11065
|
+
return requestId ? `zk-agent next --request-id ${requestId}` : walletName !== "main" ? `zk-agent next --wallet ${walletName}` : "zk-agent next";
|
|
10871
11066
|
}
|
|
10872
11067
|
function buildTopLevelWorkflowSummary(result, nextCommand) {
|
|
10873
11068
|
return {
|
|
@@ -10888,10 +11083,11 @@ function appendPaymasterMode2(command, paymasterMode) {
|
|
|
10888
11083
|
if (!paymasterMode) return command;
|
|
10889
11084
|
return `${command} --paymaster-mode ${paymasterMode}`;
|
|
10890
11085
|
}
|
|
10891
|
-
function topLevelNextLines(scope, lines, onboardingSummary) {
|
|
11086
|
+
function topLevelNextLines(scope, lines, onboardingSummary, productEntrySummary) {
|
|
10892
11087
|
return [
|
|
10893
11088
|
["scope", scope],
|
|
10894
11089
|
...onboardingSummary ? onboardingSummaryLines(onboardingSummary) : [],
|
|
11090
|
+
...productEntrySummary ? productEntrySummaryLines(productEntrySummary) : [],
|
|
10895
11091
|
...lines
|
|
10896
11092
|
];
|
|
10897
11093
|
}
|
|
@@ -10901,6 +11097,13 @@ function buildNextHelpText() {
|
|
|
10901
11097
|
"Use `next` as the product entrypoint:",
|
|
10902
11098
|
" Stay on `next` until it points you at a wallet-specific or workflow-specific blocker.",
|
|
10903
11099
|
"",
|
|
11100
|
+
" What `next` answers right now:",
|
|
11101
|
+
" bootstrap: config or wallet bootstrap is still the current blocker",
|
|
11102
|
+
" recover: wallet approval or local signer readiness still needs repair",
|
|
11103
|
+
" operate: wallet readiness is clear, so the flagship workflow path is next",
|
|
11104
|
+
" workflow: a stored checkpoint is already the active question",
|
|
11105
|
+
" suite: switch only when the question becomes broader than one immediate next step",
|
|
11106
|
+
"",
|
|
10904
11107
|
" Fresh local-first routing:",
|
|
10905
11108
|
" zk-agent setup",
|
|
10906
11109
|
" zk-agent next",
|
|
@@ -10999,6 +11202,11 @@ function createNextCommand(deps) {
|
|
|
10999
11202
|
walletName: wallet2.walletName,
|
|
11000
11203
|
walletExists: true
|
|
11001
11204
|
});
|
|
11205
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11206
|
+
stage: "workflow",
|
|
11207
|
+
nextAction: nextCommand2,
|
|
11208
|
+
suiteAvailable: false
|
|
11209
|
+
});
|
|
11002
11210
|
printResult(
|
|
11003
11211
|
topLevelNextLines("workflow", [
|
|
11004
11212
|
["workflow request", requestId],
|
|
@@ -11017,7 +11225,7 @@ function createNextCommand(deps) {
|
|
|
11017
11225
|
["funding txHash", result.fundingProgress.txHash],
|
|
11018
11226
|
["funding status", result.fundingProgress.status]
|
|
11019
11227
|
] : []
|
|
11020
|
-
]),
|
|
11228
|
+
], void 0, productEntrySummary2),
|
|
11021
11229
|
{
|
|
11022
11230
|
ok: true,
|
|
11023
11231
|
scope: "workflow",
|
|
@@ -11025,6 +11233,7 @@ function createNextCommand(deps) {
|
|
|
11025
11233
|
workflowRequestId: requestId,
|
|
11026
11234
|
walletName: wallet2.walletName,
|
|
11027
11235
|
nextCommand: nextCommand2,
|
|
11236
|
+
productEntrySummary: productEntrySummary2,
|
|
11028
11237
|
agentProfile: workflowAgentProfile,
|
|
11029
11238
|
agentFollowup: agentFollowup2,
|
|
11030
11239
|
summary: buildTopLevelWorkflowSummary(result, nextCommand2),
|
|
@@ -11041,10 +11250,10 @@ function createNextCommand(deps) {
|
|
|
11041
11250
|
if (!config) {
|
|
11042
11251
|
const recommendedCommands2 = {
|
|
11043
11252
|
setup: buildSetupCommand(),
|
|
11044
|
-
afterSetup: buildTopLevelNextRecommendedCommand2(),
|
|
11253
|
+
afterSetup: buildTopLevelNextRecommendedCommand2(void 0, walletName),
|
|
11045
11254
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
11046
11255
|
};
|
|
11047
|
-
const recommendedPaths2 = buildSetupRecommendedPaths("<url>", paymasterMode);
|
|
11256
|
+
const recommendedPaths2 = buildSetupRecommendedPaths("<url>", paymasterMode, walletName);
|
|
11048
11257
|
const onboardingSummary2 = buildOnboardingSummary({
|
|
11049
11258
|
stage: "setup",
|
|
11050
11259
|
localOnly: true,
|
|
@@ -11056,6 +11265,10 @@ function createNextCommand(deps) {
|
|
|
11056
11265
|
"This scope is local-only and does not require live RPC reads."
|
|
11057
11266
|
]
|
|
11058
11267
|
});
|
|
11268
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11269
|
+
stage: "setup",
|
|
11270
|
+
nextAction: recommendedCommands2.setup
|
|
11271
|
+
});
|
|
11059
11272
|
printResult(
|
|
11060
11273
|
topLevelNextLines("setup", [
|
|
11061
11274
|
["status", "No local config found"],
|
|
@@ -11065,12 +11278,13 @@ function createNextCommand(deps) {
|
|
|
11065
11278
|
["next", recommendedCommands2.setup],
|
|
11066
11279
|
["after setup", recommendedCommands2.afterSetup],
|
|
11067
11280
|
["inspect defaults", recommendedCommands2.inspectDefaults]
|
|
11068
|
-
], onboardingSummary2),
|
|
11281
|
+
], onboardingSummary2, productEntrySummary2),
|
|
11069
11282
|
{
|
|
11070
11283
|
ok: true,
|
|
11071
11284
|
scope: "setup",
|
|
11072
11285
|
status: "action-required",
|
|
11073
11286
|
nextCommand: recommendedCommands2.setup,
|
|
11287
|
+
productEntrySummary: productEntrySummary2,
|
|
11074
11288
|
onboardingSummary: onboardingSummary2,
|
|
11075
11289
|
recommendedPaths: recommendedPaths2,
|
|
11076
11290
|
agentProfile,
|
|
@@ -11084,15 +11298,19 @@ function createNextCommand(deps) {
|
|
|
11084
11298
|
if (!wallet) {
|
|
11085
11299
|
const recommendedCommands2 = {
|
|
11086
11300
|
createWallet: appendPaymasterMode2(
|
|
11087
|
-
buildWalletCreateRecommendedCommand(),
|
|
11301
|
+
buildWalletCreateRecommendedCommand(void 0, walletName),
|
|
11088
11302
|
paymasterMode
|
|
11089
11303
|
),
|
|
11090
11304
|
relayInspect: buildRelayInspectRecommendedCommand(),
|
|
11091
11305
|
createWalletRemote: buildWalletCreateRemoteRecommendedCommand(
|
|
11092
11306
|
"<url>",
|
|
11307
|
+
paymasterMode,
|
|
11308
|
+
walletName
|
|
11309
|
+
),
|
|
11310
|
+
afterApproval: appendPaymasterMode2(
|
|
11311
|
+
buildTopLevelNextRecommendedCommand2(void 0, walletName),
|
|
11093
11312
|
paymasterMode
|
|
11094
11313
|
),
|
|
11095
|
-
afterApproval: appendPaymasterMode2(buildTopLevelNextRecommendedCommand2(), paymasterMode),
|
|
11096
11314
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
11097
11315
|
};
|
|
11098
11316
|
const recommendedPaths2 = buildWalletBootstrapRecommendedPaths(
|
|
@@ -11113,6 +11331,10 @@ function createNextCommand(deps) {
|
|
|
11113
11331
|
"Use the remote approval fallback only when the browser is not colocated with this terminal."
|
|
11114
11332
|
]
|
|
11115
11333
|
});
|
|
11334
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11335
|
+
stage: "wallet-bootstrap",
|
|
11336
|
+
nextAction: recommendedCommands2.createWallet
|
|
11337
|
+
});
|
|
11116
11338
|
printResult(
|
|
11117
11339
|
topLevelNextLines("wallet-bootstrap", [
|
|
11118
11340
|
["status", `Wallet not found: ${walletName}`],
|
|
@@ -11126,13 +11348,14 @@ function createNextCommand(deps) {
|
|
|
11126
11348
|
["remote fallback", recommendedCommands2.createWalletRemote],
|
|
11127
11349
|
["after approval", recommendedCommands2.afterApproval],
|
|
11128
11350
|
["inspect defaults", recommendedCommands2.inspectDefaults]
|
|
11129
|
-
], onboardingSummary2),
|
|
11351
|
+
], onboardingSummary2, productEntrySummary2),
|
|
11130
11352
|
{
|
|
11131
11353
|
ok: true,
|
|
11132
11354
|
scope: "wallet-bootstrap",
|
|
11133
11355
|
walletName,
|
|
11134
11356
|
config,
|
|
11135
11357
|
nextCommand: recommendedCommands2.createWallet,
|
|
11358
|
+
productEntrySummary: productEntrySummary2,
|
|
11136
11359
|
onboardingSummary: onboardingSummary2,
|
|
11137
11360
|
recommendedPaths: recommendedPaths2,
|
|
11138
11361
|
agentProfile,
|
|
@@ -11216,11 +11439,14 @@ function createNextCommand(deps) {
|
|
|
11216
11439
|
reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName),
|
|
11217
11440
|
relayInspect: buildRelayInspectRecommendedCommand(),
|
|
11218
11441
|
reapproveRemote: buildWalletReapproveRemoteRecommendedCommand(wallet.walletName),
|
|
11219
|
-
afterRecovery: appendPaymasterMode2(
|
|
11442
|
+
afterRecovery: appendPaymasterMode2(
|
|
11443
|
+
buildTopLevelNextRecommendedCommand2(void 0, wallet.walletName),
|
|
11444
|
+
paymasterMode
|
|
11445
|
+
)
|
|
11220
11446
|
} : !inspection.localExecutionKeyStored ? {
|
|
11221
11447
|
attachSigner: buildWalletSignerAttachRecommendedCommand(wallet.walletName),
|
|
11222
11448
|
afterRecovery: appendPaymasterMode2(
|
|
11223
|
-
buildTopLevelNextRecommendedCommand2(),
|
|
11449
|
+
buildTopLevelNextRecommendedCommand2(void 0, wallet.walletName),
|
|
11224
11450
|
paymasterMode
|
|
11225
11451
|
)
|
|
11226
11452
|
} : {};
|
|
@@ -11242,7 +11468,13 @@ function createNextCommand(deps) {
|
|
|
11242
11468
|
currentSurface: "next",
|
|
11243
11469
|
recommendedNow: summary.status === "ready",
|
|
11244
11470
|
walletName: wallet.walletName,
|
|
11245
|
-
chain: wallet.chain
|
|
11471
|
+
chain: wallet.chain,
|
|
11472
|
+
recommendedJourneyId: summary.status === "ready" ? "send-value-now" : null
|
|
11473
|
+
});
|
|
11474
|
+
const productEntrySummary = buildProductEntrySummary({
|
|
11475
|
+
stage: onboardingSummary.stage,
|
|
11476
|
+
nextAction: nextCommand,
|
|
11477
|
+
suiteAvailable: summary.status === "ready"
|
|
11246
11478
|
});
|
|
11247
11479
|
printResult(
|
|
11248
11480
|
topLevelNextLines("wallet", [
|
|
@@ -11263,11 +11495,12 @@ function createNextCommand(deps) {
|
|
|
11263
11495
|
...mergedRecommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", mergedRecommendedCommands.inspectPaymasterToken]] : [],
|
|
11264
11496
|
["inspect token", mergedRecommendedCommands.inspectToken],
|
|
11265
11497
|
["inspect defaults", mergedRecommendedCommands.inspectDefaults]
|
|
11266
|
-
], onboardingSummary),
|
|
11498
|
+
], onboardingSummary, productEntrySummary),
|
|
11267
11499
|
{
|
|
11268
11500
|
ok: true,
|
|
11269
11501
|
scope: "wallet",
|
|
11270
11502
|
walletName: wallet.walletName,
|
|
11503
|
+
productEntrySummary,
|
|
11271
11504
|
onboardingSummary,
|
|
11272
11505
|
recommendedPaths,
|
|
11273
11506
|
agentProfile,
|
|
@@ -11299,10 +11532,18 @@ function buildDoctorHelpText() {
|
|
|
11299
11532
|
" zk-agent doctor --wallet main",
|
|
11300
11533
|
" zk-agent doctor --wallet main --relay-url https://relay.example.com",
|
|
11301
11534
|
"",
|
|
11535
|
+
" What `doctor` answers right now:",
|
|
11536
|
+
" bootstrap: local config or wallet bootstrap is still missing",
|
|
11537
|
+
" recover: local approval or signer state still needs repair",
|
|
11538
|
+
" operate: local readiness is clear, so return to `zk-agent next` for the live path",
|
|
11539
|
+
" suite: once readiness is clear, the broader packaged post-flagship surface is available too",
|
|
11540
|
+
"",
|
|
11302
11541
|
"Default behavior:",
|
|
11303
11542
|
" Inspects saved config, local wallet approval metadata, local signer state,",
|
|
11304
11543
|
" and the shortest next command without requiring live RPC reads.",
|
|
11305
11544
|
" Run this before guessing whether the blocker is setup, wallet approval, or local signer state.",
|
|
11545
|
+
" When doctor shows local readiness is clear and the question is broader than one next step:",
|
|
11546
|
+
" zk-agent suite",
|
|
11306
11547
|
"",
|
|
11307
11548
|
"Remote-browser variant:",
|
|
11308
11549
|
" Pass --relay-url when you want the remote approval fallback commands",
|
|
@@ -11328,25 +11569,25 @@ function summarizeLocalWalletState(wallet) {
|
|
|
11328
11569
|
signerSource: wallet.localExecutionAuthority?.source || (wallet.sessionPayload?.sessionPrivateKey ? "legacy-session-payload" : null)
|
|
11329
11570
|
};
|
|
11330
11571
|
}
|
|
11331
|
-
function buildSetupRecommendedCommands() {
|
|
11572
|
+
function buildSetupRecommendedCommands(walletName) {
|
|
11332
11573
|
return {
|
|
11333
11574
|
setup: "zk-agent setup",
|
|
11334
|
-
next: buildTopLevelNextRecommendedCommand(),
|
|
11575
|
+
next: buildTopLevelNextRecommendedCommand(void 0, void 0, walletName),
|
|
11335
11576
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
11336
11577
|
};
|
|
11337
11578
|
}
|
|
11338
11579
|
function buildWalletBootstrapRecommendedCommands(walletName, relayUrl) {
|
|
11339
11580
|
return {
|
|
11340
|
-
next: buildTopLevelNextRecommendedCommand(),
|
|
11581
|
+
next: buildTopLevelNextRecommendedCommand(void 0, void 0, walletName),
|
|
11341
11582
|
inspectDefaults: buildDefaultsRecommendedCommand(),
|
|
11342
|
-
createWallet: buildWalletCreateRecommendedCommand(),
|
|
11583
|
+
createWallet: buildWalletCreateRecommendedCommand(void 0, walletName),
|
|
11343
11584
|
relayInspect: buildRelayInspectRecommendedCommand(relayUrl),
|
|
11344
11585
|
createWalletRemote: buildWalletCreateRemoteRecommendedCommand(relayUrl, void 0, walletName)
|
|
11345
11586
|
};
|
|
11346
11587
|
}
|
|
11347
11588
|
function buildWalletRecoveryRecommendedCommands(wallet, relayUrl) {
|
|
11348
11589
|
const shared = {
|
|
11349
|
-
next: buildTopLevelNextRecommendedCommand(),
|
|
11590
|
+
next: buildTopLevelNextRecommendedCommand(void 0, void 0, wallet.walletName),
|
|
11350
11591
|
walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
|
|
11351
11592
|
walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
|
|
11352
11593
|
signerShow: buildWalletSignerShowRecommendedCommand(wallet.walletName),
|
|
@@ -11367,7 +11608,8 @@ function buildWalletRecoveryRecommendedCommands(wallet, relayUrl) {
|
|
|
11367
11608
|
}
|
|
11368
11609
|
function buildWalletReadyRecommendedCommands(wallet) {
|
|
11369
11610
|
return {
|
|
11370
|
-
next: buildTopLevelNextRecommendedCommand(),
|
|
11611
|
+
next: buildTopLevelNextRecommendedCommand(void 0, void 0, wallet.walletName),
|
|
11612
|
+
suite: buildSuiteRecommendedCommand(wallet.walletName, wallet.chain),
|
|
11371
11613
|
walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
|
|
11372
11614
|
walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
|
|
11373
11615
|
workflowPay: buildWorkflowPayRecommendedCommand(wallet.walletName),
|
|
@@ -11376,7 +11618,7 @@ function buildWalletReadyRecommendedCommands(wallet) {
|
|
|
11376
11618
|
}
|
|
11377
11619
|
function buildDoctorResult(options) {
|
|
11378
11620
|
if (!options.config) {
|
|
11379
|
-
const recommendedCommands2 = buildSetupRecommendedCommands();
|
|
11621
|
+
const recommendedCommands2 = buildSetupRecommendedCommands(options.walletName);
|
|
11380
11622
|
const onboardingSummary2 = buildOnboardingSummary({
|
|
11381
11623
|
stage: "setup",
|
|
11382
11624
|
localOnly: true,
|
|
@@ -11391,10 +11633,16 @@ function buildDoctorResult(options) {
|
|
|
11391
11633
|
"Doctor is local-only by default and does not require live RPC reads."
|
|
11392
11634
|
]
|
|
11393
11635
|
});
|
|
11636
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11637
|
+
currentSurface: "doctor",
|
|
11638
|
+
stage: "setup",
|
|
11639
|
+
nextAction: recommendedCommands2.setup
|
|
11640
|
+
});
|
|
11394
11641
|
return {
|
|
11395
11642
|
scope: "setup",
|
|
11396
11643
|
nextAction: recommendedCommands2.setup,
|
|
11397
|
-
recommendedPaths: buildSetupRecommendedPaths(options.relayUrl),
|
|
11644
|
+
recommendedPaths: buildSetupRecommendedPaths(options.relayUrl, void 0, options.walletName),
|
|
11645
|
+
productEntrySummary: productEntrySummary2,
|
|
11398
11646
|
onboardingSummary: onboardingSummary2,
|
|
11399
11647
|
summary: {
|
|
11400
11648
|
stage: "setup",
|
|
@@ -11432,10 +11680,16 @@ function buildDoctorResult(options) {
|
|
|
11432
11680
|
"Use the remote relay path only when the browser is not colocated with this terminal."
|
|
11433
11681
|
]
|
|
11434
11682
|
});
|
|
11683
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11684
|
+
currentSurface: "doctor",
|
|
11685
|
+
stage: "wallet-bootstrap",
|
|
11686
|
+
nextAction: recommendedCommands2.createWallet
|
|
11687
|
+
});
|
|
11435
11688
|
return {
|
|
11436
11689
|
scope: "wallet-bootstrap",
|
|
11437
11690
|
nextAction: recommendedCommands2.createWallet,
|
|
11438
11691
|
recommendedPaths: buildWalletBootstrapRecommendedPaths(options.relayUrl, void 0, options.walletName),
|
|
11692
|
+
productEntrySummary: productEntrySummary2,
|
|
11439
11693
|
onboardingSummary: onboardingSummary2,
|
|
11440
11694
|
summary: {
|
|
11441
11695
|
stage: "wallet-bootstrap",
|
|
@@ -11475,6 +11729,11 @@ function buildDoctorResult(options) {
|
|
|
11475
11729
|
"Use the remote reapproval path only when the browser cannot return directly to this terminal."
|
|
11476
11730
|
]
|
|
11477
11731
|
});
|
|
11732
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11733
|
+
currentSurface: "doctor",
|
|
11734
|
+
stage: "wallet-recovery",
|
|
11735
|
+
nextAction: recommendedCommands2.reapprove
|
|
11736
|
+
});
|
|
11478
11737
|
return {
|
|
11479
11738
|
scope: "wallet-recovery",
|
|
11480
11739
|
nextAction: recommendedCommands2.reapprove,
|
|
@@ -11482,6 +11741,7 @@ function buildDoctorResult(options) {
|
|
|
11482
11741
|
options.wallet.walletName,
|
|
11483
11742
|
options.relayUrl
|
|
11484
11743
|
),
|
|
11744
|
+
productEntrySummary: productEntrySummary2,
|
|
11485
11745
|
onboardingSummary: onboardingSummary2,
|
|
11486
11746
|
summary: {
|
|
11487
11747
|
stage: "wallet-recovery",
|
|
@@ -11522,10 +11782,16 @@ function buildDoctorResult(options) {
|
|
|
11522
11782
|
"Doctor is local-only: it confirms stored signer state, not live chain deployment or gas balance."
|
|
11523
11783
|
]
|
|
11524
11784
|
});
|
|
11785
|
+
const productEntrySummary2 = buildProductEntrySummary({
|
|
11786
|
+
currentSurface: "doctor",
|
|
11787
|
+
stage: "wallet-recovery",
|
|
11788
|
+
nextAction: attachSigner
|
|
11789
|
+
});
|
|
11525
11790
|
return {
|
|
11526
11791
|
scope: "wallet-recovery",
|
|
11527
11792
|
nextAction: attachSigner,
|
|
11528
11793
|
recommendedPaths: buildSignerRecoveryRecommendedPaths(options.wallet.walletName),
|
|
11794
|
+
productEntrySummary: productEntrySummary2,
|
|
11529
11795
|
onboardingSummary: onboardingSummary2,
|
|
11530
11796
|
summary: {
|
|
11531
11797
|
stage: "wallet-recovery",
|
|
@@ -11561,13 +11827,29 @@ function buildDoctorResult(options) {
|
|
|
11561
11827
|
"Run zk-agent next for the current shortest live path; doctor does not confirm RPC reachability, deployment state, or funding."
|
|
11562
11828
|
]
|
|
11563
11829
|
});
|
|
11830
|
+
const productEntrySummary = buildProductEntrySummary({
|
|
11831
|
+
currentSurface: "doctor",
|
|
11832
|
+
stage: "wallet-ready",
|
|
11833
|
+
nextAction: recommendedCommands.next,
|
|
11834
|
+
suiteAvailable: true,
|
|
11835
|
+
nextSurface: "next"
|
|
11836
|
+
});
|
|
11837
|
+
const suiteHandoffSummary = buildSuiteHandoffSummary({
|
|
11838
|
+
currentSurface: "doctor",
|
|
11839
|
+
recommendedNow: true,
|
|
11840
|
+
walletName: options.wallet.walletName,
|
|
11841
|
+
chain: options.wallet.chain,
|
|
11842
|
+
recommendedJourneyId: "send-value-now"
|
|
11843
|
+
});
|
|
11564
11844
|
return {
|
|
11565
11845
|
scope: "wallet-ready",
|
|
11566
11846
|
nextAction: recommendedCommands.next,
|
|
11567
11847
|
recommendedPaths: {
|
|
11568
11848
|
local: [recommendedCommands.next]
|
|
11569
11849
|
},
|
|
11850
|
+
productEntrySummary,
|
|
11570
11851
|
onboardingSummary,
|
|
11852
|
+
suiteHandoffSummary,
|
|
11571
11853
|
summary: {
|
|
11572
11854
|
stage: "wallet-ready",
|
|
11573
11855
|
configExists: true,
|
|
@@ -11589,6 +11871,7 @@ function buildDoctorLines(input) {
|
|
|
11589
11871
|
const lines = [
|
|
11590
11872
|
["scope", input.scope],
|
|
11591
11873
|
...onboardingSummaryLines(input.onboardingSummary),
|
|
11874
|
+
...productEntrySummaryLines(input.productEntrySummary),
|
|
11592
11875
|
["config", input.config ? "present" : "missing"]
|
|
11593
11876
|
];
|
|
11594
11877
|
if (input.config) {
|
|
@@ -11625,6 +11908,9 @@ function buildDoctorLines(input) {
|
|
|
11625
11908
|
}
|
|
11626
11909
|
lines.push(["next", input.nextAction]);
|
|
11627
11910
|
lines.push(...recommendedPathLines(input.recommendedPaths));
|
|
11911
|
+
if (input.suiteHandoffSummary) {
|
|
11912
|
+
lines.push(...suiteHandoffLines(input.suiteHandoffSummary));
|
|
11913
|
+
}
|
|
11628
11914
|
if (input.recommendedCommands.createWallet) {
|
|
11629
11915
|
lines.push(["create wallet (local)", input.recommendedCommands.createWallet]);
|
|
11630
11916
|
}
|
|
@@ -11637,6 +11923,9 @@ function buildDoctorLines(input) {
|
|
|
11637
11923
|
if (input.recommendedCommands.workflowPay) {
|
|
11638
11924
|
lines.push(["workflow pay", input.recommendedCommands.workflowPay]);
|
|
11639
11925
|
}
|
|
11926
|
+
if (input.recommendedCommands.suite) {
|
|
11927
|
+
lines.push(["suite command", input.recommendedCommands.suite]);
|
|
11928
|
+
}
|
|
11640
11929
|
if (input.recommendedCommands.relayInspect) {
|
|
11641
11930
|
lines.push(["relay inspect", input.recommendedCommands.relayInspect]);
|
|
11642
11931
|
}
|
|
@@ -11679,7 +11968,9 @@ function createDoctorCommand() {
|
|
|
11679
11968
|
config,
|
|
11680
11969
|
wallet,
|
|
11681
11970
|
onboardingSummary: result.onboardingSummary,
|
|
11971
|
+
productEntrySummary: result.productEntrySummary,
|
|
11682
11972
|
summary: result.summary,
|
|
11973
|
+
suiteHandoffSummary: "suiteHandoffSummary" in result ? result.suiteHandoffSummary : void 0,
|
|
11683
11974
|
recommendedPaths: result.recommendedPaths,
|
|
11684
11975
|
recommendedCommands: result.recommendedCommands,
|
|
11685
11976
|
nextAction: result.nextAction
|
|
@@ -11700,8 +11991,10 @@ function createDoctorCommand() {
|
|
|
11700
11991
|
exists: false
|
|
11701
11992
|
},
|
|
11702
11993
|
wallet,
|
|
11994
|
+
productEntrySummary: result.productEntrySummary,
|
|
11703
11995
|
onboardingSummary: result.onboardingSummary,
|
|
11704
11996
|
summary: result.summary,
|
|
11997
|
+
..."suiteHandoffSummary" in result ? { suiteHandoffSummary: result.suiteHandoffSummary } : {},
|
|
11705
11998
|
agentProfile,
|
|
11706
11999
|
agentFollowup,
|
|
11707
12000
|
nextAction: result.nextAction,
|
|
@@ -11805,7 +12098,11 @@ function createAgentCommand() {
|
|
|
11805
12098
|
"after",
|
|
11806
12099
|
[
|
|
11807
12100
|
"",
|
|
11808
|
-
" Agent
|
|
12101
|
+
" Agent profile surface:",
|
|
12102
|
+
" Use this layer only when you want explicit local operator identity metadata on top of the wallet path.",
|
|
12103
|
+
" Wallet approval and workflow execution still work without a saved local agent profile.",
|
|
12104
|
+
"",
|
|
12105
|
+
" Basic local identity path:",
|
|
11809
12106
|
" zk-agent agent status",
|
|
11810
12107
|
' zk-agent agent set --name "SED Operator" --wallet main',
|
|
11811
12108
|
" zk-agent agent show",
|
|
@@ -11814,12 +12111,9 @@ function createAgentCommand() {
|
|
|
11814
12111
|
" zk-agent agent export",
|
|
11815
12112
|
" zk-agent agent import --payload @agent-profile.json --overwrite",
|
|
11816
12113
|
"",
|
|
11817
|
-
"
|
|
12114
|
+
" Clear the saved local profile:",
|
|
11818
12115
|
" zk-agent agent clear",
|
|
11819
12116
|
"",
|
|
11820
|
-
" This profile is optional. Wallet approval and workflow execution still work",
|
|
11821
|
-
" without a saved local agent profile.",
|
|
11822
|
-
"",
|
|
11823
12117
|
"Examples:",
|
|
11824
12118
|
" zk-agent agent status",
|
|
11825
12119
|
' zk-agent agent set --name "SED Operator" --wallet main',
|
|
@@ -12597,8 +12891,615 @@ function createDefaultsCommand() {
|
|
|
12597
12891
|
});
|
|
12598
12892
|
}
|
|
12599
12893
|
|
|
12600
|
-
// src/commands/
|
|
12894
|
+
// src/commands/payment.ts
|
|
12895
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
12601
12896
|
import { Command as Command7 } from "commander";
|
|
12897
|
+
|
|
12898
|
+
// ../agent-pay/src/execution-plan.ts
|
|
12899
|
+
function buildPaymentExecutionPlan(record) {
|
|
12900
|
+
return {
|
|
12901
|
+
action: record.asset.kind === "native" ? "native-transfer" : "erc20-transfer",
|
|
12902
|
+
surface: record.executionPreference.surface,
|
|
12903
|
+
walletId: record.walletId,
|
|
12904
|
+
walletName: record.walletName,
|
|
12905
|
+
chain: record.chain,
|
|
12906
|
+
chainId: record.chainId,
|
|
12907
|
+
paymasterMode: record.executionPreference.paymasterMode,
|
|
12908
|
+
payeeAddress: record.payee.address,
|
|
12909
|
+
asset: record.asset
|
|
12910
|
+
};
|
|
12911
|
+
}
|
|
12912
|
+
|
|
12913
|
+
// ../agent-pay/src/payment-request.ts
|
|
12914
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
12915
|
+
var PAYMENT_REQUEST_STATUS_TRANSITIONS = {
|
|
12916
|
+
draft: ["draft", "ready", "cancelled"],
|
|
12917
|
+
ready: ["draft", "ready", "paid", "cancelled"],
|
|
12918
|
+
paid: ["paid"],
|
|
12919
|
+
cancelled: ["cancelled"]
|
|
12920
|
+
};
|
|
12921
|
+
function nowIso2() {
|
|
12922
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
12923
|
+
}
|
|
12924
|
+
function createPaymentHistoryEventId() {
|
|
12925
|
+
return `payevt-${randomBytes4(4).toString("hex")}`;
|
|
12926
|
+
}
|
|
12927
|
+
function normalizeOptionalString4(value) {
|
|
12928
|
+
const trimmed = value?.trim();
|
|
12929
|
+
return trimmed ? trimmed : void 0;
|
|
12930
|
+
}
|
|
12931
|
+
function normalizeMetadata2(metadata) {
|
|
12932
|
+
if (!metadata) return {};
|
|
12933
|
+
const normalized = {};
|
|
12934
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
12935
|
+
const normalizedKey = key.trim();
|
|
12936
|
+
const normalizedValue = value.trim();
|
|
12937
|
+
if (!normalizedKey || !normalizedValue) continue;
|
|
12938
|
+
normalized[normalizedKey] = normalizedValue;
|
|
12939
|
+
}
|
|
12940
|
+
return normalized;
|
|
12941
|
+
}
|
|
12942
|
+
function normalizePaymentAsset(asset) {
|
|
12943
|
+
const amount = asset.amount.trim();
|
|
12944
|
+
if (!amount) {
|
|
12945
|
+
throw new AgentError("PAYMENT_AMOUNT_REQUIRED", "Payment amount is required.");
|
|
12946
|
+
}
|
|
12947
|
+
if (asset.kind === "native") {
|
|
12948
|
+
return {
|
|
12949
|
+
kind: "native",
|
|
12950
|
+
amount,
|
|
12951
|
+
symbol: normalizeOptionalString4(asset.symbol)
|
|
12952
|
+
};
|
|
12953
|
+
}
|
|
12954
|
+
const tokenAddress = asset.tokenAddress?.trim();
|
|
12955
|
+
if (!tokenAddress) {
|
|
12956
|
+
throw new AgentError(
|
|
12957
|
+
"PAYMENT_TOKEN_REQUIRED",
|
|
12958
|
+
"ERC-20 payment requests require a token address."
|
|
12959
|
+
);
|
|
12960
|
+
}
|
|
12961
|
+
if (!Number.isInteger(asset.decimals) || Number(asset.decimals) < 0) {
|
|
12962
|
+
throw new AgentError(
|
|
12963
|
+
"PAYMENT_TOKEN_DECIMALS_REQUIRED",
|
|
12964
|
+
"ERC-20 payment requests require non-negative token decimals."
|
|
12965
|
+
);
|
|
12966
|
+
}
|
|
12967
|
+
return {
|
|
12968
|
+
kind: "erc20",
|
|
12969
|
+
amount,
|
|
12970
|
+
tokenAddress,
|
|
12971
|
+
decimals: Number(asset.decimals),
|
|
12972
|
+
symbol: normalizeOptionalString4(asset.symbol)
|
|
12973
|
+
};
|
|
12974
|
+
}
|
|
12975
|
+
function inferExecutionSurface(asset) {
|
|
12976
|
+
return asset.kind === "native" ? "workflow-pay" : "send-token";
|
|
12977
|
+
}
|
|
12978
|
+
function createPaymentHistoryEvent(input) {
|
|
12979
|
+
return {
|
|
12980
|
+
eventId: createPaymentHistoryEventId(),
|
|
12981
|
+
type: input.type,
|
|
12982
|
+
at: input.at,
|
|
12983
|
+
status: input.status,
|
|
12984
|
+
previousStatus: input.previousStatus,
|
|
12985
|
+
txHash: normalizeOptionalString4(input.txHash),
|
|
12986
|
+
note: normalizeOptionalString4(input.note)
|
|
12987
|
+
};
|
|
12988
|
+
}
|
|
12989
|
+
function buildLegacyPaymentHistory(record) {
|
|
12990
|
+
return [
|
|
12991
|
+
{
|
|
12992
|
+
eventId: `payevt-${record.requestId}-legacy-created`,
|
|
12993
|
+
type: "created",
|
|
12994
|
+
at: record.createdAt,
|
|
12995
|
+
status: record.settlement.status,
|
|
12996
|
+
txHash: record.settlement.txHash,
|
|
12997
|
+
note: record.settlement.note
|
|
12998
|
+
}
|
|
12999
|
+
];
|
|
13000
|
+
}
|
|
13001
|
+
function migratePaymentRequestRecord(record) {
|
|
13002
|
+
return {
|
|
13003
|
+
...record,
|
|
13004
|
+
history: Array.isArray(record.history) && record.history.length > 0 ? record.history.map((event) => ({
|
|
13005
|
+
...event,
|
|
13006
|
+
txHash: normalizeOptionalString4(event.txHash),
|
|
13007
|
+
note: normalizeOptionalString4(event.note)
|
|
13008
|
+
})) : buildLegacyPaymentHistory(record)
|
|
13009
|
+
};
|
|
13010
|
+
}
|
|
13011
|
+
function createPaymentRequestRecord(input) {
|
|
13012
|
+
const timestamp = nowIso2();
|
|
13013
|
+
const payeeAddress = input.payeeAddress.trim();
|
|
13014
|
+
if (!payeeAddress) {
|
|
13015
|
+
throw new AgentError("PAYMENT_PAYEE_REQUIRED", "Payment payee address is required.");
|
|
13016
|
+
}
|
|
13017
|
+
const asset = normalizePaymentAsset(input.asset);
|
|
13018
|
+
const status = input.status ?? "ready";
|
|
13019
|
+
return {
|
|
13020
|
+
format: "zk-agent-payment-request",
|
|
13021
|
+
version: 1,
|
|
13022
|
+
requestId: input.requestId.trim(),
|
|
13023
|
+
walletId: input.walletId.trim(),
|
|
13024
|
+
walletName: input.walletName.trim(),
|
|
13025
|
+
walletAddress: input.walletAddress.trim(),
|
|
13026
|
+
chain: input.chain.trim(),
|
|
13027
|
+
chainId: input.chainId,
|
|
13028
|
+
payer: {
|
|
13029
|
+
walletId: input.walletId.trim(),
|
|
13030
|
+
walletName: input.walletName.trim(),
|
|
13031
|
+
walletAddress: input.walletAddress.trim(),
|
|
13032
|
+
name: normalizeOptionalString4(input.payerName)
|
|
13033
|
+
},
|
|
13034
|
+
payee: {
|
|
13035
|
+
address: payeeAddress,
|
|
13036
|
+
name: normalizeOptionalString4(input.payeeName)
|
|
13037
|
+
},
|
|
13038
|
+
asset,
|
|
13039
|
+
description: normalizeOptionalString4(input.description),
|
|
13040
|
+
memo: normalizeOptionalString4(input.memo),
|
|
13041
|
+
metadata: normalizeMetadata2(input.metadata),
|
|
13042
|
+
executionPreference: {
|
|
13043
|
+
surface: inferExecutionSurface(asset),
|
|
13044
|
+
paymasterMode: input.paymasterMode ?? "none"
|
|
13045
|
+
},
|
|
13046
|
+
settlement: {
|
|
13047
|
+
status
|
|
13048
|
+
},
|
|
13049
|
+
history: [
|
|
13050
|
+
createPaymentHistoryEvent({
|
|
13051
|
+
type: "created",
|
|
13052
|
+
at: timestamp,
|
|
13053
|
+
status
|
|
13054
|
+
})
|
|
13055
|
+
],
|
|
13056
|
+
createdAt: timestamp,
|
|
13057
|
+
updatedAt: timestamp
|
|
13058
|
+
};
|
|
13059
|
+
}
|
|
13060
|
+
function applyPaymentRequestStatusUpdate(record, input) {
|
|
13061
|
+
const nextStatus = input.status;
|
|
13062
|
+
const allowedTransitions = PAYMENT_REQUEST_STATUS_TRANSITIONS[record.settlement.status];
|
|
13063
|
+
if (!allowedTransitions.includes(nextStatus)) {
|
|
13064
|
+
throw new AgentError(
|
|
13065
|
+
"PAYMENT_STATUS_TRANSITION_INVALID",
|
|
13066
|
+
`Cannot move payment request ${record.requestId} from ${record.settlement.status} to ${nextStatus}.`,
|
|
13067
|
+
{
|
|
13068
|
+
currentStatus: record.settlement.status,
|
|
13069
|
+
nextStatus,
|
|
13070
|
+
allowedTransitions
|
|
13071
|
+
}
|
|
13072
|
+
);
|
|
13073
|
+
}
|
|
13074
|
+
const timestamp = nowIso2();
|
|
13075
|
+
const nextTxHash = normalizeOptionalString4(input.txHash);
|
|
13076
|
+
const nextNote = normalizeOptionalString4(input.note);
|
|
13077
|
+
return {
|
|
13078
|
+
...record,
|
|
13079
|
+
updatedAt: timestamp,
|
|
13080
|
+
settlement: {
|
|
13081
|
+
status: nextStatus,
|
|
13082
|
+
paidAt: nextStatus === "paid" ? timestamp : record.settlement.paidAt,
|
|
13083
|
+
cancelledAt: nextStatus === "cancelled" ? timestamp : record.settlement.cancelledAt,
|
|
13084
|
+
txHash: nextTxHash ?? record.settlement.txHash,
|
|
13085
|
+
note: nextNote ?? record.settlement.note
|
|
13086
|
+
},
|
|
13087
|
+
history: [
|
|
13088
|
+
...record.history,
|
|
13089
|
+
createPaymentHistoryEvent({
|
|
13090
|
+
type: "status-updated",
|
|
13091
|
+
at: timestamp,
|
|
13092
|
+
status: nextStatus,
|
|
13093
|
+
previousStatus: record.settlement.status,
|
|
13094
|
+
txHash: nextTxHash,
|
|
13095
|
+
note: nextNote
|
|
13096
|
+
})
|
|
13097
|
+
]
|
|
13098
|
+
};
|
|
13099
|
+
}
|
|
13100
|
+
|
|
13101
|
+
// ../agent-pay/src/storage.ts
|
|
13102
|
+
var PAYMENT_REQUEST_COLLECTION = "payments";
|
|
13103
|
+
async function savePaymentRequest(record) {
|
|
13104
|
+
await saveEncryptedStorageRecord(
|
|
13105
|
+
PAYMENT_REQUEST_COLLECTION,
|
|
13106
|
+
record.requestId,
|
|
13107
|
+
migratePaymentRequestRecord(record)
|
|
13108
|
+
);
|
|
13109
|
+
}
|
|
13110
|
+
async function loadPaymentRequest(requestId) {
|
|
13111
|
+
const record = await loadEncryptedStorageRecord(
|
|
13112
|
+
PAYMENT_REQUEST_COLLECTION,
|
|
13113
|
+
requestId
|
|
13114
|
+
);
|
|
13115
|
+
return record ? migratePaymentRequestRecord(record) : null;
|
|
13116
|
+
}
|
|
13117
|
+
async function listPaymentRequestIds() {
|
|
13118
|
+
return listEncryptedStorageRecordIds(PAYMENT_REQUEST_COLLECTION);
|
|
13119
|
+
}
|
|
13120
|
+
async function deletePaymentRequest(requestId) {
|
|
13121
|
+
return deleteEncryptedStorageRecord(PAYMENT_REQUEST_COLLECTION, requestId);
|
|
13122
|
+
}
|
|
13123
|
+
async function renamePaymentRequestWalletReferences(options) {
|
|
13124
|
+
const currentName = options.previousWalletName.trim();
|
|
13125
|
+
const targetName = options.nextWalletName.trim();
|
|
13126
|
+
const walletId = options.walletId?.trim();
|
|
13127
|
+
if (!currentName) throw new Error("Current wallet name is required.");
|
|
13128
|
+
if (!targetName) throw new Error("New wallet name is required.");
|
|
13129
|
+
if (currentName === targetName) return [];
|
|
13130
|
+
const updatedRequestIds = [];
|
|
13131
|
+
for (const requestId of await listPaymentRequestIds()) {
|
|
13132
|
+
const paymentRequest = await loadPaymentRequest(requestId);
|
|
13133
|
+
if (!paymentRequest) continue;
|
|
13134
|
+
const matchesWallet = walletId && paymentRequest.walletId ? paymentRequest.walletId === walletId : paymentRequest.walletName === currentName;
|
|
13135
|
+
if (!matchesWallet) continue;
|
|
13136
|
+
if (walletId) {
|
|
13137
|
+
paymentRequest.walletId = walletId;
|
|
13138
|
+
paymentRequest.payer.walletId = walletId;
|
|
13139
|
+
}
|
|
13140
|
+
paymentRequest.walletName = targetName;
|
|
13141
|
+
paymentRequest.payer.walletName = targetName;
|
|
13142
|
+
await savePaymentRequest(paymentRequest);
|
|
13143
|
+
updatedRequestIds.push(requestId);
|
|
13144
|
+
}
|
|
13145
|
+
return updatedRequestIds;
|
|
13146
|
+
}
|
|
13147
|
+
|
|
13148
|
+
// ../agent-pay/src/service.ts
|
|
13149
|
+
async function requirePaymentRequest(requestId) {
|
|
13150
|
+
const record = await loadPaymentRequest(requestId);
|
|
13151
|
+
if (!record) {
|
|
13152
|
+
throw new AgentError(
|
|
13153
|
+
"PAYMENT_REQUEST_NOT_FOUND",
|
|
13154
|
+
`Payment request not found: ${requestId}`
|
|
13155
|
+
);
|
|
13156
|
+
}
|
|
13157
|
+
return record;
|
|
13158
|
+
}
|
|
13159
|
+
async function createStoredPaymentRequest(input) {
|
|
13160
|
+
const paymentRequest = createPaymentRequestRecord(input);
|
|
13161
|
+
await savePaymentRequest(paymentRequest);
|
|
13162
|
+
return {
|
|
13163
|
+
paymentRequest,
|
|
13164
|
+
executionPlan: buildPaymentExecutionPlan(paymentRequest)
|
|
13165
|
+
};
|
|
13166
|
+
}
|
|
13167
|
+
async function getStoredPaymentRequest(requestId) {
|
|
13168
|
+
const paymentRequest = await requirePaymentRequest(requestId);
|
|
13169
|
+
return {
|
|
13170
|
+
paymentRequest,
|
|
13171
|
+
executionPlan: buildPaymentExecutionPlan(paymentRequest)
|
|
13172
|
+
};
|
|
13173
|
+
}
|
|
13174
|
+
async function listStoredPaymentRequests(input = {}) {
|
|
13175
|
+
const requestIds = await listPaymentRequestIds();
|
|
13176
|
+
const requests = [];
|
|
13177
|
+
for (const requestId of requestIds) {
|
|
13178
|
+
const record = await loadPaymentRequest(requestId);
|
|
13179
|
+
if (!record) continue;
|
|
13180
|
+
if (input.walletName && record.walletName !== input.walletName) continue;
|
|
13181
|
+
if (input.status && record.settlement.status !== input.status) continue;
|
|
13182
|
+
requests.push(record);
|
|
13183
|
+
}
|
|
13184
|
+
return requests.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
13185
|
+
}
|
|
13186
|
+
async function updateStoredPaymentRequestStatus(input) {
|
|
13187
|
+
const paymentRequest = await requirePaymentRequest(input.requestId);
|
|
13188
|
+
const updated = applyPaymentRequestStatusUpdate(paymentRequest, input);
|
|
13189
|
+
await savePaymentRequest(updated);
|
|
13190
|
+
return {
|
|
13191
|
+
paymentRequest: updated,
|
|
13192
|
+
executionPlan: buildPaymentExecutionPlan(updated)
|
|
13193
|
+
};
|
|
13194
|
+
}
|
|
13195
|
+
async function removeStoredPaymentRequest(requestId) {
|
|
13196
|
+
return deletePaymentRequest(requestId);
|
|
13197
|
+
}
|
|
13198
|
+
|
|
13199
|
+
// src/commands/payment.ts
|
|
13200
|
+
function parseMetadataEntries2(entries) {
|
|
13201
|
+
const metadata = {};
|
|
13202
|
+
for (const entry of entries) {
|
|
13203
|
+
const separatorIndex = entry.indexOf("=");
|
|
13204
|
+
if (separatorIndex <= 0 || separatorIndex === entry.length - 1) {
|
|
13205
|
+
throw new AgentError(
|
|
13206
|
+
"PAYMENT_METADATA_INVALID",
|
|
13207
|
+
`Invalid metadata entry: ${entry}. Use key=value.`
|
|
13208
|
+
);
|
|
13209
|
+
}
|
|
13210
|
+
const key = entry.slice(0, separatorIndex).trim();
|
|
13211
|
+
const value = entry.slice(separatorIndex + 1).trim();
|
|
13212
|
+
if (!key || !value) {
|
|
13213
|
+
throw new AgentError(
|
|
13214
|
+
"PAYMENT_METADATA_INVALID",
|
|
13215
|
+
`Invalid metadata entry: ${entry}. Use key=value.`
|
|
13216
|
+
);
|
|
13217
|
+
}
|
|
13218
|
+
metadata[key] = value;
|
|
13219
|
+
}
|
|
13220
|
+
return metadata;
|
|
13221
|
+
}
|
|
13222
|
+
function resolvePaymentStatus(value) {
|
|
13223
|
+
const normalized = value?.trim().toLowerCase();
|
|
13224
|
+
if (!normalized) return "ready";
|
|
13225
|
+
if (normalized === "draft" || normalized === "ready" || normalized === "paid" || normalized === "cancelled") {
|
|
13226
|
+
return normalized;
|
|
13227
|
+
}
|
|
13228
|
+
throw new AgentError(
|
|
13229
|
+
"PAYMENT_STATUS_INVALID",
|
|
13230
|
+
`Unsupported payment status: ${value}. Use draft, ready, paid, or cancelled.`
|
|
13231
|
+
);
|
|
13232
|
+
}
|
|
13233
|
+
function resolvePaymasterMode2(value) {
|
|
13234
|
+
const normalized = value?.trim().toLowerCase();
|
|
13235
|
+
if (!normalized) return void 0;
|
|
13236
|
+
if (normalized === "none" || normalized === "sponsored" || normalized === "approval-based") {
|
|
13237
|
+
return normalized;
|
|
13238
|
+
}
|
|
13239
|
+
throw new AgentError(
|
|
13240
|
+
"PAYMENT_PAYMASTER_MODE_INVALID",
|
|
13241
|
+
`Unsupported paymaster mode: ${value}. Use none, sponsored, or approval-based.`
|
|
13242
|
+
);
|
|
13243
|
+
}
|
|
13244
|
+
function buildPaymentRequestId(value) {
|
|
13245
|
+
const trimmed = value?.trim();
|
|
13246
|
+
if (trimmed) return trimmed;
|
|
13247
|
+
return `payreq-${randomBytes5(4).toString("hex")}`;
|
|
13248
|
+
}
|
|
13249
|
+
function formatPaymentAsset(record) {
|
|
13250
|
+
const symbol = record.asset.kind === "native" ? record.asset.symbol || "native" : record.asset.symbol || record.asset.tokenAddress || "erc20";
|
|
13251
|
+
return `${record.asset.amount} ${symbol}`;
|
|
13252
|
+
}
|
|
13253
|
+
function buildPaymentExecuteCommand(plan) {
|
|
13254
|
+
if (plan.asset.kind === "native") {
|
|
13255
|
+
return buildWorkflowPayRecommendedCommand(
|
|
13256
|
+
plan.walletName,
|
|
13257
|
+
plan.paymasterMode
|
|
13258
|
+
).replace("--to <address>", `--to ${plan.payeeAddress}`).replace("--amount <amount>", `--amount ${plan.asset.amount}`);
|
|
13259
|
+
}
|
|
13260
|
+
return buildSendTokenRecommendedCommand({
|
|
13261
|
+
walletName: plan.walletName,
|
|
13262
|
+
to: plan.payeeAddress,
|
|
13263
|
+
amount: plan.asset.amount,
|
|
13264
|
+
tokenAddress: plan.asset.tokenAddress,
|
|
13265
|
+
symbol: plan.asset.symbol,
|
|
13266
|
+
decimals: plan.asset.decimals,
|
|
13267
|
+
paymasterMode: plan.paymasterMode
|
|
13268
|
+
});
|
|
13269
|
+
}
|
|
13270
|
+
function buildPaymentRecommendedCommands(record, executionPlan) {
|
|
13271
|
+
return {
|
|
13272
|
+
list: buildPaymentListRecommendedCommand(),
|
|
13273
|
+
show: buildPaymentShowRecommendedCommand(record.requestId),
|
|
13274
|
+
execute: buildPaymentExecuteCommand(executionPlan),
|
|
13275
|
+
...record.settlement.status === "draft" ? {
|
|
13276
|
+
markReady: buildPaymentSetStatusRecommendedCommand(record.requestId, "ready"),
|
|
13277
|
+
cancel: buildPaymentSetStatusRecommendedCommand(record.requestId, "cancelled")
|
|
13278
|
+
} : {},
|
|
13279
|
+
...record.settlement.status === "ready" ? {
|
|
13280
|
+
markDraft: buildPaymentSetStatusRecommendedCommand(record.requestId, "draft"),
|
|
13281
|
+
markPaid: buildPaymentSetStatusRecommendedCommand(
|
|
13282
|
+
record.requestId,
|
|
13283
|
+
"paid",
|
|
13284
|
+
"<tx-hash>"
|
|
13285
|
+
),
|
|
13286
|
+
cancel: buildPaymentSetStatusRecommendedCommand(record.requestId, "cancelled")
|
|
13287
|
+
} : {},
|
|
13288
|
+
remove: buildPaymentRemoveRecommendedCommand(record.requestId)
|
|
13289
|
+
};
|
|
13290
|
+
}
|
|
13291
|
+
function paymentRequestLines(record, executionPlan) {
|
|
13292
|
+
const lines = [
|
|
13293
|
+
["request", record.requestId],
|
|
13294
|
+
["status", record.settlement.status],
|
|
13295
|
+
["wallet", record.walletName],
|
|
13296
|
+
["chain", `${record.chain} (${record.chainId})`],
|
|
13297
|
+
["payer", `${record.payer.name || record.payer.walletName} ${record.payer.walletAddress}`],
|
|
13298
|
+
["payee", `${record.payee.name || "payee"} ${record.payee.address}`],
|
|
13299
|
+
["asset", formatPaymentAsset(record)],
|
|
13300
|
+
["execution surface", record.executionPreference.surface],
|
|
13301
|
+
["paymaster mode", record.executionPreference.paymasterMode],
|
|
13302
|
+
["execute", buildPaymentExecuteCommand(executionPlan)],
|
|
13303
|
+
["show", buildPaymentShowRecommendedCommand(record.requestId)],
|
|
13304
|
+
["remove", buildPaymentRemoveRecommendedCommand(record.requestId)]
|
|
13305
|
+
];
|
|
13306
|
+
if (record.description) lines.splice(7, 0, ["description", record.description]);
|
|
13307
|
+
if (record.memo) lines.splice(record.description ? 8 : 7, 0, ["memo", record.memo]);
|
|
13308
|
+
if (record.settlement.txHash) lines.push(["txHash", record.settlement.txHash]);
|
|
13309
|
+
if (record.settlement.note) lines.push(["note", record.settlement.note]);
|
|
13310
|
+
if (record.settlement.paidAt) lines.push(["paid at", record.settlement.paidAt]);
|
|
13311
|
+
if (record.settlement.cancelledAt) lines.push(["cancelled at", record.settlement.cancelledAt]);
|
|
13312
|
+
lines.push(["history events", String(record.history.length)]);
|
|
13313
|
+
lines.push(["metadata keys", String(Object.keys(record.metadata).length)]);
|
|
13314
|
+
return lines;
|
|
13315
|
+
}
|
|
13316
|
+
function buildPaymentExecutionPlanJson(plan) {
|
|
13317
|
+
return {
|
|
13318
|
+
...plan,
|
|
13319
|
+
command: buildPaymentExecuteCommand(plan)
|
|
13320
|
+
};
|
|
13321
|
+
}
|
|
13322
|
+
function buildPaymentListSummary(record) {
|
|
13323
|
+
return `${record.requestId} ${record.settlement.status} ${formatPaymentAsset(record)} -> ${record.payee.address} (${record.walletName})`;
|
|
13324
|
+
}
|
|
13325
|
+
function createPaymentCommand() {
|
|
13326
|
+
const payment = new Command7("payment").description(
|
|
13327
|
+
"Manage local-first Agent Pay request records separately from the execution-layer workflow and send commands"
|
|
13328
|
+
);
|
|
13329
|
+
payment.addHelpText(
|
|
13330
|
+
"after",
|
|
13331
|
+
[
|
|
13332
|
+
"",
|
|
13333
|
+
" Payment request surface:",
|
|
13334
|
+
" Use this layer to capture payer/payee intent and local settlement state before or after execution.",
|
|
13335
|
+
" `workflow pay` and `send-token` still execute the transfer; `payment` stores the request record and status lifecycle.",
|
|
13336
|
+
"",
|
|
13337
|
+
" First platform path:",
|
|
13338
|
+
" zk-agent payment create --wallet main --to <address> --amount <amount>",
|
|
13339
|
+
" zk-agent payment show --request-id <id>",
|
|
13340
|
+
" zk-agent payment set-status --request-id <id> --status paid --tx-hash <tx-hash>",
|
|
13341
|
+
"",
|
|
13342
|
+
" ERC-20 request path:",
|
|
13343
|
+
" zk-agent payment create --wallet main --to <address> --amount <amount> --symbol USDC",
|
|
13344
|
+
"",
|
|
13345
|
+
" Stored request management:",
|
|
13346
|
+
" zk-agent payment list",
|
|
13347
|
+
" zk-agent payment remove --request-id <id>"
|
|
13348
|
+
].join("\n")
|
|
13349
|
+
);
|
|
13350
|
+
payment.command("create").description("Create a local payment request record for native value or an ERC-20 transfer").option("--wallet <name>", "Stored payer wallet name", "main").requiredOption("--to <address>", "Payee address").requiredOption("--amount <value>", "Amount in human-readable units").option("--token <address>", "ERC-20 token contract address").option("--symbol <symbol>", "ERC-20 token symbol for registry-backed resolution").option("--decimals <value>", "ERC-20 token decimals when registry metadata is unavailable").option("--payee-name <name>", "Optional payee display name").option("--payer-name <name>", "Optional payer display name").option("--description <text>", "Short payment description").option("--memo <text>", "Optional memo or invoice reference").option("--metadata <key=value>", "Additional payment metadata", collectRepeatedString2, []).option("--paymaster-mode <mode>", "Optional execution preference: none, sponsored, or approval-based").option("--status <status>", "Initial local payment status: draft, ready, paid, or cancelled").option("--request-id <id>", "Optional explicit payment request id").action(async (options) => {
|
|
13351
|
+
const wallet = await loadWalletSession(options.wallet);
|
|
13352
|
+
if (!wallet) {
|
|
13353
|
+
throw new AgentError("PAYMENT_WALLET_NOT_FOUND", `Wallet not found: ${options.wallet}`);
|
|
13354
|
+
}
|
|
13355
|
+
if (!wallet.walletId) {
|
|
13356
|
+
throw new AgentError(
|
|
13357
|
+
"WALLET_ID_MISSING",
|
|
13358
|
+
`Wallet ${wallet.walletName} is missing a stable walletId. Re-save or reapprove the wallet session before creating a payment request.`
|
|
13359
|
+
);
|
|
13360
|
+
}
|
|
13361
|
+
const paymasterMode = resolvePaymasterMode2(options.paymasterMode) ?? wallet.paymasterMode ?? "none";
|
|
13362
|
+
const status = resolvePaymentStatus(options.status);
|
|
13363
|
+
const metadata = parseMetadataEntries2(options.metadata);
|
|
13364
|
+
const requestId = buildPaymentRequestId(options.requestId);
|
|
13365
|
+
const hasTokenInput = Boolean(options.token?.trim() || options.symbol?.trim());
|
|
13366
|
+
const asset = hasTokenInput ? await resolveRequiredTokenInput({
|
|
13367
|
+
tokenAddress: options.token,
|
|
13368
|
+
symbol: options.symbol,
|
|
13369
|
+
decimals: options.decimals,
|
|
13370
|
+
chain: wallet.chain,
|
|
13371
|
+
tokenOptionLabel: "--token",
|
|
13372
|
+
symbolOptionLabel: "--symbol",
|
|
13373
|
+
decimalsOptionLabel: "--decimals"
|
|
13374
|
+
}).then((token) => ({
|
|
13375
|
+
kind: "erc20",
|
|
13376
|
+
amount: options.amount,
|
|
13377
|
+
tokenAddress: token.address,
|
|
13378
|
+
decimals: token.decimals,
|
|
13379
|
+
symbol: token.symbol
|
|
13380
|
+
})) : {
|
|
13381
|
+
kind: "native",
|
|
13382
|
+
amount: options.amount
|
|
13383
|
+
};
|
|
13384
|
+
const result = await createStoredPaymentRequest({
|
|
13385
|
+
requestId,
|
|
13386
|
+
walletId: wallet.walletId,
|
|
13387
|
+
walletName: wallet.walletName,
|
|
13388
|
+
walletAddress: wallet.walletAddress,
|
|
13389
|
+
chain: wallet.chain,
|
|
13390
|
+
chainId: wallet.chainId,
|
|
13391
|
+
payerName: options.payerName,
|
|
13392
|
+
payeeAddress: options.to,
|
|
13393
|
+
payeeName: options.payeeName,
|
|
13394
|
+
asset,
|
|
13395
|
+
description: options.description,
|
|
13396
|
+
memo: options.memo,
|
|
13397
|
+
metadata,
|
|
13398
|
+
paymasterMode,
|
|
13399
|
+
status
|
|
13400
|
+
});
|
|
13401
|
+
printResult(paymentRequestLines(result.paymentRequest, result.executionPlan), {
|
|
13402
|
+
ok: true,
|
|
13403
|
+
paymentRequest: result.paymentRequest,
|
|
13404
|
+
executionPlan: buildPaymentExecutionPlanJson(result.executionPlan),
|
|
13405
|
+
recommendedCommands: buildPaymentRecommendedCommands(
|
|
13406
|
+
result.paymentRequest,
|
|
13407
|
+
result.executionPlan
|
|
13408
|
+
)
|
|
13409
|
+
});
|
|
13410
|
+
});
|
|
13411
|
+
payment.command("list").description("List stored local payment request records").option("--wallet <name>", "Optional payer wallet filter").option("--status <status>", "Optional status filter: draft, ready, paid, or cancelled").action(async (options) => {
|
|
13412
|
+
const statusFilter = options.status ? resolvePaymentStatus(options.status) : void 0;
|
|
13413
|
+
const requests = await listStoredPaymentRequests({
|
|
13414
|
+
walletName: options.wallet,
|
|
13415
|
+
status: statusFilter
|
|
13416
|
+
});
|
|
13417
|
+
printResult(
|
|
13418
|
+
requests.length > 0 ? requests.flatMap((record) => [
|
|
13419
|
+
["payment", buildPaymentListSummary(record)],
|
|
13420
|
+
["show", buildPaymentShowRecommendedCommand(record.requestId)]
|
|
13421
|
+
]) : [
|
|
13422
|
+
["status", "No stored payment requests"],
|
|
13423
|
+
["next", "zk-agent payment create --wallet main --to <address> --amount <amount>"]
|
|
13424
|
+
],
|
|
13425
|
+
{
|
|
13426
|
+
ok: true,
|
|
13427
|
+
count: requests.length,
|
|
13428
|
+
filters: {
|
|
13429
|
+
walletName: options.wallet || null,
|
|
13430
|
+
status: statusFilter || null
|
|
13431
|
+
},
|
|
13432
|
+
requests,
|
|
13433
|
+
recommendedCommands: requests.length === 0 ? {
|
|
13434
|
+
create: "zk-agent payment create --wallet main --to <address> --amount <amount>"
|
|
13435
|
+
} : {
|
|
13436
|
+
list: buildPaymentListRecommendedCommand()
|
|
13437
|
+
}
|
|
13438
|
+
}
|
|
13439
|
+
);
|
|
13440
|
+
});
|
|
13441
|
+
payment.command("show").description("Show one stored payment request record").requiredOption("--request-id <id>", "Stored payment request id").action(async (options) => {
|
|
13442
|
+
const result = await getStoredPaymentRequest(options.requestId);
|
|
13443
|
+
printResult(paymentRequestLines(result.paymentRequest, result.executionPlan), {
|
|
13444
|
+
ok: true,
|
|
13445
|
+
paymentRequest: result.paymentRequest,
|
|
13446
|
+
executionPlan: buildPaymentExecutionPlanJson(result.executionPlan),
|
|
13447
|
+
recommendedCommands: buildPaymentRecommendedCommands(
|
|
13448
|
+
result.paymentRequest,
|
|
13449
|
+
result.executionPlan
|
|
13450
|
+
)
|
|
13451
|
+
});
|
|
13452
|
+
});
|
|
13453
|
+
payment.command("set-status").description("Update the local settlement status of one stored payment request").requiredOption("--request-id <id>", "Stored payment request id").requiredOption("--status <status>", "Next status: draft, ready, paid, or cancelled").option("--tx-hash <hash>", "Optional settlement transaction hash").option("--note <text>", "Optional operator note for the status update").action(async (options) => {
|
|
13454
|
+
const result = await updateStoredPaymentRequestStatus({
|
|
13455
|
+
requestId: options.requestId,
|
|
13456
|
+
status: resolvePaymentStatus(options.status),
|
|
13457
|
+
txHash: options.txHash,
|
|
13458
|
+
note: options.note
|
|
13459
|
+
});
|
|
13460
|
+
printResult(paymentRequestLines(result.paymentRequest, result.executionPlan), {
|
|
13461
|
+
ok: true,
|
|
13462
|
+
paymentRequest: result.paymentRequest,
|
|
13463
|
+
executionPlan: buildPaymentExecutionPlanJson(result.executionPlan),
|
|
13464
|
+
recommendedCommands: buildPaymentRecommendedCommands(
|
|
13465
|
+
result.paymentRequest,
|
|
13466
|
+
result.executionPlan
|
|
13467
|
+
)
|
|
13468
|
+
});
|
|
13469
|
+
});
|
|
13470
|
+
payment.command("remove").description("Delete one stored payment request record").requiredOption("--request-id <id>", "Stored payment request id").action(async (options) => {
|
|
13471
|
+
const removed = await removeStoredPaymentRequest(options.requestId);
|
|
13472
|
+
if (!removed) {
|
|
13473
|
+
throw new AgentError(
|
|
13474
|
+
"PAYMENT_REQUEST_NOT_FOUND",
|
|
13475
|
+
`Payment request not found: ${options.requestId}`
|
|
13476
|
+
);
|
|
13477
|
+
}
|
|
13478
|
+
printResult(
|
|
13479
|
+
[
|
|
13480
|
+
["status", "Payment request removed"],
|
|
13481
|
+
["request", options.requestId],
|
|
13482
|
+
["next", buildPaymentListRecommendedCommand()]
|
|
13483
|
+
],
|
|
13484
|
+
{
|
|
13485
|
+
ok: true,
|
|
13486
|
+
requestId: options.requestId,
|
|
13487
|
+
removed: true,
|
|
13488
|
+
recommendedCommands: {
|
|
13489
|
+
list: buildPaymentListRecommendedCommand(),
|
|
13490
|
+
create: "zk-agent payment create --wallet main --to <address> --amount <amount>"
|
|
13491
|
+
}
|
|
13492
|
+
}
|
|
13493
|
+
);
|
|
13494
|
+
});
|
|
13495
|
+
return payment;
|
|
13496
|
+
}
|
|
13497
|
+
function collectRepeatedString2(value, previous) {
|
|
13498
|
+
return [...previous, value];
|
|
13499
|
+
}
|
|
13500
|
+
|
|
13501
|
+
// src/commands/resolve-token.ts
|
|
13502
|
+
import { Command as Command8 } from "commander";
|
|
12602
13503
|
function resolveResolveTokenCommandDeps(deps) {
|
|
12603
13504
|
return {
|
|
12604
13505
|
loadWallet: deps?.loadWallet ?? (async (walletName) => {
|
|
@@ -12656,7 +13557,7 @@ function buildResolveTokenDiscoverySummary(result) {
|
|
|
12656
13557
|
}
|
|
12657
13558
|
function createResolveTokenCommand(deps) {
|
|
12658
13559
|
const resolvedDeps = resolveResolveTokenCommandDeps(deps);
|
|
12659
|
-
return new
|
|
13560
|
+
return new Command8("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").addHelpText(
|
|
12660
13561
|
"after",
|
|
12661
13562
|
[
|
|
12662
13563
|
"",
|
|
@@ -12790,33 +13691,67 @@ function normalizeSource(value) {
|
|
|
12790
13691
|
}
|
|
12791
13692
|
|
|
12792
13693
|
// src/commands/suite.ts
|
|
12793
|
-
import { Command as
|
|
13694
|
+
import { Command as Command9 } from "commander";
|
|
12794
13695
|
|
|
12795
13696
|
// src/lib/operator-suite.ts
|
|
12796
13697
|
function buildOperatorSuitePayload(options = {}) {
|
|
12797
13698
|
const walletName = options.walletName?.trim() || "main";
|
|
12798
13699
|
const chain = options.chain?.trim() || "zksync-sepolia";
|
|
13700
|
+
const includeOnboarding = options.includeOnboarding === true;
|
|
12799
13701
|
const flagshipCommand = buildWorkflowPayRecommendedCommand(walletName);
|
|
12800
13702
|
const inspectDefaults = buildDefaultsRecommendedCommand();
|
|
13703
|
+
const workflowSurfaceCommand = "zk-agent workflow --help";
|
|
13704
|
+
const relaySurfaceCommand = "zk-agent relay --help";
|
|
12801
13705
|
const discoveryCommand = buildAssetsRecommendedCommand(walletName);
|
|
12802
13706
|
const paymasterCommand = buildWorkflowPayRecommendedCommand(walletName, "approval-based");
|
|
12803
13707
|
const fundingCommand = buildWorkflowFundRecommendedCommand(walletName);
|
|
13708
|
+
const nextCommand = buildTopLevelNextRecommendedCommand(void 0, void 0, walletName);
|
|
13709
|
+
const hostedRelayInspectCommand = buildRelayInspectRecommendedCommand("<url>");
|
|
13710
|
+
const hostedCreateWalletCommand = buildWalletCreateRemoteRecommendedCommand(
|
|
13711
|
+
"<url>",
|
|
13712
|
+
void 0,
|
|
13713
|
+
walletName
|
|
13714
|
+
);
|
|
13715
|
+
const hostedReapproveCommand = buildWalletReapproveRemoteRecommendedCommand(
|
|
13716
|
+
walletName,
|
|
13717
|
+
"<url>"
|
|
13718
|
+
);
|
|
13719
|
+
const suiteCommand = buildSuiteRecommendedCommand(walletName, chain, {
|
|
13720
|
+
includeOnboarding
|
|
13721
|
+
});
|
|
13722
|
+
const preflightPaths = includeOnboarding ? buildSetupRecommendedPaths("<url>", void 0, walletName) : void 0;
|
|
13723
|
+
const preflight = preflightPaths ? {
|
|
13724
|
+
id: "first-run-preflight",
|
|
13725
|
+
title: "First-Run Preflight",
|
|
13726
|
+
goal: "Start from a fresh install, write local defaults, and bootstrap a writable wallet session before using the packaged operator surface.",
|
|
13727
|
+
useWhen: "Use this when the machine is new, the wallet is not ready yet, or you want the full operator map before choosing local-first versus remote-browser approval.",
|
|
13728
|
+
diagnosticCommand: walletName === "main" ? "zk-agent doctor" : `zk-agent doctor --wallet ${walletName}`,
|
|
13729
|
+
localPath: preflightPaths.local,
|
|
13730
|
+
remoteBrowserPath: preflightPaths.remoteBrowser,
|
|
13731
|
+
afterWalletReady: buildSuiteRecommendedCommand(walletName, chain)
|
|
13732
|
+
} : void 0;
|
|
12804
13733
|
const flagship = {
|
|
13734
|
+
category: "operate",
|
|
13735
|
+
surface: "workflow",
|
|
12805
13736
|
id: "flagship-pay",
|
|
12806
13737
|
title: "Flagship Pay",
|
|
12807
13738
|
goal: "Run the default zkSync-native native-send path through the workflow layer.",
|
|
12808
13739
|
useWhen: "Start here when the wallet is already ready and the next real goal is a native send.",
|
|
12809
13740
|
primaryCommand: flagshipCommand,
|
|
12810
|
-
|
|
13741
|
+
surfaceCommand: workflowSurfaceCommand,
|
|
13742
|
+
supportingCommands: [nextCommand, buildWalletStatusRecommendedCommand(walletName), inspectDefaults],
|
|
12811
13743
|
skillPath: "skills/zk-aa/SKILL.md"
|
|
12812
13744
|
};
|
|
12813
13745
|
const slices = [
|
|
12814
13746
|
{
|
|
13747
|
+
category: "discover",
|
|
13748
|
+
surface: "discovery",
|
|
12815
13749
|
id: "discovery-defaults",
|
|
12816
13750
|
title: "Discovery / Defaults",
|
|
12817
13751
|
goal: "Discover owned assets, tracked defaults, and symbol-first token resolution before acting.",
|
|
12818
13752
|
useWhen: "Use this before tokenized actions or whenever asset/default context is unclear.",
|
|
12819
13753
|
primaryCommand: discoveryCommand,
|
|
13754
|
+
surfaceCommand: inspectDefaults,
|
|
12820
13755
|
supportingCommands: [
|
|
12821
13756
|
inspectDefaults,
|
|
12822
13757
|
`zk-agent tokens --chain ${chain}`,
|
|
@@ -12826,11 +13761,14 @@ function buildOperatorSuitePayload(options = {}) {
|
|
|
12826
13761
|
smokeCommand: `pnpm smoke:discovery -- --wallet ${walletName}`
|
|
12827
13762
|
},
|
|
12828
13763
|
{
|
|
13764
|
+
category: "pay",
|
|
13765
|
+
surface: "workflow",
|
|
12829
13766
|
id: "paymaster-readiness",
|
|
12830
13767
|
title: "Paymaster Readiness",
|
|
12831
13768
|
goal: "Stay on the approval-based flagship path and recover the exact fee-token/default metadata when needed.",
|
|
12832
13769
|
useWhen: "Use this when approval-based pay or another sponsored write needs fee-token/default recovery.",
|
|
12833
13770
|
primaryCommand: paymasterCommand,
|
|
13771
|
+
surfaceCommand: workflowSurfaceCommand,
|
|
12834
13772
|
supportingCommands: [
|
|
12835
13773
|
inspectDefaults,
|
|
12836
13774
|
buildPaymasterFeeTokensRecommendedCommand(chain),
|
|
@@ -12840,11 +13778,14 @@ function buildOperatorSuitePayload(options = {}) {
|
|
|
12840
13778
|
smokeCommand: `pnpm smoke:paymaster-success -- --wallet ${walletName}`
|
|
12841
13779
|
},
|
|
12842
13780
|
{
|
|
13781
|
+
category: "fund",
|
|
13782
|
+
surface: "workflow",
|
|
12843
13783
|
id: "funding-readiness",
|
|
12844
13784
|
title: "Funding Readiness",
|
|
12845
13785
|
goal: "Ask the workflow layer for the exact funding route before executing bridge/deposit follow-up.",
|
|
12846
13786
|
useWhen: "Use this when the workflow path is blocked on gas or the CLI says funding is required.",
|
|
12847
13787
|
primaryCommand: fundingCommand,
|
|
13788
|
+
surfaceCommand: workflowSurfaceCommand,
|
|
12848
13789
|
supportingCommands: [
|
|
12849
13790
|
buildWorkflowFundRunRecommendedCommand(walletName),
|
|
12850
13791
|
`zk-agent fund --wallet ${walletName} --amount <amount>`,
|
|
@@ -12852,48 +13793,197 @@ function buildOperatorSuitePayload(options = {}) {
|
|
|
12852
13793
|
],
|
|
12853
13794
|
skillPath: "skills/zk-funding/SKILL.md",
|
|
12854
13795
|
smokeCommand: `pnpm smoke:funding-readiness -- --wallet ${walletName}`
|
|
13796
|
+
},
|
|
13797
|
+
{
|
|
13798
|
+
category: "recover",
|
|
13799
|
+
surface: "relay",
|
|
13800
|
+
id: "hosted-approval-recovery",
|
|
13801
|
+
title: "Hosted Approval Recovery",
|
|
13802
|
+
goal: "Validate a hosted relay URL and switch to the remote approval path when the browser is not colocated or a writable session must be reapproved remotely.",
|
|
13803
|
+
useWhen: "Use this when local callback is not viable, the browser is remote, or an expired writable session must be recovered through the single-host hosted relay baseline.",
|
|
13804
|
+
primaryCommand: hostedRelayInspectCommand,
|
|
13805
|
+
surfaceCommand: relaySurfaceCommand,
|
|
13806
|
+
supportingCommands: [
|
|
13807
|
+
hostedCreateWalletCommand,
|
|
13808
|
+
hostedReapproveCommand,
|
|
13809
|
+
`pnpm smoke:hosted-operated-baseline -- --wallet ${walletName} --relay-url <url> --reapprove --prompt-code --plan`
|
|
13810
|
+
],
|
|
13811
|
+
skillPath: "skills/zk-relay/SKILL.md"
|
|
12855
13812
|
}
|
|
12856
13813
|
];
|
|
13814
|
+
const surfaces = [
|
|
13815
|
+
{
|
|
13816
|
+
surface: "workflow",
|
|
13817
|
+
title: "Workflow Surface",
|
|
13818
|
+
useWhen: "Use this when the question is already about execution, approval-based pay, or funding recovery after suite has identified the right slice.",
|
|
13819
|
+
command: workflowSurfaceCommand,
|
|
13820
|
+
categoryIds: ["operate", "pay", "fund"],
|
|
13821
|
+
entryIds: [flagship.id, "paymaster-readiness", "funding-readiness"]
|
|
13822
|
+
},
|
|
13823
|
+
{
|
|
13824
|
+
surface: "discovery",
|
|
13825
|
+
title: "Discovery Surface",
|
|
13826
|
+
useWhen: "Use this when the question is about assets, defaults, token ownership, or symbol-first inspection after suite has identified the discovery slice.",
|
|
13827
|
+
command: inspectDefaults,
|
|
13828
|
+
categoryIds: ["discover"],
|
|
13829
|
+
entryIds: ["discovery-defaults"]
|
|
13830
|
+
},
|
|
13831
|
+
{
|
|
13832
|
+
surface: "relay",
|
|
13833
|
+
title: "Relay Surface",
|
|
13834
|
+
useWhen: "Use this when the browser is remote or hosted approval readiness must be checked before wallet recovery can continue.",
|
|
13835
|
+
command: relaySurfaceCommand,
|
|
13836
|
+
categoryIds: ["recover"],
|
|
13837
|
+
entryIds: ["hosted-approval-recovery"]
|
|
13838
|
+
}
|
|
13839
|
+
];
|
|
13840
|
+
const journeys = [
|
|
13841
|
+
{
|
|
13842
|
+
id: "send-value-now",
|
|
13843
|
+
title: "Send Value Now",
|
|
13844
|
+
operatorQuestion: "I already have a ready wallet and want the shortest path to send native value now.",
|
|
13845
|
+
useWhen: "Use this when the wallet is already ready and the operator wants the flagship zkSync-native pay path first.",
|
|
13846
|
+
startCommand: flagshipCommand,
|
|
13847
|
+
surface: "workflow",
|
|
13848
|
+
categoryIds: ["operate"],
|
|
13849
|
+
entryIds: [flagship.id]
|
|
13850
|
+
},
|
|
13851
|
+
{
|
|
13852
|
+
id: "inspect-before-acting",
|
|
13853
|
+
title: "Inspect Before Acting",
|
|
13854
|
+
operatorQuestion: "I need to inspect assets, defaults, or token metadata before I choose a tokenized action.",
|
|
13855
|
+
useWhen: "Use this when asset visibility, defaults, or symbol-first token inspection is still the real blocker.",
|
|
13856
|
+
startCommand: discoveryCommand,
|
|
13857
|
+
surface: "discovery",
|
|
13858
|
+
categoryIds: ["discover"],
|
|
13859
|
+
entryIds: ["discovery-defaults"]
|
|
13860
|
+
},
|
|
13861
|
+
{
|
|
13862
|
+
id: "unstick-a-write",
|
|
13863
|
+
title: "Unstick a Write",
|
|
13864
|
+
operatorQuestion: "The write path is blocked on fee-token/default state or funding, and I need the shortest recovery route.",
|
|
13865
|
+
useWhen: "Use this when approval-based pay or a workflow write is blocked and the CLI needs to recover paymaster or funding readiness.",
|
|
13866
|
+
startCommand: paymasterCommand,
|
|
13867
|
+
surface: "workflow",
|
|
13868
|
+
categoryIds: ["pay", "fund"],
|
|
13869
|
+
entryIds: ["paymaster-readiness", "funding-readiness"]
|
|
13870
|
+
},
|
|
13871
|
+
{
|
|
13872
|
+
id: "recover-remote-approval",
|
|
13873
|
+
title: "Recover Remote Approval",
|
|
13874
|
+
operatorQuestion: "The browser is remote or local callback is not viable, so approval must move to the hosted relay path.",
|
|
13875
|
+
useWhen: "Use this when a writable session must be recovered through the single-host hosted relay baseline.",
|
|
13876
|
+
startCommand: hostedRelayInspectCommand,
|
|
13877
|
+
surface: "relay",
|
|
13878
|
+
categoryIds: ["recover"],
|
|
13879
|
+
entryIds: ["hosted-approval-recovery"]
|
|
13880
|
+
}
|
|
13881
|
+
];
|
|
13882
|
+
const recommendedJourney = {
|
|
13883
|
+
id: journeys[0].id,
|
|
13884
|
+
title: journeys[0].title,
|
|
13885
|
+
startCommand: journeys[0].startCommand,
|
|
13886
|
+
surface: journeys[0].surface,
|
|
13887
|
+
useWhen: journeys[0].useWhen
|
|
13888
|
+
};
|
|
12857
13889
|
return {
|
|
12858
13890
|
ok: true,
|
|
12859
13891
|
summary: {
|
|
12860
13892
|
suiteId: "zk-agent-operator-suite",
|
|
13893
|
+
catalogView: "operator-catalog",
|
|
12861
13894
|
walletName,
|
|
12862
13895
|
chain,
|
|
12863
13896
|
stage: "wallet-ready-post-flagship",
|
|
12864
|
-
useWhen: "Use suite after wallet readiness when you want one packaged surface for flagship pay plus the current post-flagship discovery, paymaster, and
|
|
13897
|
+
useWhen: "Use suite after wallet readiness when you want one packaged surface for flagship pay plus the current post-flagship discovery, paymaster, funding, and hosted recovery slices.",
|
|
13898
|
+
entryModes: ["local-first", "hosted-recovery"],
|
|
13899
|
+
startHereJourneyId: recommendedJourney.id,
|
|
13900
|
+
journeyOrder: journeys.map((entry) => entry.id),
|
|
13901
|
+
surfaceOrder: ["workflow", "discovery", "relay"],
|
|
13902
|
+
categoryOrder: [flagship.category, ...slices.map((entry) => entry.category)],
|
|
12865
13903
|
flagshipId: flagship.id,
|
|
12866
13904
|
postFlagshipSliceIds: slices.map((entry) => entry.id),
|
|
12867
13905
|
recommendedOrder: [flagship.id, ...slices.map((entry) => entry.id)],
|
|
12868
13906
|
nextAction: flagship.primaryCommand
|
|
12869
13907
|
},
|
|
13908
|
+
...preflight ? { preflight } : {},
|
|
13909
|
+
recommendedJourney,
|
|
13910
|
+
journeys,
|
|
13911
|
+
surfaces,
|
|
12870
13912
|
flagship,
|
|
12871
13913
|
slices,
|
|
12872
13914
|
recommendedCommands: {
|
|
12873
|
-
suite:
|
|
13915
|
+
suite: suiteCommand,
|
|
12874
13916
|
flagship: flagshipCommand,
|
|
13917
|
+
workflowSurface: workflowSurfaceCommand,
|
|
13918
|
+
discoverySurface: inspectDefaults,
|
|
13919
|
+
relaySurface: relaySurfaceCommand,
|
|
12875
13920
|
discovery: discoveryCommand,
|
|
12876
13921
|
paymaster: paymasterCommand,
|
|
12877
13922
|
funding: fundingCommand,
|
|
13923
|
+
hostedApproval: hostedRelayInspectCommand,
|
|
12878
13924
|
inspectDefaults
|
|
12879
13925
|
}
|
|
12880
13926
|
};
|
|
12881
13927
|
}
|
|
12882
13928
|
function operatorSuiteLines(payload) {
|
|
13929
|
+
const preflightLines = payload.preflight ? [
|
|
13930
|
+
["preflight", formatRecommendedPath(payload.preflight.localPath)],
|
|
13931
|
+
...payload.preflight.remoteBrowserPath?.length ? [["preflight (remote-browser)", formatRecommendedPath(payload.preflight.remoteBrowserPath)]] : [],
|
|
13932
|
+
["preflight when", payload.preflight.useWhen],
|
|
13933
|
+
["preflight diagnose", payload.preflight.diagnosticCommand],
|
|
13934
|
+
["preflight handoff", payload.preflight.afterWalletReady]
|
|
13935
|
+
] : [];
|
|
13936
|
+
const journeyLines = payload.journeys.flatMap((journey) => [
|
|
13937
|
+
[`journey ${journey.id}`, journey.startCommand],
|
|
13938
|
+
[`journey ${journey.id} surface`, journey.surface],
|
|
13939
|
+
[`journey ${journey.id} categories`, journey.categoryIds.join(" -> ")],
|
|
13940
|
+
[`journey ${journey.id} entries`, journey.entryIds.join(" -> ")],
|
|
13941
|
+
[`journey ${journey.id} when`, journey.useWhen]
|
|
13942
|
+
]);
|
|
12883
13943
|
const sliceLines = payload.slices.flatMap((entry) => [
|
|
13944
|
+
[`${entry.title.toLowerCase()} category`, entry.category],
|
|
13945
|
+
[`${entry.title.toLowerCase()} surface`, entry.surface],
|
|
13946
|
+
[`${entry.title.toLowerCase()} surface command`, entry.surfaceCommand],
|
|
12884
13947
|
[entry.title.toLowerCase(), formatRecommendedPath([entry.primaryCommand, ...entry.supportingCommands])],
|
|
12885
13948
|
[`${entry.title.toLowerCase()} when`, entry.useWhen],
|
|
12886
13949
|
[`${entry.title.toLowerCase()} skill`, entry.skillPath],
|
|
12887
13950
|
...entry.smokeCommand ? [[`${entry.title.toLowerCase()} smoke`, entry.smokeCommand]] : []
|
|
12888
13951
|
]);
|
|
13952
|
+
const surfaceLines = payload.surfaces.flatMap((surface) => [
|
|
13953
|
+
[`${surface.surface} surface`, surface.command],
|
|
13954
|
+
[`${surface.surface} surface categories`, surface.categoryIds.join(" -> ")],
|
|
13955
|
+
[`${surface.surface} surface entries`, surface.entryIds.join(" -> ")],
|
|
13956
|
+
[`${surface.surface} surface when`, surface.useWhen]
|
|
13957
|
+
]);
|
|
12889
13958
|
return [
|
|
12890
13959
|
["suite", payload.summary.suiteId],
|
|
13960
|
+
["catalog", payload.summary.catalogView],
|
|
12891
13961
|
["wallet", payload.summary.walletName],
|
|
12892
13962
|
["chain", payload.summary.chain],
|
|
12893
13963
|
["stage", payload.summary.stage],
|
|
12894
13964
|
["use when", payload.summary.useWhen],
|
|
13965
|
+
["entry modes", payload.summary.entryModes.join(" -> ")],
|
|
13966
|
+
["start here journey", payload.summary.startHereJourneyId],
|
|
13967
|
+
["start here", payload.recommendedJourney.startCommand],
|
|
13968
|
+
["start here surface", payload.recommendedJourney.surface],
|
|
13969
|
+
["start here when", payload.recommendedJourney.useWhen],
|
|
13970
|
+
["journey order", payload.summary.journeyOrder.join(" -> ")],
|
|
13971
|
+
["surface order", payload.summary.surfaceOrder.join(" -> ")],
|
|
13972
|
+
["category order", payload.summary.categoryOrder.join(" -> ")],
|
|
13973
|
+
...preflightLines,
|
|
13974
|
+
...journeyLines,
|
|
13975
|
+
...surfaceLines,
|
|
12895
13976
|
["recommended order", payload.summary.recommendedOrder.join(" -> ")],
|
|
12896
|
-
[payload.flagship.title.toLowerCase()
|
|
13977
|
+
[`${payload.flagship.title.toLowerCase()} category`, payload.flagship.category],
|
|
13978
|
+
[`${payload.flagship.title.toLowerCase()} surface`, payload.flagship.surface],
|
|
13979
|
+
[`${payload.flagship.title.toLowerCase()} surface command`, payload.flagship.surfaceCommand],
|
|
13980
|
+
[
|
|
13981
|
+
payload.flagship.title.toLowerCase(),
|
|
13982
|
+
formatRecommendedPath([
|
|
13983
|
+
payload.flagship.primaryCommand,
|
|
13984
|
+
buildTopLevelNextRecommendedCommand(void 0, void 0, payload.summary.walletName)
|
|
13985
|
+
])
|
|
13986
|
+
],
|
|
12897
13987
|
[`${payload.flagship.title.toLowerCase()} when`, payload.flagship.useWhen],
|
|
12898
13988
|
[`${payload.flagship.title.toLowerCase()} skill`, payload.flagship.skillPath],
|
|
12899
13989
|
...sliceLines,
|
|
@@ -12903,35 +13993,70 @@ function operatorSuiteLines(payload) {
|
|
|
12903
13993
|
|
|
12904
13994
|
// src/commands/suite.ts
|
|
12905
13995
|
function createSuiteCommand() {
|
|
12906
|
-
return new
|
|
13996
|
+
return new Command9("suite").description("Show the flagship and post-flagship zkSync-native operator suite").option("--wallet <name>", "Wallet name used in example commands", "main").option("--chain <chain>", "Chain key used in example commands", "zksync-sepolia").option("--include-onboarding", "Include the first-run preflight and wallet-bootstrap map", false).addHelpText(
|
|
12907
13997
|
"after",
|
|
12908
13998
|
[
|
|
12909
13999
|
"",
|
|
12910
14000
|
" Use `suite` after wallet readiness when you want one packaged surface",
|
|
12911
14001
|
" for flagship pay plus the current post-flagship slices.",
|
|
12912
14002
|
"",
|
|
14003
|
+
" What `suite` answers right now:",
|
|
14004
|
+
" operate: send native value through the flagship workflow path",
|
|
14005
|
+
" discover: inspect owned assets and defaults before tokenized actions",
|
|
14006
|
+
" pay: stay on the approval-based paymaster path with exact fee-token follow-up",
|
|
14007
|
+
" fund: recover from gas/funding blockers without guessing the route",
|
|
14008
|
+
" recover: switch to hosted relay approval when the browser is remote",
|
|
14009
|
+
"",
|
|
14010
|
+
" Most common operator journeys:",
|
|
14011
|
+
" send value now: go straight to the flagship pay path",
|
|
14012
|
+
" inspect before acting: open assets/defaults/token inspection first",
|
|
14013
|
+
" unstick a write: recover paymaster/funding readiness on the workflow path",
|
|
14014
|
+
" recover remote approval: move approval to the hosted relay path",
|
|
14015
|
+
"",
|
|
14016
|
+
" If you only need one default starting point inside suite:",
|
|
14017
|
+
" send value now",
|
|
14018
|
+
"",
|
|
14019
|
+
" Where `suite` hands you off next:",
|
|
14020
|
+
" workflow: flagship pay, approval-based pay, and funding recovery",
|
|
14021
|
+
" discovery: assets, defaults, and token inspection",
|
|
14022
|
+
" relay: hosted approval recovery and relay readiness",
|
|
14023
|
+
"",
|
|
14024
|
+
" For the full first-run to post-flagship map:",
|
|
14025
|
+
" zk-agent suite --include-onboarding",
|
|
14026
|
+
"",
|
|
12913
14027
|
" Recommended order inside the suite:",
|
|
12914
14028
|
" zk-agent workflow pay --wallet main --to <address> --amount <amount>",
|
|
12915
14029
|
" zk-agent assets --wallet main",
|
|
12916
14030
|
" zk-agent workflow pay --wallet main --to <address> --amount <amount> --paymaster-mode approval-based",
|
|
12917
14031
|
" zk-agent workflow fund --wallet main",
|
|
14032
|
+
" zk-agent relay inspect --relay-url <url>",
|
|
12918
14033
|
"",
|
|
12919
14034
|
" Pass `--wallet` or `--chain` to retarget the entire suite contract.",
|
|
14035
|
+
" Pass `--include-onboarding` when you want setup, doctor, and wallet bootstrap",
|
|
14036
|
+
" guidance in the same packaged readout.",
|
|
12920
14037
|
"",
|
|
12921
|
-
" In JSON mode, `summary.
|
|
12922
|
-
"
|
|
14038
|
+
" In JSON mode, `summary.catalogView`, `summary.entryModes`,",
|
|
14039
|
+
" `summary.startHereJourneyId`, `summary.journeyOrder`,",
|
|
14040
|
+
" `summary.surfaceOrder`, top-level `recommendedJourney`, top-level",
|
|
14041
|
+
" `journeys[]`, top-level `surfaces[]`, `summary.categoryOrder`,",
|
|
14042
|
+
" `summary.recommendedOrder`, optional `preflight`, and each entry",
|
|
14043
|
+
" `category` + `surface` + `surfaceCommand` + `useWhen` field explain",
|
|
14044
|
+
" which slice to choose and which deeper surface owns it next.",
|
|
14045
|
+
" `recommendedCommands.workflowSurface|discoverySurface|relaySurface`",
|
|
14046
|
+
" expose the direct deeper-surface entry commands."
|
|
12923
14047
|
].join("\n")
|
|
12924
14048
|
).action((options) => {
|
|
12925
14049
|
const payload = buildOperatorSuitePayload({
|
|
12926
14050
|
walletName: options.wallet,
|
|
12927
|
-
chain: options.chain
|
|
14051
|
+
chain: options.chain,
|
|
14052
|
+
includeOnboarding: options.includeOnboarding
|
|
12928
14053
|
});
|
|
12929
14054
|
printResult(operatorSuiteLines(payload), payload);
|
|
12930
14055
|
});
|
|
12931
14056
|
}
|
|
12932
14057
|
|
|
12933
14058
|
// src/commands/tokens.ts
|
|
12934
|
-
import { Command as
|
|
14059
|
+
import { Command as Command10 } from "commander";
|
|
12935
14060
|
var provider2 = new ZkSyncWalletProvider();
|
|
12936
14061
|
function resolveTokensCommandDeps(deps) {
|
|
12937
14062
|
return {
|
|
@@ -13061,7 +14186,7 @@ function buildTokenDiscoverySummary(result) {
|
|
|
13061
14186
|
}
|
|
13062
14187
|
function createTokensCommand(deps) {
|
|
13063
14188
|
const resolvedDeps = resolveTokensCommandDeps(deps);
|
|
13064
|
-
return new
|
|
14189
|
+
return new Command10("tokens").description("List discoverable tokens from the configured local-first token registry, or inspect the owned ERC-20 registry subset for one wallet").addHelpText(
|
|
13065
14190
|
"after",
|
|
13066
14191
|
[
|
|
13067
14192
|
"",
|
|
@@ -13266,7 +14391,7 @@ function normalizeRole2(value) {
|
|
|
13266
14391
|
}
|
|
13267
14392
|
|
|
13268
14393
|
// src/commands/relay.ts
|
|
13269
|
-
import { Command as
|
|
14394
|
+
import { Command as Command11 } from "commander";
|
|
13270
14395
|
|
|
13271
14396
|
// src/lib/relay.ts
|
|
13272
14397
|
import { createServer } from "node:http";
|
|
@@ -14131,14 +15256,18 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
14131
15256
|
};
|
|
14132
15257
|
}
|
|
14133
15258
|
function createRelayCommand() {
|
|
14134
|
-
const relay = new
|
|
15259
|
+
const relay = new Command11("relay").description(
|
|
14135
15260
|
"Serve and inspect the single-host connector relay baseline for hosted approval"
|
|
14136
15261
|
);
|
|
14137
15262
|
relay.addHelpText(
|
|
14138
15263
|
"after",
|
|
14139
15264
|
[
|
|
14140
15265
|
"",
|
|
14141
|
-
"
|
|
15266
|
+
" Relay surface:",
|
|
15267
|
+
" Use this layer only when approval must happen through a publicly reachable hosted path.",
|
|
15268
|
+
" Keep `wallet create|reapprove --await-local` as the default baseline when the browser and terminal are colocated.",
|
|
15269
|
+
"",
|
|
15270
|
+
" Hosted remote-approval path today:",
|
|
14142
15271
|
" zk-agent relay serve --public-origin https://relay.example.com",
|
|
14143
15272
|
" zk-agent relay inspect --relay-url <url>",
|
|
14144
15273
|
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
@@ -14150,9 +15279,6 @@ function createRelayCommand() {
|
|
|
14150
15279
|
" one same-origin share-link + approval UI surface",
|
|
14151
15280
|
" Do not assume multi-host or load-balanced durability.",
|
|
14152
15281
|
"",
|
|
14153
|
-
" Keep `wallet create|reapprove --await-local` as the default baseline when",
|
|
14154
|
-
" the browser and terminal are colocated.",
|
|
14155
|
-
"",
|
|
14156
15282
|
" Use `relay inspect` before sending operators to a hosted share link so",
|
|
14157
15283
|
" the public origin, connector UI, and hosted-readiness contract are visible."
|
|
14158
15284
|
].join("\n")
|
|
@@ -14392,7 +15518,7 @@ function createRelayCommand() {
|
|
|
14392
15518
|
// src/commands/wallet.ts
|
|
14393
15519
|
import { createServer as createServer2 } from "node:http";
|
|
14394
15520
|
import { createInterface } from "node:readline/promises";
|
|
14395
|
-
import { Command as
|
|
15521
|
+
import { Command as Command12 } from "commander";
|
|
14396
15522
|
|
|
14397
15523
|
// ../account-profiles/src/profiles.ts
|
|
14398
15524
|
import fs8 from "node:fs";
|
|
@@ -14977,8 +16103,9 @@ function stripSensitiveWalletRecord(wallet) {
|
|
|
14977
16103
|
};
|
|
14978
16104
|
}
|
|
14979
16105
|
function sanitizeWalletRecord(wallet) {
|
|
16106
|
+
const { walletId: _walletId, ...rest } = stripSensitiveWalletRecord(wallet);
|
|
14980
16107
|
return {
|
|
14981
|
-
...
|
|
16108
|
+
...rest,
|
|
14982
16109
|
sessionPayload: sanitizeSessionPayload(wallet.sessionPayload)
|
|
14983
16110
|
};
|
|
14984
16111
|
}
|
|
@@ -17059,62 +18186,62 @@ async function printBuiltinSmartAccountProfiles() {
|
|
|
17059
18186
|
}
|
|
17060
18187
|
function createWalletCommand(deps) {
|
|
17061
18188
|
const resolvedDeps = resolveWalletCommandDeps(deps);
|
|
17062
|
-
const wallet = new
|
|
18189
|
+
const wallet = new Command12("wallet").description(
|
|
17063
18190
|
"Create, inspect, and recover local-first wallet sessions"
|
|
17064
18191
|
);
|
|
17065
|
-
const request = new
|
|
17066
|
-
const signer = new
|
|
18192
|
+
const request = new Command12("request").description("Inspect and finalize pending wallet requests");
|
|
18193
|
+
const signer = new Command12("signer").description(
|
|
17067
18194
|
"Inspect and manage the stored local execution signer for a wallet"
|
|
17068
18195
|
);
|
|
17069
|
-
const smartAccount = new
|
|
18196
|
+
const smartAccount = new Command12("smart-account").description(
|
|
17070
18197
|
"Predict and deploy zkSync smart-account contracts from a supplied artifact or built-in profile"
|
|
17071
18198
|
);
|
|
17072
|
-
const sedLite = new
|
|
18199
|
+
const sedLite = new Command12("sed-lite").description(
|
|
17073
18200
|
"Inspect and manage the SED modular smart-account profile"
|
|
17074
18201
|
);
|
|
17075
|
-
const nativeCapHook = new
|
|
18202
|
+
const nativeCapHook = new Command12("native-cap-hook").description(
|
|
17076
18203
|
"Inspect and manage the first SED Lite validation-hook policy: native per-transaction spend caps"
|
|
17077
18204
|
);
|
|
17078
|
-
const targetAllowlistHook = new
|
|
18205
|
+
const targetAllowlistHook = new Command12("target-allowlist-hook").description(
|
|
17079
18206
|
"Inspect and manage the SED Lite validation-hook policy that restricts transactions to an allowlisted target set"
|
|
17080
18207
|
);
|
|
17081
|
-
const selectorAllowlistHook = new
|
|
18208
|
+
const selectorAllowlistHook = new Command12("selector-allowlist-hook").description(
|
|
17082
18209
|
"Inspect and manage the SED Lite validation-hook policy that restricts contract calls to allowlisted target and selector pairs"
|
|
17083
18210
|
);
|
|
17084
|
-
const dailySpendLimit = new
|
|
18211
|
+
const dailySpendLimit = new Command12("daily-spend-limit").description(
|
|
17085
18212
|
"Read and update the native-token daily spend limit used by the built-in daily-spend-limit smart-account profile"
|
|
17086
18213
|
);
|
|
17087
|
-
const paymaster = new
|
|
18214
|
+
const paymaster = new Command12("paymaster").description(
|
|
17088
18215
|
"Manage saved paymaster defaults for stored wallets"
|
|
17089
18216
|
);
|
|
17090
18217
|
wallet.addHelpText(
|
|
17091
18218
|
"after",
|
|
17092
18219
|
[
|
|
17093
18220
|
"",
|
|
17094
|
-
"
|
|
17095
|
-
" Use this layer when the blocker is specifically
|
|
17096
|
-
"
|
|
18221
|
+
"Wallet surface:",
|
|
18222
|
+
" Use this layer when the blocker is specifically wallet approval, signer state, or session recovery.",
|
|
18223
|
+
" If the CLI still needs to decide whether the problem is setup, wallet readiness, or workflow continuation, start with `zk-agent next` or `zk-agent doctor`.",
|
|
17097
18224
|
"",
|
|
17098
|
-
" First bootstrap:",
|
|
18225
|
+
" First local-first bootstrap:",
|
|
17099
18226
|
" zk-agent wallet create --await-local",
|
|
17100
18227
|
" zk-agent next",
|
|
17101
18228
|
"",
|
|
17102
|
-
"
|
|
18229
|
+
" Repair an existing wallet session:",
|
|
17103
18230
|
" zk-agent wallet reapprove --name main --await-local",
|
|
17104
18231
|
" zk-agent next",
|
|
17105
18232
|
"",
|
|
17106
|
-
"
|
|
18233
|
+
" Repair signer-only local execution state:",
|
|
17107
18234
|
" zk-agent wallet signer attach --name main --private-key <hex>",
|
|
17108
18235
|
" zk-agent next",
|
|
17109
18236
|
"",
|
|
17110
|
-
" Wallet-
|
|
18237
|
+
" Wallet-scoped diagnosis:",
|
|
17111
18238
|
" zk-agent wallet status --name main",
|
|
17112
18239
|
" zk-agent wallet next --name main",
|
|
17113
18240
|
"",
|
|
17114
|
-
"
|
|
18241
|
+
" Switch to the packaged catalog after wallet readiness:",
|
|
17115
18242
|
" zk-agent suite",
|
|
17116
18243
|
"",
|
|
17117
|
-
" Hosted remote approval
|
|
18244
|
+
" Hosted remote approval only when the browser is remote:",
|
|
17118
18245
|
" zk-agent relay inspect --relay-url <url>",
|
|
17119
18246
|
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
17120
18247
|
" zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
|
|
@@ -17592,6 +18719,13 @@ function createWalletCommand(deps) {
|
|
|
17592
18719
|
wallet.command("list").description("List stored wallets").action(async () => printWalletList());
|
|
17593
18720
|
wallet.command("rename").description("Rename a stored wallet and update any local pending requests that reference it").option("--name <name>", "Current wallet name", "main").requiredOption("--new-name <name>", "New wallet name").action(async (options) => {
|
|
17594
18721
|
const result = await renameWalletSession(options.name, options.newName);
|
|
18722
|
+
const updatedPaymentRequestIds = await renamePaymentRequestWalletReferences(
|
|
18723
|
+
{
|
|
18724
|
+
walletId: result.wallet.walletId,
|
|
18725
|
+
previousWalletName: options.name,
|
|
18726
|
+
nextWalletName: options.newName
|
|
18727
|
+
}
|
|
18728
|
+
);
|
|
17595
18729
|
printResult(
|
|
17596
18730
|
[
|
|
17597
18731
|
["status", "Wallet renamed"],
|
|
@@ -17599,6 +18733,7 @@ function createWalletCommand(deps) {
|
|
|
17599
18733
|
["to", result.wallet.walletName],
|
|
17600
18734
|
["address", result.wallet.walletAddress],
|
|
17601
18735
|
["requests updated", String(result.updatedRequestIds.length)],
|
|
18736
|
+
["payment requests updated", String(updatedPaymentRequestIds.length)],
|
|
17602
18737
|
["workflow checkpoints updated", String(result.updatedWorkflowRequestIds.length)],
|
|
17603
18738
|
...walletFollowUpLines(result.wallet)
|
|
17604
18739
|
],
|
|
@@ -17608,6 +18743,7 @@ function createWalletCommand(deps) {
|
|
|
17608
18743
|
previousWalletName: options.name,
|
|
17609
18744
|
wallet: sanitizeWalletRecord(result.wallet),
|
|
17610
18745
|
updatedRequestIds: result.updatedRequestIds,
|
|
18746
|
+
updatedPaymentRequestIds,
|
|
17611
18747
|
updatedWorkflowRequestIds: result.updatedWorkflowRequestIds,
|
|
17612
18748
|
recommendedCommands: buildWalletFollowUpRecommendedCommands(result.wallet)
|
|
17613
18749
|
}
|
|
@@ -17713,7 +18849,8 @@ function createWalletCommand(deps) {
|
|
|
17713
18849
|
currentSurface: "wallet",
|
|
17714
18850
|
recommendedNow: summary.status === "ready",
|
|
17715
18851
|
walletName: walletRecord.walletName,
|
|
17716
|
-
chain: summary.chain
|
|
18852
|
+
chain: summary.chain,
|
|
18853
|
+
recommendedJourneyId: summary.status === "ready" ? "send-value-now" : null
|
|
17717
18854
|
});
|
|
17718
18855
|
printResult(
|
|
17719
18856
|
[
|
|
@@ -17756,7 +18893,8 @@ function createWalletCommand(deps) {
|
|
|
17756
18893
|
currentSurface: "wallet",
|
|
17757
18894
|
recommendedNow: summary.status === "ready",
|
|
17758
18895
|
walletName: walletRecord.walletName,
|
|
17759
|
-
chain: summary.chain
|
|
18896
|
+
chain: summary.chain,
|
|
18897
|
+
recommendedJourneyId: summary.status === "ready" ? "send-value-now" : null
|
|
17760
18898
|
});
|
|
17761
18899
|
printResult(
|
|
17762
18900
|
[
|
|
@@ -19731,8 +20869,8 @@ function createWalletCommand(deps) {
|
|
|
19731
20869
|
}
|
|
19732
20870
|
|
|
19733
20871
|
// src/commands/workflow.ts
|
|
19734
|
-
import { randomBytes as
|
|
19735
|
-
import { Command as
|
|
20872
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
20873
|
+
import { Command as Command13 } from "commander";
|
|
19736
20874
|
var defaultProvider2 = new ZkSyncWalletProvider();
|
|
19737
20875
|
var defaultDefiProvider2 = new ZkSyncDefiProvider({
|
|
19738
20876
|
walletWriter: defaultProvider2
|
|
@@ -19799,7 +20937,7 @@ function parseBooleanString(value, label) {
|
|
|
19799
20937
|
throw new Error(`${label} must be true or false`);
|
|
19800
20938
|
}
|
|
19801
20939
|
function generateWorkflowRequestId() {
|
|
19802
|
-
return
|
|
20940
|
+
return randomBytes6(4).toString("hex");
|
|
19803
20941
|
}
|
|
19804
20942
|
async function reserveWorkflowRequestId(requestId) {
|
|
19805
20943
|
const explicit = requestId?.trim();
|
|
@@ -21438,25 +22576,26 @@ function assertWorkflowResumeReady(result) {
|
|
|
21438
22576
|
function buildWorkflowHelpText() {
|
|
21439
22577
|
return [
|
|
21440
22578
|
"",
|
|
21441
|
-
"
|
|
22579
|
+
" Workflow surface:",
|
|
22580
|
+
" Use this layer when the question is already an explicit workflow, checkpoint, or execution state.",
|
|
22581
|
+
" If the CLI still needs to choose across setup, wallet readiness, or recovery, go back to `zk-agent next` or `zk-agent doctor`.",
|
|
22582
|
+
"",
|
|
22583
|
+
" Fastest flagship pay path:",
|
|
21442
22584
|
" zk-agent workflow pay --wallet main --to <address> --amount <amount>",
|
|
21443
22585
|
"",
|
|
21444
|
-
"
|
|
22586
|
+
" Multi-intent guided path:",
|
|
21445
22587
|
" zk-agent workflow auto --wallet main --intent <intent> [goal flags] --create-checkpoint --execute-when-ready",
|
|
21446
22588
|
"",
|
|
21447
|
-
"
|
|
22589
|
+
" Checkpoint lifecycle when you want explicit control:",
|
|
21448
22590
|
" zk-agent workflow start --wallet main --intent <intent> [goal flags]",
|
|
21449
22591
|
" zk-agent workflow status --request-id <id>",
|
|
21450
22592
|
" zk-agent workflow next --request-id <id>",
|
|
21451
22593
|
" zk-agent workflow resume --request-id <id> [--broadcast]",
|
|
21452
22594
|
"",
|
|
21453
|
-
"
|
|
21454
|
-
" zk-agent suite",
|
|
21455
|
-
"",
|
|
21456
|
-
" Funding-only step:",
|
|
22595
|
+
" Funding-only recovery when execution is blocked on gas:",
|
|
21457
22596
|
" zk-agent workflow fund --wallet main --amount <amount> --execute",
|
|
21458
22597
|
"",
|
|
21459
|
-
"
|
|
22598
|
+
" Discovery / token recovery before the workflow can continue:",
|
|
21460
22599
|
" zk-agent assets --wallet main",
|
|
21461
22600
|
" zk-agent tokens --wallet main --owned",
|
|
21462
22601
|
" zk-agent tokens --chain zksync-sepolia",
|
|
@@ -21467,6 +22606,9 @@ function buildWorkflowHelpText() {
|
|
|
21467
22606
|
" zk-agent resolve-token --chain zksync-sepolia --symbol <symbol> --role paymaster-fee-token",
|
|
21468
22607
|
" zk-agent defaults",
|
|
21469
22608
|
"",
|
|
22609
|
+
" When the question becomes broader than one explicit workflow:",
|
|
22610
|
+
" zk-agent suite",
|
|
22611
|
+
"",
|
|
21470
22612
|
" Lower-level one-shot escape hatch:",
|
|
21471
22613
|
" zk-agent workflow run --wallet main --intent <intent> [goal flags]"
|
|
21472
22614
|
].join("\n");
|
|
@@ -21501,7 +22643,7 @@ function applyWorkflowHelpCommandOrder(workflow) {
|
|
|
21501
22643
|
}
|
|
21502
22644
|
function createWorkflowCommand(deps) {
|
|
21503
22645
|
const resolvedDeps = resolveWorkflowCommandDeps(deps);
|
|
21504
|
-
const workflow = new
|
|
22646
|
+
const workflow = new Command13("workflow").description(
|
|
21505
22647
|
"Plan, persist, and execute higher-level wallet workflows"
|
|
21506
22648
|
);
|
|
21507
22649
|
workflow.addHelpText("after", buildWorkflowHelpText());
|
|
@@ -22187,6 +23329,23 @@ function buildDefaultOperatorPathHelpText() {
|
|
|
22187
23329
|
"",
|
|
22188
23330
|
"Operator suite beyond flagship pay:",
|
|
22189
23331
|
" zk-agent suite",
|
|
23332
|
+
" zk-agent suite --include-onboarding",
|
|
23333
|
+
"",
|
|
23334
|
+
"First local Agent Pay primitive:",
|
|
23335
|
+
" zk-agent payment create --wallet main --to <address> --amount <amount>",
|
|
23336
|
+
" zk-agent payment list",
|
|
23337
|
+
"",
|
|
23338
|
+
"Product routing by operator question:",
|
|
23339
|
+
" next -> bootstrap | recover | operate | workflow",
|
|
23340
|
+
" suite -> operate | discover | pay | fund | recover",
|
|
23341
|
+
"",
|
|
23342
|
+
"Payment-first default path after wallet readiness:",
|
|
23343
|
+
" send native value now -> stay on approval-based pay when fee-token/default state matters -> recover funding only when blocked",
|
|
23344
|
+
" Default start inside suite: send value now",
|
|
23345
|
+
"",
|
|
23346
|
+
"Use `next` while the CLI still needs to choose across setup, wallet readiness, or stored workflow continuation.",
|
|
23347
|
+
"Use `suite` once wallet readiness is no longer the blocker and you want the packaged post-flagship surface.",
|
|
23348
|
+
"Use `zk-agent suite --include-onboarding` when you want one readout from first-run bootstrap through the packaged operator catalog.",
|
|
22190
23349
|
"",
|
|
22191
23350
|
"Validated first-run baseline:",
|
|
22192
23351
|
" setup defaults to zksync-sepolia and the local connector at http://localhost:4444",
|
|
@@ -22211,6 +23370,7 @@ var ROOT_HELP_COMMAND_ORDER = [
|
|
|
22211
23370
|
"wallet",
|
|
22212
23371
|
"workflow",
|
|
22213
23372
|
"suite",
|
|
23373
|
+
"payment",
|
|
22214
23374
|
"assets",
|
|
22215
23375
|
"balances",
|
|
22216
23376
|
"fund",
|
|
@@ -22244,7 +23404,7 @@ function applyRootHelpCommandOrder(program) {
|
|
|
22244
23404
|
program.commands = sortedCommands;
|
|
22245
23405
|
}
|
|
22246
23406
|
function createProgram() {
|
|
22247
|
-
const program = new
|
|
23407
|
+
const program = new Command14().name("zk-agent").description(
|
|
22248
23408
|
"Local-first zkSync-native CLI for wallet approval, workflow execution, and single-host hosted relay recovery"
|
|
22249
23409
|
).showHelpAfterError().option("--json", "Force JSON output for agent harnesses", false).hook("preAction", (thisCommand) => {
|
|
22250
23410
|
if (thisCommand.optsWithGlobals().json) process.env.ZK_AGENT_OUTPUT = "json";
|
|
@@ -22255,6 +23415,7 @@ function createProgram() {
|
|
|
22255
23415
|
program.addCommand(createAgentCommand());
|
|
22256
23416
|
program.addCommand(createDefaultsCommand());
|
|
22257
23417
|
program.addCommand(createSuiteCommand());
|
|
23418
|
+
program.addCommand(createPaymentCommand());
|
|
22258
23419
|
program.addCommand(createTokensCommand());
|
|
22259
23420
|
program.addCommand(createResolveTokenCommand());
|
|
22260
23421
|
program.addCommand(createRelayCommand());
|