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.
- package/README.md +23 -8
- package/dist/builtin-account-profiles/artifacts/daily-spend-limit/Account.json +693 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/Account.json +970 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/EOAValidator.json +50 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/NativePerTxLimitHook.json +267 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/TargetAllowlistHook.json +346 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/TargetSelectorAllowlistHook.json +643 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/AAFactory.sol +28 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/Account.sol +179 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/SpendLimit.sol +85 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/Account.sol +230 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/Auth.sol +16 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/BootloaderAuth.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/EOAValidator.sol +23 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/IValidationHook.sol +20 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/IValidator.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ModuleAuth.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ModuleManager.sol +46 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/NativePerTxLimitHook.sol +67 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/OwnerManager.sol +25 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/SelfAuth.sol +9 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/TargetAllowlistHook.sol +110 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/TargetSelectorAllowlistHook.sol +263 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ValidationHookManager.sol +76 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ValidatorManager.sol +31 -0
- package/dist/builtin-account-profiles/package.json +5 -0
- package/dist/connector-ui/assets/index-BnFLonFL.css +1 -0
- package/dist/connector-ui/assets/index-WTJRR5fK.js +40 -0
- package/dist/connector-ui/index.html +13 -0
- package/dist/index.js +248 -26
- 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
|
|
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(
|
|
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(
|
|
11949
|
-
status_url: relayStatusUrl(
|
|
11950
|
-
approval_url: relayShareUrl(
|
|
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(
|
|
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(
|
|
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").
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
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 :
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 (!
|
|
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 :
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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.
|
|
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",
|