zk-agent-cli 0.1.0-beta.7 → 0.1.0-beta.9
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 +82 -2
- package/dist/index.js +1291 -80
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7722,6 +7722,10 @@ function formatHumanErrorMessage(error) {
|
|
|
7722
7722
|
pushDetailLine(lines, "reason", details.reason);
|
|
7723
7723
|
pushDetailLine(lines, "note", details.note);
|
|
7724
7724
|
pushDetailLine(lines, "suggested action", details.suggestedAction);
|
|
7725
|
+
pushDetailLine(lines, "status command", details.statusCommand);
|
|
7726
|
+
pushDetailLine(lines, "approve command", details.approveCommand);
|
|
7727
|
+
pushDetailLine(lines, "relay inspect command", details.relayInspectCommand);
|
|
7728
|
+
pushDetailLine(lines, "reissue remote approval command", details.reissueRemoteApprovalCommand);
|
|
7725
7729
|
pushDetailLine(lines, "validation domain", details.validationDomain);
|
|
7726
7730
|
pushDetailLine(lines, "validation stage", details.validationStage);
|
|
7727
7731
|
const validation = asRecord2(details.validation);
|
|
@@ -7741,6 +7745,71 @@ function formatHumanErrorMessage(error) {
|
|
|
7741
7745
|
return lines.join("\n");
|
|
7742
7746
|
}
|
|
7743
7747
|
|
|
7748
|
+
// src/lib/discovery-summary.ts
|
|
7749
|
+
function createEmptyDiscoverySourceCounts() {
|
|
7750
|
+
return {
|
|
7751
|
+
localDeployments: 0,
|
|
7752
|
+
tokenDirectory: 0,
|
|
7753
|
+
unknown: 0
|
|
7754
|
+
};
|
|
7755
|
+
}
|
|
7756
|
+
function createEmptyDiscoveryRoleCounts() {
|
|
7757
|
+
return Object.fromEntries(
|
|
7758
|
+
REGISTRY_TOKEN_ROLES.map((role) => [role, 0])
|
|
7759
|
+
);
|
|
7760
|
+
}
|
|
7761
|
+
function summarizeDiscoveryEntrySources(entries) {
|
|
7762
|
+
const counts = createEmptyDiscoverySourceCounts();
|
|
7763
|
+
for (const entry of entries) {
|
|
7764
|
+
if (entry.source === "local-deployments") {
|
|
7765
|
+
counts.localDeployments += 1;
|
|
7766
|
+
continue;
|
|
7767
|
+
}
|
|
7768
|
+
if (entry.source === "token-directory") {
|
|
7769
|
+
counts.tokenDirectory += 1;
|
|
7770
|
+
continue;
|
|
7771
|
+
}
|
|
7772
|
+
counts.unknown += 1;
|
|
7773
|
+
}
|
|
7774
|
+
return counts;
|
|
7775
|
+
}
|
|
7776
|
+
function summarizeDiscoveryRoleMatches(entries) {
|
|
7777
|
+
const counts = createEmptyDiscoveryRoleCounts();
|
|
7778
|
+
for (const entry of entries) {
|
|
7779
|
+
for (const match of entry.defaultsRegistryMatches || []) {
|
|
7780
|
+
counts[match.role] += 1;
|
|
7781
|
+
}
|
|
7782
|
+
}
|
|
7783
|
+
return counts;
|
|
7784
|
+
}
|
|
7785
|
+
function countCurrentValidatedDefaultEntries(entries) {
|
|
7786
|
+
return entries.filter(
|
|
7787
|
+
(entry) => (entry.defaultsRegistryMatches || []).some((match) => match.isCurrentValidatedDefault)
|
|
7788
|
+
).length;
|
|
7789
|
+
}
|
|
7790
|
+
function listUniqueDiscoveryChains(entries) {
|
|
7791
|
+
return [...new Set(
|
|
7792
|
+
entries.map((entry) => entry.chainKey?.trim()).filter((value) => Boolean(value))
|
|
7793
|
+
)];
|
|
7794
|
+
}
|
|
7795
|
+
function firstDiscoverySymbol(entries) {
|
|
7796
|
+
return entries.find((entry) => entry.symbol?.trim())?.symbol?.trim() || null;
|
|
7797
|
+
}
|
|
7798
|
+
function firstDiscoverySource(entries) {
|
|
7799
|
+
if (entries.length === 0) return null;
|
|
7800
|
+
return entries[0]?.source || "unknown";
|
|
7801
|
+
}
|
|
7802
|
+
function summarizeTokenRegistrySources(sources) {
|
|
7803
|
+
return sources.map((source) => ({
|
|
7804
|
+
id: source.id,
|
|
7805
|
+
enabled: source.enabled,
|
|
7806
|
+
exists: source.exists
|
|
7807
|
+
}));
|
|
7808
|
+
}
|
|
7809
|
+
function findNativeBalance(balances) {
|
|
7810
|
+
return balances.find((balance) => balance.type === "native") || null;
|
|
7811
|
+
}
|
|
7812
|
+
|
|
7744
7813
|
// src/lib/recommended-commands.ts
|
|
7745
7814
|
function appendPaymasterMode(command, paymasterMode) {
|
|
7746
7815
|
if (!paymasterMode || paymasterMode === "none") {
|
|
@@ -7758,6 +7827,18 @@ function buildTopLevelNextRecommendedCommand(requestId, paymasterMode) {
|
|
|
7758
7827
|
function buildWalletCreateRecommendedCommand() {
|
|
7759
7828
|
return "zk-agent wallet create --await-local";
|
|
7760
7829
|
}
|
|
7830
|
+
function buildRelayInspectRecommendedCommand(relayUrl = "<url>") {
|
|
7831
|
+
return `zk-agent relay inspect --relay-url ${relayUrl}`;
|
|
7832
|
+
}
|
|
7833
|
+
function buildWalletCreateRemoteRecommendedCommand(relayUrl = "<url>", paymasterMode, walletName = "main", accountKind = "smart-account") {
|
|
7834
|
+
const command = [
|
|
7835
|
+
"zk-agent wallet create",
|
|
7836
|
+
walletName !== "main" ? `--name ${walletName}` : "",
|
|
7837
|
+
accountKind !== "smart-account" ? `--account-kind ${accountKind}` : "",
|
|
7838
|
+
`--relay-url ${relayUrl} --wait-relay --prompt-code`
|
|
7839
|
+
].filter(Boolean).join(" ");
|
|
7840
|
+
return appendPaymasterMode(command, paymasterMode);
|
|
7841
|
+
}
|
|
7761
7842
|
function buildWalletListRecommendedCommand() {
|
|
7762
7843
|
return "zk-agent wallet list";
|
|
7763
7844
|
}
|
|
@@ -7784,6 +7865,12 @@ function buildResolveTokenRecommendedCommand(chain, symbol, role, source) {
|
|
|
7784
7865
|
const withRole = role ? `${command} --role ${role}` : command;
|
|
7785
7866
|
return source ? `${withRole} --source ${source}` : withRole;
|
|
7786
7867
|
}
|
|
7868
|
+
function buildPaymasterFeeTokensRecommendedCommand(chain) {
|
|
7869
|
+
return buildTokensRecommendedCommand(chain, void 0, "paymaster-fee-token");
|
|
7870
|
+
}
|
|
7871
|
+
function buildPaymasterFeeTokenResolveRecommendedCommand(chain, symbol) {
|
|
7872
|
+
return buildResolveTokenRecommendedCommand(chain, symbol, "paymaster-fee-token");
|
|
7873
|
+
}
|
|
7787
7874
|
function buildDiscoveryRecommendedCommands(input) {
|
|
7788
7875
|
return {
|
|
7789
7876
|
inspectDefaults: buildDefaultsRecommendedCommand(),
|
|
@@ -7814,6 +7901,9 @@ function buildDiscoveryRecommendedCommands(input) {
|
|
|
7814
7901
|
function buildWalletReapproveRecommendedCommand(walletName) {
|
|
7815
7902
|
return `zk-agent wallet reapprove --name ${walletName} --await-local`;
|
|
7816
7903
|
}
|
|
7904
|
+
function buildWalletReapproveRemoteRecommendedCommand(walletName, relayUrl = "<url>") {
|
|
7905
|
+
return `zk-agent wallet reapprove --name ${walletName} --relay-url ${relayUrl} --wait-relay --prompt-code`;
|
|
7906
|
+
}
|
|
7817
7907
|
function buildWalletNextRecommendedCommand(walletName) {
|
|
7818
7908
|
return `zk-agent wallet next --name ${walletName}`;
|
|
7819
7909
|
}
|
|
@@ -8507,9 +8597,15 @@ function workflowFollowupLines(recommendedCommands) {
|
|
|
8507
8597
|
if (recommendedCommands.discoverOwnedTokens) {
|
|
8508
8598
|
lines.push(["discover owned tokens", recommendedCommands.discoverOwnedTokens]);
|
|
8509
8599
|
}
|
|
8600
|
+
if (recommendedCommands.discoverPaymasterTokens) {
|
|
8601
|
+
lines.push(["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]);
|
|
8602
|
+
}
|
|
8510
8603
|
if (recommendedCommands.discoverTokens) {
|
|
8511
8604
|
lines.push(["discover tokens", recommendedCommands.discoverTokens]);
|
|
8512
8605
|
}
|
|
8606
|
+
if (recommendedCommands.inspectPaymasterToken) {
|
|
8607
|
+
lines.push(["inspect paymaster token", recommendedCommands.inspectPaymasterToken]);
|
|
8608
|
+
}
|
|
8513
8609
|
if (recommendedCommands.inspectToken) {
|
|
8514
8610
|
lines.push(["inspect token", recommendedCommands.inspectToken]);
|
|
8515
8611
|
}
|
|
@@ -9150,6 +9246,27 @@ function linesForMultiBalances(result) {
|
|
|
9150
9246
|
}
|
|
9151
9247
|
return lines;
|
|
9152
9248
|
}
|
|
9249
|
+
function buildAssetsDiscoverySummary(result) {
|
|
9250
|
+
const nativeBalance = findNativeBalance(result.balances);
|
|
9251
|
+
const ownedTokenSymbols = (result.ownedTokenRegistry?.entries || []).map((entry) => entry.symbol?.trim()).filter((value) => Boolean(value));
|
|
9252
|
+
return {
|
|
9253
|
+
walletName: result.walletName,
|
|
9254
|
+
chain: result.chain,
|
|
9255
|
+
chainId: result.chainId,
|
|
9256
|
+
assetCount: result.balances.length,
|
|
9257
|
+
nativeAssetSymbol: nativeBalance?.symbol || null,
|
|
9258
|
+
nativeAssetBalance: nativeBalance?.balance || null,
|
|
9259
|
+
ownedTokenCount: result.ownedTokenRegistry?.entryCount || 0,
|
|
9260
|
+
primaryOwnedTokenSymbol: firstDiscoverySymbol(result.ownedTokenRegistry?.entries || []),
|
|
9261
|
+
ownedTokenSymbols,
|
|
9262
|
+
ownedTokenSourceCounts: result.ownedTokenRegistry?.summary.sourceCounts || null,
|
|
9263
|
+
ownedBridgeMappingCounts: result.ownedTokenRegistry?.summary.bridgeMappingCounts || null,
|
|
9264
|
+
ownedRegistryRoleCounts: result.ownedTokenRegistry?.summary.registryRoleCounts || null
|
|
9265
|
+
};
|
|
9266
|
+
}
|
|
9267
|
+
function buildBalancesDiscoverySummary(result) {
|
|
9268
|
+
return buildAssetsDiscoverySummary(result);
|
|
9269
|
+
}
|
|
9153
9270
|
function withPaymasterOptions(command) {
|
|
9154
9271
|
return command.option("--paymaster-mode <mode>", "none, sponsored, or approval-based").option("--paymaster-address <address>", "Explicit paymaster contract address override").option("--paymaster-token <address>", "ERC-20 token address for approval-based paymaster mode");
|
|
9155
9272
|
}
|
|
@@ -9209,12 +9326,46 @@ function createBalancesCommand(deps) {
|
|
|
9209
9326
|
provider: resolvedDeps.provider,
|
|
9210
9327
|
ownedTokens: options.ownedTokens
|
|
9211
9328
|
});
|
|
9212
|
-
|
|
9329
|
+
const discoverySummary = options.ownedTokens && "ownedTokenRegistry" in payload ? buildBalancesDiscoverySummary(payload) : void 0;
|
|
9330
|
+
const recommendedCommands = options.ownedTokens ? buildDiscoveryRecommendedCommands({
|
|
9331
|
+
walletName,
|
|
9332
|
+
chain: payload.chain
|
|
9333
|
+
}) : void 0;
|
|
9334
|
+
printResult(
|
|
9335
|
+
[
|
|
9336
|
+
...linesForSingleBalances(payload),
|
|
9337
|
+
...recommendedCommands ? workflowFollowupLines(recommendedCommands) : []
|
|
9338
|
+
],
|
|
9339
|
+
{
|
|
9340
|
+
ok: true,
|
|
9341
|
+
...discoverySummary ? { discoverySummary } : {},
|
|
9342
|
+
...recommendedCommands ? { recommendedCommands } : {},
|
|
9343
|
+
...payload
|
|
9344
|
+
}
|
|
9345
|
+
);
|
|
9213
9346
|
});
|
|
9214
9347
|
}
|
|
9215
9348
|
function createAssetsCommand(deps) {
|
|
9216
9349
|
const resolvedDeps = resolveBalancesCommandDeps(deps);
|
|
9217
|
-
return new Command("assets").description("Fetch the preferred single-chain asset view with native balance plus registry-backed ERC-20 holdings").
|
|
9350
|
+
return new Command("assets").description("Fetch the preferred single-chain asset view with native balance plus registry-backed ERC-20 holdings").addHelpText(
|
|
9351
|
+
"after",
|
|
9352
|
+
[
|
|
9353
|
+
"",
|
|
9354
|
+
"Discovery asset path:",
|
|
9355
|
+
" Preferred single-chain asset entrypoint:",
|
|
9356
|
+
" zk-agent assets --wallet main",
|
|
9357
|
+
"",
|
|
9358
|
+
" Narrower owned ERC-20 registry subset:",
|
|
9359
|
+
" zk-agent tokens --wallet main --owned",
|
|
9360
|
+
"",
|
|
9361
|
+
" Symbol-first token lookup before a tokenized command:",
|
|
9362
|
+
" zk-agent tokens --chain zksync-sepolia --symbol USDC",
|
|
9363
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol USDC",
|
|
9364
|
+
"",
|
|
9365
|
+
" For the machine-readable registry/default catalog:",
|
|
9366
|
+
" zk-agent defaults"
|
|
9367
|
+
].join("\n")
|
|
9368
|
+
).option("--wallet <name>", "Wallet name", "main").option("--chain <chain>", "Single chain override").action(async (options) => {
|
|
9218
9369
|
const walletName = options.wallet;
|
|
9219
9370
|
const wallet = await resolvedDeps.loadWallet(walletName);
|
|
9220
9371
|
if (!wallet) throw new Error(`Wallet not found: ${walletName}`);
|
|
@@ -9230,9 +9381,12 @@ function createAssetsCommand(deps) {
|
|
|
9230
9381
|
chain: payload.chain,
|
|
9231
9382
|
includeAssets: false
|
|
9232
9383
|
});
|
|
9384
|
+
const discoverySummary = buildAssetsDiscoverySummary(
|
|
9385
|
+
payload
|
|
9386
|
+
);
|
|
9233
9387
|
printResult(
|
|
9234
9388
|
[...linesForSingleBalances(payload), ...workflowFollowupLines(recommendedCommands)],
|
|
9235
|
-
{ ok: true, recommendedCommands, ...payload }
|
|
9389
|
+
{ ok: true, discoverySummary, recommendedCommands, ...payload }
|
|
9236
9390
|
);
|
|
9237
9391
|
});
|
|
9238
9392
|
}
|
|
@@ -9912,11 +10066,35 @@ function createPlannedCommands() {
|
|
|
9912
10066
|
|
|
9913
10067
|
// src/commands/setup.ts
|
|
9914
10068
|
import { Command as Command2 } from "commander";
|
|
10069
|
+
function buildSetupHelpText() {
|
|
10070
|
+
return [
|
|
10071
|
+
"",
|
|
10072
|
+
"What setup does:",
|
|
10073
|
+
" Writes the local default chain and connector URL used by the first-run path.",
|
|
10074
|
+
"",
|
|
10075
|
+
"After setup, stay on the canonical local-first path:",
|
|
10076
|
+
" zk-agent next",
|
|
10077
|
+
" zk-agent wallet create --await-local",
|
|
10078
|
+
" zk-agent next",
|
|
10079
|
+
"",
|
|
10080
|
+
"If the browser is not colocated with this terminal, switch at the wallet step:",
|
|
10081
|
+
" zk-agent relay inspect --relay-url <url>",
|
|
10082
|
+
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
10083
|
+
" zk-agent next",
|
|
10084
|
+
"",
|
|
10085
|
+
"Environment note:",
|
|
10086
|
+
" No custom .env is required for setup, next, or wallet request creation.",
|
|
10087
|
+
" Add RPC env vars later, before live reads or broadcasts."
|
|
10088
|
+
].join("\n");
|
|
10089
|
+
}
|
|
9915
10090
|
function createInitCommand() {
|
|
9916
|
-
return new Command2("init").alias("setup").description("Initialize local zk-agent configuration").option("--default-chain <chain>", "Default chain key", "zksync-era").option("--connector-url <url>", "Connector UI base URL", "http://localhost:4444").option("--force", "Overwrite an existing config", false).action(async (options) => {
|
|
10091
|
+
return new Command2("init").alias("setup").description("Initialize local zk-agent configuration for the default operator path").addHelpText("after", buildSetupHelpText()).option("--default-chain <chain>", "Default chain key", "zksync-era").option("--connector-url <url>", "Connector UI base URL", "http://localhost:4444").option("--force", "Overwrite an existing config", false).action(async (options) => {
|
|
9917
10092
|
const recommendedCommands = {
|
|
10093
|
+
next: buildTopLevelNextRecommendedCommand(),
|
|
9918
10094
|
inspectDefaults: buildDefaultsRecommendedCommand(),
|
|
9919
10095
|
createWallet: buildWalletCreateRecommendedCommand(),
|
|
10096
|
+
relayInspect: buildRelayInspectRecommendedCommand(),
|
|
10097
|
+
createWalletRemote: buildWalletCreateRemoteRecommendedCommand(),
|
|
9920
10098
|
afterWalletApproval: buildTopLevelNextRecommendedCommand()
|
|
9921
10099
|
};
|
|
9922
10100
|
const existing = await loadProjectConfig();
|
|
@@ -9926,8 +10104,11 @@ function createInitCommand() {
|
|
|
9926
10104
|
["status", "Config already exists. Re-run with --force to overwrite."],
|
|
9927
10105
|
["default chain", existing.defaultChain],
|
|
9928
10106
|
["connector", existing.connectorUrl],
|
|
10107
|
+
["next", recommendedCommands.next],
|
|
9929
10108
|
["inspect defaults", recommendedCommands.inspectDefaults],
|
|
9930
|
-
["create wallet", recommendedCommands.createWallet],
|
|
10109
|
+
["create wallet (local)", recommendedCommands.createWallet],
|
|
10110
|
+
["relay inspect", recommendedCommands.relayInspect],
|
|
10111
|
+
["create wallet (remote)", recommendedCommands.createWalletRemote],
|
|
9931
10112
|
["after approval", recommendedCommands.afterWalletApproval]
|
|
9932
10113
|
],
|
|
9933
10114
|
{
|
|
@@ -9952,8 +10133,11 @@ function createInitCommand() {
|
|
|
9952
10133
|
["status", "Config saved"],
|
|
9953
10134
|
["default chain", config.defaultChain],
|
|
9954
10135
|
["connector", config.connectorUrl],
|
|
10136
|
+
["next", recommendedCommands.next],
|
|
9955
10137
|
["inspect defaults", recommendedCommands.inspectDefaults],
|
|
9956
|
-
["create wallet", recommendedCommands.createWallet],
|
|
10138
|
+
["create wallet (local)", recommendedCommands.createWallet],
|
|
10139
|
+
["relay inspect", recommendedCommands.relayInspect],
|
|
10140
|
+
["create wallet (remote)", recommendedCommands.createWalletRemote],
|
|
9957
10141
|
["after approval", recommendedCommands.afterWalletApproval]
|
|
9958
10142
|
],
|
|
9959
10143
|
{ ok: true, config, recommendedCommands }
|
|
@@ -10330,6 +10514,36 @@ function buildWalletNextRecommendedCommands(walletName, summary) {
|
|
|
10330
10514
|
...summary.recommendedCommand ? { nextAction: summary.recommendedCommand } : {}
|
|
10331
10515
|
};
|
|
10332
10516
|
}
|
|
10517
|
+
function workflowIntentSupportsTokenDiscovery(intent) {
|
|
10518
|
+
return intent === "send-token" || intent === "swap" || intent === "bridge" || intent === "deposit" || intent === "withdraw";
|
|
10519
|
+
}
|
|
10520
|
+
function buildWalletTokenDiscoverySummary(input) {
|
|
10521
|
+
if (!input.recommendedCommands) {
|
|
10522
|
+
return void 0;
|
|
10523
|
+
}
|
|
10524
|
+
const hasTokenDiscovery = Boolean(input.recommendedCommands.discoverAssets) || Boolean(input.recommendedCommands.discoverOwnedTokens) || Boolean(input.recommendedCommands.discoverTokens) || Boolean(input.recommendedCommands.inspectToken) || Boolean(input.recommendedCommands.discoverPaymasterTokens) || Boolean(input.recommendedCommands.inspectPaymasterToken);
|
|
10525
|
+
if (!hasTokenDiscovery) {
|
|
10526
|
+
return void 0;
|
|
10527
|
+
}
|
|
10528
|
+
return {
|
|
10529
|
+
walletName: input.walletName,
|
|
10530
|
+
chain: input.chain,
|
|
10531
|
+
intent: input.intent || null,
|
|
10532
|
+
nextAction: input.nextAction || null,
|
|
10533
|
+
paymasterMode: input.paymasterMode || null,
|
|
10534
|
+
tokenizedIntent: workflowIntentSupportsTokenDiscovery(input.intent),
|
|
10535
|
+
includesAssetDiscovery: Boolean(input.recommendedCommands.discoverAssets),
|
|
10536
|
+
includesOwnedTokenDiscovery: Boolean(input.recommendedCommands.discoverOwnedTokens),
|
|
10537
|
+
includesChainTokenDiscovery: Boolean(input.recommendedCommands.discoverTokens),
|
|
10538
|
+
includesDirectTokenInspection: Boolean(input.recommendedCommands.inspectToken),
|
|
10539
|
+
includesPaymasterTokenDiscovery: Boolean(
|
|
10540
|
+
input.recommendedCommands.discoverPaymasterTokens
|
|
10541
|
+
),
|
|
10542
|
+
includesPaymasterTokenInspection: Boolean(
|
|
10543
|
+
input.recommendedCommands.inspectPaymasterToken
|
|
10544
|
+
)
|
|
10545
|
+
};
|
|
10546
|
+
}
|
|
10333
10547
|
function walletNextLines(summary) {
|
|
10334
10548
|
const lines = [
|
|
10335
10549
|
["wallet", summary.walletName],
|
|
@@ -10364,7 +10578,7 @@ var defaultProvider = new ZkSyncWalletProvider();
|
|
|
10364
10578
|
var defaultDefiProvider = new ZkSyncDefiProvider({
|
|
10365
10579
|
walletWriter: defaultProvider
|
|
10366
10580
|
});
|
|
10367
|
-
function
|
|
10581
|
+
function workflowIntentSupportsTokenDiscovery2(intent) {
|
|
10368
10582
|
return intent === "send-token" || intent === "swap" || intent === "bridge" || intent === "deposit" || intent === "withdraw";
|
|
10369
10583
|
}
|
|
10370
10584
|
function buildTopLevelWorkflowRecommendedCommands(input) {
|
|
@@ -10378,14 +10592,22 @@ function buildTopLevelWorkflowRecommendedCommands(input) {
|
|
|
10378
10592
|
delete: buildWorkflowDeleteRecommendedCommand(input.requestId),
|
|
10379
10593
|
walletStatus: buildWalletStatusRecommendedCommand(input.walletName),
|
|
10380
10594
|
...input.nextAction ? { nextAction: input.nextAction } : {},
|
|
10381
|
-
...
|
|
10595
|
+
...workflowIntentSupportsTokenDiscovery2(input.intent) ? {
|
|
10382
10596
|
discoverAssets: buildAssetsRecommendedCommand(input.walletName),
|
|
10383
10597
|
discoverOwnedTokens: buildOwnedTokensRecommendedCommand(input.walletName),
|
|
10384
10598
|
discoverTokens: buildTokensRecommendedCommand(input.chain),
|
|
10385
10599
|
inspectToken: buildResolveTokenRecommendedCommand(input.chain)
|
|
10600
|
+
} : {},
|
|
10601
|
+
...input.paymasterMode === "approval-based" ? {
|
|
10602
|
+
discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(input.chain),
|
|
10603
|
+
inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(input.chain)
|
|
10386
10604
|
} : {}
|
|
10387
10605
|
};
|
|
10388
10606
|
}
|
|
10607
|
+
function extractCheckpointPaymasterMode(checkpoint) {
|
|
10608
|
+
if (!("paymaster" in checkpoint.goal)) return void 0;
|
|
10609
|
+
return checkpoint.goal.paymaster?.mode;
|
|
10610
|
+
}
|
|
10389
10611
|
function resolveNextCommandDeps(deps) {
|
|
10390
10612
|
return {
|
|
10391
10613
|
provider: deps?.provider ?? defaultProvider,
|
|
@@ -10415,6 +10637,11 @@ function buildNextHelpText() {
|
|
|
10415
10637
|
" zk-agent wallet create --await-local",
|
|
10416
10638
|
" zk-agent next",
|
|
10417
10639
|
"",
|
|
10640
|
+
" If the browser is remote, switch at the wallet step instead of waiting for a local callback:",
|
|
10641
|
+
" zk-agent relay inspect --relay-url <url>",
|
|
10642
|
+
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
10643
|
+
" zk-agent next",
|
|
10644
|
+
"",
|
|
10418
10645
|
" Continue a stored workflow checkpoint:",
|
|
10419
10646
|
" zk-agent next --request-id <id>",
|
|
10420
10647
|
"",
|
|
@@ -10470,7 +10697,16 @@ function createNextCommand(deps) {
|
|
|
10470
10697
|
walletName: wallet2.walletName,
|
|
10471
10698
|
nextAction: nextCommand2,
|
|
10472
10699
|
chain: result.plan.chain,
|
|
10473
|
-
intent: result.intent
|
|
10700
|
+
intent: result.intent,
|
|
10701
|
+
paymasterMode: extractCheckpointPaymasterMode(updatedCheckpoint)
|
|
10702
|
+
});
|
|
10703
|
+
const tokenDiscoverySummary2 = buildWalletTokenDiscoverySummary({
|
|
10704
|
+
walletName: wallet2.walletName,
|
|
10705
|
+
chain: result.plan.chain,
|
|
10706
|
+
intent: result.intent,
|
|
10707
|
+
nextAction: nextCommand2,
|
|
10708
|
+
paymasterMode: extractCheckpointPaymasterMode(updatedCheckpoint),
|
|
10709
|
+
recommendedCommands: recommendedCommands2
|
|
10474
10710
|
});
|
|
10475
10711
|
const workflowAgentProfile = await loadAgentIdentitySummary(wallet2.walletName);
|
|
10476
10712
|
const agentFollowup2 = buildAgentFollowup(workflowAgentProfile, {
|
|
@@ -10506,6 +10742,7 @@ function createNextCommand(deps) {
|
|
|
10506
10742
|
agentFollowup: agentFollowup2,
|
|
10507
10743
|
result,
|
|
10508
10744
|
checkpoint: updatedCheckpoint,
|
|
10745
|
+
tokenDiscoverySummary: tokenDiscoverySummary2,
|
|
10509
10746
|
recommendedCommands: recommendedCommands2
|
|
10510
10747
|
}
|
|
10511
10748
|
);
|
|
@@ -10515,6 +10752,7 @@ function createNextCommand(deps) {
|
|
|
10515
10752
|
if (!config) {
|
|
10516
10753
|
const recommendedCommands2 = {
|
|
10517
10754
|
setup: buildSetupCommand(),
|
|
10755
|
+
afterSetup: buildTopLevelNextRecommendedCommand2(),
|
|
10518
10756
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
10519
10757
|
};
|
|
10520
10758
|
printResult(
|
|
@@ -10523,6 +10761,7 @@ function createNextCommand(deps) {
|
|
|
10523
10761
|
...agentProfileLines(agentProfile),
|
|
10524
10762
|
...agentFollowupLines(defaultAgentFollowup),
|
|
10525
10763
|
["next", recommendedCommands2.setup],
|
|
10764
|
+
["after setup", recommendedCommands2.afterSetup],
|
|
10526
10765
|
["inspect defaults", recommendedCommands2.inspectDefaults]
|
|
10527
10766
|
]),
|
|
10528
10767
|
{
|
|
@@ -10544,6 +10783,11 @@ function createNextCommand(deps) {
|
|
|
10544
10783
|
buildWalletCreateRecommendedCommand(),
|
|
10545
10784
|
paymasterMode
|
|
10546
10785
|
),
|
|
10786
|
+
relayInspect: buildRelayInspectRecommendedCommand(),
|
|
10787
|
+
createWalletRemote: buildWalletCreateRemoteRecommendedCommand(
|
|
10788
|
+
"<url>",
|
|
10789
|
+
paymasterMode
|
|
10790
|
+
),
|
|
10547
10791
|
afterApproval: appendPaymasterMode2(buildTopLevelNextRecommendedCommand2(), paymasterMode),
|
|
10548
10792
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
10549
10793
|
};
|
|
@@ -10555,6 +10799,8 @@ function createNextCommand(deps) {
|
|
|
10555
10799
|
...agentProfileLines(agentProfile),
|
|
10556
10800
|
...agentFollowupLines(defaultAgentFollowup),
|
|
10557
10801
|
["next", recommendedCommands2.createWallet],
|
|
10802
|
+
["relay inspect", recommendedCommands2.relayInspect],
|
|
10803
|
+
["remote fallback", recommendedCommands2.createWalletRemote],
|
|
10558
10804
|
["after approval", recommendedCommands2.afterApproval],
|
|
10559
10805
|
["inspect defaults", recommendedCommands2.inspectDefaults]
|
|
10560
10806
|
]),
|
|
@@ -10608,6 +10854,10 @@ function createNextCommand(deps) {
|
|
|
10608
10854
|
walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
|
|
10609
10855
|
discoverAssets: buildAssetsRecommendedCommand(wallet.walletName),
|
|
10610
10856
|
discoverOwnedTokens: buildOwnedTokensRecommendedCommand(wallet.walletName),
|
|
10857
|
+
...paymasterMode === "approval-based" ? {
|
|
10858
|
+
discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(wallet.chain),
|
|
10859
|
+
inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(wallet.chain)
|
|
10860
|
+
} : {},
|
|
10611
10861
|
discoverTokens: buildTokensRecommendedCommand(wallet.chain),
|
|
10612
10862
|
inspectToken: buildResolveTokenRecommendedCommand(wallet.chain),
|
|
10613
10863
|
workflowPay,
|
|
@@ -10615,6 +10865,13 @@ function createNextCommand(deps) {
|
|
|
10615
10865
|
nextAction: nextCommand,
|
|
10616
10866
|
inspectDefaults: buildDefaultsRecommendedCommand()
|
|
10617
10867
|
};
|
|
10868
|
+
const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
|
|
10869
|
+
walletName: wallet.walletName,
|
|
10870
|
+
chain: wallet.chain,
|
|
10871
|
+
nextAction: nextCommand,
|
|
10872
|
+
paymasterMode,
|
|
10873
|
+
recommendedCommands
|
|
10874
|
+
});
|
|
10618
10875
|
printResult(
|
|
10619
10876
|
topLevelNextLines("wallet", [
|
|
10620
10877
|
...walletNextLines(summary),
|
|
@@ -10623,7 +10880,9 @@ function createNextCommand(deps) {
|
|
|
10623
10880
|
...summary.recommendedCommand ? [] : [["next", workflowPay]],
|
|
10624
10881
|
["discover assets", recommendedCommands.discoverAssets],
|
|
10625
10882
|
["discover owned tokens", recommendedCommands.discoverOwnedTokens],
|
|
10883
|
+
...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
|
|
10626
10884
|
["discover tokens", recommendedCommands.discoverTokens],
|
|
10885
|
+
...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
|
|
10627
10886
|
["inspect token", recommendedCommands.inspectToken],
|
|
10628
10887
|
["inspect defaults", recommendedCommands.inspectDefaults]
|
|
10629
10888
|
]),
|
|
@@ -10636,6 +10895,7 @@ function createNextCommand(deps) {
|
|
|
10636
10895
|
inspection,
|
|
10637
10896
|
summary,
|
|
10638
10897
|
nextCommand,
|
|
10898
|
+
tokenDiscoverySummary,
|
|
10639
10899
|
recommendedCommands
|
|
10640
10900
|
}
|
|
10641
10901
|
);
|
|
@@ -10740,6 +11000,21 @@ function createAgentCommand() {
|
|
|
10740
11000
|
agent.addHelpText(
|
|
10741
11001
|
"after",
|
|
10742
11002
|
[
|
|
11003
|
+
"",
|
|
11004
|
+
" Agent identity path:",
|
|
11005
|
+
" zk-agent agent status",
|
|
11006
|
+
' zk-agent agent set --name "SED Operator" --wallet main',
|
|
11007
|
+
" zk-agent agent show",
|
|
11008
|
+
"",
|
|
11009
|
+
" Portable local profile management:",
|
|
11010
|
+
" zk-agent agent export",
|
|
11011
|
+
" zk-agent agent import --payload @agent-profile.json --overwrite",
|
|
11012
|
+
"",
|
|
11013
|
+
" Remove the saved local profile:",
|
|
11014
|
+
" zk-agent agent clear",
|
|
11015
|
+
"",
|
|
11016
|
+
" This profile is optional. Wallet approval and workflow execution still work",
|
|
11017
|
+
" without a saved local agent profile.",
|
|
10743
11018
|
"",
|
|
10744
11019
|
"Examples:",
|
|
10745
11020
|
" zk-agent agent status",
|
|
@@ -10913,6 +11188,80 @@ function createAgentCommand() {
|
|
|
10913
11188
|
|
|
10914
11189
|
// src/commands/defaults.ts
|
|
10915
11190
|
import { Command as Command5 } from "commander";
|
|
11191
|
+
function inferPrimaryDiscoveryChain(defaults) {
|
|
11192
|
+
return defaults.defaultSelections.paymaster.validatedDefault?.chain || defaults.defaultSelections.swap.validatedDefault?.chain || defaults.defaultSelections.bridge.validatedWithdraw?.fromChain || defaults.defaultSelections.bridge.validatedDeposit?.toChain || defaults.validated.feeTokenEraVm?.chain || defaults.builtinChains.find((chain) => chain.key === "zksync-sepolia")?.key || defaults.builtinChains[0]?.key || "zksync-sepolia";
|
|
11193
|
+
}
|
|
11194
|
+
function inferExampleTokenSymbol(defaults) {
|
|
11195
|
+
return defaults.defaultSelections.swap.validatedDefault?.trackedTokenA.symbol || defaults.defaultSelections.paymaster.validatedApprovalBased?.feeTokenSymbol || defaults.validated.feeTokenEraVm?.symbol || defaults.registry.tokens.find((entry) => entry.symbol?.trim())?.symbol || "USDC";
|
|
11196
|
+
}
|
|
11197
|
+
function inferPaymasterFeeTokenSymbol(defaults) {
|
|
11198
|
+
return defaults.defaultSelections.paymaster.validatedApprovalBased?.feeTokenSymbol || defaults.validated.feeTokenEraVm?.symbol || null;
|
|
11199
|
+
}
|
|
11200
|
+
function buildDefaultsRecommendedCommands(defaults) {
|
|
11201
|
+
const primaryChain = inferPrimaryDiscoveryChain(defaults);
|
|
11202
|
+
const exampleSymbol = inferExampleTokenSymbol(defaults);
|
|
11203
|
+
const paymasterFeeTokenSymbol = inferPaymasterFeeTokenSymbol(defaults) || exampleSymbol;
|
|
11204
|
+
return {
|
|
11205
|
+
inspectDefaults: buildDefaultsRecommendedCommand(),
|
|
11206
|
+
discoverTokens: buildTokensRecommendedCommand(primaryChain),
|
|
11207
|
+
inspectToken: buildResolveTokenRecommendedCommand(primaryChain, exampleSymbol),
|
|
11208
|
+
discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(primaryChain),
|
|
11209
|
+
inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(
|
|
11210
|
+
primaryChain,
|
|
11211
|
+
paymasterFeeTokenSymbol
|
|
11212
|
+
)
|
|
11213
|
+
};
|
|
11214
|
+
}
|
|
11215
|
+
function buildDefaultsSummary(input) {
|
|
11216
|
+
const { defaults, localTokenRegistry, tokenRegistrySources, tokenDirectoryChains } = input;
|
|
11217
|
+
const primaryChain = inferPrimaryDiscoveryChain(defaults);
|
|
11218
|
+
const exampleTokenSymbol = inferExampleTokenSymbol(defaults);
|
|
11219
|
+
const paymasterFeeTokenSymbol = inferPaymasterFeeTokenSymbol(defaults);
|
|
11220
|
+
return {
|
|
11221
|
+
primaryDiscoveryChain: primaryChain,
|
|
11222
|
+
exampleTokenSymbol,
|
|
11223
|
+
paymasterFeeTokenSymbol,
|
|
11224
|
+
localTokenCount: localTokenRegistry.length,
|
|
11225
|
+
tokenDirectoryChainCount: tokenDirectoryChains.length,
|
|
11226
|
+
tokenRegistrySources: tokenRegistrySources.map((source) => ({
|
|
11227
|
+
id: source.id,
|
|
11228
|
+
enabled: source.enabled,
|
|
11229
|
+
exists: source.exists
|
|
11230
|
+
})),
|
|
11231
|
+
resolvedDefaults: {
|
|
11232
|
+
swap: defaults.defaultSelections.swap.validatedDefault ? {
|
|
11233
|
+
entryId: defaults.defaultSelections.swap.validatedDefault.entryId,
|
|
11234
|
+
chain: defaults.defaultSelections.swap.validatedDefault.chain,
|
|
11235
|
+
protocol: defaults.defaultSelections.swap.validatedDefault.protocol,
|
|
11236
|
+
status: defaults.defaultSelections.swap.validatedDefault.status
|
|
11237
|
+
} : null,
|
|
11238
|
+
bridgeDeposit: defaults.defaultSelections.bridge.validatedDeposit ? {
|
|
11239
|
+
entryId: defaults.defaultSelections.bridge.validatedDeposit.entryId,
|
|
11240
|
+
fromChain: defaults.defaultSelections.bridge.validatedDeposit.fromChain,
|
|
11241
|
+
toChain: defaults.defaultSelections.bridge.validatedDeposit.toChain,
|
|
11242
|
+
status: defaults.defaultSelections.bridge.validatedDeposit.status
|
|
11243
|
+
} : null,
|
|
11244
|
+
bridgeWithdraw: defaults.defaultSelections.bridge.validatedWithdraw ? {
|
|
11245
|
+
entryId: defaults.defaultSelections.bridge.validatedWithdraw.entryId,
|
|
11246
|
+
fromChain: defaults.defaultSelections.bridge.validatedWithdraw.fromChain,
|
|
11247
|
+
toChain: defaults.defaultSelections.bridge.validatedWithdraw.toChain,
|
|
11248
|
+
status: defaults.defaultSelections.bridge.validatedWithdraw.status,
|
|
11249
|
+
requiresFinalize: defaults.defaultSelections.bridge.validatedWithdraw.requiresFinalize
|
|
11250
|
+
} : null,
|
|
11251
|
+
paymasterDefault: defaults.defaultSelections.paymaster.validatedDefault ? {
|
|
11252
|
+
entryId: defaults.defaultSelections.paymaster.validatedDefault.entryId,
|
|
11253
|
+
chain: defaults.defaultSelections.paymaster.validatedDefault.chain,
|
|
11254
|
+
mode: defaults.defaultSelections.paymaster.validatedDefault.mode,
|
|
11255
|
+
status: defaults.defaultSelections.paymaster.validatedDefault.status
|
|
11256
|
+
} : null,
|
|
11257
|
+
paymasterByMode: {
|
|
11258
|
+
none: defaults.defaultSelections.paymaster.validatedNone?.entryId || null,
|
|
11259
|
+
sponsored: defaults.defaultSelections.paymaster.validatedSponsored?.entryId || null,
|
|
11260
|
+
approvalBased: defaults.defaultSelections.paymaster.validatedApprovalBased?.entryId || null
|
|
11261
|
+
}
|
|
11262
|
+
}
|
|
11263
|
+
};
|
|
11264
|
+
}
|
|
10916
11265
|
function formatTrackedTokenSummary(token) {
|
|
10917
11266
|
if (!token.address) return null;
|
|
10918
11267
|
const label = token.symbol || token.address;
|
|
@@ -11386,19 +11735,56 @@ function buildDefaultsLines(input) {
|
|
|
11386
11735
|
return lines;
|
|
11387
11736
|
}
|
|
11388
11737
|
function createDefaultsCommand() {
|
|
11389
|
-
return new Command5("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").
|
|
11738
|
+
return new Command5("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").addHelpText(
|
|
11739
|
+
"after",
|
|
11740
|
+
[
|
|
11741
|
+
"",
|
|
11742
|
+
"Discovery defaults path:",
|
|
11743
|
+
" Use `defaults` as the machine-readable registry escape hatch for:",
|
|
11744
|
+
" - validated or fallback swap / bridge paths",
|
|
11745
|
+
" - tracked token roles and source order",
|
|
11746
|
+
" - paymaster defaults and supported modes",
|
|
11747
|
+
"",
|
|
11748
|
+
" For wallet-scoped asset discovery, prefer:",
|
|
11749
|
+
" zk-agent assets --wallet main",
|
|
11750
|
+
"",
|
|
11751
|
+
" For symbol-first token discovery, prefer:",
|
|
11752
|
+
" zk-agent tokens --chain zksync-sepolia",
|
|
11753
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol USDC"
|
|
11754
|
+
].join("\n")
|
|
11755
|
+
).action(async () => {
|
|
11390
11756
|
const defaults = loadValidatedDefaults();
|
|
11391
11757
|
const localTokenRegistry = listLocalTokenRegistryEntries();
|
|
11392
11758
|
const tokenRegistrySources = describeDefaultTokenRegistrySources();
|
|
11393
11759
|
const tokenDirectoryChains = await listTokenDirectoryIndexedChains();
|
|
11760
|
+
const recommendedCommands = buildDefaultsRecommendedCommands(defaults);
|
|
11761
|
+
const summary = buildDefaultsSummary({
|
|
11762
|
+
defaults,
|
|
11763
|
+
localTokenRegistry,
|
|
11764
|
+
tokenRegistrySources,
|
|
11765
|
+
tokenDirectoryChains
|
|
11766
|
+
});
|
|
11394
11767
|
const lines = buildDefaultsLines({
|
|
11395
11768
|
defaults,
|
|
11396
11769
|
localTokenRegistry,
|
|
11397
11770
|
tokenRegistrySources,
|
|
11398
11771
|
tokenDirectoryChains
|
|
11399
11772
|
});
|
|
11773
|
+
lines.push([
|
|
11774
|
+
"next discovery chain",
|
|
11775
|
+
summary.primaryDiscoveryChain
|
|
11776
|
+
]);
|
|
11777
|
+
lines.push([
|
|
11778
|
+
"example token",
|
|
11779
|
+
summary.exampleTokenSymbol
|
|
11780
|
+
]);
|
|
11781
|
+
if (summary.paymasterFeeTokenSymbol) {
|
|
11782
|
+
lines.push(["paymaster fee token symbol", summary.paymasterFeeTokenSymbol]);
|
|
11783
|
+
}
|
|
11400
11784
|
printResult(lines, {
|
|
11401
11785
|
ok: true,
|
|
11786
|
+
summary,
|
|
11787
|
+
recommendedCommands,
|
|
11402
11788
|
defaults,
|
|
11403
11789
|
localTokenRegistry,
|
|
11404
11790
|
tokenRegistrySources,
|
|
@@ -11444,9 +11830,49 @@ async function resolveActiveChain(options, deps) {
|
|
|
11444
11830
|
}
|
|
11445
11831
|
);
|
|
11446
11832
|
}
|
|
11833
|
+
function buildResolveTokenDiscoverySummary(result) {
|
|
11834
|
+
return {
|
|
11835
|
+
chain: result.chainKey,
|
|
11836
|
+
chainId: result.chainId,
|
|
11837
|
+
queryType: result.queryType,
|
|
11838
|
+
query: result.queryType === "symbol" ? result.symbol || null : result.address || null,
|
|
11839
|
+
roleFilter: result.role || null,
|
|
11840
|
+
sourceFilter: result.source || null,
|
|
11841
|
+
matchCount: result.matchCount,
|
|
11842
|
+
ambiguous: result.ambiguous,
|
|
11843
|
+
primarySymbol: result.primaryMatch?.symbol || null,
|
|
11844
|
+
primaryAddress: result.primaryMatch?.address || null,
|
|
11845
|
+
primaryDecimals: result.primaryMatch?.decimals ?? null,
|
|
11846
|
+
primarySource: result.primaryMatch?.source || (result.primaryMatch ? "unknown" : null),
|
|
11847
|
+
sourceCounts: summarizeDiscoveryEntrySources(result.matches),
|
|
11848
|
+
roleMatchCounts: summarizeDiscoveryRoleMatches(result.matches),
|
|
11849
|
+
currentDefaultEntryCount: countCurrentValidatedDefaultEntries(result.matches),
|
|
11850
|
+
tokenRegistrySources: summarizeTokenRegistrySources(result.tokenRegistrySources)
|
|
11851
|
+
};
|
|
11852
|
+
}
|
|
11447
11853
|
function createResolveTokenCommand(deps) {
|
|
11448
11854
|
const resolvedDeps = resolveResolveTokenCommandDeps(deps);
|
|
11449
|
-
return new Command6("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").
|
|
11855
|
+
return new Command6("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").addHelpText(
|
|
11856
|
+
"after",
|
|
11857
|
+
[
|
|
11858
|
+
"",
|
|
11859
|
+
"Resolve-token path:",
|
|
11860
|
+
" Symbol-first resolution on one active chain:",
|
|
11861
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol USDC",
|
|
11862
|
+
"",
|
|
11863
|
+
" Use the stored wallet to infer the active chain:",
|
|
11864
|
+
" zk-agent resolve-token --wallet main --symbol USDC",
|
|
11865
|
+
"",
|
|
11866
|
+
" Use broader chain discovery before resolution when you still need the candidate set:",
|
|
11867
|
+
" zk-agent tokens --chain zksync-sepolia",
|
|
11868
|
+
"",
|
|
11869
|
+
" Use the wallet asset entrypoint when the real question is balances/holdings:",
|
|
11870
|
+
" zk-agent assets --wallet main",
|
|
11871
|
+
"",
|
|
11872
|
+
" Use the registry/default catalog when you need tracked roles or source order:",
|
|
11873
|
+
" zk-agent defaults"
|
|
11874
|
+
].join("\n")
|
|
11875
|
+
).option("--wallet <name>", "Optional stored wallet name to infer the active chain").option("--chain <chain>", "Chain key or chain id override").option("--symbol <symbol>", "Token symbol to resolve on the active chain").option("--address <address>", "Token address to inspect on the active chain").option(
|
|
11450
11876
|
"--role <role>",
|
|
11451
11877
|
`Optional defaults-registry role filter: ${REGISTRY_TOKEN_ROLES.join(", ")}`
|
|
11452
11878
|
).option(
|
|
@@ -11528,6 +11954,7 @@ function createResolveTokenCommand(deps) {
|
|
|
11528
11954
|
lines.push(...workflowFollowupLines(recommendedCommands));
|
|
11529
11955
|
printResult(lines, {
|
|
11530
11956
|
ok: true,
|
|
11957
|
+
discoverySummary: buildResolveTokenDiscoverySummary(result),
|
|
11531
11958
|
recommendedCommands,
|
|
11532
11959
|
...result
|
|
11533
11960
|
});
|
|
@@ -11647,9 +12074,71 @@ function ownedTokenSummaryLines2(summary) {
|
|
|
11647
12074
|
}
|
|
11648
12075
|
return lines;
|
|
11649
12076
|
}
|
|
12077
|
+
function buildOwnedTokensDiscoverySummary(result) {
|
|
12078
|
+
return {
|
|
12079
|
+
mode: "owned-registry-erc20",
|
|
12080
|
+
walletName: result.walletName,
|
|
12081
|
+
chainScope: result.chainFilter.chainKey,
|
|
12082
|
+
chainCount: 1,
|
|
12083
|
+
entryCount: result.entryCount,
|
|
12084
|
+
symbolFilter: result.symbol || null,
|
|
12085
|
+
roleFilter: result.role || null,
|
|
12086
|
+
sourceFilter: result.source || null,
|
|
12087
|
+
primarySymbol: firstDiscoverySymbol(result.entries),
|
|
12088
|
+
primarySource: firstDiscoverySource(result.entries),
|
|
12089
|
+
sourceCounts: result.summary.sourceCounts,
|
|
12090
|
+
roleMatchCounts: result.summary.registryRoleCounts,
|
|
12091
|
+
currentDefaultEntryCount: countCurrentValidatedDefaultEntries(result.entries),
|
|
12092
|
+
probeFailureCount: result.probeFailureCount,
|
|
12093
|
+
bridgeMappingCounts: result.summary.bridgeMappingCounts,
|
|
12094
|
+
tokenRegistrySources: summarizeTokenRegistrySources(result.tokenRegistrySources)
|
|
12095
|
+
};
|
|
12096
|
+
}
|
|
12097
|
+
function buildTokenDiscoverySummary(result) {
|
|
12098
|
+
return {
|
|
12099
|
+
mode: "discoverable",
|
|
12100
|
+
walletName: null,
|
|
12101
|
+
chainScope: result.chainFilter?.chainKey || "all-built-in-chains",
|
|
12102
|
+
chainCount: result.chainFilter ? 1 : listUniqueDiscoveryChains(result.entries).length,
|
|
12103
|
+
entryCount: result.entryCount,
|
|
12104
|
+
symbolFilter: result.symbol || null,
|
|
12105
|
+
roleFilter: result.role || null,
|
|
12106
|
+
sourceFilter: result.source || null,
|
|
12107
|
+
primarySymbol: firstDiscoverySymbol(result.entries),
|
|
12108
|
+
primarySource: firstDiscoverySource(result.entries),
|
|
12109
|
+
sourceCounts: summarizeDiscoveryEntrySources(result.entries),
|
|
12110
|
+
roleMatchCounts: summarizeDiscoveryRoleMatches(result.entries),
|
|
12111
|
+
currentDefaultEntryCount: countCurrentValidatedDefaultEntries(result.entries),
|
|
12112
|
+
probeFailureCount: null,
|
|
12113
|
+
bridgeMappingCounts: null,
|
|
12114
|
+
tokenRegistrySources: summarizeTokenRegistrySources(result.tokenRegistrySources)
|
|
12115
|
+
};
|
|
12116
|
+
}
|
|
11650
12117
|
function createTokensCommand(deps) {
|
|
11651
12118
|
const resolvedDeps = resolveTokensCommandDeps(deps);
|
|
11652
|
-
return new Command7("tokens").description("List discoverable tokens from the configured local-first token registry, or inspect the owned ERC-20 registry subset for one wallet").
|
|
12119
|
+
return new Command7("tokens").description("List discoverable tokens from the configured local-first token registry, or inspect the owned ERC-20 registry subset for one wallet").addHelpText(
|
|
12120
|
+
"after",
|
|
12121
|
+
[
|
|
12122
|
+
"",
|
|
12123
|
+
"Discovery token path:",
|
|
12124
|
+
" Start with the preferred wallet asset view when you need balances plus tracked ERC-20 holdings:",
|
|
12125
|
+
" zk-agent assets --wallet main",
|
|
12126
|
+
"",
|
|
12127
|
+
" Use the narrower owned ERC-20 registry subset when you only want held tokens:",
|
|
12128
|
+
" zk-agent tokens --wallet main --owned",
|
|
12129
|
+
"",
|
|
12130
|
+
" Use chain-scoped discovery before choosing a token address:",
|
|
12131
|
+
" zk-agent tokens --chain zksync-sepolia",
|
|
12132
|
+
" zk-agent tokens --chain zksync-sepolia --symbol USDC",
|
|
12133
|
+
" zk-agent tokens --chain zksync-sepolia --role paymaster-fee-token",
|
|
12134
|
+
"",
|
|
12135
|
+
" For one direct token-resolution check:",
|
|
12136
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol USDC",
|
|
12137
|
+
"",
|
|
12138
|
+
" For the full defaults/registry catalog:",
|
|
12139
|
+
" zk-agent defaults"
|
|
12140
|
+
].join("\n")
|
|
12141
|
+
).option("--wallet <name>", "Optional stored wallet name to infer the active chain").option("--chain <chain>", "Chain key or chain id override").option("--symbol <symbol>", "Optional exact symbol filter").option(
|
|
11653
12142
|
"--role <role>",
|
|
11654
12143
|
`Optional defaults-registry role filter: ${REGISTRY_TOKEN_ROLES.join(", ")}`
|
|
11655
12144
|
).option(
|
|
@@ -11758,6 +12247,7 @@ function createTokensCommand(deps) {
|
|
|
11758
12247
|
lines2.push(...workflowFollowupLines(recommendedCommands2));
|
|
11759
12248
|
printResult(lines2, {
|
|
11760
12249
|
ok: true,
|
|
12250
|
+
discoverySummary: buildOwnedTokensDiscoverySummary(result2),
|
|
11761
12251
|
recommendedCommands: recommendedCommands2,
|
|
11762
12252
|
...result2
|
|
11763
12253
|
});
|
|
@@ -11813,6 +12303,7 @@ function createTokensCommand(deps) {
|
|
|
11813
12303
|
lines.push(...workflowFollowupLines(recommendedCommands));
|
|
11814
12304
|
printResult(lines, {
|
|
11815
12305
|
ok: true,
|
|
12306
|
+
discoverySummary: buildTokenDiscoverySummary(result),
|
|
11816
12307
|
recommendedCommands,
|
|
11817
12308
|
...result
|
|
11818
12309
|
});
|
|
@@ -11975,6 +12466,8 @@ var RELAY_BODY_LIMIT_BYTES = 1024 * 1024;
|
|
|
11975
12466
|
var RELAY_SERVICE = "zk-agent-relay";
|
|
11976
12467
|
var RELAY_PROTOCOL = "zk-agent-session-relay";
|
|
11977
12468
|
var RELAY_SCHEMA_VERSION = 1;
|
|
12469
|
+
var RELAY_STATE_BACKEND = "local-filesystem";
|
|
12470
|
+
var RELAY_DEPLOYMENT_SCOPE = "single-host";
|
|
11978
12471
|
function relayDir() {
|
|
11979
12472
|
const directory = path7.join(storageDir(), "relay");
|
|
11980
12473
|
if (!fs7.existsSync(directory)) {
|
|
@@ -12010,11 +12503,15 @@ function sanitizeRelayRecord(record) {
|
|
|
12010
12503
|
}
|
|
12011
12504
|
function relayStatusResponse(baseUrl, record) {
|
|
12012
12505
|
const sanitized = sanitizeRelayRecord(record);
|
|
12506
|
+
const shareUrl = relayShareUrl(baseUrl, sanitized.request_id);
|
|
12507
|
+
const statusUrl = relayStatusUrl(baseUrl, sanitized.request_id);
|
|
12013
12508
|
return {
|
|
12014
12509
|
request_id: sanitized.request_id,
|
|
12015
12510
|
status: relayStatus(record),
|
|
12016
12511
|
approval_ready: Boolean(record.encrypted_payload),
|
|
12017
|
-
|
|
12512
|
+
share_url: shareUrl,
|
|
12513
|
+
status_url: statusUrl,
|
|
12514
|
+
approval_url: shareUrl,
|
|
12018
12515
|
expires_at: sanitized.expires_at,
|
|
12019
12516
|
request: sanitized.request,
|
|
12020
12517
|
approval_submitted_at: sanitized.approval_submitted_at
|
|
@@ -12111,6 +12608,9 @@ function relayHealthResponse(bindBaseUrl, publicBaseUrl, connectorUiAvailable, p
|
|
|
12111
12608
|
origin: normalizeRelayBaseUrl(bindBaseUrl),
|
|
12112
12609
|
public_origin: normalizeRelayBaseUrl(publicBaseUrl),
|
|
12113
12610
|
public_origin_source: publicOriginSource,
|
|
12611
|
+
state_backend: RELAY_STATE_BACKEND,
|
|
12612
|
+
deployment_scope: RELAY_DEPLOYMENT_SCOPE,
|
|
12613
|
+
same_host_restart_persists: true,
|
|
12114
12614
|
connector_ui_available: connectorUiAvailable,
|
|
12115
12615
|
capabilities: relayCapabilities(connectorUiAvailable)
|
|
12116
12616
|
};
|
|
@@ -12357,6 +12857,12 @@ function isRelayCapability(value) {
|
|
|
12357
12857
|
function isRelayPublicOriginSource(value) {
|
|
12358
12858
|
return value === "configured" || value === "bind-origin-default";
|
|
12359
12859
|
}
|
|
12860
|
+
function isRelayStateBackend(value) {
|
|
12861
|
+
return value === "local-filesystem";
|
|
12862
|
+
}
|
|
12863
|
+
function isRelayDeploymentScope(value) {
|
|
12864
|
+
return value === "single-host";
|
|
12865
|
+
}
|
|
12360
12866
|
function asRelayHealthResponse(value) {
|
|
12361
12867
|
if (!isRecord3(value)) return null;
|
|
12362
12868
|
if (value.ok !== true) return null;
|
|
@@ -12369,6 +12875,15 @@ function asRelayHealthResponse(value) {
|
|
|
12369
12875
|
if (typeof value.public_origin_source !== "undefined" && !isRelayPublicOriginSource(value.public_origin_source)) {
|
|
12370
12876
|
return null;
|
|
12371
12877
|
}
|
|
12878
|
+
if (typeof value.state_backend !== "undefined" && !isRelayStateBackend(value.state_backend)) {
|
|
12879
|
+
return null;
|
|
12880
|
+
}
|
|
12881
|
+
if (typeof value.deployment_scope !== "undefined" && !isRelayDeploymentScope(value.deployment_scope)) {
|
|
12882
|
+
return null;
|
|
12883
|
+
}
|
|
12884
|
+
if (typeof value.same_host_restart_persists !== "undefined" && typeof value.same_host_restart_persists !== "boolean") {
|
|
12885
|
+
return null;
|
|
12886
|
+
}
|
|
12372
12887
|
if (typeof value.connector_ui_available !== "boolean") return null;
|
|
12373
12888
|
if (!Array.isArray(value.capabilities) || !value.capabilities.every(isRelayCapability)) {
|
|
12374
12889
|
return null;
|
|
@@ -12410,6 +12925,15 @@ function inferRelayPublicOriginSource(options) {
|
|
|
12410
12925
|
}
|
|
12411
12926
|
return normalizedOrigin === normalizedPublicOrigin ? "bind-origin-default" : "configured";
|
|
12412
12927
|
}
|
|
12928
|
+
function inferRelayStateBackend(relayMode) {
|
|
12929
|
+
return relayMode === "local-file" ? "local-filesystem" : null;
|
|
12930
|
+
}
|
|
12931
|
+
function inferRelayDeploymentScope(relayMode) {
|
|
12932
|
+
return relayMode === "local-file" ? "single-host" : null;
|
|
12933
|
+
}
|
|
12934
|
+
function inferSameHostRestartPersists(relayMode) {
|
|
12935
|
+
return relayMode === "local-file" ? true : null;
|
|
12936
|
+
}
|
|
12413
12937
|
function relayHostedReadinessNotes(options) {
|
|
12414
12938
|
const notes = [];
|
|
12415
12939
|
if (!options.compatible) {
|
|
@@ -12430,6 +12954,17 @@ function relayHostedReadinessNotes(options) {
|
|
|
12430
12954
|
}
|
|
12431
12955
|
return notes;
|
|
12432
12956
|
}
|
|
12957
|
+
function relayOperationalContractNotes(options) {
|
|
12958
|
+
if (!options.compatible) {
|
|
12959
|
+
return [];
|
|
12960
|
+
}
|
|
12961
|
+
if (options.stateBackend === "local-filesystem" && options.deploymentScope === "single-host" && options.sameHostRestartPersists === true) {
|
|
12962
|
+
return [
|
|
12963
|
+
"Relay state is stored on the relay host local filesystem. Restarts on the same host keep pending approval state, but multi-instance or load-balanced deployments do not share relay state."
|
|
12964
|
+
];
|
|
12965
|
+
}
|
|
12966
|
+
return [];
|
|
12967
|
+
}
|
|
12433
12968
|
function relayOriginRelationshipNotes(options) {
|
|
12434
12969
|
const notes = [];
|
|
12435
12970
|
const relayUrlMatchesOrigin = relayUrlMatches(options.relayUrl, options.origin);
|
|
@@ -12446,6 +12981,20 @@ function relayOriginRelationshipNotes(options) {
|
|
|
12446
12981
|
}
|
|
12447
12982
|
return notes;
|
|
12448
12983
|
}
|
|
12984
|
+
function buildRelayDeploymentSummary(options) {
|
|
12985
|
+
return {
|
|
12986
|
+
origin: options.origin,
|
|
12987
|
+
publicOrigin: options.publicOrigin,
|
|
12988
|
+
publicOriginSource: options.publicOriginSource,
|
|
12989
|
+
shareLinkBaseUrl: options.shareLinkBaseUrl,
|
|
12990
|
+
statusApiBaseUrl: options.statusApiBaseUrl,
|
|
12991
|
+
publicOriginConfigured: options.publicOriginSource === "configured",
|
|
12992
|
+
publicOriginLooksLocal: options.publicOriginLooksLocal,
|
|
12993
|
+
connectorUiAvailable: options.connectorUiAvailable,
|
|
12994
|
+
hostedShareRedirectReady: options.hostedShareRedirectReady,
|
|
12995
|
+
singleHostFileState: options.stateBackend === "local-filesystem" && options.deploymentScope === "single-host" && options.sameHostRestartPersists === true
|
|
12996
|
+
};
|
|
12997
|
+
}
|
|
12449
12998
|
function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
12450
12999
|
const health = asRelayHealthResponse(rawHealth);
|
|
12451
13000
|
const fallbackPublicOrigin = isRecord3(rawHealth) && typeof rawHealth.public_origin === "string" ? rawHealth.public_origin : relayUrl;
|
|
@@ -12454,6 +13003,9 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12454
13003
|
origin: health?.origin || null,
|
|
12455
13004
|
publicOrigin
|
|
12456
13005
|
});
|
|
13006
|
+
const stateBackend = health?.state_backend || inferRelayStateBackend(health?.relay_mode || null);
|
|
13007
|
+
const deploymentScope = health?.deployment_scope || inferRelayDeploymentScope(health?.relay_mode || null);
|
|
13008
|
+
const sameHostRestartPersists = typeof health?.same_host_restart_persists === "boolean" ? health.same_host_restart_persists : inferSameHostRestartPersists(health?.relay_mode || null);
|
|
12457
13009
|
const compatible = Boolean(health && hasCoreRelayCapabilities(health.capabilities));
|
|
12458
13010
|
const connectorUiAvailable = health?.connector_ui_available ?? null;
|
|
12459
13011
|
const relayUrlMatchesOrigin = relayUrlMatches(relayUrl, health?.origin || null);
|
|
@@ -12461,6 +13013,19 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12461
13013
|
const publicOriginLooksLocal = relayPublicOriginLooksLocal(publicOrigin);
|
|
12462
13014
|
const hostedShareRedirectReady = compatible && connectorUiAvailable === true && !publicOriginLooksLocal;
|
|
12463
13015
|
const { shareLinkBaseUrl, statusApiBaseUrl } = buildAdvertisedRelayBases(publicOrigin);
|
|
13016
|
+
const deploymentSummary = buildRelayDeploymentSummary({
|
|
13017
|
+
origin: health?.origin || null,
|
|
13018
|
+
publicOrigin,
|
|
13019
|
+
publicOriginSource,
|
|
13020
|
+
shareLinkBaseUrl,
|
|
13021
|
+
statusApiBaseUrl,
|
|
13022
|
+
publicOriginLooksLocal,
|
|
13023
|
+
connectorUiAvailable,
|
|
13024
|
+
hostedShareRedirectReady,
|
|
13025
|
+
stateBackend,
|
|
13026
|
+
deploymentScope,
|
|
13027
|
+
sameHostRestartPersists
|
|
13028
|
+
});
|
|
12464
13029
|
const notes = [
|
|
12465
13030
|
...relayHostedReadinessNotes({
|
|
12466
13031
|
compatible,
|
|
@@ -12468,6 +13033,12 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12468
13033
|
publicOriginSource,
|
|
12469
13034
|
connectorUiAvailable
|
|
12470
13035
|
}),
|
|
13036
|
+
...relayOperationalContractNotes({
|
|
13037
|
+
compatible,
|
|
13038
|
+
stateBackend,
|
|
13039
|
+
deploymentScope,
|
|
13040
|
+
sameHostRestartPersists
|
|
13041
|
+
}),
|
|
12471
13042
|
...relayOriginRelationshipNotes({
|
|
12472
13043
|
relayUrl,
|
|
12473
13044
|
origin: health?.origin || null,
|
|
@@ -12486,6 +13057,9 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12486
13057
|
origin: health?.origin || null,
|
|
12487
13058
|
publicOrigin,
|
|
12488
13059
|
publicOriginSource,
|
|
13060
|
+
stateBackend,
|
|
13061
|
+
deploymentScope,
|
|
13062
|
+
sameHostRestartPersists,
|
|
12489
13063
|
shareLinkBaseUrl,
|
|
12490
13064
|
statusApiBaseUrl,
|
|
12491
13065
|
relayUrlMatchesOrigin,
|
|
@@ -12493,6 +13067,7 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12493
13067
|
publicOriginLooksLocal,
|
|
12494
13068
|
connectorUiAvailable,
|
|
12495
13069
|
hostedShareRedirectReady,
|
|
13070
|
+
deploymentSummary,
|
|
12496
13071
|
capabilities: health?.capabilities || [],
|
|
12497
13072
|
recommendedCommands: compatible ? buildRelayServeRecommendedCommands(publicOrigin) : {},
|
|
12498
13073
|
notes
|
|
@@ -12500,6 +13075,23 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
|
|
|
12500
13075
|
}
|
|
12501
13076
|
function createRelayCommand() {
|
|
12502
13077
|
const relay = new Command8("relay").description("Run the local connector relay prototype server");
|
|
13078
|
+
relay.addHelpText(
|
|
13079
|
+
"after",
|
|
13080
|
+
[
|
|
13081
|
+
"",
|
|
13082
|
+
" Hosted remote-approval path:",
|
|
13083
|
+
" zk-agent relay serve --public-origin https://relay.example.com",
|
|
13084
|
+
" zk-agent relay inspect --relay-url <url>",
|
|
13085
|
+
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
13086
|
+
" zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
|
|
13087
|
+
"",
|
|
13088
|
+
" Keep `wallet create|reapprove --await-local` as the default baseline when",
|
|
13089
|
+
" the browser and terminal are colocated.",
|
|
13090
|
+
"",
|
|
13091
|
+
" Use `relay inspect` before sending operators to a hosted share link so",
|
|
13092
|
+
" the public origin, connector UI, and hosted-readiness contract are visible."
|
|
13093
|
+
].join("\n")
|
|
13094
|
+
);
|
|
12503
13095
|
relay.command("serve").description("Serve the local relay API and, when available, the built connector UI").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind (0 = choose a free port)", "4445").option(
|
|
12504
13096
|
"--public-origin <url>",
|
|
12505
13097
|
"Public base URL to advertise in share/status links when the relay is behind a tunnel or reverse proxy"
|
|
@@ -12521,6 +13113,19 @@ function createRelayCommand() {
|
|
|
12521
13113
|
const hostedShareRedirectReady = connectorUiAvailable && !publicOriginLooksLocal;
|
|
12522
13114
|
const { shareLinkBaseUrl, statusApiBaseUrl } = buildAdvertisedRelayBases(publicOrigin);
|
|
12523
13115
|
const recommendedCommands = buildRelayServeRecommendedCommands(publicOrigin);
|
|
13116
|
+
const deploymentSummary = buildRelayDeploymentSummary({
|
|
13117
|
+
origin: server.origin,
|
|
13118
|
+
publicOrigin,
|
|
13119
|
+
publicOriginSource,
|
|
13120
|
+
shareLinkBaseUrl,
|
|
13121
|
+
statusApiBaseUrl,
|
|
13122
|
+
publicOriginLooksLocal,
|
|
13123
|
+
connectorUiAvailable,
|
|
13124
|
+
hostedShareRedirectReady,
|
|
13125
|
+
stateBackend: "local-filesystem",
|
|
13126
|
+
deploymentScope: "single-host",
|
|
13127
|
+
sameHostRestartPersists: true
|
|
13128
|
+
});
|
|
12524
13129
|
const notes = relayHostedReadinessNotes({
|
|
12525
13130
|
compatible: true,
|
|
12526
13131
|
publicOrigin,
|
|
@@ -12533,9 +13138,13 @@ function createRelayCommand() {
|
|
|
12533
13138
|
origin: server.origin,
|
|
12534
13139
|
publicOrigin,
|
|
12535
13140
|
publicOriginSource,
|
|
13141
|
+
stateBackend: "local-filesystem",
|
|
13142
|
+
deploymentScope: "single-host",
|
|
13143
|
+
sameHostRestartPersists: true,
|
|
12536
13144
|
shareLinkBaseUrl,
|
|
12537
13145
|
statusApiBaseUrl,
|
|
12538
13146
|
publicOriginLooksLocal,
|
|
13147
|
+
deploymentSummary,
|
|
12539
13148
|
port: server.port,
|
|
12540
13149
|
healthUrl: `${server.origin}/health`,
|
|
12541
13150
|
publicHealthUrl: `${publicOrigin}/health`,
|
|
@@ -12562,6 +13171,12 @@ function createRelayCommand() {
|
|
|
12562
13171
|
humanLine("public origin", publicOrigin);
|
|
12563
13172
|
}
|
|
12564
13173
|
humanLine("public origin source", publicOriginSource);
|
|
13174
|
+
humanLine("state backend", payload.stateBackend);
|
|
13175
|
+
humanLine("deployment scope", payload.deploymentScope);
|
|
13176
|
+
humanLine(
|
|
13177
|
+
"same-host restart persists",
|
|
13178
|
+
payload.sameHostRestartPersists ? "yes" : "no"
|
|
13179
|
+
);
|
|
12565
13180
|
humanLine("share-link base", shareLinkBaseUrl);
|
|
12566
13181
|
humanLine("status api base", statusApiBaseUrl);
|
|
12567
13182
|
humanLine("health", `${server.origin}/health`);
|
|
@@ -12618,6 +13233,18 @@ function createRelayCommand() {
|
|
|
12618
13233
|
if (payload.publicOriginSource) {
|
|
12619
13234
|
humanLine("public origin source", payload.publicOriginSource);
|
|
12620
13235
|
}
|
|
13236
|
+
if (payload.stateBackend) {
|
|
13237
|
+
humanLine("state backend", payload.stateBackend);
|
|
13238
|
+
}
|
|
13239
|
+
if (payload.deploymentScope) {
|
|
13240
|
+
humanLine("deployment scope", payload.deploymentScope);
|
|
13241
|
+
}
|
|
13242
|
+
if (payload.sameHostRestartPersists !== null) {
|
|
13243
|
+
humanLine(
|
|
13244
|
+
"same-host restart persists",
|
|
13245
|
+
payload.sameHostRestartPersists ? "yes" : "no"
|
|
13246
|
+
);
|
|
13247
|
+
}
|
|
12621
13248
|
humanLine("share-link base", payload.shareLinkBaseUrl);
|
|
12622
13249
|
humanLine("status api base", payload.statusApiBaseUrl);
|
|
12623
13250
|
if (payload.relayUrlMatchesOrigin !== null) {
|
|
@@ -13260,6 +13887,39 @@ function relayOutputAliases(relay) {
|
|
|
13260
13887
|
relayStatusApiBaseUrl: statusApiBaseUrl
|
|
13261
13888
|
};
|
|
13262
13889
|
}
|
|
13890
|
+
function determineRelayRecoveryMode(options) {
|
|
13891
|
+
if (options.recommendedCommands.reissueRemoteApproval && options.nextAction === options.recommendedCommands.reissueRemoteApproval) {
|
|
13892
|
+
return "reissue-remote-approval";
|
|
13893
|
+
}
|
|
13894
|
+
if (options.recommendedCommands.relayInspect && options.nextAction === options.recommendedCommands.relayInspect) {
|
|
13895
|
+
return "inspect-relay";
|
|
13896
|
+
}
|
|
13897
|
+
if (options.recommendedCommands.approve && options.nextAction === options.recommendedCommands.approve) {
|
|
13898
|
+
return "approve";
|
|
13899
|
+
}
|
|
13900
|
+
return "status-poll";
|
|
13901
|
+
}
|
|
13902
|
+
function buildRelayRecoverySummary(options) {
|
|
13903
|
+
const aliases = relayOutputAliases(options.relay);
|
|
13904
|
+
return {
|
|
13905
|
+
requestId: options.requestId,
|
|
13906
|
+
walletName: options.walletName || null,
|
|
13907
|
+
relayUrl: options.relayUrl,
|
|
13908
|
+
relayStatus: options.relayStatus ?? options.relay?.status ?? null,
|
|
13909
|
+
approvalReady: typeof options.approvalReady === "boolean" ? options.approvalReady : options.relay && "approval_ready" in options.relay ? options.relay.approval_ready : null,
|
|
13910
|
+
nextAction: options.nextAction,
|
|
13911
|
+
shareLinkBaseUrl: aliases.relayShareLinkBaseUrl || null,
|
|
13912
|
+
statusApiBaseUrl: aliases.relayStatusApiBaseUrl || null,
|
|
13913
|
+
recoveryMode: determineRelayRecoveryMode({
|
|
13914
|
+
nextAction: options.nextAction,
|
|
13915
|
+
recommendedCommands: options.recommendedCommands
|
|
13916
|
+
}),
|
|
13917
|
+
includesStatusPoll: Boolean(options.recommendedCommands.status),
|
|
13918
|
+
includesApprove: Boolean(options.recommendedCommands.approve),
|
|
13919
|
+
includesRelayInspect: Boolean(options.recommendedCommands.relayInspect),
|
|
13920
|
+
includesRemoteReissue: Boolean(options.recommendedCommands.reissueRemoteApproval)
|
|
13921
|
+
};
|
|
13922
|
+
}
|
|
13263
13923
|
function sanitizeWalletRequestRecord(request) {
|
|
13264
13924
|
const { sessionSecretKey: _sessionSecretKey, ...rest } = request;
|
|
13265
13925
|
return rest;
|
|
@@ -14527,6 +15187,197 @@ function buildPendingRequestRecommendedCommands(walletName, requestId, relayUrl,
|
|
|
14527
15187
|
function buildPendingRequestNextAction(recommendedCommands) {
|
|
14528
15188
|
return recommendedCommands.relayStatus ?? recommendedCommands.awaitLocal;
|
|
14529
15189
|
}
|
|
15190
|
+
function buildRelayWaitGuidanceLines(options) {
|
|
15191
|
+
return [
|
|
15192
|
+
["status", "Waiting for relay approval"],
|
|
15193
|
+
["request", options.requestId],
|
|
15194
|
+
["wallet", options.walletName],
|
|
15195
|
+
["share url", options.relay.share_url],
|
|
15196
|
+
["status url", options.relay.status_url],
|
|
15197
|
+
["approval url", options.relay.approval_url],
|
|
15198
|
+
["expires", options.expiresAt],
|
|
15199
|
+
["browser step", "Open the share url in a browser and complete connector approval."],
|
|
15200
|
+
[
|
|
15201
|
+
"terminal step",
|
|
15202
|
+
options.codeEntry === "prompt" ? "After the relay is ready, enter the 6-digit approval code in this terminal." : "The CLI will finalize automatically with the provided 6-digit approval code once the relay is ready."
|
|
15203
|
+
],
|
|
15204
|
+
["fallback status", options.statusCommand],
|
|
15205
|
+
["fallback approve", options.approveCommand]
|
|
15206
|
+
];
|
|
15207
|
+
}
|
|
15208
|
+
function printRelayWaitGuidance(options) {
|
|
15209
|
+
if (shouldJsonOutput()) return;
|
|
15210
|
+
for (const [label, value] of buildRelayWaitGuidanceLines(options)) {
|
|
15211
|
+
humanLine(label, value);
|
|
15212
|
+
}
|
|
15213
|
+
}
|
|
15214
|
+
async function buildRelayStatusFollowUp(options) {
|
|
15215
|
+
if (options.relay.status === "expired") {
|
|
15216
|
+
return await buildRelayExpiredRecoveryCommands({
|
|
15217
|
+
walletName: options.relay.request?.walletName,
|
|
15218
|
+
relayUrl: options.relayUrl,
|
|
15219
|
+
paymasterMode: options.relay.request?.requestedPaymasterMode,
|
|
15220
|
+
accountKind: options.relay.request?.requestedAccountKind
|
|
15221
|
+
});
|
|
15222
|
+
}
|
|
15223
|
+
if (options.relay.approval_ready) {
|
|
15224
|
+
const approve = buildWalletRequestRelayApproveRecommendedCommand(
|
|
15225
|
+
options.relay.request_id,
|
|
15226
|
+
options.relayUrl
|
|
15227
|
+
);
|
|
15228
|
+
return {
|
|
15229
|
+
nextAction: approve,
|
|
15230
|
+
recommendedCommands: {
|
|
15231
|
+
status: buildWalletRequestRelayStatusRecommendedCommand(
|
|
15232
|
+
options.relay.request_id,
|
|
15233
|
+
options.relayUrl
|
|
15234
|
+
),
|
|
15235
|
+
approve
|
|
15236
|
+
}
|
|
15237
|
+
};
|
|
15238
|
+
}
|
|
15239
|
+
return {
|
|
15240
|
+
nextAction: buildWalletRequestRelayStatusRecommendedCommand(
|
|
15241
|
+
options.relay.request_id,
|
|
15242
|
+
options.relayUrl
|
|
15243
|
+
),
|
|
15244
|
+
recommendedCommands: {
|
|
15245
|
+
status: buildWalletRequestRelayStatusRecommendedCommand(
|
|
15246
|
+
options.relay.request_id,
|
|
15247
|
+
options.relayUrl
|
|
15248
|
+
)
|
|
15249
|
+
}
|
|
15250
|
+
};
|
|
15251
|
+
}
|
|
15252
|
+
async function buildRelayExpiredRecoveryCommands(options) {
|
|
15253
|
+
const relayInspect = buildRelayInspectRecommendedCommand(options.relayUrl);
|
|
15254
|
+
const walletName = options.walletName?.trim();
|
|
15255
|
+
if (!walletName) {
|
|
15256
|
+
return {
|
|
15257
|
+
nextAction: relayInspect,
|
|
15258
|
+
recommendedCommands: {
|
|
15259
|
+
relayInspect
|
|
15260
|
+
},
|
|
15261
|
+
note: "Relay approval expired. Inspect the hosted relay, then reissue the wallet request again."
|
|
15262
|
+
};
|
|
15263
|
+
}
|
|
15264
|
+
const existingWallet = await loadWalletSession(walletName);
|
|
15265
|
+
const reissueRemoteApproval = existingWallet ? buildWalletReapproveRemoteRecommendedCommand(walletName, options.relayUrl) : buildWalletCreateRemoteRecommendedCommand(
|
|
15266
|
+
options.relayUrl,
|
|
15267
|
+
options.paymasterMode,
|
|
15268
|
+
walletName,
|
|
15269
|
+
options.accountKind
|
|
15270
|
+
);
|
|
15271
|
+
return {
|
|
15272
|
+
nextAction: reissueRemoteApproval,
|
|
15273
|
+
recommendedCommands: {
|
|
15274
|
+
relayInspect,
|
|
15275
|
+
reissueRemoteApproval
|
|
15276
|
+
},
|
|
15277
|
+
note: "Relay approval expired. Reissue the remote request. If the original request used scoped session flags, add those same policy flags again."
|
|
15278
|
+
};
|
|
15279
|
+
}
|
|
15280
|
+
function buildRelayApprovalTimeoutError(options) {
|
|
15281
|
+
const statusCommand = buildWalletRequestRelayStatusRecommendedCommand(
|
|
15282
|
+
options.requestId,
|
|
15283
|
+
options.relayUrl
|
|
15284
|
+
);
|
|
15285
|
+
const approveCommand = buildWalletRequestRelayApproveRecommendedCommand(
|
|
15286
|
+
options.requestId,
|
|
15287
|
+
options.relayUrl
|
|
15288
|
+
);
|
|
15289
|
+
return new AgentError(
|
|
15290
|
+
"RELAY_APPROVAL_TIMEOUT",
|
|
15291
|
+
`Timed out waiting for relay approval after ${Math.ceil(options.timeoutMs / 1e3)} seconds.`,
|
|
15292
|
+
{
|
|
15293
|
+
requestId: options.requestId,
|
|
15294
|
+
relayUrl: options.relayUrl,
|
|
15295
|
+
timeoutMs: options.timeoutMs,
|
|
15296
|
+
intervalMs: options.intervalMs,
|
|
15297
|
+
retryable: true,
|
|
15298
|
+
statusCommand,
|
|
15299
|
+
approveCommand,
|
|
15300
|
+
relayRecoverySummary: buildRelayRecoverySummary({
|
|
15301
|
+
requestId: options.requestId,
|
|
15302
|
+
walletName: options.walletName,
|
|
15303
|
+
relayUrl: options.relayUrl,
|
|
15304
|
+
relayStatus: null,
|
|
15305
|
+
approvalReady: null,
|
|
15306
|
+
nextAction: statusCommand,
|
|
15307
|
+
recommendedCommands: {
|
|
15308
|
+
status: statusCommand,
|
|
15309
|
+
approve: approveCommand
|
|
15310
|
+
}
|
|
15311
|
+
}),
|
|
15312
|
+
suggestedAction: "Check the current relay status, then finalize the wallet approval once approval_ready=true."
|
|
15313
|
+
}
|
|
15314
|
+
);
|
|
15315
|
+
}
|
|
15316
|
+
async function buildRelayApprovalExpiredError(options) {
|
|
15317
|
+
const recovery = await buildRelayExpiredRecoveryCommands({
|
|
15318
|
+
walletName: options.walletName,
|
|
15319
|
+
relayUrl: options.relayUrl,
|
|
15320
|
+
paymasterMode: options.paymasterMode,
|
|
15321
|
+
accountKind: options.accountKind
|
|
15322
|
+
});
|
|
15323
|
+
return new AgentError(
|
|
15324
|
+
"RELAY_APPROVAL_EXPIRED",
|
|
15325
|
+
`Relay approval expired before the encrypted payload was ready for request ${options.requestId}.`,
|
|
15326
|
+
{
|
|
15327
|
+
requestId: options.requestId,
|
|
15328
|
+
relayUrl: options.relayUrl,
|
|
15329
|
+
retryable: true,
|
|
15330
|
+
note: recovery.note,
|
|
15331
|
+
relayInspectCommand: recovery.recommendedCommands.relayInspect,
|
|
15332
|
+
reissueRemoteApprovalCommand: recovery.recommendedCommands.reissueRemoteApproval,
|
|
15333
|
+
relayRecoverySummary: buildRelayRecoverySummary({
|
|
15334
|
+
requestId: options.requestId,
|
|
15335
|
+
walletName: options.walletName,
|
|
15336
|
+
relayUrl: options.relayUrl,
|
|
15337
|
+
relayStatus: "expired",
|
|
15338
|
+
approvalReady: false,
|
|
15339
|
+
nextAction: recovery.nextAction,
|
|
15340
|
+
recommendedCommands: recovery.recommendedCommands
|
|
15341
|
+
}),
|
|
15342
|
+
suggestedAction: "Inspect the hosted relay, then reissue the remote approval request."
|
|
15343
|
+
}
|
|
15344
|
+
);
|
|
15345
|
+
}
|
|
15346
|
+
function buildRelayApprovalNotReadyError(options) {
|
|
15347
|
+
const statusCommand = buildWalletRequestRelayStatusRecommendedCommand(
|
|
15348
|
+
options.requestId,
|
|
15349
|
+
options.relayUrl
|
|
15350
|
+
);
|
|
15351
|
+
const approveCommand = buildWalletRequestRelayApproveRecommendedCommand(
|
|
15352
|
+
options.requestId,
|
|
15353
|
+
options.relayUrl
|
|
15354
|
+
);
|
|
15355
|
+
return new AgentError(
|
|
15356
|
+
"RELAY_APPROVAL_NOT_READY",
|
|
15357
|
+
`Relay approval is not ready yet for request ${options.requestId}.`,
|
|
15358
|
+
{
|
|
15359
|
+
requestId: options.requestId,
|
|
15360
|
+
relayUrl: options.relayUrl,
|
|
15361
|
+
status: options.status,
|
|
15362
|
+
approvalReady: options.approvalReady,
|
|
15363
|
+
retryable: true,
|
|
15364
|
+
statusCommand,
|
|
15365
|
+
approveCommand,
|
|
15366
|
+
relayRecoverySummary: buildRelayRecoverySummary({
|
|
15367
|
+
requestId: options.requestId,
|
|
15368
|
+
relayUrl: options.relayUrl,
|
|
15369
|
+
relayStatus: options.status,
|
|
15370
|
+
approvalReady: options.approvalReady,
|
|
15371
|
+
nextAction: statusCommand,
|
|
15372
|
+
recommendedCommands: {
|
|
15373
|
+
status: statusCommand,
|
|
15374
|
+
approve: approveCommand
|
|
15375
|
+
}
|
|
15376
|
+
}),
|
|
15377
|
+
suggestedAction: "Check the current relay status, then retry approval once approval_ready=true."
|
|
15378
|
+
}
|
|
15379
|
+
);
|
|
15380
|
+
}
|
|
14530
15381
|
function buildRequestListEntryRecommendedCommands(walletName, requestId, paymasterMode) {
|
|
14531
15382
|
return {
|
|
14532
15383
|
show: buildWalletRequestShowRecommendedCommand(requestId),
|
|
@@ -14669,25 +15520,56 @@ async function fetchEncryptedRelayApprovalPayload(relayUrl, requestId, options)
|
|
|
14669
15520
|
intervalMs: options.intervalMs ?? 2e3
|
|
14670
15521
|
});
|
|
14671
15522
|
if (!relay.approval_ready) {
|
|
14672
|
-
throw
|
|
15523
|
+
throw await buildRelayApprovalExpiredError({
|
|
15524
|
+
requestId,
|
|
15525
|
+
relayUrl
|
|
15526
|
+
});
|
|
14673
15527
|
}
|
|
14674
15528
|
}
|
|
14675
15529
|
const approval = await fetchRelayApproval(relayUrl, requestId);
|
|
14676
15530
|
if (!approval.approval_ready || !approval.encrypted_payload) {
|
|
14677
|
-
throw
|
|
15531
|
+
throw buildRelayApprovalNotReadyError({
|
|
15532
|
+
requestId,
|
|
15533
|
+
relayUrl,
|
|
15534
|
+
status: approval.status,
|
|
15535
|
+
approvalReady: approval.approval_ready
|
|
15536
|
+
});
|
|
14678
15537
|
}
|
|
14679
15538
|
return approval.encrypted_payload;
|
|
14680
15539
|
}
|
|
14681
15540
|
async function finalizePublishedRelayWalletRequest(options) {
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
15541
|
+
let encryptedPayload;
|
|
15542
|
+
try {
|
|
15543
|
+
encryptedPayload = await fetchEncryptedRelayApprovalPayload(
|
|
15544
|
+
options.relayUrl,
|
|
15545
|
+
options.walletRequest.requestId,
|
|
15546
|
+
{
|
|
15547
|
+
wait: true,
|
|
15548
|
+
timeoutMs: options.timeoutMs,
|
|
15549
|
+
intervalMs: options.intervalMs
|
|
15550
|
+
}
|
|
15551
|
+
);
|
|
15552
|
+
} catch (error) {
|
|
15553
|
+
if (error instanceof Error && error.message.startsWith("Timed out waiting for relay approval after ")) {
|
|
15554
|
+
throw buildRelayApprovalTimeoutError({
|
|
15555
|
+
requestId: options.walletRequest.requestId,
|
|
15556
|
+
walletName: options.walletRequest.walletName,
|
|
15557
|
+
relayUrl: options.relayUrl,
|
|
15558
|
+
timeoutMs: options.timeoutMs,
|
|
15559
|
+
intervalMs: options.intervalMs
|
|
15560
|
+
});
|
|
14689
15561
|
}
|
|
14690
|
-
|
|
15562
|
+
if (error instanceof AgentError && error.code === "RELAY_APPROVAL_EXPIRED") {
|
|
15563
|
+
throw await buildRelayApprovalExpiredError({
|
|
15564
|
+
requestId: options.walletRequest.requestId,
|
|
15565
|
+
walletName: options.walletRequest.walletName,
|
|
15566
|
+
relayUrl: options.relayUrl,
|
|
15567
|
+
paymasterMode: options.walletRequest.requestedPaymasterMode,
|
|
15568
|
+
accountKind: options.walletRequest.requestedAccountKind
|
|
15569
|
+
});
|
|
15570
|
+
}
|
|
15571
|
+
throw error;
|
|
15572
|
+
}
|
|
14691
15573
|
const code = options.code || (options.promptCode ? await readApprovalCodeFromStdin() : void 0);
|
|
14692
15574
|
if (!code) {
|
|
14693
15575
|
throw new Error("Missing relay approval code.");
|
|
@@ -15054,7 +15936,9 @@ async function printBuiltinSmartAccountProfiles() {
|
|
|
15054
15936
|
}
|
|
15055
15937
|
function createWalletCommand(deps) {
|
|
15056
15938
|
const resolvedDeps = resolveWalletCommandDeps(deps);
|
|
15057
|
-
const wallet = new Command9("wallet").description(
|
|
15939
|
+
const wallet = new Command9("wallet").description(
|
|
15940
|
+
"Create, inspect, and recover local-first wallet sessions"
|
|
15941
|
+
);
|
|
15058
15942
|
const request = new Command9("request").description("Inspect and finalize pending wallet requests");
|
|
15059
15943
|
const signer = new Command9("signer").description(
|
|
15060
15944
|
"Inspect and manage the stored local execution signer for a wallet"
|
|
@@ -15104,7 +15988,8 @@ function createWalletCommand(deps) {
|
|
|
15104
15988
|
" Hosted remote approval path:",
|
|
15105
15989
|
" zk-agent relay inspect --relay-url <url>",
|
|
15106
15990
|
" zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
|
|
15107
|
-
" zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code"
|
|
15991
|
+
" zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
|
|
15992
|
+
" zk-agent next"
|
|
15108
15993
|
].join("\n")
|
|
15109
15994
|
);
|
|
15110
15995
|
request.addHelpText(
|
|
@@ -15118,7 +16003,11 @@ function createWalletCommand(deps) {
|
|
|
15118
16003
|
" Remote relay completion:",
|
|
15119
16004
|
" zk-agent wallet request relay-publish --request-id <id> --relay-url <url>",
|
|
15120
16005
|
" zk-agent wallet request relay-status --request-id <id> --relay-url <url> --wait",
|
|
15121
|
-
" zk-agent wallet request approve --request-id <id> --relay-url <url> --code <code> --wait"
|
|
16006
|
+
" zk-agent wallet request approve --request-id <id> --relay-url <url> --code <code> --wait",
|
|
16007
|
+
"",
|
|
16008
|
+
" If relay-status returns status = expired:",
|
|
16009
|
+
" zk-agent relay inspect --relay-url <url>",
|
|
16010
|
+
" zk-agent wallet create|reapprove --relay-url <url> --wait-relay --prompt-code"
|
|
15122
16011
|
].join("\n")
|
|
15123
16012
|
);
|
|
15124
16013
|
signer.addHelpText(
|
|
@@ -15217,6 +16106,23 @@ function createWalletCommand(deps) {
|
|
|
15217
16106
|
}
|
|
15218
16107
|
const relay = options.relayUrl ? await publishWalletRequestToRelay(request2, options.relayUrl) : void 0;
|
|
15219
16108
|
if (relayWaitOptions) {
|
|
16109
|
+
if (relay) {
|
|
16110
|
+
printRelayWaitGuidance({
|
|
16111
|
+
requestId: request2.requestId,
|
|
16112
|
+
walletName: request2.walletName,
|
|
16113
|
+
relay,
|
|
16114
|
+
expiresAt: request2.expiresAt,
|
|
16115
|
+
codeEntry: relayWaitOptions.promptCode ? "prompt" : "provided",
|
|
16116
|
+
statusCommand: buildWalletRequestRelayStatusRecommendedCommand(
|
|
16117
|
+
request2.requestId,
|
|
16118
|
+
relayWaitOptions.relayUrl
|
|
16119
|
+
),
|
|
16120
|
+
approveCommand: buildWalletRequestRelayApproveRecommendedCommand(
|
|
16121
|
+
request2.requestId,
|
|
16122
|
+
relayWaitOptions.relayUrl
|
|
16123
|
+
)
|
|
16124
|
+
});
|
|
16125
|
+
}
|
|
15220
16126
|
const { payload, walletRecord } = await finalizePublishedRelayWalletRequest({
|
|
15221
16127
|
walletRequest: request2,
|
|
15222
16128
|
...relayWaitOptions
|
|
@@ -15248,6 +16154,20 @@ function createWalletCommand(deps) {
|
|
|
15248
16154
|
options.relayUrl,
|
|
15249
16155
|
request2.requestedPaymasterMode
|
|
15250
16156
|
);
|
|
16157
|
+
const nextAction = buildPendingRequestNextAction(recommendedCommands);
|
|
16158
|
+
const relayRecoverySummary = relay && recommendedCommands.relayStatus && recommendedCommands.relayApprove ? buildRelayRecoverySummary({
|
|
16159
|
+
requestId: request2.requestId,
|
|
16160
|
+
walletName: request2.walletName,
|
|
16161
|
+
relayUrl: options.relayUrl,
|
|
16162
|
+
relayStatus: relay.status,
|
|
16163
|
+
approvalReady: null,
|
|
16164
|
+
nextAction,
|
|
16165
|
+
recommendedCommands: {
|
|
16166
|
+
status: recommendedCommands.relayStatus,
|
|
16167
|
+
approve: recommendedCommands.relayApprove
|
|
16168
|
+
},
|
|
16169
|
+
relay
|
|
16170
|
+
}) : void 0;
|
|
15251
16171
|
printResult(
|
|
15252
16172
|
[
|
|
15253
16173
|
["wallet", request2.walletName],
|
|
@@ -15290,6 +16210,7 @@ function createWalletCommand(deps) {
|
|
|
15290
16210
|
approvalUrl: request2.approvalUrl,
|
|
15291
16211
|
relay,
|
|
15292
16212
|
...relayOutputAliases(relay),
|
|
16213
|
+
relayRecoverySummary,
|
|
15293
16214
|
expiresAt: request2.expiresAt,
|
|
15294
16215
|
chain: request2.chain,
|
|
15295
16216
|
chainId: request2.chainId,
|
|
@@ -15297,7 +16218,7 @@ function createWalletCommand(deps) {
|
|
|
15297
16218
|
paymasterMode: request2.requestedPaymasterMode,
|
|
15298
16219
|
capabilities: request2.requestedCapabilities,
|
|
15299
16220
|
sessionScope: request2.requestedSessionScope,
|
|
15300
|
-
nextAction
|
|
16221
|
+
nextAction,
|
|
15301
16222
|
recommendedCommands
|
|
15302
16223
|
}
|
|
15303
16224
|
);
|
|
@@ -15365,6 +16286,23 @@ function createWalletCommand(deps) {
|
|
|
15365
16286
|
}
|
|
15366
16287
|
const relay = options.relayUrl ? await publishWalletRequestToRelay(request2, options.relayUrl) : void 0;
|
|
15367
16288
|
if (relayWaitOptions) {
|
|
16289
|
+
if (relay) {
|
|
16290
|
+
printRelayWaitGuidance({
|
|
16291
|
+
requestId: request2.requestId,
|
|
16292
|
+
walletName: request2.walletName,
|
|
16293
|
+
relay,
|
|
16294
|
+
expiresAt: request2.expiresAt,
|
|
16295
|
+
codeEntry: relayWaitOptions.promptCode ? "prompt" : "provided",
|
|
16296
|
+
statusCommand: buildWalletRequestRelayStatusRecommendedCommand(
|
|
16297
|
+
request2.requestId,
|
|
16298
|
+
relayWaitOptions.relayUrl
|
|
16299
|
+
),
|
|
16300
|
+
approveCommand: buildWalletRequestRelayApproveRecommendedCommand(
|
|
16301
|
+
request2.requestId,
|
|
16302
|
+
relayWaitOptions.relayUrl
|
|
16303
|
+
)
|
|
16304
|
+
});
|
|
16305
|
+
}
|
|
15368
16306
|
const { payload, walletRecord: approvedWallet } = await finalizePublishedRelayWalletRequest({
|
|
15369
16307
|
walletRequest: request2,
|
|
15370
16308
|
...relayWaitOptions
|
|
@@ -15396,6 +16334,20 @@ function createWalletCommand(deps) {
|
|
|
15396
16334
|
options.relayUrl,
|
|
15397
16335
|
request2.requestedPaymasterMode
|
|
15398
16336
|
);
|
|
16337
|
+
const nextAction = buildPendingRequestNextAction(recommendedCommands);
|
|
16338
|
+
const relayRecoverySummary = relay && recommendedCommands.relayStatus && recommendedCommands.relayApprove ? buildRelayRecoverySummary({
|
|
16339
|
+
requestId: request2.requestId,
|
|
16340
|
+
walletName: request2.walletName,
|
|
16341
|
+
relayUrl: options.relayUrl,
|
|
16342
|
+
relayStatus: relay.status,
|
|
16343
|
+
approvalReady: null,
|
|
16344
|
+
nextAction,
|
|
16345
|
+
recommendedCommands: {
|
|
16346
|
+
status: recommendedCommands.relayStatus,
|
|
16347
|
+
approve: recommendedCommands.relayApprove
|
|
16348
|
+
},
|
|
16349
|
+
relay
|
|
16350
|
+
}) : void 0;
|
|
15399
16351
|
printResult(
|
|
15400
16352
|
[
|
|
15401
16353
|
["wallet", request2.walletName],
|
|
@@ -15438,7 +16390,8 @@ function createWalletCommand(deps) {
|
|
|
15438
16390
|
request: sanitizeWalletRequestRecord(request2),
|
|
15439
16391
|
relay,
|
|
15440
16392
|
...relayOutputAliases(relay),
|
|
15441
|
-
|
|
16393
|
+
relayRecoverySummary,
|
|
16394
|
+
nextAction,
|
|
15442
16395
|
recommendedCommands
|
|
15443
16396
|
}
|
|
15444
16397
|
);
|
|
@@ -15582,6 +16535,13 @@ function createWalletCommand(deps) {
|
|
|
15582
16535
|
walletRecord.walletName,
|
|
15583
16536
|
summary
|
|
15584
16537
|
);
|
|
16538
|
+
const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
|
|
16539
|
+
walletName: walletRecord.walletName,
|
|
16540
|
+
chain: summary.chain,
|
|
16541
|
+
nextAction: summary.recommendedCommand,
|
|
16542
|
+
paymasterMode: resolveEffectivePaymasterSelection(walletRecord)?.mode,
|
|
16543
|
+
recommendedCommands
|
|
16544
|
+
});
|
|
15585
16545
|
printResult(
|
|
15586
16546
|
[
|
|
15587
16547
|
...walletNextLines(summary),
|
|
@@ -15595,6 +16555,7 @@ function createWalletCommand(deps) {
|
|
|
15595
16555
|
ok: true,
|
|
15596
16556
|
inspection,
|
|
15597
16557
|
summary,
|
|
16558
|
+
tokenDiscoverySummary,
|
|
15598
16559
|
recommendedCommands
|
|
15599
16560
|
}
|
|
15600
16561
|
);
|
|
@@ -15758,6 +16719,30 @@ function createWalletCommand(deps) {
|
|
|
15758
16719
|
request.command("relay-publish").description("Publish a stored wallet request to a relay server and get a shareable approval URL").requiredOption("--request-id <id>", "Wallet request id").requiredOption("--relay-url <url>", "Relay server base URL").action(async (options) => {
|
|
15759
16720
|
const walletRequest = await requireActiveWalletRequest(options.requestId);
|
|
15760
16721
|
const relay = await publishWalletRequestToRelay(walletRequest, options.relayUrl);
|
|
16722
|
+
const nextAction = buildWalletRequestRelayStatusRecommendedCommand(
|
|
16723
|
+
relay.request_id,
|
|
16724
|
+
options.relayUrl
|
|
16725
|
+
);
|
|
16726
|
+
const recommendedCommands = {
|
|
16727
|
+
status: buildWalletRequestRelayStatusRecommendedCommand(
|
|
16728
|
+
relay.request_id,
|
|
16729
|
+
options.relayUrl
|
|
16730
|
+
),
|
|
16731
|
+
approve: buildWalletRequestRelayApproveRecommendedCommand(
|
|
16732
|
+
relay.request_id,
|
|
16733
|
+
options.relayUrl
|
|
16734
|
+
)
|
|
16735
|
+
};
|
|
16736
|
+
const relayRecoverySummary = buildRelayRecoverySummary({
|
|
16737
|
+
requestId: relay.request_id,
|
|
16738
|
+
walletName: walletRequest.walletName,
|
|
16739
|
+
relayUrl: options.relayUrl,
|
|
16740
|
+
relayStatus: relay.status,
|
|
16741
|
+
approvalReady: null,
|
|
16742
|
+
nextAction,
|
|
16743
|
+
recommendedCommands,
|
|
16744
|
+
relay
|
|
16745
|
+
});
|
|
15761
16746
|
printResult(
|
|
15762
16747
|
[
|
|
15763
16748
|
["status", relay.status],
|
|
@@ -15766,58 +16751,82 @@ function createWalletCommand(deps) {
|
|
|
15766
16751
|
["status url", relay.status_url],
|
|
15767
16752
|
["share-link base", relay.share_url.replace(/\/[^/]+$/, "")],
|
|
15768
16753
|
["status api base", relay.status_url.replace(/\/[^/]+$/, "")],
|
|
15769
|
-
["next status",
|
|
15770
|
-
["next approve",
|
|
16754
|
+
["next status", recommendedCommands.status],
|
|
16755
|
+
["next approve", recommendedCommands.approve]
|
|
15771
16756
|
],
|
|
15772
16757
|
{
|
|
15773
16758
|
ok: true,
|
|
15774
16759
|
walletRequestId: walletRequest.requestId,
|
|
15775
16760
|
relay,
|
|
15776
16761
|
...relayOutputAliases(relay),
|
|
16762
|
+
relayRecoverySummary,
|
|
15777
16763
|
request: sanitizeWalletRequestRecord(walletRequest),
|
|
15778
|
-
nextAction
|
|
15779
|
-
recommendedCommands
|
|
15780
|
-
status: buildWalletRequestRelayStatusRecommendedCommand(relay.request_id, options.relayUrl),
|
|
15781
|
-
approve: buildWalletRequestRelayApproveRecommendedCommand(relay.request_id, options.relayUrl)
|
|
15782
|
-
}
|
|
16764
|
+
nextAction,
|
|
16765
|
+
recommendedCommands
|
|
15783
16766
|
}
|
|
15784
16767
|
);
|
|
15785
16768
|
});
|
|
15786
16769
|
request.command("relay-status").description("Inspect the relay status of a published wallet request, optionally waiting until approval is ready").requiredOption("--request-id <id>", "Wallet request id").requiredOption("--relay-url <url>", "Relay server base URL").option("--wait", "Poll until the encrypted relay approval is ready or the request expires").option("--timeout-seconds <seconds>", "How long to wait while polling relay status", "600").option("--interval-ms <milliseconds>", "How often to poll relay status while waiting", "2000").action(async (options) => {
|
|
15787
|
-
const
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
16770
|
+
const timeoutMs = parsePositiveIntegerOption(options.timeoutSeconds, "--timeout-seconds", 600) * 1e3;
|
|
16771
|
+
const intervalMs = parsePositiveIntegerOption(options.intervalMs, "--interval-ms", 2e3);
|
|
16772
|
+
const walletRequest = await loadWalletRequest(options.requestId);
|
|
16773
|
+
let relay;
|
|
16774
|
+
try {
|
|
16775
|
+
relay = options.wait ? await waitForRelayApprovalReady(options.relayUrl, options.requestId, {
|
|
16776
|
+
timeoutMs,
|
|
16777
|
+
intervalMs
|
|
16778
|
+
}) : await fetchRelayStatus(options.relayUrl, options.requestId);
|
|
16779
|
+
} catch (error) {
|
|
16780
|
+
if (options.wait && error instanceof Error && error.message.startsWith("Timed out waiting for relay approval after ")) {
|
|
16781
|
+
throw buildRelayApprovalTimeoutError({
|
|
16782
|
+
requestId: options.requestId,
|
|
16783
|
+
walletName: walletRequest?.walletName,
|
|
16784
|
+
relayUrl: options.relayUrl,
|
|
16785
|
+
timeoutMs,
|
|
16786
|
+
intervalMs
|
|
16787
|
+
});
|
|
16788
|
+
}
|
|
16789
|
+
throw error;
|
|
16790
|
+
}
|
|
16791
|
+
const followUp = await buildRelayStatusFollowUp({
|
|
16792
|
+
relay,
|
|
16793
|
+
relayUrl: options.relayUrl
|
|
16794
|
+
});
|
|
16795
|
+
const relayRecoverySummary = buildRelayRecoverySummary({
|
|
16796
|
+
requestId: relay.request_id,
|
|
16797
|
+
walletName: relay.request?.walletName || walletRequest?.walletName,
|
|
16798
|
+
relayUrl: options.relayUrl,
|
|
16799
|
+
relayStatus: relay.status,
|
|
16800
|
+
approvalReady: relay.approval_ready,
|
|
16801
|
+
nextAction: followUp.nextAction,
|
|
16802
|
+
recommendedCommands: followUp.recommendedCommands,
|
|
16803
|
+
relay
|
|
16804
|
+
});
|
|
15791
16805
|
printResult(
|
|
15792
16806
|
[
|
|
15793
16807
|
["status", relay.status],
|
|
15794
16808
|
["request", relay.request_id],
|
|
15795
16809
|
["approval ready", relay.approval_ready ? "yes" : "no"],
|
|
15796
|
-
["share url", relay.
|
|
15797
|
-
["
|
|
15798
|
-
["
|
|
16810
|
+
["share url", relay.share_url],
|
|
16811
|
+
["status url", relay.status_url],
|
|
16812
|
+
["approval url", relay.approval_url],
|
|
16813
|
+
["share-link base", relay.share_url.replace(/\/[^/]+$/, "")],
|
|
16814
|
+
["status api base", relay.status_url.replace(/\/[^/]+$/, "")],
|
|
15799
16815
|
["expires", relay.expires_at],
|
|
15800
|
-
["
|
|
15801
|
-
...
|
|
15802
|
-
|
|
15803
|
-
|
|
15804
|
-
]] : []
|
|
16816
|
+
...followUp.note ? [["note", followUp.note]] : [],
|
|
16817
|
+
...Object.entries(followUp.recommendedCommands).map(
|
|
16818
|
+
([label, command]) => [label, command]
|
|
16819
|
+
)
|
|
15805
16820
|
],
|
|
15806
16821
|
{
|
|
15807
16822
|
ok: true,
|
|
15808
16823
|
walletRequestId: relay.request_id,
|
|
15809
16824
|
relay,
|
|
15810
16825
|
...relayOutputAliases(relay),
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
approve: buildWalletRequestRelayApproveRecommendedCommand(
|
|
15816
|
-
relay.request_id,
|
|
15817
|
-
options.relayUrl
|
|
15818
|
-
)
|
|
15819
|
-
} : {}
|
|
15820
|
-
}
|
|
16826
|
+
relayRecoverySummary,
|
|
16827
|
+
nextAction: followUp.nextAction,
|
|
16828
|
+
recommendedCommands: followUp.recommendedCommands,
|
|
16829
|
+
...followUp.note ? { note: followUp.note } : {}
|
|
15821
16830
|
}
|
|
15822
16831
|
);
|
|
15823
16832
|
});
|
|
@@ -15830,6 +16839,24 @@ function createWalletCommand(deps) {
|
|
|
15830
16839
|
if (options.wait && !options.relayUrl) {
|
|
15831
16840
|
throw new Error("--wait is only supported together with --relay-url.");
|
|
15832
16841
|
}
|
|
16842
|
+
if (options.wait && options.relayUrl && !shouldJsonOutput()) {
|
|
16843
|
+
const relayStatus2 = await fetchRelayStatus(options.relayUrl, walletRequest.requestId);
|
|
16844
|
+
printRelayWaitGuidance({
|
|
16845
|
+
requestId: walletRequest.requestId,
|
|
16846
|
+
walletName: walletRequest.walletName,
|
|
16847
|
+
relay: relayStatus2,
|
|
16848
|
+
expiresAt: walletRequest.expiresAt,
|
|
16849
|
+
codeEntry: "provided",
|
|
16850
|
+
statusCommand: buildWalletRequestRelayStatusRecommendedCommand(
|
|
16851
|
+
walletRequest.requestId,
|
|
16852
|
+
options.relayUrl
|
|
16853
|
+
),
|
|
16854
|
+
approveCommand: buildWalletRequestRelayApproveRecommendedCommand(
|
|
16855
|
+
walletRequest.requestId,
|
|
16856
|
+
options.relayUrl
|
|
16857
|
+
)
|
|
16858
|
+
});
|
|
16859
|
+
}
|
|
15833
16860
|
const payload = options.payload ? parseJsonInput(options.payload) : decryptApprovedPayloadForWalletRequest(
|
|
15834
16861
|
walletRequest,
|
|
15835
16862
|
options.encryptedPayload ? parseJsonInput(options.encryptedPayload) : await fetchEncryptedRelayApprovalPayload(options.relayUrl, walletRequest.requestId, {
|
|
@@ -18137,7 +19164,16 @@ async function printWorkflowRunCommandResult(execution) {
|
|
|
18137
19164
|
walletName: execution.result.walletName,
|
|
18138
19165
|
nextAction: execution.result.nextCommand,
|
|
18139
19166
|
chain: execution.result.plan.chain,
|
|
18140
|
-
intent: execution.result.intent
|
|
19167
|
+
intent: execution.result.intent,
|
|
19168
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal)
|
|
19169
|
+
});
|
|
19170
|
+
const tokenDiscoverySummary2 = buildWorkflowTokenDiscoverySummary({
|
|
19171
|
+
walletName: execution.result.walletName,
|
|
19172
|
+
chain: execution.result.plan.chain,
|
|
19173
|
+
intent: execution.result.intent,
|
|
19174
|
+
nextAction: execution.result.nextCommand,
|
|
19175
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal),
|
|
19176
|
+
recommendedCommands: recommendedCommands2
|
|
18141
19177
|
});
|
|
18142
19178
|
printResult(
|
|
18143
19179
|
prependWorkflowRequestId(
|
|
@@ -18163,6 +19199,7 @@ async function printWorkflowRunCommandResult(execution) {
|
|
|
18163
19199
|
...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
|
|
18164
19200
|
walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
|
|
18165
19201
|
walletApproval: serializeWalletApproval(execution.walletApproval),
|
|
19202
|
+
tokenDiscoverySummary: tokenDiscoverySummary2,
|
|
18166
19203
|
recommendedCommands: recommendedCommands2
|
|
18167
19204
|
}
|
|
18168
19205
|
);
|
|
@@ -18178,7 +19215,16 @@ async function printWorkflowRunCommandResult(execution) {
|
|
|
18178
19215
|
walletName: execution.status.walletName,
|
|
18179
19216
|
nextAction: execution.status.recommendedCommand,
|
|
18180
19217
|
chain: execution.status.plan.chain,
|
|
18181
|
-
intent: execution.status.intent
|
|
19218
|
+
intent: execution.status.intent,
|
|
19219
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
|
|
19220
|
+
});
|
|
19221
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
19222
|
+
walletName: execution.status.walletName,
|
|
19223
|
+
chain: execution.status.plan.chain,
|
|
19224
|
+
intent: execution.status.intent,
|
|
19225
|
+
nextAction: execution.status.recommendedCommand,
|
|
19226
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
|
|
19227
|
+
recommendedCommands
|
|
18182
19228
|
});
|
|
18183
19229
|
printResult(
|
|
18184
19230
|
prependWorkflowRequestId(
|
|
@@ -18205,6 +19251,7 @@ async function printWorkflowRunCommandResult(execution) {
|
|
|
18205
19251
|
...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
|
|
18206
19252
|
walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
|
|
18207
19253
|
walletApproval: serializeWalletApproval(execution.walletApproval),
|
|
19254
|
+
tokenDiscoverySummary,
|
|
18208
19255
|
recommendedCommands
|
|
18209
19256
|
}
|
|
18210
19257
|
);
|
|
@@ -18450,6 +19497,7 @@ async function executeWorkflowAutoCommand(options, deps = resolveWorkflowCommand
|
|
|
18450
19497
|
action: result ? result.stage : walletApproval?.stage ?? status.status,
|
|
18451
19498
|
requestId: context.requestId,
|
|
18452
19499
|
checkpointPersisted: Boolean(checkpoint),
|
|
19500
|
+
goal: context.goal,
|
|
18453
19501
|
checkpoint,
|
|
18454
19502
|
status,
|
|
18455
19503
|
result,
|
|
@@ -18468,7 +19516,16 @@ async function printWorkflowAutoCommandResult(execution) {
|
|
|
18468
19516
|
walletName: execution.status.walletName,
|
|
18469
19517
|
nextAction,
|
|
18470
19518
|
chain: execution.status.plan.chain,
|
|
18471
|
-
intent: execution.status.intent
|
|
19519
|
+
intent: execution.status.intent,
|
|
19520
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal) ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
|
|
19521
|
+
});
|
|
19522
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
19523
|
+
walletName: execution.status.walletName,
|
|
19524
|
+
chain: execution.status.plan.chain,
|
|
19525
|
+
intent: execution.status.intent,
|
|
19526
|
+
nextAction,
|
|
19527
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal) ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
|
|
19528
|
+
recommendedCommands
|
|
18472
19529
|
});
|
|
18473
19530
|
const summaryLines = [
|
|
18474
19531
|
["source", execution.source],
|
|
@@ -18506,6 +19563,7 @@ async function printWorkflowAutoCommandResult(execution) {
|
|
|
18506
19563
|
...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
|
|
18507
19564
|
walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
|
|
18508
19565
|
walletApproval: serializeWalletApproval(execution.walletApproval),
|
|
19566
|
+
tokenDiscoverySummary,
|
|
18509
19567
|
recommendedCommands
|
|
18510
19568
|
}
|
|
18511
19569
|
);
|
|
@@ -18530,7 +19588,21 @@ function buildWorkflowCheckpointRecommendedCommands(checkpoint) {
|
|
|
18530
19588
|
walletStatus: buildWalletStatusRecommendedCommand(checkpoint.walletName)
|
|
18531
19589
|
};
|
|
18532
19590
|
}
|
|
19591
|
+
function extractWorkflowGoalPaymasterMode(goal) {
|
|
19592
|
+
if (!goal || !("paymaster" in goal)) {
|
|
19593
|
+
return void 0;
|
|
19594
|
+
}
|
|
19595
|
+
return goal.paymaster?.mode;
|
|
19596
|
+
}
|
|
19597
|
+
function extractPaymasterModeFromCommand(command) {
|
|
19598
|
+
if (!command) {
|
|
19599
|
+
return void 0;
|
|
19600
|
+
}
|
|
19601
|
+
const match = command.match(/--paymaster-mode (none|sponsored|approval-based)\b/);
|
|
19602
|
+
return match?.[1];
|
|
19603
|
+
}
|
|
18533
19604
|
function buildWorkflowRuntimeRecommendedCommands(input) {
|
|
19605
|
+
const paymasterMode = extractPaymasterModeFromCommand(input.nextAction) ?? input.paymasterMode;
|
|
18534
19606
|
return {
|
|
18535
19607
|
inspectDefaults: "zk-agent defaults",
|
|
18536
19608
|
list: buildWorkflowListRecommendedCommand(),
|
|
@@ -18547,30 +19619,76 @@ function buildWorkflowRuntimeRecommendedCommands(input) {
|
|
|
18547
19619
|
...input.nextAction ? {
|
|
18548
19620
|
nextAction: input.nextAction
|
|
18549
19621
|
} : {},
|
|
18550
|
-
...input.chain && input.intent &&
|
|
19622
|
+
...input.chain && input.intent && workflowIntentSupportsTokenDiscovery3(input.intent) ? {
|
|
18551
19623
|
...input.walletName ? {
|
|
18552
19624
|
discoverAssets: `zk-agent assets --wallet ${input.walletName}`,
|
|
18553
19625
|
discoverOwnedTokens: `zk-agent tokens --wallet ${input.walletName} --owned`
|
|
18554
19626
|
} : {},
|
|
18555
19627
|
discoverTokens: `zk-agent tokens --chain ${input.chain}`,
|
|
18556
19628
|
inspectToken: `zk-agent resolve-token --chain ${input.chain} --symbol <symbol>`
|
|
19629
|
+
} : {},
|
|
19630
|
+
...input.chain && paymasterMode === "approval-based" ? {
|
|
19631
|
+
discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(input.chain),
|
|
19632
|
+
inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(input.chain)
|
|
18557
19633
|
} : {}
|
|
18558
19634
|
};
|
|
18559
19635
|
}
|
|
18560
|
-
function
|
|
19636
|
+
function workflowIntentSupportsTokenDiscovery3(intent) {
|
|
18561
19637
|
return intent === "send-token" || intent === "swap" || intent === "bridge" || intent === "deposit" || intent === "withdraw";
|
|
18562
19638
|
}
|
|
19639
|
+
function buildWorkflowTokenDiscoverySummary(input) {
|
|
19640
|
+
if (!input.recommendedCommands) {
|
|
19641
|
+
return void 0;
|
|
19642
|
+
}
|
|
19643
|
+
const hasTokenDiscovery = Boolean(input.recommendedCommands.discoverAssets) || Boolean(input.recommendedCommands.discoverOwnedTokens) || Boolean(input.recommendedCommands.discoverTokens) || Boolean(input.recommendedCommands.inspectToken) || Boolean(input.recommendedCommands.discoverPaymasterTokens) || Boolean(input.recommendedCommands.inspectPaymasterToken);
|
|
19644
|
+
if (!hasTokenDiscovery) {
|
|
19645
|
+
return void 0;
|
|
19646
|
+
}
|
|
19647
|
+
return {
|
|
19648
|
+
walletName: input.walletName || null,
|
|
19649
|
+
chain: input.chain || null,
|
|
19650
|
+
intent: input.intent || null,
|
|
19651
|
+
nextAction: input.nextAction || null,
|
|
19652
|
+
paymasterMode: input.paymasterMode || null,
|
|
19653
|
+
tokenizedIntent: input.intent ? workflowIntentSupportsTokenDiscovery3(input.intent) : false,
|
|
19654
|
+
includesAssetDiscovery: Boolean(input.recommendedCommands.discoverAssets),
|
|
19655
|
+
includesOwnedTokenDiscovery: Boolean(input.recommendedCommands.discoverOwnedTokens),
|
|
19656
|
+
includesChainTokenDiscovery: Boolean(input.recommendedCommands.discoverTokens),
|
|
19657
|
+
includesDirectTokenInspection: Boolean(input.recommendedCommands.inspectToken),
|
|
19658
|
+
includesPaymasterTokenDiscovery: Boolean(
|
|
19659
|
+
input.recommendedCommands.discoverPaymasterTokens
|
|
19660
|
+
),
|
|
19661
|
+
includesPaymasterTokenInspection: Boolean(
|
|
19662
|
+
input.recommendedCommands.inspectPaymasterToken
|
|
19663
|
+
)
|
|
19664
|
+
};
|
|
19665
|
+
}
|
|
19666
|
+
function buildWorkflowTokenInputErrorSummary(input) {
|
|
19667
|
+
return {
|
|
19668
|
+
chain: input.chain || null,
|
|
19669
|
+
queryType: input.tokenAddress ? "address" : input.symbol ? "symbol" : null,
|
|
19670
|
+
query: input.tokenAddress || input.symbol || null,
|
|
19671
|
+
roleFilter: input.role || null,
|
|
19672
|
+
includesChainTokenDiscovery: Boolean(input.recommendedCommands.discoverTokens),
|
|
19673
|
+
includesDirectTokenInspection: Boolean(input.recommendedCommands.inspectToken),
|
|
19674
|
+
workflowHelp: input.recommendedCommands.workflowHelp
|
|
19675
|
+
};
|
|
19676
|
+
}
|
|
18563
19677
|
function buildWorkflowPlanRecommendedCommands(plan) {
|
|
18564
19678
|
return {
|
|
18565
19679
|
inspectDefaults: "zk-agent defaults",
|
|
18566
19680
|
next: plan.recommendedCommand,
|
|
18567
19681
|
goal: plan.goalCommand,
|
|
18568
19682
|
workflowHelp: "zk-agent workflow --help",
|
|
18569
|
-
...
|
|
19683
|
+
...workflowIntentSupportsTokenDiscovery3(plan.intent) ? {
|
|
18570
19684
|
discoverAssets: buildAssetsRecommendedCommand(plan.walletName),
|
|
18571
19685
|
discoverOwnedTokens: buildOwnedTokensRecommendedCommand(plan.walletName),
|
|
18572
19686
|
discoverTokens: buildTokensRecommendedCommand(plan.chain),
|
|
18573
19687
|
inspectToken: buildResolveTokenRecommendedCommand(plan.chain)
|
|
19688
|
+
} : {},
|
|
19689
|
+
...plan.paymasterMode === "approval-based" ? {
|
|
19690
|
+
discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(plan.chain),
|
|
19691
|
+
inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(plan.chain)
|
|
18574
19692
|
} : {}
|
|
18575
19693
|
};
|
|
18576
19694
|
}
|
|
@@ -18606,6 +19724,13 @@ function buildWorkflowTokenErrorRecommendedCommands(error) {
|
|
|
18606
19724
|
}
|
|
18607
19725
|
function printWorkflowTokenInputError(error) {
|
|
18608
19726
|
const recommendedCommands = buildWorkflowTokenErrorRecommendedCommands(error);
|
|
19727
|
+
const tokenDiscoverySummary = buildWorkflowTokenInputErrorSummary({
|
|
19728
|
+
chain: typeof error.details?.chain === "string" ? error.details.chain : void 0,
|
|
19729
|
+
symbol: typeof error.details?.symbol === "string" ? error.details.symbol : void 0,
|
|
19730
|
+
tokenAddress: typeof error.details?.tokenAddress === "string" ? error.details.tokenAddress : void 0,
|
|
19731
|
+
role: typeof error.details?.role === "string" ? error.details.role : void 0,
|
|
19732
|
+
recommendedCommands
|
|
19733
|
+
});
|
|
18609
19734
|
const lines = [["error", error.message], ["code", error.code]];
|
|
18610
19735
|
if (typeof error.details?.suggestedAction === "string" && error.details.suggestedAction.length > 0) {
|
|
18611
19736
|
lines.push(["suggested action", error.details.suggestedAction]);
|
|
@@ -18613,6 +19738,7 @@ function printWorkflowTokenInputError(error) {
|
|
|
18613
19738
|
lines.push(...workflowFollowupLines(recommendedCommands));
|
|
18614
19739
|
printResult(lines, {
|
|
18615
19740
|
...formatErrorPayload(error),
|
|
19741
|
+
tokenDiscoverySummary,
|
|
18616
19742
|
recommendedCommands
|
|
18617
19743
|
});
|
|
18618
19744
|
process.exitCode = 1;
|
|
@@ -18818,6 +19944,7 @@ async function executeWorkflowRunCommand(options, deps = resolveWorkflowCommandD
|
|
|
18818
19944
|
if (inspection.walletApproval?.stage === "request-created" || inspection.result.status === "blocked") {
|
|
18819
19945
|
return {
|
|
18820
19946
|
requestId: inspection.requestId,
|
|
19947
|
+
goal: context.goal,
|
|
18821
19948
|
status: inspection.result,
|
|
18822
19949
|
walletApproval: inspection.walletApproval,
|
|
18823
19950
|
checkpoint: inspection.checkpoint
|
|
@@ -18855,6 +19982,7 @@ async function executeWorkflowRunCommand(options, deps = resolveWorkflowCommandD
|
|
|
18855
19982
|
);
|
|
18856
19983
|
return {
|
|
18857
19984
|
requestId: context.requestId,
|
|
19985
|
+
goal: context.goal,
|
|
18858
19986
|
result,
|
|
18859
19987
|
walletApproval
|
|
18860
19988
|
};
|
|
@@ -18931,14 +20059,13 @@ function assertWorkflowResumeReady(result) {
|
|
|
18931
20059
|
}
|
|
18932
20060
|
function buildWorkflowHelpText() {
|
|
18933
20061
|
return [
|
|
18934
|
-
"",
|
|
18935
|
-
"Default workflow path:",
|
|
18936
|
-
" Guided default:",
|
|
18937
|
-
" zk-agent workflow auto --wallet main --intent <intent> [goal flags] --create-checkpoint --execute-when-ready",
|
|
18938
20062
|
"",
|
|
18939
20063
|
" Flagship native pay path:",
|
|
18940
20064
|
" zk-agent workflow pay --wallet main --to <address> --amount <amount>",
|
|
18941
20065
|
"",
|
|
20066
|
+
" Broader multi-intent guided path:",
|
|
20067
|
+
" zk-agent workflow auto --wallet main --intent <intent> [goal flags] --create-checkpoint --execute-when-ready",
|
|
20068
|
+
"",
|
|
18942
20069
|
" Checkpointed execution:",
|
|
18943
20070
|
" zk-agent workflow start --wallet main --intent <intent> [goal flags]",
|
|
18944
20071
|
" zk-agent workflow status --request-id <id>",
|
|
@@ -18948,13 +20075,24 @@ function buildWorkflowHelpText() {
|
|
|
18948
20075
|
" Funding-only step:",
|
|
18949
20076
|
" zk-agent workflow fund --wallet main --amount <amount> --execute",
|
|
18950
20077
|
"",
|
|
20078
|
+
" Token/discovery recovery path:",
|
|
20079
|
+
" zk-agent assets --wallet main",
|
|
20080
|
+
" zk-agent tokens --wallet main --owned",
|
|
20081
|
+
" zk-agent tokens --chain zksync-sepolia",
|
|
20082
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol USDC",
|
|
20083
|
+
"",
|
|
20084
|
+
" Approval-based paymaster fee-token recovery:",
|
|
20085
|
+
" zk-agent tokens --chain zksync-sepolia --role paymaster-fee-token",
|
|
20086
|
+
" zk-agent resolve-token --chain zksync-sepolia --symbol <symbol> --role paymaster-fee-token",
|
|
20087
|
+
" zk-agent defaults",
|
|
20088
|
+
"",
|
|
18951
20089
|
" Lower-level one-shot escape hatch:",
|
|
18952
20090
|
" zk-agent workflow run --wallet main --intent <intent> [goal flags]"
|
|
18953
20091
|
].join("\n");
|
|
18954
20092
|
}
|
|
18955
20093
|
var WORKFLOW_HELP_COMMAND_ORDER = [
|
|
18956
|
-
"auto",
|
|
18957
20094
|
"pay",
|
|
20095
|
+
"auto",
|
|
18958
20096
|
"start",
|
|
18959
20097
|
"status",
|
|
18960
20098
|
"next",
|
|
@@ -18983,7 +20121,7 @@ function applyWorkflowHelpCommandOrder(workflow) {
|
|
|
18983
20121
|
function createWorkflowCommand(deps) {
|
|
18984
20122
|
const resolvedDeps = resolveWorkflowCommandDeps(deps);
|
|
18985
20123
|
const workflow = new Command10("workflow").description(
|
|
18986
|
-
"
|
|
20124
|
+
"Plan, persist, and execute higher-level wallet workflows"
|
|
18987
20125
|
);
|
|
18988
20126
|
workflow.addHelpText("after", buildWorkflowHelpText());
|
|
18989
20127
|
workflow.command("plan").description("Plan the prerequisite and execution steps for one concrete wallet workflow").requiredOption(
|
|
@@ -18995,15 +20133,27 @@ function createWorkflowCommand(deps) {
|
|
|
18995
20133
|
).option("--to-chain <chain>", "Optional destination chain override for bridge workflows").option("--paymaster-mode <mode>", "none, sponsored, or approval-based").option("--paymaster-address <address>", "Explicit paymaster contract address override").option("--paymaster-token <address>", "ERC-20 token address for approval-based paymaster mode").action(
|
|
18996
20134
|
async (options) => {
|
|
18997
20135
|
const intent = parseWorkflowIntent(options.intent);
|
|
20136
|
+
const paymasterInput = resolveWorkflowPaymasterInput(options);
|
|
18998
20137
|
const { inspection, plan } = await loadWorkflowPlanState(
|
|
18999
20138
|
options.wallet,
|
|
19000
20139
|
intent,
|
|
19001
20140
|
parseWorkflowSwapProtocol(options.protocol),
|
|
19002
20141
|
options.toChain,
|
|
19003
|
-
|
|
20142
|
+
paymasterInput,
|
|
19004
20143
|
resolvedDeps
|
|
19005
20144
|
);
|
|
19006
|
-
const recommendedCommands = buildWorkflowPlanRecommendedCommands(
|
|
20145
|
+
const recommendedCommands = buildWorkflowPlanRecommendedCommands({
|
|
20146
|
+
...plan,
|
|
20147
|
+
paymasterMode: paymasterInput?.mode
|
|
20148
|
+
});
|
|
20149
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
20150
|
+
walletName: plan.walletName,
|
|
20151
|
+
chain: plan.chain,
|
|
20152
|
+
intent: plan.intent,
|
|
20153
|
+
paymasterMode: paymasterInput?.mode,
|
|
20154
|
+
nextAction: plan.recommendedCommand,
|
|
20155
|
+
recommendedCommands
|
|
20156
|
+
});
|
|
19007
20157
|
const agentProfile = await loadWorkflowAgentProfile(plan.walletName);
|
|
19008
20158
|
const agentFollowup = buildAgentFollowup(agentProfile, {
|
|
19009
20159
|
walletName: plan.walletName,
|
|
@@ -19021,6 +20171,7 @@ function createWorkflowCommand(deps) {
|
|
|
19021
20171
|
agentFollowup,
|
|
19022
20172
|
inspection,
|
|
19023
20173
|
plan,
|
|
20174
|
+
tokenDiscoverySummary,
|
|
19024
20175
|
recommendedCommands
|
|
19025
20176
|
}
|
|
19026
20177
|
);
|
|
@@ -19221,7 +20372,16 @@ function createWorkflowCommand(deps) {
|
|
|
19221
20372
|
walletName: inspection.result.walletName,
|
|
19222
20373
|
nextAction: inspection.result.recommendedCommand,
|
|
19223
20374
|
chain: inspection.result.plan.chain,
|
|
19224
|
-
intent: inspection.result.intent
|
|
20375
|
+
intent: inspection.result.intent,
|
|
20376
|
+
paymasterMode: inspection.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(inspection.checkpoint?.goal)
|
|
20377
|
+
});
|
|
20378
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
20379
|
+
walletName: inspection.result.walletName,
|
|
20380
|
+
chain: inspection.result.plan.chain,
|
|
20381
|
+
intent: inspection.result.intent,
|
|
20382
|
+
nextAction: inspection.result.recommendedCommand,
|
|
20383
|
+
paymasterMode: inspection.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(inspection.checkpoint?.goal),
|
|
20384
|
+
recommendedCommands
|
|
19225
20385
|
});
|
|
19226
20386
|
const agentProfile = await loadWorkflowAgentProfile(inspection.result.walletName);
|
|
19227
20387
|
const agentFollowup = buildAgentFollowup(agentProfile, {
|
|
@@ -19253,6 +20413,7 @@ function createWorkflowCommand(deps) {
|
|
|
19253
20413
|
...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
|
|
19254
20414
|
walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
|
|
19255
20415
|
walletApproval: serializeWalletApproval(inspection.walletApproval),
|
|
20416
|
+
tokenDiscoverySummary,
|
|
19256
20417
|
recommendedCommands
|
|
19257
20418
|
}
|
|
19258
20419
|
);
|
|
@@ -19272,7 +20433,16 @@ function createWorkflowCommand(deps) {
|
|
|
19272
20433
|
walletName: inspection.result.walletName,
|
|
19273
20434
|
nextAction: nextCommand,
|
|
19274
20435
|
chain: inspection.result.plan.chain,
|
|
19275
|
-
intent: inspection.result.intent
|
|
20436
|
+
intent: inspection.result.intent,
|
|
20437
|
+
paymasterMode: inspection.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(inspection.checkpoint?.goal)
|
|
20438
|
+
});
|
|
20439
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
20440
|
+
walletName: inspection.result.walletName,
|
|
20441
|
+
chain: inspection.result.plan.chain,
|
|
20442
|
+
intent: inspection.result.intent,
|
|
20443
|
+
nextAction: nextCommand,
|
|
20444
|
+
paymasterMode: inspection.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(inspection.checkpoint?.goal),
|
|
20445
|
+
recommendedCommands
|
|
19276
20446
|
});
|
|
19277
20447
|
const agentProfile = await loadWorkflowAgentProfile(inspection.result.walletName);
|
|
19278
20448
|
const agentFollowup = buildAgentFollowup(agentProfile, {
|
|
@@ -19317,6 +20487,7 @@ function createWorkflowCommand(deps) {
|
|
|
19317
20487
|
...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
|
|
19318
20488
|
walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
|
|
19319
20489
|
walletApproval: serializeWalletApproval(inspection.walletApproval),
|
|
20490
|
+
tokenDiscoverySummary,
|
|
19320
20491
|
recommendedCommands
|
|
19321
20492
|
}
|
|
19322
20493
|
);
|
|
@@ -19337,7 +20508,16 @@ function createWorkflowCommand(deps) {
|
|
|
19337
20508
|
walletName: inspection.result.walletName,
|
|
19338
20509
|
nextAction: inspection.result.recommendedCommand,
|
|
19339
20510
|
chain: inspection.result.plan.chain,
|
|
19340
|
-
intent: inspection.result.intent
|
|
20511
|
+
intent: inspection.result.intent,
|
|
20512
|
+
paymasterMode: inspection.walletApproval.request.requestedPaymasterMode
|
|
20513
|
+
});
|
|
20514
|
+
const tokenDiscoverySummary2 = buildWorkflowTokenDiscoverySummary({
|
|
20515
|
+
walletName: inspection.result.walletName,
|
|
20516
|
+
chain: inspection.result.plan.chain,
|
|
20517
|
+
intent: inspection.result.intent,
|
|
20518
|
+
nextAction: inspection.result.recommendedCommand,
|
|
20519
|
+
paymasterMode: inspection.walletApproval.request.requestedPaymasterMode,
|
|
20520
|
+
recommendedCommands: recommendedCommands2
|
|
19341
20521
|
});
|
|
19342
20522
|
const agentProfile2 = await loadWorkflowAgentProfile(inspection.result.walletName);
|
|
19343
20523
|
const agentFollowup2 = buildAgentFollowup(agentProfile2, {
|
|
@@ -19369,6 +20549,7 @@ function createWorkflowCommand(deps) {
|
|
|
19369
20549
|
...workflowWalletApprovalRelayAliases(inspection.walletApproval.relay),
|
|
19370
20550
|
walletApprovalRecommendedCommands: inspection.walletApproval.recommendedCommands,
|
|
19371
20551
|
walletApproval: serializeWalletApproval(inspection.walletApproval),
|
|
20552
|
+
tokenDiscoverySummary: tokenDiscoverySummary2,
|
|
19372
20553
|
recommendedCommands: recommendedCommands2
|
|
19373
20554
|
}
|
|
19374
20555
|
);
|
|
@@ -19388,7 +20569,16 @@ function createWorkflowCommand(deps) {
|
|
|
19388
20569
|
walletName: execution.status.walletName,
|
|
19389
20570
|
nextAction: execution.status.recommendedCommand,
|
|
19390
20571
|
chain: execution.status.plan.chain,
|
|
19391
|
-
intent: execution.status.intent
|
|
20572
|
+
intent: execution.status.intent,
|
|
20573
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
|
|
20574
|
+
});
|
|
20575
|
+
const tokenDiscoverySummary2 = buildWorkflowTokenDiscoverySummary({
|
|
20576
|
+
walletName: execution.status.walletName,
|
|
20577
|
+
chain: execution.status.plan.chain,
|
|
20578
|
+
intent: execution.status.intent,
|
|
20579
|
+
nextAction: execution.status.recommendedCommand,
|
|
20580
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
|
|
20581
|
+
recommendedCommands: recommendedCommands2
|
|
19392
20582
|
});
|
|
19393
20583
|
const agentProfile2 = await loadWorkflowAgentProfile(execution.status.walletName);
|
|
19394
20584
|
const agentFollowup2 = buildAgentFollowup(agentProfile2, {
|
|
@@ -19420,6 +20610,7 @@ function createWorkflowCommand(deps) {
|
|
|
19420
20610
|
...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
|
|
19421
20611
|
walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
|
|
19422
20612
|
walletApproval: serializeWalletApproval(execution.walletApproval),
|
|
20613
|
+
tokenDiscoverySummary: tokenDiscoverySummary2,
|
|
19423
20614
|
recommendedCommands: recommendedCommands2
|
|
19424
20615
|
}
|
|
19425
20616
|
);
|
|
@@ -19430,7 +20621,16 @@ function createWorkflowCommand(deps) {
|
|
|
19430
20621
|
walletName: execution.result.walletName,
|
|
19431
20622
|
nextAction: execution.result.nextCommand,
|
|
19432
20623
|
chain: execution.result.plan.chain,
|
|
19433
|
-
intent: execution.result.intent
|
|
20624
|
+
intent: execution.result.intent,
|
|
20625
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal)
|
|
20626
|
+
});
|
|
20627
|
+
const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
|
|
20628
|
+
walletName: execution.result.walletName,
|
|
20629
|
+
chain: execution.result.plan.chain,
|
|
20630
|
+
intent: execution.result.intent,
|
|
20631
|
+
nextAction: execution.result.nextCommand,
|
|
20632
|
+
paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal),
|
|
20633
|
+
recommendedCommands
|
|
19434
20634
|
});
|
|
19435
20635
|
const agentProfile = await loadWorkflowAgentProfile(execution.result.walletName);
|
|
19436
20636
|
const agentFollowup = buildAgentFollowup(agentProfile, {
|
|
@@ -19462,6 +20662,7 @@ function createWorkflowCommand(deps) {
|
|
|
19462
20662
|
...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
|
|
19463
20663
|
walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
|
|
19464
20664
|
walletApproval: serializeWalletApproval(inspection.walletApproval),
|
|
20665
|
+
tokenDiscoverySummary,
|
|
19465
20666
|
recommendedCommands
|
|
19466
20667
|
}
|
|
19467
20668
|
);
|
|
@@ -19497,16 +20698,24 @@ function createWorkflowCommand(deps) {
|
|
|
19497
20698
|
function buildDefaultOperatorPathHelpText() {
|
|
19498
20699
|
return [
|
|
19499
20700
|
"",
|
|
19500
|
-
"
|
|
20701
|
+
"Public entrypoints:",
|
|
20702
|
+
" Agent harness: npx skills add https://github.com/AgiWeb3/zk-agent-cli",
|
|
20703
|
+
" One-shot CLI: npx zk-agent-cli --help",
|
|
20704
|
+
" Global CLI: npm install -g zk-agent-cli",
|
|
20705
|
+
"",
|
|
20706
|
+
"Canonical terminal path:",
|
|
19501
20707
|
" zk-agent setup",
|
|
19502
20708
|
" zk-agent next",
|
|
19503
20709
|
" zk-agent wallet create --await-local",
|
|
19504
20710
|
" zk-agent next",
|
|
19505
20711
|
` ${buildWorkflowPayRecommendedCommand("main")}`,
|
|
19506
20712
|
"",
|
|
20713
|
+
"No custom .env is required for setup, next, or wallet create/reapprove request generation.",
|
|
20714
|
+
"Add RPC env vars later, before live reads or broadcasts.",
|
|
20715
|
+
"",
|
|
19507
20716
|
"Use `zk-agent next --request-id <id>` to continue a stored workflow checkpoint.",
|
|
19508
|
-
"Use `zk-agent relay inspect --relay-url <url>`
|
|
19509
|
-
"Use `zk-agent wallet --help` for
|
|
20717
|
+
"Use `zk-agent relay inspect --relay-url <url>` plus `zk-agent wallet create|reapprove --relay-url <url> --wait-relay --prompt-code` when the browser is not colocated.",
|
|
20718
|
+
"Use `zk-agent wallet --help` for wallet recovery details and `zk-agent workflow --help` when the intent is broader than the flagship native-send path."
|
|
19510
20719
|
].join("\n");
|
|
19511
20720
|
}
|
|
19512
20721
|
var ROOT_HELP_COMMAND_ORDER = [
|
|
@@ -19547,7 +20756,9 @@ function applyRootHelpCommandOrder(program) {
|
|
|
19547
20756
|
program.commands = sortedCommands;
|
|
19548
20757
|
}
|
|
19549
20758
|
function createProgram() {
|
|
19550
|
-
const program = new Command11().name("zk-agent").description(
|
|
20759
|
+
const program = new Command11().name("zk-agent").description(
|
|
20760
|
+
"Local-first zkSync Era CLI for wallet approval, workflow execution, and hosted relay recovery"
|
|
20761
|
+
).showHelpAfterError().option("--json", "Force JSON output for agent harnesses", false).hook("preAction", (thisCommand) => {
|
|
19551
20762
|
if (thisCommand.optsWithGlobals().json) process.env.ZK_AGENT_OUTPUT = "json";
|
|
19552
20763
|
});
|
|
19553
20764
|
program.addCommand(createInitCommand());
|