zk-agent-cli 0.1.0-beta.1 → 0.1.0-beta.3

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.
Files changed (31) hide show
  1. package/README.md +23 -8
  2. package/dist/builtin-account-profiles/artifacts/daily-spend-limit/Account.json +693 -0
  3. package/dist/builtin-account-profiles/artifacts/sed-lite/Account.json +970 -0
  4. package/dist/builtin-account-profiles/artifacts/sed-lite/EOAValidator.json +50 -0
  5. package/dist/builtin-account-profiles/artifacts/sed-lite/NativePerTxLimitHook.json +267 -0
  6. package/dist/builtin-account-profiles/artifacts/sed-lite/TargetAllowlistHook.json +346 -0
  7. package/dist/builtin-account-profiles/artifacts/sed-lite/TargetSelectorAllowlistHook.json +643 -0
  8. package/dist/builtin-account-profiles/contracts/daily-spend-limit/AAFactory.sol +28 -0
  9. package/dist/builtin-account-profiles/contracts/daily-spend-limit/Account.sol +179 -0
  10. package/dist/builtin-account-profiles/contracts/daily-spend-limit/SpendLimit.sol +85 -0
  11. package/dist/builtin-account-profiles/contracts/sed-lite/Account.sol +230 -0
  12. package/dist/builtin-account-profiles/contracts/sed-lite/Auth.sol +16 -0
  13. package/dist/builtin-account-profiles/contracts/sed-lite/BootloaderAuth.sol +11 -0
  14. package/dist/builtin-account-profiles/contracts/sed-lite/EOAValidator.sol +23 -0
  15. package/dist/builtin-account-profiles/contracts/sed-lite/IValidationHook.sol +20 -0
  16. package/dist/builtin-account-profiles/contracts/sed-lite/IValidator.sol +11 -0
  17. package/dist/builtin-account-profiles/contracts/sed-lite/ModuleAuth.sol +11 -0
  18. package/dist/builtin-account-profiles/contracts/sed-lite/ModuleManager.sol +46 -0
  19. package/dist/builtin-account-profiles/contracts/sed-lite/NativePerTxLimitHook.sol +67 -0
  20. package/dist/builtin-account-profiles/contracts/sed-lite/OwnerManager.sol +25 -0
  21. package/dist/builtin-account-profiles/contracts/sed-lite/SelfAuth.sol +9 -0
  22. package/dist/builtin-account-profiles/contracts/sed-lite/TargetAllowlistHook.sol +110 -0
  23. package/dist/builtin-account-profiles/contracts/sed-lite/TargetSelectorAllowlistHook.sol +263 -0
  24. package/dist/builtin-account-profiles/contracts/sed-lite/ValidationHookManager.sol +76 -0
  25. package/dist/builtin-account-profiles/contracts/sed-lite/ValidatorManager.sol +31 -0
  26. package/dist/builtin-account-profiles/package.json +5 -0
  27. package/dist/connector-ui/assets/index-BnFLonFL.css +1 -0
  28. package/dist/connector-ui/assets/index-WTJRR5fK.js +40 -0
  29. package/dist/connector-ui/index.html +13 -0
  30. package/dist/index.js +248 -26
  31. package/package.json +1 -1
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>zk-agent connector</title>
7
+ <script type="module" crossorigin src="/assets/index-WTJRR5fK.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-BnFLonFL.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
package/dist/index.js CHANGED
@@ -11748,6 +11748,9 @@ import fs7 from "node:fs";
11748
11748
  import path6 from "node:path";
11749
11749
  import { fileURLToPath as fileURLToPath3 } from "node:url";
11750
11750
  var RELAY_BODY_LIMIT_BYTES = 1024 * 1024;
11751
+ var RELAY_SERVICE = "zk-agent-relay";
11752
+ var RELAY_PROTOCOL = "zk-agent-session-relay";
11753
+ var RELAY_SCHEMA_VERSION = 1;
11751
11754
  function relayDir() {
11752
11755
  const directory = path6.join(storageDir(), "relay");
11753
11756
  if (!fs7.existsSync(directory)) {
@@ -11837,6 +11840,8 @@ function resolveConnectorUiDistRoot() {
11837
11840
  const currentFile = fileURLToPath3(import.meta.url);
11838
11841
  const currentDir2 = path6.dirname(currentFile);
11839
11842
  const candidates = [
11843
+ path6.resolve(currentDir2, "../connector-ui"),
11844
+ path6.resolve(currentDir2, "../../dist/connector-ui"),
11840
11845
  path6.resolve(currentDir2, "../../../zk-connector-ui/dist"),
11841
11846
  path6.resolve(currentDir2, "../../zk-connector-ui/dist")
11842
11847
  ];
@@ -11857,6 +11862,32 @@ function contentTypeFor(filePath) {
11857
11862
  function normalizeRelayBaseUrl(baseUrl) {
11858
11863
  return baseUrl.replace(/\/+$/, "");
11859
11864
  }
11865
+ function resolveRelayPublicBaseUrl(actualBaseUrl, publicOrigin) {
11866
+ return publicOrigin?.trim() ? normalizeRelayBaseUrl(new URL(publicOrigin.trim()).toString()) : normalizeRelayBaseUrl(actualBaseUrl);
11867
+ }
11868
+ function relayCapabilities(connectorUiAvailable) {
11869
+ return [
11870
+ "create-request",
11871
+ "read-status",
11872
+ "fetch-approval",
11873
+ "submit-approval",
11874
+ "share-redirect",
11875
+ ...connectorUiAvailable ? ["connector-ui"] : []
11876
+ ];
11877
+ }
11878
+ function relayHealthResponse(actualBaseUrl, publicBaseUrl, connectorUiAvailable) {
11879
+ return {
11880
+ ok: true,
11881
+ service: RELAY_SERVICE,
11882
+ protocol: RELAY_PROTOCOL,
11883
+ schema_version: RELAY_SCHEMA_VERSION,
11884
+ relay_mode: "local-file",
11885
+ origin: normalizeRelayBaseUrl(actualBaseUrl),
11886
+ public_origin: normalizeRelayBaseUrl(publicBaseUrl),
11887
+ connector_ui_available: connectorUiAvailable,
11888
+ capabilities: relayCapabilities(connectorUiAvailable)
11889
+ };
11890
+ }
11860
11891
  function relayShareUrl(baseUrl, requestId) {
11861
11892
  return `${normalizeRelayBaseUrl(baseUrl)}/r/${requestId}`;
11862
11893
  }
@@ -11886,6 +11917,13 @@ async function fetchRelayStatus(baseUrl, requestId) {
11886
11917
  }
11887
11918
  return await response.json();
11888
11919
  }
11920
+ async function fetchRelayHealth(baseUrl) {
11921
+ const response = await fetch(`${normalizeRelayBaseUrl(baseUrl)}/health`);
11922
+ if (!response.ok) {
11923
+ throw new Error(`Relay health fetch failed with status ${response.status}`);
11924
+ }
11925
+ return await response.json();
11926
+ }
11889
11927
  function sleep(ms) {
11890
11928
  return new Promise((resolve) => {
11891
11929
  setTimeout(resolve, ms);
@@ -11922,13 +11960,18 @@ async function startRelayServer(options) {
11922
11960
  const requestUrl = new URL(request.url || "/", `http://${request.headers.host || "localhost"}`);
11923
11961
  const pathname = requestUrl.pathname;
11924
11962
  const method = request.method || "GET";
11925
- const baseUrl = `${requestUrl.protocol}//${requestUrl.host}`;
11963
+ const actualBaseUrl = `${requestUrl.protocol}//${requestUrl.host}`;
11964
+ const publicBaseUrl = resolveRelayPublicBaseUrl(actualBaseUrl, options.publicOrigin);
11926
11965
  if (method === "OPTIONS") {
11927
11966
  writeJson2(response, 204, {});
11928
11967
  return;
11929
11968
  }
11930
11969
  if (method === "GET" && pathname === "/health") {
11931
- writeJson2(response, 200, { ok: true });
11970
+ writeJson2(
11971
+ response,
11972
+ 200,
11973
+ relayHealthResponse(actualBaseUrl, publicBaseUrl, Boolean(uiDistRoot))
11974
+ );
11932
11975
  return;
11933
11976
  }
11934
11977
  if (method === "POST" && pathname === "/api/requests") {
@@ -11945,9 +11988,9 @@ async function startRelayServer(options) {
11945
11988
  writeJson2(response, existing ? 200 : 201, {
11946
11989
  request_id: record.request_id,
11947
11990
  status: relayStatus(record),
11948
- share_url: relayShareUrl(baseUrl, record.request_id),
11949
- status_url: relayStatusUrl(baseUrl, record.request_id),
11950
- approval_url: relayShareUrl(baseUrl, record.request_id)
11991
+ share_url: relayShareUrl(publicBaseUrl, record.request_id),
11992
+ status_url: relayStatusUrl(publicBaseUrl, record.request_id),
11993
+ approval_url: relayShareUrl(publicBaseUrl, record.request_id)
11951
11994
  });
11952
11995
  return;
11953
11996
  }
@@ -11958,7 +12001,7 @@ async function startRelayServer(options) {
11958
12001
  writeJson2(response, 404, { error: `Relay request not found: ${requestMatch[1]}` });
11959
12002
  return;
11960
12003
  }
11961
- writeJson2(response, 200, relayStatusResponse(baseUrl, record));
12004
+ writeJson2(response, 200, relayStatusResponse(publicBaseUrl, record));
11962
12005
  return;
11963
12006
  }
11964
12007
  const approvalMatch = pathname.match(/^\/api\/requests\/([^/]+)\/approval$/);
@@ -11989,7 +12032,7 @@ async function startRelayServer(options) {
11989
12032
  response.statusCode = 302;
11990
12033
  response.setHeader(
11991
12034
  "Location",
11992
- `/?relayRequestUrl=${encodeURIComponent(relayStatusUrl(baseUrl, shareMatch[1]))}`
12035
+ `/?relayRequestUrl=${encodeURIComponent(relayStatusUrl(publicBaseUrl, shareMatch[1]))}`
11993
12036
  );
11994
12037
  response.end();
11995
12038
  return;
@@ -12033,6 +12076,7 @@ async function startRelayServer(options) {
12033
12076
  });
12034
12077
  });
12035
12078
  return {
12079
+ connectorUiAvailable: Boolean(uiDistRoot),
12036
12080
  origin: `http://${address.address}:${address.port}`,
12037
12081
  port: address.port,
12038
12082
  close: async () => await new Promise((resolve, reject) => {
@@ -12054,9 +12098,104 @@ function buildRelayServeRecommendedCommands(relayUrl) {
12054
12098
  reapproveWallet: `zk-agent wallet reapprove --name main --relay-url ${relayUrl}`
12055
12099
  };
12056
12100
  }
12101
+ function isRecord3(value) {
12102
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12103
+ }
12104
+ function isRelayCapability(value) {
12105
+ return [
12106
+ "create-request",
12107
+ "read-status",
12108
+ "fetch-approval",
12109
+ "submit-approval",
12110
+ "share-redirect",
12111
+ "connector-ui"
12112
+ ].includes(String(value));
12113
+ }
12114
+ function asRelayHealthResponse(value) {
12115
+ if (!isRecord3(value)) return null;
12116
+ if (value.ok !== true) return null;
12117
+ if (value.service !== "zk-agent-relay") return null;
12118
+ if (value.protocol !== "zk-agent-session-relay") return null;
12119
+ if (value.schema_version !== 1) return null;
12120
+ if (value.relay_mode !== "local-file") return null;
12121
+ if (typeof value.origin !== "string") return null;
12122
+ if (typeof value.public_origin !== "string") return null;
12123
+ if (typeof value.connector_ui_available !== "boolean") return null;
12124
+ if (!Array.isArray(value.capabilities) || !value.capabilities.every(isRelayCapability)) {
12125
+ return null;
12126
+ }
12127
+ return value;
12128
+ }
12129
+ function hasCoreRelayCapabilities(capabilities) {
12130
+ const capabilitySet = new Set(capabilities);
12131
+ return capabilitySet.has("create-request") && capabilitySet.has("read-status") && capabilitySet.has("fetch-approval") && capabilitySet.has("submit-approval") && capabilitySet.has("share-redirect");
12132
+ }
12133
+ function relayPublicOriginLooksLocal(origin) {
12134
+ try {
12135
+ const { hostname } = new URL(origin);
12136
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "0.0.0.0" || hostname === "::1" || hostname === "[::1]";
12137
+ } catch {
12138
+ return false;
12139
+ }
12140
+ }
12141
+ function relayHostedReadinessNotes(options) {
12142
+ const notes = [];
12143
+ if (!options.compatible) {
12144
+ notes.push(
12145
+ "Relay health responded, but it did not advertise the full zk-agent relay compatibility contract."
12146
+ );
12147
+ return notes;
12148
+ }
12149
+ if (relayPublicOriginLooksLocal(options.publicOrigin)) {
12150
+ notes.push(
12151
+ "Relay compatibility is present, but the advertised public origin still points at a local-only address. Set --public-origin to the externally reachable URL before using this as a hosted approval path."
12152
+ );
12153
+ }
12154
+ if (options.connectorUiAvailable === false) {
12155
+ notes.push(
12156
+ "Relay compatibility is present, but the built connector UI is not available at this relay. Hosted share-link approval needs a connector UI build or another externally reachable approval UI."
12157
+ );
12158
+ }
12159
+ return notes;
12160
+ }
12161
+ function buildRelayInspectPayload(relayUrl, rawHealth) {
12162
+ const health = asRelayHealthResponse(rawHealth);
12163
+ const fallbackPublicOrigin = isRecord3(rawHealth) && typeof rawHealth.public_origin === "string" ? rawHealth.public_origin : relayUrl;
12164
+ const publicOrigin = health?.public_origin || fallbackPublicOrigin;
12165
+ const compatible = Boolean(health && hasCoreRelayCapabilities(health.capabilities));
12166
+ const connectorUiAvailable = health?.connector_ui_available ?? null;
12167
+ const publicOriginLooksLocal = relayPublicOriginLooksLocal(publicOrigin);
12168
+ const hostedShareRedirectReady = compatible && connectorUiAvailable === true && !publicOriginLooksLocal;
12169
+ const notes = relayHostedReadinessNotes({
12170
+ compatible,
12171
+ publicOrigin,
12172
+ connectorUiAvailable
12173
+ });
12174
+ return {
12175
+ ok: true,
12176
+ status: "relay-inspected",
12177
+ relayUrl,
12178
+ compatible,
12179
+ service: health?.service || null,
12180
+ protocol: health?.protocol || null,
12181
+ schemaVersion: health?.schema_version || null,
12182
+ relayMode: health?.relay_mode || null,
12183
+ origin: health?.origin || null,
12184
+ publicOrigin,
12185
+ publicOriginLooksLocal,
12186
+ connectorUiAvailable,
12187
+ hostedShareRedirectReady,
12188
+ capabilities: health?.capabilities || [],
12189
+ recommendedCommands: compatible ? buildRelayServeRecommendedCommands(publicOrigin) : {},
12190
+ notes
12191
+ };
12192
+ }
12057
12193
  function createRelayCommand() {
12058
12194
  const relay = new Command8("relay").description("Run the local connector relay prototype server");
12059
- 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").action(async (options) => {
12195
+ 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(
12196
+ "--public-origin <url>",
12197
+ "Public base URL to advertise in share/status links when the relay is behind a tunnel or reverse proxy"
12198
+ ).action(async (options) => {
12060
12199
  const host = options.host?.trim() || "127.0.0.1";
12061
12200
  const parsedPort = Number.parseInt(options.port || "4445", 10);
12062
12201
  if (!Number.isInteger(parsedPort) || parsedPort < 0 || parsedPort > 65535) {
@@ -12064,25 +12203,60 @@ function createRelayCommand() {
12064
12203
  }
12065
12204
  const server = await startRelayServer({
12066
12205
  host,
12067
- port: parsedPort
12206
+ port: parsedPort,
12207
+ publicOrigin: options.publicOrigin?.trim()
12208
+ });
12209
+ const publicOrigin = options.publicOrigin?.trim() || server.origin;
12210
+ const publicOriginLooksLocal = relayPublicOriginLooksLocal(publicOrigin);
12211
+ const connectorUiAvailable = server.connectorUiAvailable;
12212
+ const hostedShareRedirectReady = connectorUiAvailable && !publicOriginLooksLocal;
12213
+ const recommendedCommands = buildRelayServeRecommendedCommands(publicOrigin);
12214
+ const notes = relayHostedReadinessNotes({
12215
+ compatible: true,
12216
+ publicOrigin,
12217
+ connectorUiAvailable
12068
12218
  });
12069
- const recommendedCommands = buildRelayServeRecommendedCommands(server.origin);
12070
12219
  const payload = {
12071
12220
  ok: true,
12072
12221
  status: "relay-serving",
12073
12222
  origin: server.origin,
12223
+ publicOrigin,
12224
+ publicOriginLooksLocal,
12074
12225
  port: server.port,
12075
12226
  healthUrl: `${server.origin}/health`,
12076
- recommendedCommands
12227
+ publicHealthUrl: `${publicOrigin}/health`,
12228
+ relayMode: "local-file",
12229
+ connectorUiAvailable,
12230
+ hostedShareRedirectReady,
12231
+ capabilities: [
12232
+ "create-request",
12233
+ "read-status",
12234
+ "fetch-approval",
12235
+ "submit-approval",
12236
+ "share-redirect",
12237
+ ...connectorUiAvailable ? ["connector-ui"] : []
12238
+ ],
12239
+ recommendedCommands,
12240
+ notes
12077
12241
  };
12078
12242
  if (shouldJsonOutput()) {
12079
12243
  jsonOut(payload);
12080
12244
  } else {
12081
12245
  humanLine("status", "relay-serving");
12082
12246
  humanLine("origin", server.origin);
12247
+ if (publicOrigin !== server.origin) {
12248
+ humanLine("public origin", publicOrigin);
12249
+ }
12083
12250
  humanLine("health", `${server.origin}/health`);
12251
+ humanLine("hosted ready", hostedShareRedirectReady ? "yes" : "no");
12252
+ if (connectorUiAvailable !== null) {
12253
+ humanLine("connector ui", connectorUiAvailable ? "available" : "missing");
12254
+ }
12084
12255
  humanLine("create wallet", recommendedCommands.createWallet);
12085
12256
  humanLine("reapprove wallet", recommendedCommands.reapproveWallet);
12257
+ for (const note of notes) {
12258
+ humanLine("note", note);
12259
+ }
12086
12260
  }
12087
12261
  const shutdown = async () => {
12088
12262
  process.off("SIGINT", handleSignal);
@@ -12098,6 +12272,53 @@ function createRelayCommand() {
12098
12272
  await new Promise(() => {
12099
12273
  });
12100
12274
  });
12275
+ relay.command("inspect").description("Inspect a relay URL for zk-agent compatibility and hosted remote-approval readiness").requiredOption("--relay-url <url>", "Relay server base URL to inspect").action(async (options) => {
12276
+ const relayUrl = options.relayUrl.trim();
12277
+ const rawHealth = await fetchRelayHealth(relayUrl);
12278
+ const payload = buildRelayInspectPayload(relayUrl, rawHealth);
12279
+ if (shouldJsonOutput()) {
12280
+ jsonOut(payload);
12281
+ return;
12282
+ }
12283
+ humanLine("status", "relay-inspected");
12284
+ humanLine("relay url", relayUrl);
12285
+ humanLine("compatible", payload.compatible ? "yes" : "no");
12286
+ if (payload.service) {
12287
+ humanLine("service", payload.service);
12288
+ }
12289
+ if (payload.protocol) {
12290
+ humanLine("protocol", payload.protocol);
12291
+ }
12292
+ if (payload.relayMode) {
12293
+ humanLine("mode", payload.relayMode);
12294
+ }
12295
+ if (payload.origin) {
12296
+ humanLine("origin", payload.origin);
12297
+ }
12298
+ if (payload.publicOrigin) {
12299
+ humanLine("public origin", payload.publicOrigin);
12300
+ }
12301
+ humanLine("public origin local", payload.publicOriginLooksLocal ? "yes" : "no");
12302
+ if (payload.connectorUiAvailable !== null) {
12303
+ humanLine("connector ui", payload.connectorUiAvailable ? "available" : "missing");
12304
+ }
12305
+ humanLine("hosted ready", payload.hostedShareRedirectReady ? "yes" : "no");
12306
+ if (payload.capabilities.length > 0) {
12307
+ humanLine("capabilities", payload.capabilities.join(", "));
12308
+ }
12309
+ if (payload.compatible) {
12310
+ if (payload.recommendedCommands.createWallet) {
12311
+ humanLine("create wallet", payload.recommendedCommands.createWallet);
12312
+ }
12313
+ if (payload.recommendedCommands.reapproveWallet) {
12314
+ humanLine("reapprove wallet", payload.recommendedCommands.reapproveWallet);
12315
+ }
12316
+ } else {
12317
+ for (const note of payload.notes) {
12318
+ humanLine("note", note);
12319
+ }
12320
+ }
12321
+ });
12101
12322
  return relay;
12102
12323
  }
12103
12324
 
@@ -12127,6 +12348,7 @@ function resolvePackageRoot() {
12127
12348
  const cwd = process.cwd();
12128
12349
  const candidates = [
12129
12350
  process.env.ZK_AGENT_ACCOUNT_PROFILES_ROOT,
12351
+ path7.join(moduleRoot, "dist", "builtin-account-profiles"),
12130
12352
  moduleRoot,
12131
12353
  path7.join(cwd, "packages", "account-profiles"),
12132
12354
  path7.join(cwd, "account-profiles"),
@@ -12165,14 +12387,14 @@ function normalizeHexString(value, label) {
12165
12387
  }
12166
12388
  return prefixed;
12167
12389
  }
12168
- function isRecord3(value) {
12390
+ function isRecord4(value) {
12169
12391
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12170
12392
  }
12171
12393
  function parseArtifactFile(artifactPath2) {
12172
12394
  const raw = JSON.parse(fs8.readFileSync(artifactPath2, "utf8"));
12173
- if (!isRecord3(raw)) throw new Error(`Artifact at ${artifactPath2} must be a JSON object`);
12395
+ if (!isRecord4(raw)) throw new Error(`Artifact at ${artifactPath2} must be a JSON object`);
12174
12396
  if (!Array.isArray(raw.abi)) throw new Error(`Artifact at ${artifactPath2} must include an abi array`);
12175
- const bytecodeCandidate = typeof raw.bytecode === "string" ? raw.bytecode : isRecord3(raw.evm) && isRecord3(raw.evm.bytecode) && typeof raw.evm.bytecode.object === "string" ? raw.evm.bytecode.object : void 0;
12397
+ const bytecodeCandidate = typeof raw.bytecode === "string" ? raw.bytecode : isRecord4(raw.evm) && isRecord4(raw.evm.bytecode) && typeof raw.evm.bytecode.object === "string" ? raw.evm.bytecode.object : void 0;
12176
12398
  if (!bytecodeCandidate) {
12177
12399
  throw new Error(`Artifact at ${artifactPath2} must include bytecode or evm.bytecode.object`);
12178
12400
  }
@@ -12184,7 +12406,7 @@ function parseArtifactFile(artifactPath2) {
12184
12406
  }
12185
12407
  return normalizeHexString(entry, `factoryDeps[${index}]`);
12186
12408
  });
12187
- } else if (isRecord3(raw.factoryDeps)) {
12409
+ } else if (isRecord4(raw.factoryDeps)) {
12188
12410
  factoryDeps = Object.values(raw.factoryDeps).map((entry, index) => {
12189
12411
  if (typeof entry !== "string") {
12190
12412
  throw new Error(`factoryDeps value ${index} in ${artifactPath2} must be a hex string`);
@@ -12201,7 +12423,7 @@ function parseArtifactFile(artifactPath2) {
12201
12423
  }
12202
12424
  function missingArtifactError(profileId, artifactPath2) {
12203
12425
  return new Error(
12204
- `Built-in smart-account profile "${profileId}" is source-only right now. Expected compiled artifact at ${artifactPath2}. Compile the profile with a zkSync EraVM toolchain before using --profile ${profileId}.`
12426
+ `Built-in smart-account profile "${profileId}" is not available in this runtime. Expected a compiled artifact at ${artifactPath2}. If you are running from source, compile the profile with a zkSync EraVM toolchain or point ZK_AGENT_ACCOUNT_PROFILES_ROOT at a checked-out ${PACKAGE_NAME} package directory.`
12205
12427
  );
12206
12428
  }
12207
12429
  function contractPath(...segments) {
@@ -12236,7 +12458,7 @@ function createDailySpendLimitProfile() {
12236
12458
  "The checked-in Solidity source uses 24 hours instead of the tutorial 1 minute reset window.",
12237
12459
  "AAFactory is kept as a reference helper, but the CLI deploy path targets the account artifact directly.",
12238
12460
  ...packageRootResolved ? [] : [
12239
- `Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys.`
12461
+ `Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys when source checkout is required.`
12240
12462
  ]
12241
12463
  ],
12242
12464
  buildConstructorArgs(context) {
@@ -12283,7 +12505,7 @@ function createSedLiteProfile() {
12283
12505
  "The first standalone policy hook, NativePerTxLimitHook, is now deployed and live-validated on zkSync Sepolia.",
12284
12506
  "The second standalone policy hook, TargetAllowlistHook, is now deployed and live-validated on zkSync Sepolia.",
12285
12507
  ...packageRootResolved ? [] : [
12286
- `Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys.`
12508
+ `Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys when source checkout is required.`
12287
12509
  ]
12288
12510
  ],
12289
12511
  buildConstructorArgs(context) {
@@ -12755,7 +12977,7 @@ function requireSmartAccountWallet(wallet) {
12755
12977
  }
12756
12978
  return wallet;
12757
12979
  }
12758
- function isRecord4(value) {
12980
+ function isRecord5(value) {
12759
12981
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12760
12982
  }
12761
12983
  function cloneWalletSessionRecord(wallet) {
@@ -12788,11 +13010,11 @@ function cloneWalletSessionRecord(wallet) {
12788
13010
  };
12789
13011
  }
12790
13012
  function isWalletExportRecord(value) {
12791
- return isRecord4(value) && value.format === "zk-agent-wallet-export" && value.version === 1 && typeof value.exportedAt === "string" && typeof value.sensitiveDataIncluded === "boolean" && isRecord4(value.wallet);
13013
+ return isRecord5(value) && value.format === "zk-agent-wallet-export" && value.version === 1 && typeof value.exportedAt === "string" && typeof value.sensitiveDataIncluded === "boolean" && isRecord5(value.wallet);
12792
13014
  }
12793
13015
  function parseWalletExportRecord(value) {
12794
13016
  const raw = parseJsonInput(value);
12795
- const candidate = isRecord4(raw) && isRecord4(raw.export) ? raw.export : raw;
13017
+ const candidate = isRecord5(raw) && isRecord5(raw.export) ? raw.export : raw;
12796
13018
  if (!isWalletExportRecord(candidate)) {
12797
13019
  throw new Error(
12798
13020
  'Restore payload must be a wallet export bundle created by "wallet export". You can pass either the raw export bundle or the full JSON output from "wallet export --json".'
@@ -12856,9 +13078,9 @@ function normalizeHexString2(value, label) {
12856
13078
  }
12857
13079
  function parseArtifactInput(value) {
12858
13080
  const raw = parseJsonInput(value);
12859
- if (!isRecord4(raw)) throw new Error("Artifact must be a JSON object");
13081
+ if (!isRecord5(raw)) throw new Error("Artifact must be a JSON object");
12860
13082
  if (!Array.isArray(raw.abi)) throw new Error("Artifact must include an abi array");
12861
- const bytecodeCandidate = typeof raw.bytecode === "string" ? raw.bytecode : isRecord4(raw.evm) && isRecord4(raw.evm.bytecode) && typeof raw.evm.bytecode.object === "string" ? raw.evm.bytecode.object : void 0;
13083
+ const bytecodeCandidate = typeof raw.bytecode === "string" ? raw.bytecode : isRecord5(raw.evm) && isRecord5(raw.evm.bytecode) && typeof raw.evm.bytecode.object === "string" ? raw.evm.bytecode.object : void 0;
12862
13084
  if (!bytecodeCandidate) {
12863
13085
  throw new Error("Artifact must include bytecode or evm.bytecode.object");
12864
13086
  }
@@ -12870,7 +13092,7 @@ function parseArtifactInput(value) {
12870
13092
  }
12871
13093
  return normalizeHexString2(entry, `factoryDeps[${index}]`);
12872
13094
  });
12873
- } else if (isRecord4(raw.factoryDeps)) {
13095
+ } else if (isRecord5(raw.factoryDeps)) {
12874
13096
  factoryDeps = Object.values(raw.factoryDeps).map((entry, index) => {
12875
13097
  if (typeof entry !== "string") {
12876
13098
  throw new Error(`factoryDeps value ${index} must be a hex string`);
@@ -13922,7 +14144,7 @@ async function createWalletReapprovalRequest(options) {
13922
14144
  return request;
13923
14145
  }
13924
14146
  function ensureSessionPayload(value) {
13925
- if (!isRecord4(value)) {
14147
+ if (!isRecord5(value)) {
13926
14148
  throw new Error("Approved callback payload must include a payload object.");
13927
14149
  }
13928
14150
  return value;
@@ -14201,7 +14423,7 @@ async function awaitLocalWalletApproval(options) {
14201
14423
  try {
14202
14424
  assertRequestActive(walletRequest.expiresAt);
14203
14425
  const body = await readLocalApprovalBody(requestMessage);
14204
- if (!isRecord4(body)) {
14426
+ if (!isRecord5(body)) {
14205
14427
  throw new Error("Approved callback body must be a JSON object.");
14206
14428
  }
14207
14429
  const callbackRequestId = typeof body.requestId === "string" ? body.requestId : void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zk-agent-cli",
3
- "version": "0.1.0-beta.1",
3
+ "version": "0.1.0-beta.3",
4
4
  "description": "Local-first zkSync Era and ZK Stack agent CLI with wallet session recovery, workflow orchestration, relay-backed approval, and SED smart-account support.",
5
5
  "license": "MIT",
6
6
  "type": "module",