@zeroxyz/cli 1.8.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1647 -1774
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -76582,7 +76582,7 @@ init_esm_shims();
|
|
|
76582
76582
|
|
|
76583
76583
|
// package.json
|
|
76584
76584
|
var package_default = {
|
|
76585
|
-
version: "1.
|
|
76585
|
+
version: "1.10.0"};
|
|
76586
76586
|
|
|
76587
76587
|
// src/app.ts
|
|
76588
76588
|
init_esm_shims();
|
|
@@ -77590,7 +77590,7 @@ init_esm_shims();
|
|
|
77590
77590
|
// ../sdk/dist/index.js
|
|
77591
77591
|
init_esm_shims();
|
|
77592
77592
|
|
|
77593
|
-
// ../sdk/dist/chunk-
|
|
77593
|
+
// ../sdk/dist/chunk-NUBD543C.js
|
|
77594
77594
|
init_esm_shims();
|
|
77595
77595
|
|
|
77596
77596
|
// ../../node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@4.3.6/node_modules/viem/_esm/index.js
|
|
@@ -142971,6 +142971,8 @@ config(en_default2());
|
|
|
142971
142971
|
|
|
142972
142972
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js
|
|
142973
142973
|
var zod_default = external_exports3;
|
|
142974
|
+
|
|
142975
|
+
// ../sdk/dist/chunk-NUBD543C.js
|
|
142974
142976
|
var createManagedAccount = (client, address2) => toAccount({
|
|
142975
142977
|
address: address2,
|
|
142976
142978
|
async signMessage({ message: message2 }) {
|
|
@@ -144161,718 +144163,1346 @@ var Payments = class {
|
|
|
144161
144163
|
};
|
|
144162
144164
|
};
|
|
144163
144165
|
};
|
|
144164
|
-
var
|
|
144165
|
-
|
|
144166
|
-
|
|
144167
|
-
var
|
|
144168
|
-
|
|
144169
|
-
|
|
144170
|
-
|
|
144171
|
-
|
|
144172
|
-
|
|
144173
|
-
|
|
144174
|
-
|
|
144175
|
-
|
|
144176
|
-
|
|
144177
|
-
|
|
144178
|
-
var
|
|
144179
|
-
|
|
144180
|
-
|
|
144181
|
-
|
|
144182
|
-
|
|
144183
|
-
|
|
144184
|
-
|
|
144185
|
-
|
|
144186
|
-
|
|
144187
|
-
|
|
144188
|
-
|
|
144189
|
-
|
|
144190
|
-
|
|
144191
|
-
|
|
144192
|
-
|
|
144193
|
-
|
|
144194
|
-
|
|
144195
|
-
|
|
144196
|
-
|
|
144197
|
-
|
|
144198
|
-
|
|
144199
|
-
|
|
144200
|
-
|
|
144201
|
-
|
|
144202
|
-
|
|
144203
|
-
|
|
144204
|
-
|
|
144205
|
-
});
|
|
144206
|
-
var deviceStartResponseSchema = external_exports3.object({
|
|
144207
|
-
deviceCode: external_exports3.string(),
|
|
144208
|
-
userCode: external_exports3.string(),
|
|
144209
|
-
verificationUri: external_exports3.string(),
|
|
144210
|
-
pollInterval: external_exports3.number(),
|
|
144211
|
-
expiresAt: external_exports3.number()
|
|
144212
|
-
});
|
|
144213
|
-
var devicePollResponseSchema = external_exports3.union([
|
|
144214
|
-
// userCode + verificationUri are optional: older API deployments don't
|
|
144215
|
-
// echo them on pending.
|
|
144216
|
-
external_exports3.object({
|
|
144217
|
-
error: external_exports3.literal("authorization_pending"),
|
|
144218
|
-
userCode: external_exports3.string().optional(),
|
|
144219
|
-
verificationUri: external_exports3.string().optional()
|
|
144220
|
-
}),
|
|
144221
|
-
external_exports3.object({ error: external_exports3.literal("expired_token") }),
|
|
144222
|
-
external_exports3.object({
|
|
144223
|
-
accessToken: external_exports3.string(),
|
|
144224
|
-
refreshToken: external_exports3.string(),
|
|
144225
|
-
expiresIn: external_exports3.number(),
|
|
144226
|
-
user: internalUserDtoSchema
|
|
144227
|
-
})
|
|
144228
|
-
]);
|
|
144229
|
-
var sessionExchangeResponseSchema = external_exports3.object({
|
|
144230
|
-
token: external_exports3.string(),
|
|
144231
|
-
expiresAt: external_exports3.number()
|
|
144232
|
-
});
|
|
144233
|
-
var refreshResponseSchema = external_exports3.object({
|
|
144234
|
-
accessToken: external_exports3.string(),
|
|
144235
|
-
refreshToken: external_exports3.string()
|
|
144236
|
-
});
|
|
144237
|
-
var tryRefreshSession = async (client, callerSignal) => {
|
|
144238
|
-
const credentials = client.getCredentials();
|
|
144239
|
-
if (credentials.kind !== "session") return false;
|
|
144240
|
-
if (!credentials.refreshToken) return false;
|
|
144241
|
-
const url4 = `${client.baseUrl.replace(/\/$/, "")}/v1/auth/refresh`;
|
|
144242
|
-
const timeoutSignal = AbortSignal.timeout(client.timeout);
|
|
144243
|
-
const signal = callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal;
|
|
144244
|
-
let response;
|
|
144245
|
-
try {
|
|
144246
|
-
response = await client.fetchImpl(url4, {
|
|
144247
|
-
method: "POST",
|
|
144248
|
-
headers: { "content-type": "application/json" },
|
|
144249
|
-
body: JSON.stringify({ refreshToken: credentials.refreshToken }),
|
|
144250
|
-
signal
|
|
144251
|
-
});
|
|
144252
|
-
} catch {
|
|
144253
|
-
return false;
|
|
144166
|
+
var isShortToken = (id) => id.startsWith("z_") && id.indexOf(".", 2) !== -1;
|
|
144167
|
+
var MAX_402_PROBE_BYTES = 1024 * 1024;
|
|
144168
|
+
var MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
144169
|
+
var TEXT_CONTENT_TYPES = [
|
|
144170
|
+
"application/json",
|
|
144171
|
+
"application/xml",
|
|
144172
|
+
"application/javascript",
|
|
144173
|
+
"application/ecmascript",
|
|
144174
|
+
"application/x-www-form-urlencoded",
|
|
144175
|
+
"text/",
|
|
144176
|
+
"+json",
|
|
144177
|
+
"+xml"
|
|
144178
|
+
];
|
|
144179
|
+
var MPP_SCHEME_TOKENS = /* @__PURE__ */ new Set(["payment", "mpp"]);
|
|
144180
|
+
var splitWwwAuthenticateChallenges = (header) => {
|
|
144181
|
+
const chunks = [];
|
|
144182
|
+
let buf = "";
|
|
144183
|
+
let inQuotes = false;
|
|
144184
|
+
for (let i = 0; i < header.length; i++) {
|
|
144185
|
+
const ch = header[i];
|
|
144186
|
+
if (inQuotes) {
|
|
144187
|
+
if (ch === "\\" && i + 1 < header.length) {
|
|
144188
|
+
buf += ch + header[i + 1];
|
|
144189
|
+
i++;
|
|
144190
|
+
continue;
|
|
144191
|
+
}
|
|
144192
|
+
if (ch === '"') inQuotes = false;
|
|
144193
|
+
buf += ch;
|
|
144194
|
+
continue;
|
|
144195
|
+
}
|
|
144196
|
+
if (ch === '"') {
|
|
144197
|
+
inQuotes = true;
|
|
144198
|
+
buf += ch;
|
|
144199
|
+
continue;
|
|
144200
|
+
}
|
|
144201
|
+
if (ch === ",") {
|
|
144202
|
+
chunks.push(buf);
|
|
144203
|
+
buf = "";
|
|
144204
|
+
continue;
|
|
144205
|
+
}
|
|
144206
|
+
buf += ch;
|
|
144254
144207
|
}
|
|
144255
|
-
if (
|
|
144256
|
-
|
|
144208
|
+
if (buf.length > 0) chunks.push(buf);
|
|
144209
|
+
return chunks;
|
|
144210
|
+
};
|
|
144211
|
+
var isTextContentType = (contentType) => {
|
|
144212
|
+
if (!contentType) return true;
|
|
144213
|
+
const lower = contentType.toLowerCase();
|
|
144214
|
+
return TEXT_CONTENT_TYPES.some((marker) => lower.includes(marker));
|
|
144215
|
+
};
|
|
144216
|
+
var redactUrl2 = (url4) => {
|
|
144257
144217
|
try {
|
|
144258
|
-
|
|
144218
|
+
const u2 = new URL(url4);
|
|
144219
|
+
return `${u2.origin}${u2.pathname}`;
|
|
144259
144220
|
} catch {
|
|
144260
|
-
return
|
|
144221
|
+
return "<invalid url>";
|
|
144261
144222
|
}
|
|
144262
|
-
const parsed = refreshResponseSchema.safeParse(body);
|
|
144263
|
-
if (!parsed.success) return false;
|
|
144264
|
-
await client.applyRefreshedTokens({
|
|
144265
|
-
accessToken: parsed.data.accessToken,
|
|
144266
|
-
refreshToken: parsed.data.refreshToken
|
|
144267
|
-
});
|
|
144268
|
-
return true;
|
|
144269
|
-
};
|
|
144270
|
-
var buildSessionAuthHeaders = (accessToken) => ({
|
|
144271
|
-
authorization: `Bearer ${accessToken}`
|
|
144272
|
-
});
|
|
144273
|
-
var buildCanonicalMessage = (method, pathWithQuery, body, timestamp, nonce2) => {
|
|
144274
|
-
const bodyHash = createHash("sha256").update(body ?? "").digest("hex");
|
|
144275
|
-
return `${method}:${pathWithQuery}:${bodyHash}:${timestamp}:${nonce2}`;
|
|
144276
144223
|
};
|
|
144277
|
-
var
|
|
144278
|
-
|
|
144279
|
-
|
|
144280
|
-
|
|
144281
|
-
|
|
144282
|
-
|
|
144283
|
-
body,
|
|
144284
|
-
timestamp,
|
|
144285
|
-
nonce2
|
|
144224
|
+
var ECHO_DETECT_MIN_LEN = 16;
|
|
144225
|
+
var ECHO_DETECT_MAX_SCAN = 64 * 1024;
|
|
144226
|
+
var requestBodyEchoed = (candidate, requestBody) => {
|
|
144227
|
+
if (requestBody === void 0) return false;
|
|
144228
|
+
const asString = typeof requestBody === "string" ? requestBody : new TextDecoder("utf-8", { fatal: false }).decode(
|
|
144229
|
+
requestBody.byteLength > ECHO_DETECT_MAX_SCAN ? requestBody.subarray(0, ECHO_DETECT_MAX_SCAN) : requestBody
|
|
144286
144230
|
);
|
|
144287
|
-
|
|
144288
|
-
|
|
144289
|
-
|
|
144290
|
-
|
|
144291
|
-
|
|
144292
|
-
|
|
144293
|
-
};
|
|
144294
|
-
};
|
|
144295
|
-
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 502, 503, 504]);
|
|
144296
|
-
var sleep2 = (ms, signal) => new Promise((resolve6, reject) => {
|
|
144297
|
-
if (signal?.aborted) {
|
|
144298
|
-
reject(new DOMException("Aborted", "AbortError"));
|
|
144299
|
-
return;
|
|
144300
|
-
}
|
|
144301
|
-
const timer = setTimeout(() => {
|
|
144302
|
-
signal?.removeEventListener("abort", onAbort);
|
|
144303
|
-
resolve6();
|
|
144304
|
-
}, ms);
|
|
144305
|
-
const onAbort = () => {
|
|
144306
|
-
clearTimeout(timer);
|
|
144307
|
-
reject(new DOMException("Aborted", "AbortError"));
|
|
144308
|
-
};
|
|
144309
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
144310
|
-
});
|
|
144311
|
-
var buildPathWithQuery = (path3, query) => {
|
|
144312
|
-
const normalizedPath = path3.startsWith("/") ? path3 : `/${path3}`;
|
|
144313
|
-
if (!query) return normalizedPath;
|
|
144314
|
-
const params = new URLSearchParams();
|
|
144315
|
-
for (const [key, value] of Object.entries(query)) {
|
|
144316
|
-
if (value !== void 0) params.set(key, String(value));
|
|
144317
|
-
}
|
|
144318
|
-
const qs = params.toString();
|
|
144319
|
-
return qs ? `${normalizedPath}?${qs}` : normalizedPath;
|
|
144320
|
-
};
|
|
144321
|
-
var joinUrl = (baseUrl, pathWithQuery) => {
|
|
144322
|
-
const base3 = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
144323
|
-
return `${base3}${pathWithQuery}`;
|
|
144324
|
-
};
|
|
144325
|
-
var buildHeaders = async (client, method, pathWithQuery, hasBody, bodyStr) => {
|
|
144326
|
-
const headers = { ...client.defaultHeaders };
|
|
144327
|
-
if (hasBody) headers["content-type"] = "application/json";
|
|
144328
|
-
headers["x-zero-sdk-version"] = SDK_VERSION2;
|
|
144329
|
-
if (client.apiVersion) headers["x-zero-api-version"] = client.apiVersion;
|
|
144330
|
-
const credentials = client.getCredentials();
|
|
144331
|
-
if (credentials.kind === "session") {
|
|
144332
|
-
Object.assign(headers, buildSessionAuthHeaders(credentials.accessToken));
|
|
144333
|
-
} else if (credentials.kind === "account") {
|
|
144334
|
-
const signed = await buildAccountAuthHeaders(
|
|
144335
|
-
credentials.account,
|
|
144336
|
-
method,
|
|
144337
|
-
pathWithQuery,
|
|
144338
|
-
bodyStr
|
|
144339
|
-
);
|
|
144340
|
-
Object.assign(headers, signed);
|
|
144231
|
+
if (asString.length < ECHO_DETECT_MIN_LEN) return false;
|
|
144232
|
+
const scanLen = Math.min(asString.length, ECHO_DETECT_MAX_SCAN);
|
|
144233
|
+
for (let i = 0; i + ECHO_DETECT_MIN_LEN <= scanLen; i++) {
|
|
144234
|
+
if (candidate.includes(asString.slice(i, i + ECHO_DETECT_MIN_LEN))) {
|
|
144235
|
+
return true;
|
|
144236
|
+
}
|
|
144341
144237
|
}
|
|
144342
|
-
return
|
|
144238
|
+
return false;
|
|
144343
144239
|
};
|
|
144344
|
-
var
|
|
144240
|
+
var cancelBody2 = (response) => {
|
|
144345
144241
|
try {
|
|
144346
|
-
|
|
144242
|
+
response.body?.cancel().catch(() => {
|
|
144243
|
+
});
|
|
144347
144244
|
} catch {
|
|
144245
|
+
}
|
|
144246
|
+
};
|
|
144247
|
+
var detectPaymentRequirement = async (response) => {
|
|
144248
|
+
if (response.status !== 402) return null;
|
|
144249
|
+
const x402Header = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
|
|
144250
|
+
if (x402Header) {
|
|
144251
|
+
cancelBody2(response);
|
|
144348
144252
|
try {
|
|
144349
|
-
|
|
144253
|
+
const decoded = JSON.parse(
|
|
144254
|
+
Buffer.from(x402Header, "base64").toString("utf8")
|
|
144255
|
+
);
|
|
144256
|
+
return { protocol: "x402", raw: decoded };
|
|
144350
144257
|
} catch {
|
|
144351
|
-
return
|
|
144258
|
+
return { protocol: "x402", raw: { encoded: x402Header } };
|
|
144352
144259
|
}
|
|
144353
144260
|
}
|
|
144354
|
-
|
|
144355
|
-
|
|
144356
|
-
|
|
144357
|
-
|
|
144358
|
-
|
|
144359
|
-
|
|
144360
|
-
};
|
|
144361
|
-
var request2 = async (client, opts, schema) => {
|
|
144362
|
-
const pathWithQuery = buildPathWithQuery(opts.path, opts.query);
|
|
144363
|
-
const url4 = joinUrl(client.baseUrl, pathWithQuery);
|
|
144364
|
-
const hasBody = opts.body !== void 0;
|
|
144365
|
-
const bodyStr = hasBody ? JSON.stringify(
|
|
144366
|
-
opts.body,
|
|
144367
|
-
(_k, v) => typeof v === "bigint" ? v.toString() : v
|
|
144368
|
-
) : void 0;
|
|
144369
|
-
const configuredFetch = buildConfiguredFetch(client);
|
|
144370
|
-
const performOnce = async () => configuredFetch(url4, {
|
|
144371
|
-
method: opts.method,
|
|
144372
|
-
headers: await buildHeaders(
|
|
144373
|
-
client,
|
|
144374
|
-
opts.method,
|
|
144375
|
-
pathWithQuery,
|
|
144376
|
-
hasBody,
|
|
144377
|
-
bodyStr
|
|
144378
|
-
),
|
|
144379
|
-
body: bodyStr,
|
|
144380
|
-
signal: opts.signal
|
|
144381
|
-
});
|
|
144382
|
-
let refreshAttempted = false;
|
|
144383
|
-
const executeWithRefresh = async () => {
|
|
144384
|
-
const response = await performOnce();
|
|
144385
|
-
if (response.status !== 401 || refreshAttempted) return response;
|
|
144386
|
-
const credentials = client.getCredentials();
|
|
144387
|
-
if (credentials.kind !== "session") return response;
|
|
144388
|
-
refreshAttempted = true;
|
|
144389
|
-
const refreshed = await client.refreshSessionOnce(opts.signal);
|
|
144390
|
-
if (!refreshed) return response;
|
|
144391
|
-
return await performOnce();
|
|
144392
|
-
};
|
|
144393
|
-
let lastNetworkError;
|
|
144394
|
-
for (let attempt = 0; attempt <= client.maxRetries; attempt++) {
|
|
144395
|
-
let response;
|
|
144261
|
+
const declaredLen = Number.parseInt(
|
|
144262
|
+
response.headers.get("content-length") ?? "",
|
|
144263
|
+
10
|
|
144264
|
+
);
|
|
144265
|
+
const bodyFits = !Number.isFinite(declaredLen) || declaredLen <= MAX_402_PROBE_BYTES;
|
|
144266
|
+
if (bodyFits) {
|
|
144396
144267
|
try {
|
|
144397
|
-
|
|
144398
|
-
|
|
144399
|
-
|
|
144400
|
-
|
|
144401
|
-
|
|
144402
|
-
try {
|
|
144403
|
-
await sleep2(2 ** attempt * 200, opts.signal);
|
|
144404
|
-
} catch (sleepErr) {
|
|
144405
|
-
throw new ZeroApiError("Request aborted by caller", {
|
|
144406
|
-
status: 0,
|
|
144407
|
-
cause: sleepErr
|
|
144408
|
-
});
|
|
144268
|
+
const text = await readClippedText(response, MAX_402_PROBE_BYTES);
|
|
144269
|
+
if (text) {
|
|
144270
|
+
const parsed = JSON.parse(text);
|
|
144271
|
+
if (looksLikeX402Body(parsed)) {
|
|
144272
|
+
return { protocol: "x402", raw: parsed };
|
|
144409
144273
|
}
|
|
144410
|
-
continue;
|
|
144411
|
-
}
|
|
144412
|
-
throw new ZeroApiError("Network request failed", {
|
|
144413
|
-
status: 0,
|
|
144414
|
-
cause: e2
|
|
144415
|
-
});
|
|
144416
|
-
}
|
|
144417
|
-
if (response.ok) {
|
|
144418
|
-
let text;
|
|
144419
|
-
try {
|
|
144420
|
-
text = await response.text();
|
|
144421
|
-
} catch (e2) {
|
|
144422
|
-
throw new ZeroApiError("Response body read failed", {
|
|
144423
|
-
status: response.status,
|
|
144424
|
-
cause: e2
|
|
144425
|
-
});
|
|
144426
|
-
}
|
|
144427
|
-
let json3;
|
|
144428
|
-
try {
|
|
144429
|
-
json3 = JSON.parse(text);
|
|
144430
|
-
} catch {
|
|
144431
|
-
}
|
|
144432
|
-
const parsed = schema.safeParse(json3);
|
|
144433
|
-
if (!parsed.success) {
|
|
144434
|
-
throw new ZeroValidationError(
|
|
144435
|
-
`Response did not match expected schema for ${opts.method} ${opts.path}`,
|
|
144436
|
-
{ cause: parsed.error, body: text }
|
|
144437
|
-
);
|
|
144438
144274
|
}
|
|
144439
|
-
|
|
144275
|
+
} catch {
|
|
144440
144276
|
}
|
|
144441
|
-
|
|
144442
|
-
|
|
144443
|
-
|
|
144444
|
-
|
|
144445
|
-
|
|
144446
|
-
|
|
144447
|
-
|
|
144448
|
-
|
|
144449
|
-
}
|
|
144450
|
-
continue;
|
|
144277
|
+
}
|
|
144278
|
+
const wwwAuth = response.headers.get("www-authenticate");
|
|
144279
|
+
if (wwwAuth) {
|
|
144280
|
+
const schemes = splitWwwAuthenticateChallenges(wwwAuth).map(
|
|
144281
|
+
(challenge2) => challenge2.trim().split(/\s+/)[0]?.toLowerCase() ?? ""
|
|
144282
|
+
);
|
|
144283
|
+
if (schemes.some((scheme) => MPP_SCHEME_TOKENS.has(scheme))) {
|
|
144284
|
+
cancelBody2(response);
|
|
144285
|
+
return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
|
|
144451
144286
|
}
|
|
144452
|
-
const errorBody = await parseErrorBody(response);
|
|
144453
|
-
const requestId = response.headers.get("x-request-id") ?? void 0;
|
|
144454
|
-
throw new ZeroApiError(errorMessageFromBody(errorBody, response.status), {
|
|
144455
|
-
status: response.status,
|
|
144456
|
-
requestId,
|
|
144457
|
-
body: errorBody
|
|
144458
|
-
});
|
|
144459
144287
|
}
|
|
144460
|
-
|
|
144461
|
-
|
|
144462
|
-
cause: lastNetworkError
|
|
144463
|
-
});
|
|
144288
|
+
cancelBody2(response);
|
|
144289
|
+
return { protocol: "unknown", raw: {} };
|
|
144464
144290
|
};
|
|
144465
|
-
var
|
|
144466
|
-
|
|
144467
|
-
|
|
144468
|
-
|
|
144469
|
-
|
|
144470
|
-
|
|
144471
|
-
{
|
|
144472
|
-
|
|
144473
|
-
|
|
144474
|
-
|
|
144475
|
-
|
|
144476
|
-
|
|
144477
|
-
|
|
144478
|
-
|
|
144479
|
-
|
|
144480
|
-
|
|
144481
|
-
|
|
144482
|
-
method: "POST",
|
|
144483
|
-
path: "/v1/auth/device/poll",
|
|
144484
|
-
body: { deviceCode },
|
|
144485
|
-
signal: opts.signal
|
|
144486
|
-
},
|
|
144487
|
-
devicePollResponseSchema
|
|
144488
|
-
);
|
|
144489
|
-
if ("error" in parsed) {
|
|
144490
|
-
return parsed.error === "authorization_pending" ? {
|
|
144491
|
-
status: "pending",
|
|
144492
|
-
userCode: parsed.userCode,
|
|
144493
|
-
verificationUri: parsed.verificationUri
|
|
144494
|
-
} : { status: "expired" };
|
|
144291
|
+
var readClippedBytes = async (response, max) => {
|
|
144292
|
+
if (response.body === null) return new Uint8Array(0);
|
|
144293
|
+
const reader = response.body.getReader();
|
|
144294
|
+
const chunks = [];
|
|
144295
|
+
let total = 0;
|
|
144296
|
+
try {
|
|
144297
|
+
while (total < max) {
|
|
144298
|
+
const { done, value } = await reader.read();
|
|
144299
|
+
if (done) break;
|
|
144300
|
+
if (!value) continue;
|
|
144301
|
+
chunks.push(value);
|
|
144302
|
+
total += value.byteLength;
|
|
144303
|
+
}
|
|
144304
|
+
} finally {
|
|
144305
|
+
try {
|
|
144306
|
+
await reader.cancel();
|
|
144307
|
+
} catch {
|
|
144495
144308
|
}
|
|
144309
|
+
}
|
|
144310
|
+
const merged = new Uint8Array(Math.min(total, max));
|
|
144311
|
+
let offset = 0;
|
|
144312
|
+
for (const c of chunks) {
|
|
144313
|
+
const take = Math.min(c.byteLength, max - offset);
|
|
144314
|
+
merged.set(c.subarray(0, take), offset);
|
|
144315
|
+
offset += take;
|
|
144316
|
+
if (offset >= max) break;
|
|
144317
|
+
}
|
|
144318
|
+
return merged;
|
|
144319
|
+
};
|
|
144320
|
+
var readClippedText = async (response, max) => {
|
|
144321
|
+
const bytes = await readClippedBytes(response, max);
|
|
144322
|
+
return new TextDecoder().decode(bytes);
|
|
144323
|
+
};
|
|
144324
|
+
var parseResponseBody = async (response, max) => {
|
|
144325
|
+
const contentType = response.headers.get("content-type");
|
|
144326
|
+
const bytes = await readClippedBytes(response, max + 1);
|
|
144327
|
+
const truncated = bytes.byteLength > max;
|
|
144328
|
+
const view = truncated ? bytes.subarray(0, max) : bytes;
|
|
144329
|
+
const buf = Buffer.from(view.buffer, view.byteOffset, view.byteLength);
|
|
144330
|
+
if (!isTextContentType(contentType)) {
|
|
144331
|
+
const base644 = buf.toString("base64");
|
|
144496
144332
|
return {
|
|
144497
|
-
|
|
144498
|
-
|
|
144499
|
-
|
|
144500
|
-
|
|
144501
|
-
user: parsed.user
|
|
144333
|
+
body: base644,
|
|
144334
|
+
bodyRaw: base644,
|
|
144335
|
+
bodyEncoding: "base64",
|
|
144336
|
+
truncated
|
|
144502
144337
|
};
|
|
144503
|
-
}
|
|
144338
|
+
}
|
|
144339
|
+
const text = buf.toString("utf8");
|
|
144340
|
+
if (contentType?.toLowerCase().includes("json")) {
|
|
144341
|
+
try {
|
|
144342
|
+
return { body: JSON.parse(text), bodyRaw: text, truncated };
|
|
144343
|
+
} catch {
|
|
144344
|
+
}
|
|
144345
|
+
}
|
|
144346
|
+
return { body: text, bodyRaw: text, truncated };
|
|
144504
144347
|
};
|
|
144505
|
-
var
|
|
144506
|
-
|
|
144507
|
-
|
|
144508
|
-
|
|
144509
|
-
|
|
144348
|
+
var UPSTREAM_ERROR_FIELDS = [
|
|
144349
|
+
"error",
|
|
144350
|
+
"message",
|
|
144351
|
+
"detail",
|
|
144352
|
+
"reason",
|
|
144353
|
+
"error_description"
|
|
144354
|
+
];
|
|
144355
|
+
var UPSTREAM_ERROR_MAX_LEN = 200;
|
|
144356
|
+
var ERROR_SNIPPET_BYTES = 500;
|
|
144357
|
+
var clampUpstreamMessage = (value) => {
|
|
144358
|
+
const trimmed = value.trim();
|
|
144359
|
+
if (!trimmed) return void 0;
|
|
144360
|
+
return trimmed.length > UPSTREAM_ERROR_MAX_LEN ? `${trimmed.slice(0, UPSTREAM_ERROR_MAX_LEN)}\u2026` : trimmed;
|
|
144510
144361
|
};
|
|
144511
|
-
var
|
|
144512
|
-
|
|
144513
|
-
|
|
144514
|
-
|
|
144515
|
-
|
|
144516
|
-
`Sign endpoint refused ${op} (HTTP 402)${detail}`,
|
|
144517
|
-
{ cause: err }
|
|
144518
|
-
);
|
|
144362
|
+
var tryParseJson = (text) => {
|
|
144363
|
+
try {
|
|
144364
|
+
return JSON.parse(text);
|
|
144365
|
+
} catch {
|
|
144366
|
+
return null;
|
|
144519
144367
|
}
|
|
144520
|
-
throw err;
|
|
144521
144368
|
};
|
|
144522
|
-
var
|
|
144523
|
-
|
|
144524
|
-
|
|
144525
|
-
|
|
144369
|
+
var extractUpstreamErrorMessage = (body) => {
|
|
144370
|
+
const parsed = tryParseJson(body);
|
|
144371
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
144372
|
+
return clampUpstreamMessage(body);
|
|
144526
144373
|
}
|
|
144527
|
-
|
|
144528
|
-
|
|
144529
|
-
|
|
144530
|
-
|
|
144531
|
-
|
|
144532
|
-
|
|
144533
|
-
|
|
144534
|
-
|
|
144535
|
-
|
|
144536
|
-
|
|
144537
|
-
|
|
144538
|
-
|
|
144539
|
-
|
|
144540
|
-
|
|
144541
|
-
|
|
144374
|
+
const record3 = parsed;
|
|
144375
|
+
for (const field of UPSTREAM_ERROR_FIELDS) {
|
|
144376
|
+
const value = record3[field];
|
|
144377
|
+
if (typeof value === "string" && value.length > 0) {
|
|
144378
|
+
return clampUpstreamMessage(value);
|
|
144379
|
+
}
|
|
144380
|
+
if (value && typeof value === "object") {
|
|
144381
|
+
const nested = value.message;
|
|
144382
|
+
if (typeof nested === "string" && nested.length > 0) {
|
|
144383
|
+
return clampUpstreamMessage(nested);
|
|
144384
|
+
}
|
|
144385
|
+
}
|
|
144386
|
+
}
|
|
144387
|
+
return void 0;
|
|
144388
|
+
};
|
|
144389
|
+
var buildUpstreamError = (status, bodyRaw, bodyEncoding) => {
|
|
144390
|
+
if (status >= 200 && status < 300) return void 0;
|
|
144391
|
+
if (bodyRaw === null || bodyRaw.length === 0) return void 0;
|
|
144392
|
+
if (bodyEncoding === "base64") return void 0;
|
|
144393
|
+
const snippet = bodyRaw.slice(0, ERROR_SNIPPET_BYTES);
|
|
144394
|
+
return {
|
|
144395
|
+
status,
|
|
144396
|
+
message: extractUpstreamErrorMessage(bodyRaw),
|
|
144397
|
+
snippetHash: createHash("sha256").update(snippet).digest("hex"),
|
|
144398
|
+
snippetLength: snippet.length
|
|
144399
|
+
};
|
|
144400
|
+
};
|
|
144401
|
+
var computeOutcome = (status, payment, warnings) => {
|
|
144402
|
+
if (warnings.includes(FETCH_WARNINGS.mppSessionCloseFailed))
|
|
144403
|
+
return "payment_close_failed";
|
|
144404
|
+
if (status === 402 && payment !== null) return "payment_rejected";
|
|
144405
|
+
if (status === 402) return "payment_failed";
|
|
144406
|
+
if (status >= 400) return "server_error";
|
|
144407
|
+
return "success";
|
|
144408
|
+
};
|
|
144409
|
+
var errorFetchResult = (startedAt, error48, skipReason, capabilityIdRequested, outcome, status = null) => {
|
|
144410
|
+
const result = {
|
|
144411
|
+
runId: null,
|
|
144412
|
+
ok: false,
|
|
144413
|
+
status,
|
|
144414
|
+
latencyMs: Date.now() - startedAt,
|
|
144415
|
+
payment: null,
|
|
144416
|
+
outcome,
|
|
144417
|
+
body: null,
|
|
144418
|
+
bodyRaw: null,
|
|
144419
|
+
error: error48
|
|
144420
|
+
};
|
|
144421
|
+
if (capabilityIdRequested) result.runTrackingSkipped = [skipReason];
|
|
144422
|
+
return result;
|
|
144423
|
+
};
|
|
144424
|
+
var resolveRecordingClient = (client, opts) => {
|
|
144425
|
+
const credentials = client.getCredentials();
|
|
144426
|
+
const recordingClient = opts.account ? client.withAccount(opts.account) : client;
|
|
144427
|
+
const canRecord = opts.account !== void 0 || credentials.kind === "account" || credentials.kind === "session";
|
|
144428
|
+
return { recordingClient, canRecord };
|
|
144429
|
+
};
|
|
144430
|
+
var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) => {
|
|
144431
|
+
const effectiveCapId = opts.capabilityId;
|
|
144432
|
+
if (effectiveCapId === void 0) return;
|
|
144433
|
+
const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
|
|
144434
|
+
if (!canRecord) return;
|
|
144435
|
+
const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : isShortToken(effectiveCapId) ? "from_search" : opts.fetchOrigin;
|
|
144436
|
+
try {
|
|
144437
|
+
const created = await recordingClient.runs.create({
|
|
144438
|
+
capabilityId: effectiveCapId,
|
|
144439
|
+
...opts.searchId && { searchId: opts.searchId },
|
|
144440
|
+
...fetchOriginForRecord && { fetchOrigin: fetchOriginForRecord },
|
|
144441
|
+
...result.status !== null && { status: result.status },
|
|
144442
|
+
latencyMs: result.latencyMs,
|
|
144443
|
+
...opts.requestSchema && { requestSchema: opts.requestSchema }
|
|
144444
|
+
});
|
|
144445
|
+
result.runId = created.runId;
|
|
144446
|
+
delete result.runTrackingSkipped;
|
|
144447
|
+
} catch {
|
|
144448
|
+
}
|
|
144449
|
+
};
|
|
144450
|
+
var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested, capabilityIdOverride) => {
|
|
144451
|
+
const result = errorFetchResult(
|
|
144452
|
+
startedAt,
|
|
144453
|
+
err.message,
|
|
144454
|
+
"timeout",
|
|
144455
|
+
capabilityIdRequested,
|
|
144456
|
+
"network_error"
|
|
144542
144457
|
);
|
|
144543
|
-
|
|
144544
|
-
|
|
144545
|
-
|
|
144546
|
-
|
|
144547
|
-
|
|
144548
|
-
|
|
144549
|
-
|
|
144458
|
+
await recordErrorFetchRun(client, opts, result);
|
|
144459
|
+
};
|
|
144460
|
+
var sniffJsonShapeBytes = (buf) => {
|
|
144461
|
+
let i = 0;
|
|
144462
|
+
if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) {
|
|
144463
|
+
i = 3;
|
|
144464
|
+
}
|
|
144465
|
+
while (i < buf.length && (buf[i] === 32 || buf[i] === 9 || buf[i] === 10 || buf[i] === 13)) {
|
|
144466
|
+
i++;
|
|
144467
|
+
}
|
|
144468
|
+
if (i >= buf.length) return false;
|
|
144469
|
+
return buf[i] === 123 || buf[i] === 91;
|
|
144470
|
+
};
|
|
144471
|
+
var withDefaultContentType = (headers, body) => {
|
|
144472
|
+
if (!headers && body === void 0) return void 0;
|
|
144473
|
+
const next = headers ? { ...headers } : {};
|
|
144474
|
+
if (body === void 0) return next;
|
|
144475
|
+
const hasContentType = Object.keys(next).some(
|
|
144476
|
+
(k3) => k3.toLowerCase() === "content-type"
|
|
144550
144477
|
);
|
|
144551
|
-
|
|
144552
|
-
|
|
144553
|
-
|
|
144554
|
-
|
|
144555
|
-
|
|
144556
|
-
|
|
144557
|
-
|
|
144558
|
-
|
|
144559
|
-
|
|
144560
|
-
|
|
144561
|
-
|
|
144562
|
-
|
|
144478
|
+
if (!hasContentType) {
|
|
144479
|
+
next["content-type"] = typeof body === "string" || sniffJsonShapeBytes(body) ? "application/json" : "application/octet-stream";
|
|
144480
|
+
}
|
|
144481
|
+
return next;
|
|
144482
|
+
};
|
|
144483
|
+
var clientFetch = async (client, url4, opts = {}) => {
|
|
144484
|
+
const startedAt = Date.now();
|
|
144485
|
+
const capabilityIdRequested = opts.capabilityId !== void 0;
|
|
144486
|
+
const normalized = normalizeTransportEnvelopeRequest(url4, {
|
|
144487
|
+
method: opts.method,
|
|
144488
|
+
body: opts.body
|
|
144489
|
+
});
|
|
144490
|
+
const requestUrl = normalized.url;
|
|
144491
|
+
const requestBody = normalized.body;
|
|
144492
|
+
const method = normalized.method ?? (requestBody !== void 0 ? "POST" : "GET");
|
|
144493
|
+
const { canRecord: canRecordForResolve } = resolveRecordingClient(
|
|
144494
|
+
client,
|
|
144495
|
+
opts
|
|
144563
144496
|
);
|
|
144564
|
-
|
|
144565
|
-
|
|
144566
|
-
|
|
144567
|
-
|
|
144568
|
-
|
|
144569
|
-
|
|
144570
|
-
|
|
144571
|
-
await request2(
|
|
144572
|
-
this.client,
|
|
144573
|
-
{
|
|
144574
|
-
method: "POST",
|
|
144575
|
-
path: "/v1/auth/logout",
|
|
144576
|
-
body: { refreshToken },
|
|
144577
|
-
signal: opts.signal
|
|
144578
|
-
},
|
|
144579
|
-
external_exports3.unknown()
|
|
144580
|
-
);
|
|
144497
|
+
const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl2(requestUrl), method).catch(() => null) : Promise.resolve(null);
|
|
144498
|
+
const probeHeaders = withDefaultContentType(opts.headers, requestBody);
|
|
144499
|
+
const requestInit = {
|
|
144500
|
+
method,
|
|
144501
|
+
headers: probeHeaders,
|
|
144502
|
+
body: requestBody,
|
|
144503
|
+
signal: opts.signal
|
|
144581
144504
|
};
|
|
144582
|
-
|
|
144583
|
-
|
|
144584
|
-
|
|
144585
|
-
|
|
144586
|
-
|
|
144587
|
-
|
|
144588
|
-
|
|
144589
|
-
|
|
144590
|
-
|
|
144591
|
-
|
|
144592
|
-
|
|
144593
|
-
|
|
144594
|
-
|
|
144595
|
-
|
|
144596
|
-
|
|
144597
|
-
|
|
144598
|
-
|
|
144505
|
+
const configuredFetch = buildConfiguredFetch(client, {
|
|
144506
|
+
timeoutMs: opts.timeoutMs
|
|
144507
|
+
});
|
|
144508
|
+
let response;
|
|
144509
|
+
let payment = null;
|
|
144510
|
+
const skipReasons = [];
|
|
144511
|
+
const warnings = [];
|
|
144512
|
+
try {
|
|
144513
|
+
response = await configuredFetch(requestUrl, requestInit);
|
|
144514
|
+
} catch (err) {
|
|
144515
|
+
if (err instanceof ZeroTimeoutError) {
|
|
144516
|
+
await recordTimeoutRun(
|
|
144517
|
+
client,
|
|
144518
|
+
opts,
|
|
144519
|
+
err,
|
|
144520
|
+
startedAt,
|
|
144521
|
+
capabilityIdRequested
|
|
144599
144522
|
);
|
|
144523
|
+
throw err;
|
|
144600
144524
|
}
|
|
144601
|
-
|
|
144602
|
-
|
|
144603
|
-
const
|
|
144604
|
-
|
|
144605
|
-
|
|
144606
|
-
|
|
144607
|
-
|
|
144608
|
-
|
|
144609
|
-
const parsed = await request2(
|
|
144610
|
-
this.client,
|
|
144611
|
-
{
|
|
144612
|
-
method: "POST",
|
|
144613
|
-
path: "/v1/users/me/sign-message",
|
|
144614
|
-
body: { message: normalizeMessage(input.message) }
|
|
144615
|
-
},
|
|
144616
|
-
signResponseSchema
|
|
144617
|
-
);
|
|
144618
|
-
this.assertSignerMatches(parsed.walletAddress, opts.expectedAddress);
|
|
144619
|
-
return parsed.signature;
|
|
144620
|
-
} catch (err) {
|
|
144621
|
-
repackageSignFailure(err, "signMessage");
|
|
144622
|
-
}
|
|
144623
|
-
}
|
|
144624
|
-
throw new ZeroAuthError(
|
|
144625
|
-
"auth_no_credentials",
|
|
144626
|
-
"signMessage() requires the client to be constructed with `account` or `session`."
|
|
144525
|
+
if (err instanceof ZeroError) throw err;
|
|
144526
|
+
const errMessage = err instanceof Error ? err.message : String(err);
|
|
144527
|
+
const result2 = errorFetchResult(
|
|
144528
|
+
startedAt,
|
|
144529
|
+
errMessage,
|
|
144530
|
+
"fetch_failed_before_response",
|
|
144531
|
+
capabilityIdRequested,
|
|
144532
|
+
"network_error"
|
|
144627
144533
|
);
|
|
144628
|
-
|
|
144629
|
-
|
|
144630
|
-
|
|
144631
|
-
|
|
144632
|
-
|
|
144534
|
+
await recordErrorFetchRun(client, opts, result2);
|
|
144535
|
+
return result2;
|
|
144536
|
+
}
|
|
144537
|
+
if (response.status === 402) {
|
|
144538
|
+
const requirement = await detectPaymentRequirement(response);
|
|
144539
|
+
if (requirement?.protocol === "x402" || requirement?.protocol === "mpp") {
|
|
144540
|
+
const payCall = requirement.protocol === "x402" ? client.payments.pay : client.payments.payMpp;
|
|
144633
144541
|
try {
|
|
144634
|
-
const
|
|
144635
|
-
|
|
144636
|
-
|
|
144637
|
-
|
|
144638
|
-
|
|
144639
|
-
|
|
144640
|
-
|
|
144641
|
-
|
|
144642
|
-
|
|
144643
|
-
|
|
144644
|
-
|
|
144542
|
+
const paid = await payCall({
|
|
144543
|
+
url: requestUrl,
|
|
144544
|
+
method,
|
|
144545
|
+
// Fresh clone for the paid retry — same rationale as
|
|
144546
|
+
// the probe-side clone above. Re-derives the default
|
|
144547
|
+
// Content-Type so the paid leg matches the probe.
|
|
144548
|
+
headers: withDefaultContentType(opts.headers, requestBody),
|
|
144549
|
+
body: requestBody,
|
|
144550
|
+
maxPay: opts.maxPay,
|
|
144551
|
+
account: opts.account,
|
|
144552
|
+
signal: opts.signal,
|
|
144553
|
+
timeoutMs: opts.timeoutMs,
|
|
144554
|
+
...opts.displayCostAmount && {
|
|
144555
|
+
displayCostAmount: opts.displayCostAmount
|
|
144556
|
+
}
|
|
144557
|
+
});
|
|
144558
|
+
response = paid.response;
|
|
144559
|
+
payment = paid.payment;
|
|
144560
|
+
if (paid.warnings) warnings.push(...paid.warnings);
|
|
144645
144561
|
} catch (err) {
|
|
144646
|
-
|
|
144562
|
+
if (err instanceof ZeroSessionCloseFailedError) {
|
|
144563
|
+
response = err.response;
|
|
144564
|
+
payment = {
|
|
144565
|
+
protocol: "mpp",
|
|
144566
|
+
chain: tempoChainLabelFromId(err.session.chainId),
|
|
144567
|
+
txHash: null,
|
|
144568
|
+
amount: err.capturedAmount,
|
|
144569
|
+
asset: "USDC",
|
|
144570
|
+
session: err.session
|
|
144571
|
+
};
|
|
144572
|
+
warnings.push(FETCH_WARNINGS.mppSessionCloseFailed);
|
|
144573
|
+
} else if (err instanceof ZeroInsufficientFundsError) {
|
|
144574
|
+
return errorFetchResult(
|
|
144575
|
+
startedAt,
|
|
144576
|
+
err.message,
|
|
144577
|
+
FETCH_SKIP_REASONS.insufficientFunds,
|
|
144578
|
+
capabilityIdRequested,
|
|
144579
|
+
"insufficient_funds",
|
|
144580
|
+
null
|
|
144581
|
+
);
|
|
144582
|
+
} else if (err instanceof ZeroPaymentError || err instanceof ZeroAuthError) {
|
|
144583
|
+
const result2 = errorFetchResult(
|
|
144584
|
+
startedAt,
|
|
144585
|
+
err.message,
|
|
144586
|
+
"payment_failed",
|
|
144587
|
+
capabilityIdRequested,
|
|
144588
|
+
"payment_failed",
|
|
144589
|
+
402
|
|
144590
|
+
);
|
|
144591
|
+
await recordErrorFetchRun(client, opts, result2);
|
|
144592
|
+
return result2;
|
|
144593
|
+
} else if (err instanceof ZeroTimeoutError) {
|
|
144594
|
+
await recordTimeoutRun(
|
|
144595
|
+
client,
|
|
144596
|
+
opts,
|
|
144597
|
+
err,
|
|
144598
|
+
startedAt,
|
|
144599
|
+
capabilityIdRequested
|
|
144600
|
+
);
|
|
144601
|
+
throw err;
|
|
144602
|
+
} else {
|
|
144603
|
+
throw err;
|
|
144604
|
+
}
|
|
144647
144605
|
}
|
|
144648
|
-
}
|
|
144649
|
-
|
|
144650
|
-
|
|
144651
|
-
"
|
|
144652
|
-
"
|
|
144606
|
+
} else if (requirement?.protocol === "unknown") {
|
|
144607
|
+
const result2 = errorFetchResult(
|
|
144608
|
+
startedAt,
|
|
144609
|
+
"Capability returned 402 with an unrecognized payment protocol. Neither x402 nor MPP markers were detected in the response headers or body.",
|
|
144610
|
+
"unrecognized_402_protocol",
|
|
144611
|
+
capabilityIdRequested,
|
|
144612
|
+
"payment_failed",
|
|
144613
|
+
402
|
|
144653
144614
|
);
|
|
144615
|
+
await recordErrorFetchRun(client, opts, result2);
|
|
144616
|
+
return result2;
|
|
144654
144617
|
}
|
|
144655
|
-
|
|
144656
|
-
|
|
144657
|
-
|
|
144658
|
-
|
|
144659
|
-
|
|
144660
|
-
|
|
144661
|
-
|
|
144662
|
-
|
|
144663
|
-
|
|
144664
|
-
|
|
144665
|
-
|
|
144666
|
-
|
|
144667
|
-
|
|
144668
|
-
|
|
144669
|
-
|
|
144618
|
+
}
|
|
144619
|
+
const latencyMs = Date.now() - startedAt;
|
|
144620
|
+
const maxResponseBytes = opts.maxResponseBytes ?? MAX_RESPONSE_BYTES;
|
|
144621
|
+
let body;
|
|
144622
|
+
let bodyRaw;
|
|
144623
|
+
let bodyEncoding;
|
|
144624
|
+
try {
|
|
144625
|
+
const parsed = await parseResponseBody(response, maxResponseBytes);
|
|
144626
|
+
body = parsed.body;
|
|
144627
|
+
bodyRaw = parsed.bodyRaw;
|
|
144628
|
+
bodyEncoding = parsed.bodyEncoding;
|
|
144629
|
+
if (parsed.truncated) warnings.push(FETCH_WARNINGS.bodyTruncated);
|
|
144630
|
+
} catch (err) {
|
|
144631
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
144632
|
+
throw new ZeroApiError("Request aborted by caller", {
|
|
144633
|
+
status: 0,
|
|
144634
|
+
cause: err
|
|
144635
|
+
});
|
|
144670
144636
|
}
|
|
144671
|
-
|
|
144637
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
144638
|
+
const skips = [];
|
|
144639
|
+
const settledLocally = paymentHasAnchor(payment);
|
|
144640
|
+
if (settledLocally && response.status === 402) {
|
|
144641
|
+
warnings.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
144642
|
+
skips.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
144643
|
+
}
|
|
144644
|
+
if (payment !== null && !settledLocally) {
|
|
144645
|
+
warnings.push(FETCH_WARNINGS.paymentSettlementUnconfirmed);
|
|
144646
|
+
skips.push(FETCH_WARNINGS.paymentSettlementUnconfirmed);
|
|
144647
|
+
}
|
|
144648
|
+
if (payment !== null && payment.amount === "unknown") {
|
|
144649
|
+
warnings.push(FETCH_WARNINGS.paymentAmountUnknown);
|
|
144650
|
+
}
|
|
144651
|
+
skips.push(FETCH_SKIP_REASONS.bodyReadFailed);
|
|
144652
|
+
const result2 = {
|
|
144653
|
+
runId: null,
|
|
144654
|
+
ok: false,
|
|
144655
|
+
status: response.status,
|
|
144656
|
+
latencyMs: Date.now() - startedAt,
|
|
144657
|
+
payment,
|
|
144658
|
+
outcome: computeOutcome(response.status, payment, warnings),
|
|
144659
|
+
body: null,
|
|
144660
|
+
bodyRaw: null,
|
|
144661
|
+
error: message2
|
|
144662
|
+
};
|
|
144663
|
+
if (capabilityIdRequested) result2.runTrackingSkipped = skips;
|
|
144664
|
+
if (warnings.length > 0) result2.warnings = warnings;
|
|
144665
|
+
return result2;
|
|
144666
|
+
}
|
|
144667
|
+
const settled = paymentHasAnchor(payment);
|
|
144668
|
+
const paidButStill402 = settled && response.status === 402;
|
|
144669
|
+
const settlementUnconfirmed = payment !== null && !settled;
|
|
144670
|
+
if (paidButStill402) warnings.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
144671
|
+
if (settlementUnconfirmed)
|
|
144672
|
+
warnings.push(FETCH_WARNINGS.paymentSettlementUnconfirmed);
|
|
144673
|
+
if (payment !== null && payment.amount === "unknown") {
|
|
144674
|
+
warnings.push(FETCH_WARNINGS.paymentAmountUnknown);
|
|
144675
|
+
}
|
|
144676
|
+
let runId = null;
|
|
144677
|
+
const closeFailed = warnings.includes(FETCH_WARNINGS.mppSessionCloseFailed);
|
|
144678
|
+
const upstreamErrorForRecord = buildUpstreamError(
|
|
144679
|
+
response.status,
|
|
144680
|
+
bodyRaw,
|
|
144681
|
+
bodyEncoding
|
|
144682
|
+
);
|
|
144683
|
+
if (capabilityIdRequested) {
|
|
144684
|
+
if (paidButStill402)
|
|
144685
|
+
skipReasons.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
144686
|
+
else if (closeFailed)
|
|
144687
|
+
skipReasons.push(FETCH_SKIP_REASONS.mppSessionCloseFailedNotRecorded);
|
|
144688
|
+
}
|
|
144689
|
+
const resolvedCap = await resolvePromise;
|
|
144690
|
+
const effectiveCapabilityId = opts.capabilityId ?? resolvedCap?.capabilityId;
|
|
144691
|
+
const capabilityResolution = !capabilityIdRequested && canRecordForResolve ? resolvedCap !== null ? {
|
|
144692
|
+
resolved: true,
|
|
144693
|
+
capabilityId: resolvedCap.capabilityId,
|
|
144694
|
+
capabilitySlug: resolvedCap.capabilitySlug,
|
|
144695
|
+
matchedVia: resolvedCap.matchedVia
|
|
144696
|
+
} : { resolved: false } : void 0;
|
|
144697
|
+
if (effectiveCapabilityId !== void 0 && !paidButStill402 && !closeFailed) {
|
|
144698
|
+
const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
|
|
144699
|
+
if (!canRecord) {
|
|
144700
|
+
skipReasons.push("no_credentials");
|
|
144701
|
+
} else {
|
|
144702
|
+
const knownAmount = payment !== null && payment.amount !== "unknown";
|
|
144672
144703
|
try {
|
|
144673
|
-
|
|
144674
|
-
|
|
144675
|
-
{
|
|
144676
|
-
|
|
144677
|
-
|
|
144678
|
-
|
|
144704
|
+
let derived;
|
|
144705
|
+
if (opts.deriveRunMetadata) {
|
|
144706
|
+
try {
|
|
144707
|
+
derived = opts.deriveRunMetadata({
|
|
144708
|
+
status: response.status,
|
|
144709
|
+
ok: response.ok,
|
|
144710
|
+
bodyRaw,
|
|
144711
|
+
...bodyEncoding && { bodyEncoding }
|
|
144712
|
+
});
|
|
144713
|
+
} catch {
|
|
144714
|
+
}
|
|
144715
|
+
}
|
|
144716
|
+
const result2 = await recordingClient.runs.create({
|
|
144717
|
+
capabilityId: effectiveCapabilityId,
|
|
144718
|
+
searchId: opts.searchId,
|
|
144719
|
+
// Auto-resolved runs are always direct_url — they only fire when
|
|
144720
|
+
// no capabilityId was supplied (the direct_url path by definition).
|
|
144721
|
+
...opts.capabilityId === void 0 ? { fetchOrigin: "direct_url" } : opts.fetchOrigin && { fetchOrigin: opts.fetchOrigin },
|
|
144722
|
+
status: response.status,
|
|
144723
|
+
latencyMs,
|
|
144724
|
+
...opts.requestSchema && { requestSchema: opts.requestSchema },
|
|
144725
|
+
...derived?.responseSchema && {
|
|
144726
|
+
responseSchema: derived.responseSchema
|
|
144679
144727
|
},
|
|
144680
|
-
|
|
144681
|
-
|
|
144682
|
-
|
|
144683
|
-
|
|
144728
|
+
...upstreamErrorForRecord && {
|
|
144729
|
+
errorSnippetHash: upstreamErrorForRecord.snippetHash,
|
|
144730
|
+
errorSnippetLength: upstreamErrorForRecord.snippetLength
|
|
144731
|
+
},
|
|
144732
|
+
...payment && {
|
|
144733
|
+
...knownAmount && {
|
|
144734
|
+
costAmount: payment.amount,
|
|
144735
|
+
costAsset: payment.asset
|
|
144736
|
+
},
|
|
144737
|
+
paymentProtocol: payment.protocol,
|
|
144738
|
+
paymentChain: payment.chain,
|
|
144739
|
+
paymentTxHash: payment.txHash ?? void 0,
|
|
144740
|
+
paymentMode: payment.session ? "session" : "charge"
|
|
144741
|
+
}
|
|
144742
|
+
});
|
|
144743
|
+
runId = result2.runId;
|
|
144684
144744
|
} catch (err) {
|
|
144685
|
-
|
|
144745
|
+
const errorMessage22 = err instanceof Error ? err.message : String(err);
|
|
144746
|
+
const code = err instanceof ZeroError ? err.code : void 0;
|
|
144747
|
+
const skipMsg = code ? `run_create_failed:${code}: ${errorMessage22}` : `run_create_failed: ${errorMessage22}`;
|
|
144748
|
+
skipReasons.push(skipMsg);
|
|
144749
|
+
client.logger?.({
|
|
144750
|
+
level: "warn",
|
|
144751
|
+
message: "Failed to record run for fetch",
|
|
144752
|
+
meta: {
|
|
144753
|
+
url: redactUrl2(url4),
|
|
144754
|
+
capabilityId: effectiveCapabilityId,
|
|
144755
|
+
error: errorMessage22,
|
|
144756
|
+
errorCode: code
|
|
144757
|
+
}
|
|
144758
|
+
});
|
|
144686
144759
|
}
|
|
144687
144760
|
}
|
|
144688
|
-
|
|
144689
|
-
|
|
144690
|
-
|
|
144691
|
-
|
|
144692
|
-
|
|
144693
|
-
|
|
144694
|
-
|
|
144695
|
-
|
|
144696
|
-
|
|
144697
|
-
|
|
144698
|
-
const canonicalServer = getAddress(serverAddr);
|
|
144699
|
-
const canonicalExpected = getAddress(expectedAddr);
|
|
144700
|
-
if (canonicalExpected === canonicalServer) return;
|
|
144701
|
-
this.client.clearManagedAccount();
|
|
144702
|
-
throw new ZeroAuthError(
|
|
144703
|
-
"auth_error",
|
|
144704
|
-
`Managed signing wallet changed (caller expected ${canonicalExpected}, server signed as ${canonicalServer}). Cache cleared \u2014 retry to rebuild against the current wallet.`
|
|
144705
|
-
);
|
|
144761
|
+
}
|
|
144762
|
+
const result = {
|
|
144763
|
+
runId,
|
|
144764
|
+
ok: response.ok,
|
|
144765
|
+
status: response.status,
|
|
144766
|
+
latencyMs,
|
|
144767
|
+
payment,
|
|
144768
|
+
outcome: computeOutcome(response.status, payment, warnings),
|
|
144769
|
+
body,
|
|
144770
|
+
bodyRaw
|
|
144706
144771
|
};
|
|
144772
|
+
if (bodyEncoding) result.bodyEncoding = bodyEncoding;
|
|
144773
|
+
if (!response.ok) {
|
|
144774
|
+
const candidate = bodyRaw !== null && bodyRaw.length > 0 && bodyEncoding !== "base64" ? bodyRaw.slice(0, 240) : null;
|
|
144775
|
+
result.error = candidate !== null && !requestBodyEchoed(candidate, opts.body) ? candidate : `HTTP ${response.status}`;
|
|
144776
|
+
if (upstreamErrorForRecord) result.upstreamError = upstreamErrorForRecord;
|
|
144777
|
+
}
|
|
144778
|
+
if (capabilityIdRequested && skipReasons.length > 0) {
|
|
144779
|
+
result.runTrackingSkipped = skipReasons;
|
|
144780
|
+
}
|
|
144781
|
+
if (warnings.length > 0) result.warnings = warnings;
|
|
144782
|
+
if (capabilityResolution !== void 0)
|
|
144783
|
+
result.capabilityResolution = capabilityResolution;
|
|
144784
|
+
return result;
|
|
144707
144785
|
};
|
|
144708
|
-
var
|
|
144709
|
-
"
|
|
144710
|
-
|
|
144711
|
-
|
|
144712
|
-
|
|
144713
|
-
|
|
144714
|
-
"
|
|
144715
|
-
|
|
144716
|
-
|
|
144717
|
-
|
|
144718
|
-
|
|
144719
|
-
|
|
144720
|
-
|
|
144721
|
-
|
|
144722
|
-
|
|
144786
|
+
var package_default2 = {
|
|
144787
|
+
version: "0.8.0"
|
|
144788
|
+
};
|
|
144789
|
+
var SDK_VERSION2 = package_default2.version;
|
|
144790
|
+
var userWalletDtoSchema = external_exports3.object({
|
|
144791
|
+
walletAddress: external_exports3.string(),
|
|
144792
|
+
source: external_exports3.enum(["self_custody", "privy_embedded"]),
|
|
144793
|
+
isPrimary: external_exports3.boolean(),
|
|
144794
|
+
linkedAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).nullable().optional(),
|
|
144795
|
+
delegationGranted: external_exports3.boolean(),
|
|
144796
|
+
signerQuorumId: external_exports3.string().nullable(),
|
|
144797
|
+
// Per-transaction USDC cap in base units (6 dp). null = unlimited, 0 = free-only.
|
|
144798
|
+
maxTransactionUsdcBaseUnits: external_exports3.number().int().nullable()
|
|
144799
|
+
});
|
|
144800
|
+
var welcomeBonusSummarySchema = external_exports3.object({
|
|
144723
144801
|
status: external_exports3.string(),
|
|
144724
|
-
|
|
144725
|
-
|
|
144726
|
-
|
|
144727
|
-
|
|
144728
|
-
|
|
144729
|
-
|
|
144730
|
-
|
|
144802
|
+
amountUsd: external_exports3.number()
|
|
144803
|
+
});
|
|
144804
|
+
var internalUserDtoSchema = external_exports3.object({
|
|
144805
|
+
id: external_exports3.string(),
|
|
144806
|
+
email: external_exports3.string().nullable(),
|
|
144807
|
+
createdAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).optional(),
|
|
144808
|
+
lastLoginAt: external_exports3.union([external_exports3.string(), external_exports3.date()]).nullable().optional(),
|
|
144809
|
+
onboardingCompleted: external_exports3.boolean().optional(),
|
|
144810
|
+
delegationGranted: external_exports3.boolean().optional(),
|
|
144811
|
+
wallets: external_exports3.array(userWalletDtoSchema).optional(),
|
|
144812
|
+
balance: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string() }).nullable().optional(),
|
|
144813
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable().optional()
|
|
144814
|
+
});
|
|
144815
|
+
var publicUserDtoSchema = external_exports3.object({
|
|
144816
|
+
user: external_exports3.object({
|
|
144817
|
+
id: external_exports3.string(),
|
|
144818
|
+
email: external_exports3.string().nullable()
|
|
144819
|
+
}),
|
|
144820
|
+
walletAddress: external_exports3.string().nullable(),
|
|
144821
|
+
balance: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string() }).nullable(),
|
|
144822
|
+
welcomeBonus: welcomeBonusSummarySchema.nullable()
|
|
144823
|
+
});
|
|
144824
|
+
var signResponseSchema = external_exports3.object({
|
|
144825
|
+
signature: external_exports3.string().regex(/^0x[0-9a-fA-F]+$/, "must be 0x-prefixed hex"),
|
|
144826
|
+
walletAddress: external_exports3.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be 0x-prefixed 40-char hex address")
|
|
144827
|
+
});
|
|
144828
|
+
var deviceStartResponseSchema = external_exports3.object({
|
|
144829
|
+
deviceCode: external_exports3.string(),
|
|
144830
|
+
userCode: external_exports3.string(),
|
|
144831
|
+
verificationUri: external_exports3.string(),
|
|
144832
|
+
pollInterval: external_exports3.number(),
|
|
144833
|
+
expiresAt: external_exports3.number()
|
|
144834
|
+
});
|
|
144835
|
+
var devicePollResponseSchema = external_exports3.union([
|
|
144836
|
+
// userCode + verificationUri are optional: older API deployments don't
|
|
144837
|
+
// echo them on pending.
|
|
144838
|
+
external_exports3.object({
|
|
144839
|
+
error: external_exports3.literal("authorization_pending"),
|
|
144840
|
+
userCode: external_exports3.string().optional(),
|
|
144841
|
+
verificationUri: external_exports3.string().optional()
|
|
144842
|
+
}),
|
|
144843
|
+
external_exports3.object({ error: external_exports3.literal("expired_token") }),
|
|
144844
|
+
external_exports3.object({
|
|
144845
|
+
accessToken: external_exports3.string(),
|
|
144846
|
+
refreshToken: external_exports3.string(),
|
|
144847
|
+
expiresIn: external_exports3.number(),
|
|
144848
|
+
user: internalUserDtoSchema
|
|
144731
144849
|
})
|
|
144850
|
+
]);
|
|
144851
|
+
var sessionExchangeResponseSchema = external_exports3.object({
|
|
144852
|
+
token: external_exports3.string(),
|
|
144853
|
+
expiresAt: external_exports3.number()
|
|
144732
144854
|
});
|
|
144733
|
-
var
|
|
144734
|
-
|
|
144735
|
-
|
|
144736
|
-
|
|
144737
|
-
|
|
144738
|
-
|
|
144739
|
-
|
|
144740
|
-
|
|
144741
|
-
|
|
144742
|
-
|
|
144855
|
+
var refreshResponseSchema = external_exports3.object({
|
|
144856
|
+
accessToken: external_exports3.string(),
|
|
144857
|
+
refreshToken: external_exports3.string()
|
|
144858
|
+
});
|
|
144859
|
+
var tryRefreshSession = async (client, callerSignal) => {
|
|
144860
|
+
const credentials = client.getCredentials();
|
|
144861
|
+
if (credentials.kind !== "session") return false;
|
|
144862
|
+
if (!credentials.refreshToken) return false;
|
|
144863
|
+
const url4 = `${client.baseUrl.replace(/\/$/, "")}/v1/auth/refresh`;
|
|
144864
|
+
const timeoutSignal = AbortSignal.timeout(client.timeout);
|
|
144865
|
+
const signal = callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal;
|
|
144866
|
+
let response;
|
|
144867
|
+
try {
|
|
144868
|
+
response = await client.fetchImpl(url4, {
|
|
144743
144869
|
method: "POST",
|
|
144744
|
-
|
|
144745
|
-
body:
|
|
144746
|
-
signal
|
|
144747
|
-
}
|
|
144748
|
-
|
|
144749
|
-
|
|
144870
|
+
headers: { "content-type": "application/json" },
|
|
144871
|
+
body: JSON.stringify({ refreshToken: credentials.refreshToken }),
|
|
144872
|
+
signal
|
|
144873
|
+
});
|
|
144874
|
+
} catch {
|
|
144875
|
+
return false;
|
|
144876
|
+
}
|
|
144877
|
+
if (!response.ok) return false;
|
|
144878
|
+
let body;
|
|
144879
|
+
try {
|
|
144880
|
+
body = await response.json();
|
|
144881
|
+
} catch {
|
|
144882
|
+
return false;
|
|
144883
|
+
}
|
|
144884
|
+
const parsed = refreshResponseSchema.safeParse(body);
|
|
144885
|
+
if (!parsed.success) return false;
|
|
144886
|
+
await client.applyRefreshedTokens({
|
|
144887
|
+
accessToken: parsed.data.accessToken,
|
|
144888
|
+
refreshToken: parsed.data.refreshToken
|
|
144889
|
+
});
|
|
144890
|
+
return true;
|
|
144750
144891
|
};
|
|
144751
|
-
var
|
|
144752
|
-
|
|
144753
|
-
successRate: external_exports3.string(),
|
|
144754
|
-
reviews: external_exports3.number(),
|
|
144755
|
-
stars: external_exports3.string().nullable().optional(),
|
|
144756
|
-
state: external_exports3.enum(["unrated", "rated"]).optional()
|
|
144757
|
-
});
|
|
144758
|
-
var capabilityResponseSchema = external_exports3.object({
|
|
144759
|
-
uid: external_exports3.string(),
|
|
144760
|
-
slug: external_exports3.string(),
|
|
144761
|
-
name: external_exports3.string(),
|
|
144762
|
-
description: external_exports3.string(),
|
|
144763
|
-
url: external_exports3.string(),
|
|
144764
|
-
urlTemplate: external_exports3.string().nullable().optional(),
|
|
144765
|
-
method: external_exports3.string(),
|
|
144766
|
-
headers: external_exports3.record(external_exports3.string(), external_exports3.string()).nullable(),
|
|
144767
|
-
bodySchema: external_exports3.record(external_exports3.string(), external_exports3.unknown()).nullable(),
|
|
144768
|
-
responseSchema: external_exports3.record(external_exports3.string(), external_exports3.unknown()).nullable(),
|
|
144769
|
-
example: external_exports3.object({ request: external_exports3.unknown(), response: external_exports3.unknown() }).nullable(),
|
|
144770
|
-
tags: external_exports3.array(external_exports3.string()).nullable(),
|
|
144771
|
-
exampleAgentPrompt: external_exports3.string().nullable().optional(),
|
|
144772
|
-
displayCostAmount: external_exports3.string(),
|
|
144773
|
-
displayCostAsset: external_exports3.string(),
|
|
144774
|
-
reviewCount: external_exports3.number(),
|
|
144775
|
-
rating: ratingSchema,
|
|
144776
|
-
priceObserved: external_exports3.object({
|
|
144777
|
-
minCents: external_exports3.string().nullable(),
|
|
144778
|
-
medianCents: external_exports3.string().nullable(),
|
|
144779
|
-
maxCents: external_exports3.string().nullable(),
|
|
144780
|
-
// Deprecated alias for maxCents; kept for back-compat with older
|
|
144781
|
-
// API versions that still emit it.
|
|
144782
|
-
p95Cents: external_exports3.string().nullable(),
|
|
144783
|
-
sampleCount: external_exports3.number(),
|
|
144784
|
-
varies: external_exports3.boolean(),
|
|
144785
|
-
failureChargeRate: external_exports3.number().nullable()
|
|
144786
|
-
}).nullable().optional(),
|
|
144787
|
-
paymentMethods: external_exports3.array(
|
|
144788
|
-
external_exports3.object({
|
|
144789
|
-
uid: external_exports3.string(),
|
|
144790
|
-
protocol: external_exports3.string(),
|
|
144791
|
-
methodType: external_exports3.string(),
|
|
144792
|
-
chain: external_exports3.string().nullable(),
|
|
144793
|
-
mode: external_exports3.string(),
|
|
144794
|
-
costAmount: external_exports3.string(),
|
|
144795
|
-
costPer: external_exports3.string(),
|
|
144796
|
-
priority: external_exports3.number()
|
|
144797
|
-
})
|
|
144798
|
-
).nullable(),
|
|
144799
|
-
availabilityStatus: external_exports3.enum(["healthy", "unknown", "down"]).nullable().optional(),
|
|
144800
|
-
/**
|
|
144801
|
-
* @deprecated The API no longer emits `displayStatus`; it has been replaced
|
|
144802
|
-
* by the consolidated 3-value {@link capabilityResponseSchema.shape.availabilityStatus}.
|
|
144803
|
-
* Kept as an optional field for one release for back-compat (ZERO-89 soft
|
|
144804
|
-
* migration) and will be removed in the next major version.
|
|
144805
|
-
*/
|
|
144806
|
-
displayStatus: external_exports3.enum(["healthy", "stable", "degraded", "unhealthy", "unknown"]).optional(),
|
|
144807
|
-
activationCount: external_exports3.number().optional(),
|
|
144808
|
-
lastUsedAt: external_exports3.string().nullable().optional(),
|
|
144809
|
-
lastSuccessfullyRanAt: external_exports3.string().nullable().optional()
|
|
144892
|
+
var buildSessionAuthHeaders = (accessToken) => ({
|
|
144893
|
+
authorization: `Bearer ${accessToken}`
|
|
144810
144894
|
});
|
|
144811
|
-
var
|
|
144812
|
-
|
|
144813
|
-
|
|
144814
|
-
|
|
144895
|
+
var buildCanonicalMessage = (method, pathWithQuery, body, timestamp, nonce2) => {
|
|
144896
|
+
const bodyHash = createHash("sha256").update(body ?? "").digest("hex");
|
|
144897
|
+
return `${method}:${pathWithQuery}:${bodyHash}:${timestamp}:${nonce2}`;
|
|
144898
|
+
};
|
|
144899
|
+
var buildAccountAuthHeaders = async (account, method, pathWithQuery, body) => {
|
|
144900
|
+
const timestamp = Math.floor(Date.now() / 1e3).toString();
|
|
144901
|
+
const nonce2 = crypto.randomUUID();
|
|
144902
|
+
const message2 = buildCanonicalMessage(
|
|
144903
|
+
method,
|
|
144904
|
+
pathWithQuery,
|
|
144905
|
+
body,
|
|
144906
|
+
timestamp,
|
|
144907
|
+
nonce2
|
|
144908
|
+
);
|
|
144909
|
+
const signature2 = await account.signMessage({ message: message2 });
|
|
144910
|
+
return {
|
|
144911
|
+
"x-zero-address": account.address,
|
|
144912
|
+
"x-zero-timestamp": timestamp,
|
|
144913
|
+
"x-zero-nonce": nonce2,
|
|
144914
|
+
"x-zero-signature": signature2
|
|
144915
|
+
};
|
|
144916
|
+
};
|
|
144917
|
+
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 502, 503, 504]);
|
|
144918
|
+
var sleep2 = (ms, signal) => new Promise((resolve6, reject) => {
|
|
144919
|
+
if (signal?.aborted) {
|
|
144920
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
144921
|
+
return;
|
|
144922
|
+
}
|
|
144923
|
+
const timer = setTimeout(() => {
|
|
144924
|
+
signal?.removeEventListener("abort", onAbort);
|
|
144925
|
+
resolve6();
|
|
144926
|
+
}, ms);
|
|
144927
|
+
const onAbort = () => {
|
|
144928
|
+
clearTimeout(timer);
|
|
144929
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
144930
|
+
};
|
|
144931
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
144815
144932
|
});
|
|
144816
|
-
var
|
|
144933
|
+
var buildPathWithQuery = (path3, query) => {
|
|
144934
|
+
const normalizedPath = path3.startsWith("/") ? path3 : `/${path3}`;
|
|
144935
|
+
if (!query) return normalizedPath;
|
|
144936
|
+
const params = new URLSearchParams();
|
|
144937
|
+
for (const [key, value] of Object.entries(query)) {
|
|
144938
|
+
if (value !== void 0) params.set(key, String(value));
|
|
144939
|
+
}
|
|
144940
|
+
const qs = params.toString();
|
|
144941
|
+
return qs ? `${normalizedPath}?${qs}` : normalizedPath;
|
|
144942
|
+
};
|
|
144943
|
+
var joinUrl = (baseUrl, pathWithQuery) => {
|
|
144944
|
+
const base3 = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
144945
|
+
return `${base3}${pathWithQuery}`;
|
|
144946
|
+
};
|
|
144947
|
+
var buildHeaders = async (client, method, pathWithQuery, hasBody, bodyStr) => {
|
|
144948
|
+
const headers = { ...client.defaultHeaders };
|
|
144949
|
+
if (hasBody) headers["content-type"] = "application/json";
|
|
144950
|
+
headers["x-zero-sdk-version"] = SDK_VERSION2;
|
|
144951
|
+
if (client.apiVersion) headers["x-zero-api-version"] = client.apiVersion;
|
|
144952
|
+
const credentials = client.getCredentials();
|
|
144953
|
+
if (credentials.kind === "session") {
|
|
144954
|
+
Object.assign(headers, buildSessionAuthHeaders(credentials.accessToken));
|
|
144955
|
+
} else if (credentials.kind === "account") {
|
|
144956
|
+
const signed = await buildAccountAuthHeaders(
|
|
144957
|
+
credentials.account,
|
|
144958
|
+
method,
|
|
144959
|
+
pathWithQuery,
|
|
144960
|
+
bodyStr
|
|
144961
|
+
);
|
|
144962
|
+
Object.assign(headers, signed);
|
|
144963
|
+
}
|
|
144964
|
+
return headers;
|
|
144965
|
+
};
|
|
144966
|
+
var parseErrorBody = async (response) => {
|
|
144967
|
+
try {
|
|
144968
|
+
return await response.clone().json();
|
|
144969
|
+
} catch {
|
|
144970
|
+
try {
|
|
144971
|
+
return await response.text();
|
|
144972
|
+
} catch {
|
|
144973
|
+
return void 0;
|
|
144974
|
+
}
|
|
144975
|
+
}
|
|
144976
|
+
};
|
|
144977
|
+
var errorMessageFromBody = (body, status) => {
|
|
144978
|
+
if (body !== null && typeof body === "object" && "error" in body && typeof body.error === "string") {
|
|
144979
|
+
return body.error;
|
|
144980
|
+
}
|
|
144981
|
+
return `HTTP ${status}`;
|
|
144982
|
+
};
|
|
144983
|
+
var request2 = async (client, opts, schema) => {
|
|
144984
|
+
const pathWithQuery = buildPathWithQuery(opts.path, opts.query);
|
|
144985
|
+
const url4 = joinUrl(client.baseUrl, pathWithQuery);
|
|
144986
|
+
const hasBody = opts.body !== void 0;
|
|
144987
|
+
const bodyStr = hasBody ? JSON.stringify(
|
|
144988
|
+
opts.body,
|
|
144989
|
+
(_k, v) => typeof v === "bigint" ? v.toString() : v
|
|
144990
|
+
) : void 0;
|
|
144991
|
+
const configuredFetch = buildConfiguredFetch(client);
|
|
144992
|
+
const performOnce = async () => configuredFetch(url4, {
|
|
144993
|
+
method: opts.method,
|
|
144994
|
+
headers: await buildHeaders(
|
|
144995
|
+
client,
|
|
144996
|
+
opts.method,
|
|
144997
|
+
pathWithQuery,
|
|
144998
|
+
hasBody,
|
|
144999
|
+
bodyStr
|
|
145000
|
+
),
|
|
145001
|
+
body: bodyStr,
|
|
145002
|
+
signal: opts.signal
|
|
145003
|
+
});
|
|
145004
|
+
let refreshAttempted = false;
|
|
145005
|
+
const executeWithRefresh = async () => {
|
|
145006
|
+
const response = await performOnce();
|
|
145007
|
+
if (response.status !== 401 || refreshAttempted) return response;
|
|
145008
|
+
const credentials = client.getCredentials();
|
|
145009
|
+
if (credentials.kind !== "session") return response;
|
|
145010
|
+
refreshAttempted = true;
|
|
145011
|
+
const refreshed = await client.refreshSessionOnce(opts.signal);
|
|
145012
|
+
if (!refreshed) return response;
|
|
145013
|
+
return await performOnce();
|
|
145014
|
+
};
|
|
145015
|
+
let lastNetworkError;
|
|
145016
|
+
for (let attempt = 0; attempt <= client.maxRetries; attempt++) {
|
|
145017
|
+
let response;
|
|
145018
|
+
try {
|
|
145019
|
+
response = await executeWithRefresh();
|
|
145020
|
+
} catch (e2) {
|
|
145021
|
+
if (e2 instanceof ZeroError) throw e2;
|
|
145022
|
+
lastNetworkError = e2;
|
|
145023
|
+
if (attempt < client.maxRetries) {
|
|
145024
|
+
try {
|
|
145025
|
+
await sleep2(2 ** attempt * 200, opts.signal);
|
|
145026
|
+
} catch (sleepErr) {
|
|
145027
|
+
throw new ZeroApiError("Request aborted by caller", {
|
|
145028
|
+
status: 0,
|
|
145029
|
+
cause: sleepErr
|
|
145030
|
+
});
|
|
145031
|
+
}
|
|
145032
|
+
continue;
|
|
145033
|
+
}
|
|
145034
|
+
throw new ZeroApiError("Network request failed", {
|
|
145035
|
+
status: 0,
|
|
145036
|
+
cause: e2
|
|
145037
|
+
});
|
|
145038
|
+
}
|
|
145039
|
+
if (response.ok) {
|
|
145040
|
+
let text;
|
|
145041
|
+
try {
|
|
145042
|
+
text = await response.text();
|
|
145043
|
+
} catch (e2) {
|
|
145044
|
+
throw new ZeroApiError("Response body read failed", {
|
|
145045
|
+
status: response.status,
|
|
145046
|
+
cause: e2
|
|
145047
|
+
});
|
|
145048
|
+
}
|
|
145049
|
+
let json3;
|
|
145050
|
+
try {
|
|
145051
|
+
json3 = JSON.parse(text);
|
|
145052
|
+
} catch {
|
|
145053
|
+
}
|
|
145054
|
+
const parsed = schema.safeParse(json3);
|
|
145055
|
+
if (!parsed.success) {
|
|
145056
|
+
throw new ZeroValidationError(
|
|
145057
|
+
`Response did not match expected schema for ${opts.method} ${opts.path}`,
|
|
145058
|
+
{ cause: parsed.error, body: text }
|
|
145059
|
+
);
|
|
145060
|
+
}
|
|
145061
|
+
return parsed.data;
|
|
145062
|
+
}
|
|
145063
|
+
if (RETRYABLE_STATUS.has(response.status) && attempt < client.maxRetries) {
|
|
145064
|
+
try {
|
|
145065
|
+
await sleep2(2 ** attempt * 200, opts.signal);
|
|
145066
|
+
} catch (sleepErr) {
|
|
145067
|
+
throw new ZeroApiError("Request aborted by caller", {
|
|
145068
|
+
status: 0,
|
|
145069
|
+
cause: sleepErr
|
|
145070
|
+
});
|
|
145071
|
+
}
|
|
145072
|
+
continue;
|
|
145073
|
+
}
|
|
145074
|
+
const errorBody = await parseErrorBody(response);
|
|
145075
|
+
const requestId = response.headers.get("x-request-id") ?? void 0;
|
|
145076
|
+
throw new ZeroApiError(errorMessageFromBody(errorBody, response.status), {
|
|
145077
|
+
status: response.status,
|
|
145078
|
+
requestId,
|
|
145079
|
+
body: errorBody
|
|
145080
|
+
});
|
|
145081
|
+
}
|
|
145082
|
+
throw new ZeroApiError("Exhausted retries", {
|
|
145083
|
+
status: 0,
|
|
145084
|
+
cause: lastNetworkError
|
|
145085
|
+
});
|
|
145086
|
+
};
|
|
145087
|
+
var AuthDevice = class {
|
|
144817
145088
|
constructor(client) {
|
|
144818
145089
|
this.client = client;
|
|
144819
145090
|
}
|
|
144820
|
-
|
|
145091
|
+
start = (opts = {}) => request2(
|
|
144821
145092
|
this.client,
|
|
144822
145093
|
{
|
|
144823
|
-
method: "
|
|
144824
|
-
path:
|
|
144825
|
-
query: opts.searchId ? { searchId: opts.searchId } : void 0,
|
|
145094
|
+
method: "POST",
|
|
145095
|
+
path: "/v1/auth/device/start",
|
|
144826
145096
|
signal: opts.signal
|
|
144827
145097
|
},
|
|
144828
|
-
|
|
145098
|
+
deviceStartResponseSchema
|
|
144829
145099
|
);
|
|
144830
|
-
|
|
144831
|
-
|
|
144832
|
-
|
|
144833
|
-
|
|
144834
|
-
|
|
144835
|
-
|
|
144836
|
-
|
|
144837
|
-
|
|
144838
|
-
|
|
144839
|
-
|
|
144840
|
-
|
|
144841
|
-
|
|
144842
|
-
|
|
144843
|
-
|
|
144844
|
-
|
|
144845
|
-
|
|
144846
|
-
|
|
144847
|
-
},
|
|
144848
|
-
resolveCapabilityResponseSchema
|
|
144849
|
-
);
|
|
144850
|
-
} catch (err) {
|
|
144851
|
-
if (err instanceof ZeroApiError && err.status === 404) return null;
|
|
144852
|
-
throw err;
|
|
145100
|
+
poll = async (deviceCode, opts = {}) => {
|
|
145101
|
+
const parsed = await request2(
|
|
145102
|
+
this.client,
|
|
145103
|
+
{
|
|
145104
|
+
method: "POST",
|
|
145105
|
+
path: "/v1/auth/device/poll",
|
|
145106
|
+
body: { deviceCode },
|
|
145107
|
+
signal: opts.signal
|
|
145108
|
+
},
|
|
145109
|
+
devicePollResponseSchema
|
|
145110
|
+
);
|
|
145111
|
+
if ("error" in parsed) {
|
|
145112
|
+
return parsed.error === "authorization_pending" ? {
|
|
145113
|
+
status: "pending",
|
|
145114
|
+
userCode: parsed.userCode,
|
|
145115
|
+
verificationUri: parsed.verificationUri
|
|
145116
|
+
} : { status: "expired" };
|
|
144853
145117
|
}
|
|
145118
|
+
return {
|
|
145119
|
+
status: "ok",
|
|
145120
|
+
accessToken: parsed.accessToken,
|
|
145121
|
+
refreshToken: parsed.refreshToken,
|
|
145122
|
+
expiresIn: parsed.expiresIn,
|
|
145123
|
+
user: parsed.user
|
|
145124
|
+
};
|
|
144854
145125
|
};
|
|
144855
145126
|
};
|
|
144856
|
-
var
|
|
144857
|
-
|
|
144858
|
-
|
|
144859
|
-
|
|
144860
|
-
|
|
144861
|
-
|
|
144862
|
-
|
|
144863
|
-
|
|
144864
|
-
|
|
144865
|
-
|
|
144866
|
-
|
|
144867
|
-
|
|
144868
|
-
|
|
144869
|
-
|
|
144870
|
-
|
|
144871
|
-
|
|
144872
|
-
|
|
144873
|
-
|
|
144874
|
-
|
|
144875
|
-
|
|
145127
|
+
var userWalletsSchema = external_exports3.array(userWalletDtoSchema);
|
|
145128
|
+
var normalizeMessage = (message2) => {
|
|
145129
|
+
if (typeof message2 === "string") return message2;
|
|
145130
|
+
if (typeof message2.raw === "string") return message2.raw;
|
|
145131
|
+
return bytesToHex(message2.raw);
|
|
145132
|
+
};
|
|
145133
|
+
var repackageSignFailure = (err, op) => {
|
|
145134
|
+
if (err instanceof ZeroApiError && err.status === 402) {
|
|
145135
|
+
const body = err.body;
|
|
145136
|
+
const detail = body && typeof body.error === "string" ? `: ${body.error}` : "";
|
|
145137
|
+
throw new ZeroPaymentError(
|
|
145138
|
+
`Sign endpoint refused ${op} (HTTP 402)${detail}`,
|
|
145139
|
+
{ cause: err }
|
|
145140
|
+
);
|
|
145141
|
+
}
|
|
145142
|
+
throw err;
|
|
145143
|
+
};
|
|
145144
|
+
var Auth = class {
|
|
145145
|
+
constructor(client) {
|
|
145146
|
+
this.client = client;
|
|
145147
|
+
this.device = new AuthDevice(client);
|
|
145148
|
+
}
|
|
145149
|
+
device;
|
|
145150
|
+
// The internal (web-app facing) user profile. Richer than profile(): full
|
|
145151
|
+
// wallet list with per-wallet delegation/signer/limit metadata.
|
|
145152
|
+
me = (opts = {}) => request2(
|
|
145153
|
+
this.client,
|
|
145154
|
+
{ method: "GET", path: "/v1/users/me", signal: opts.signal },
|
|
145155
|
+
internalUserDtoSchema
|
|
145156
|
+
);
|
|
145157
|
+
// The public (agent-facing) profile — identity + primary wallet address +
|
|
145158
|
+
// balance + welcome-bonus, no per-wallet metadata. Same shape the MCP
|
|
145159
|
+
// get_profile tool returns; rendered by `zero auth whoami`.
|
|
145160
|
+
profile = (opts = {}) => request2(
|
|
145161
|
+
this.client,
|
|
145162
|
+
{ method: "GET", path: "/v1/users/me/profile", signal: opts.signal },
|
|
145163
|
+
publicUserDtoSchema
|
|
145164
|
+
);
|
|
145165
|
+
// The user's wallets only. Lightweight sibling of `me()` for callers that
|
|
145166
|
+
// just need wallet addresses (e.g. managed-account resolution on the pay
|
|
145167
|
+
// path) — avoids the heavier internal-profile computation behind `me()`.
|
|
145168
|
+
wallets = (opts = {}) => request2(
|
|
145169
|
+
this.client,
|
|
145170
|
+
{ method: "GET", path: "/v1/users/me/wallets", signal: opts.signal },
|
|
145171
|
+
userWalletsSchema
|
|
145172
|
+
);
|
|
145173
|
+
// Exchange an ephemeral session code (e.g. runner / sandbox handoff) for
|
|
145174
|
+
// a session access token. The returned token has no refresh path — pair
|
|
145175
|
+
// with `refreshToken: ""` when constructing the client.
|
|
145176
|
+
exchangeSessionCode = (code, opts = {}) => request2(
|
|
145177
|
+
this.client,
|
|
145178
|
+
{
|
|
145179
|
+
method: "POST",
|
|
145180
|
+
path: "/v1/session/exchange",
|
|
145181
|
+
body: { code },
|
|
145182
|
+
signal: opts.signal
|
|
145183
|
+
},
|
|
145184
|
+
sessionExchangeResponseSchema
|
|
145185
|
+
);
|
|
145186
|
+
// Server-side revoke of the refresh token. Throws ZeroApiError on any
|
|
145187
|
+
// non-2xx — callers that have already cleared local state (e.g. CLI
|
|
145188
|
+
// logout) typically want to swallow with `.catch(() => {})` so a flaky
|
|
145189
|
+
// server doesn't surface as a user-visible failure for a sign-out that
|
|
145190
|
+
// already succeeded locally. Response body is opaque; schema is
|
|
145191
|
+
// `z.unknown()` and the resolved value is discarded.
|
|
145192
|
+
logout = async (refreshToken, opts = {}) => {
|
|
145193
|
+
await request2(
|
|
145194
|
+
this.client,
|
|
145195
|
+
{
|
|
145196
|
+
method: "POST",
|
|
145197
|
+
path: "/v1/auth/logout",
|
|
145198
|
+
body: { refreshToken },
|
|
145199
|
+
signal: opts.signal
|
|
145200
|
+
},
|
|
145201
|
+
external_exports3.unknown()
|
|
145202
|
+
);
|
|
145203
|
+
};
|
|
145204
|
+
// Force a session refresh. Routes through refreshSessionOnce() so a
|
|
145205
|
+
// proactive call doesn't race a 401-driven transport refresh —
|
|
145206
|
+
// concurrent POSTs with the same refresh token kill the session
|
|
145207
|
+
// family (RFC 6819 token-theft response).
|
|
145208
|
+
refresh = async () => {
|
|
145209
|
+
const credentials = this.client.getCredentials();
|
|
145210
|
+
if (credentials.kind !== "session") {
|
|
145211
|
+
throw new ZeroAuthError(
|
|
145212
|
+
"auth_no_credentials",
|
|
145213
|
+
"refresh() requires the client to be constructed with a session \u2014 got credentials.kind=" + credentials.kind
|
|
145214
|
+
);
|
|
145215
|
+
}
|
|
145216
|
+
const ok = await this.client.refreshSessionOnce();
|
|
145217
|
+
if (!ok) {
|
|
145218
|
+
throw new ZeroAuthError(
|
|
145219
|
+
"auth_session_expired",
|
|
145220
|
+
"Session refresh failed. The refresh token may be revoked or expired."
|
|
145221
|
+
);
|
|
145222
|
+
}
|
|
145223
|
+
};
|
|
145224
|
+
signMessage = async (input, opts = {}) => {
|
|
145225
|
+
const credentials = this.client.getCredentials();
|
|
145226
|
+
if (credentials.kind === "account") {
|
|
145227
|
+
return await credentials.account.signMessage({ message: input.message });
|
|
145228
|
+
}
|
|
145229
|
+
if (credentials.kind === "session") {
|
|
145230
|
+
try {
|
|
145231
|
+
const parsed = await request2(
|
|
145232
|
+
this.client,
|
|
145233
|
+
{
|
|
145234
|
+
method: "POST",
|
|
145235
|
+
path: "/v1/users/me/sign-message",
|
|
145236
|
+
body: { message: normalizeMessage(input.message) }
|
|
145237
|
+
},
|
|
145238
|
+
signResponseSchema
|
|
145239
|
+
);
|
|
145240
|
+
this.assertSignerMatches(parsed.walletAddress, opts.expectedAddress);
|
|
145241
|
+
return parsed.signature;
|
|
145242
|
+
} catch (err) {
|
|
145243
|
+
repackageSignFailure(err, "signMessage");
|
|
145244
|
+
}
|
|
145245
|
+
}
|
|
145246
|
+
throw new ZeroAuthError(
|
|
145247
|
+
"auth_no_credentials",
|
|
145248
|
+
"signMessage() requires the client to be constructed with `account` or `session`."
|
|
145249
|
+
);
|
|
145250
|
+
};
|
|
145251
|
+
// Managed-only: BYO accounts sign locally via viem's account.signTransaction.
|
|
145252
|
+
signTransaction = async (input, opts = {}) => {
|
|
145253
|
+
const credentials = this.client.getCredentials();
|
|
145254
|
+
if (credentials.kind === "session") {
|
|
145255
|
+
try {
|
|
145256
|
+
const parsed = await request2(
|
|
145257
|
+
this.client,
|
|
145258
|
+
{
|
|
145259
|
+
method: "POST",
|
|
145260
|
+
path: "/v1/users/me/sign-transaction",
|
|
145261
|
+
body: { unsignedTransaction: input.unsignedTransaction }
|
|
145262
|
+
},
|
|
145263
|
+
signResponseSchema
|
|
145264
|
+
);
|
|
145265
|
+
this.assertSignerMatches(parsed.walletAddress, opts.expectedAddress);
|
|
145266
|
+
return parsed.signature;
|
|
145267
|
+
} catch (err) {
|
|
145268
|
+
repackageSignFailure(err, "signTransaction");
|
|
145269
|
+
}
|
|
145270
|
+
}
|
|
145271
|
+
if (credentials.kind === "account") {
|
|
145272
|
+
throw new ZeroAuthError(
|
|
145273
|
+
"auth_error",
|
|
145274
|
+
"signTransaction() is a managed-signing operation and is not supported in account mode. Sign locally with viem's account.signTransaction instead."
|
|
145275
|
+
);
|
|
145276
|
+
}
|
|
145277
|
+
throw new ZeroAuthError(
|
|
145278
|
+
"auth_no_credentials",
|
|
145279
|
+
"signTransaction() requires session credentials (managed signing)."
|
|
145280
|
+
);
|
|
145281
|
+
};
|
|
145282
|
+
signTypedData = async (input, opts = {}) => {
|
|
145283
|
+
const credentials = this.client.getCredentials();
|
|
145284
|
+
if (credentials.kind === "account") {
|
|
145285
|
+
if (!credentials.account.signTypedData) {
|
|
145286
|
+
throw new ZeroAuthError(
|
|
145287
|
+
"auth_error",
|
|
145288
|
+
"The configured viem account does not implement signTypedData."
|
|
145289
|
+
);
|
|
145290
|
+
}
|
|
145291
|
+
return await credentials.account.signTypedData(input);
|
|
145292
|
+
}
|
|
145293
|
+
if (credentials.kind === "session") {
|
|
145294
|
+
try {
|
|
145295
|
+
const parsed = await request2(
|
|
145296
|
+
this.client,
|
|
145297
|
+
{
|
|
145298
|
+
method: "POST",
|
|
145299
|
+
path: "/v1/users/me/sign-typed-data",
|
|
145300
|
+
body: { typedData: input }
|
|
145301
|
+
},
|
|
145302
|
+
signResponseSchema
|
|
145303
|
+
);
|
|
145304
|
+
this.assertSignerMatches(parsed.walletAddress, opts.expectedAddress);
|
|
145305
|
+
return parsed.signature;
|
|
145306
|
+
} catch (err) {
|
|
145307
|
+
repackageSignFailure(err, "signTypedData");
|
|
145308
|
+
}
|
|
145309
|
+
}
|
|
145310
|
+
throw new ZeroAuthError(
|
|
145311
|
+
"auth_no_credentials",
|
|
145312
|
+
"signTypedData() requires the client to be constructed with `account` or `session`."
|
|
145313
|
+
);
|
|
145314
|
+
};
|
|
145315
|
+
// Compare against the caller's pinned address (not shared cache) so
|
|
145316
|
+
// concurrent pay()s can't race past each other. Mismatch → clear + throw;
|
|
145317
|
+
// the caller's retry rebuilds against the new wallet.
|
|
145318
|
+
assertSignerMatches = (serverAddr, expectedAddr) => {
|
|
145319
|
+
if (!expectedAddr) return;
|
|
145320
|
+
const canonicalServer = getAddress(serverAddr);
|
|
145321
|
+
const canonicalExpected = getAddress(expectedAddr);
|
|
145322
|
+
if (canonicalExpected === canonicalServer) return;
|
|
145323
|
+
this.client.clearManagedAccount();
|
|
145324
|
+
throw new ZeroAuthError(
|
|
145325
|
+
"auth_error",
|
|
145326
|
+
`Managed signing wallet changed (caller expected ${canonicalExpected}, server signed as ${canonicalServer}). Cache cleared \u2014 retry to rebuild against the current wallet.`
|
|
145327
|
+
);
|
|
145328
|
+
};
|
|
145329
|
+
};
|
|
145330
|
+
var BUG_REPORT_CATEGORIES = [
|
|
145331
|
+
"search_relevance",
|
|
145332
|
+
"ranking_issue",
|
|
145333
|
+
"missing_capability",
|
|
145334
|
+
"wrong_schema",
|
|
145335
|
+
"misleading_description",
|
|
145336
|
+
"broken_execution",
|
|
145337
|
+
"payment_failure",
|
|
145338
|
+
"billing_anomaly",
|
|
145339
|
+
"cli_bug",
|
|
145340
|
+
"security",
|
|
145341
|
+
"other"
|
|
145342
|
+
];
|
|
145343
|
+
var createBugReportResponseSchema = external_exports3.object({
|
|
145344
|
+
bugReportId: external_exports3.string(),
|
|
145345
|
+
status: external_exports3.string(),
|
|
145346
|
+
deduped: external_exports3.boolean(),
|
|
145347
|
+
category: external_exports3.enum(BUG_REPORT_CATEGORIES).nullable(),
|
|
145348
|
+
title: external_exports3.string().nullable(),
|
|
145349
|
+
attached: external_exports3.object({
|
|
145350
|
+
capabilityId: external_exports3.number().nullable(),
|
|
145351
|
+
runId: external_exports3.number().nullable(),
|
|
145352
|
+
searchId: external_exports3.number().nullable()
|
|
145353
|
+
})
|
|
145354
|
+
});
|
|
145355
|
+
var BugReports = class {
|
|
145356
|
+
constructor(client) {
|
|
145357
|
+
this.client = client;
|
|
145358
|
+
}
|
|
145359
|
+
// POST /v1/bug-reports. Wallet-attributed server-side; the SDK client's
|
|
145360
|
+
// active credential drives attribution (account-mode → EIP-191 from the
|
|
145361
|
+
// wallet, session-mode → Bearer + server resolves the user's wallet).
|
|
145362
|
+
create = (input, opts = {}) => request2(
|
|
145363
|
+
this.client,
|
|
145364
|
+
{
|
|
145365
|
+
method: "POST",
|
|
145366
|
+
path: "/v1/bug-reports",
|
|
145367
|
+
body: input,
|
|
145368
|
+
signal: opts.signal
|
|
145369
|
+
},
|
|
145370
|
+
createBugReportResponseSchema
|
|
145371
|
+
);
|
|
145372
|
+
};
|
|
145373
|
+
var ratingSchema = external_exports3.object({
|
|
145374
|
+
score: external_exports3.string(),
|
|
145375
|
+
successRate: external_exports3.string(),
|
|
145376
|
+
reviews: external_exports3.number(),
|
|
145377
|
+
stars: external_exports3.string().nullable().optional(),
|
|
145378
|
+
state: external_exports3.enum(["unrated", "rated"]).optional()
|
|
145379
|
+
});
|
|
145380
|
+
var capabilityResponseSchema = external_exports3.object({
|
|
145381
|
+
uid: external_exports3.string(),
|
|
145382
|
+
slug: external_exports3.string(),
|
|
145383
|
+
name: external_exports3.string(),
|
|
145384
|
+
description: external_exports3.string(),
|
|
145385
|
+
url: external_exports3.string(),
|
|
145386
|
+
urlTemplate: external_exports3.string().nullable().optional(),
|
|
145387
|
+
method: external_exports3.string(),
|
|
145388
|
+
headers: external_exports3.record(external_exports3.string(), external_exports3.string()).nullable(),
|
|
145389
|
+
bodySchema: external_exports3.record(external_exports3.string(), external_exports3.unknown()).nullable(),
|
|
145390
|
+
responseSchema: external_exports3.record(external_exports3.string(), external_exports3.unknown()).nullable(),
|
|
145391
|
+
example: external_exports3.object({ request: external_exports3.unknown(), response: external_exports3.unknown() }).nullable(),
|
|
145392
|
+
tags: external_exports3.array(external_exports3.string()).nullable(),
|
|
145393
|
+
exampleAgentPrompt: external_exports3.string().nullable().optional(),
|
|
145394
|
+
whatItDoes: external_exports3.string().nullable().optional(),
|
|
145395
|
+
resultDescription: external_exports3.string().nullable().optional(),
|
|
145396
|
+
failureModes: external_exports3.array(external_exports3.string()).nullable().optional(),
|
|
145397
|
+
whenToPreferThis: external_exports3.string().nullable().optional(),
|
|
145398
|
+
// Agent-facing execution guide (markdown). Covers usage patterns, input
|
|
145399
|
+
// field guidance, cross-cap composition, and known failure modes.
|
|
145400
|
+
// Named after MCP tool convention: description = what it is, instructions = how to use it.
|
|
145401
|
+
instructions: external_exports3.string().nullable().optional(),
|
|
145402
|
+
displayCostAmount: external_exports3.string(),
|
|
145403
|
+
displayCostAsset: external_exports3.string(),
|
|
145404
|
+
reviewCount: external_exports3.number(),
|
|
145405
|
+
rating: ratingSchema,
|
|
145406
|
+
priceObserved: external_exports3.object({
|
|
145407
|
+
minCents: external_exports3.string().nullable(),
|
|
145408
|
+
medianCents: external_exports3.string().nullable(),
|
|
145409
|
+
maxCents: external_exports3.string().nullable(),
|
|
145410
|
+
// Deprecated alias for maxCents; kept for back-compat with older
|
|
145411
|
+
// API versions that still emit it.
|
|
145412
|
+
p95Cents: external_exports3.string().nullable(),
|
|
145413
|
+
sampleCount: external_exports3.number(),
|
|
145414
|
+
varies: external_exports3.boolean(),
|
|
145415
|
+
failureChargeRate: external_exports3.number().nullable()
|
|
145416
|
+
}).nullable().optional(),
|
|
145417
|
+
paymentMethods: external_exports3.array(
|
|
145418
|
+
external_exports3.object({
|
|
145419
|
+
uid: external_exports3.string(),
|
|
145420
|
+
protocol: external_exports3.string(),
|
|
145421
|
+
methodType: external_exports3.string(),
|
|
145422
|
+
chain: external_exports3.string().nullable(),
|
|
145423
|
+
mode: external_exports3.string(),
|
|
145424
|
+
costAmount: external_exports3.string(),
|
|
145425
|
+
costPer: external_exports3.string(),
|
|
145426
|
+
priority: external_exports3.number()
|
|
145427
|
+
})
|
|
145428
|
+
).nullable(),
|
|
145429
|
+
availabilityStatus: external_exports3.enum(["healthy", "unknown", "down"]).nullable().optional(),
|
|
145430
|
+
/**
|
|
145431
|
+
* @deprecated The API no longer emits `displayStatus`; it has been replaced
|
|
145432
|
+
* by the consolidated 3-value {@link capabilityResponseSchema.shape.availabilityStatus}.
|
|
145433
|
+
* Kept as an optional field for one release for back-compat (ZERO-89 soft
|
|
145434
|
+
* migration) and will be removed in the next major version.
|
|
145435
|
+
*/
|
|
145436
|
+
displayStatus: external_exports3.enum(["healthy", "stable", "degraded", "unhealthy", "unknown"]).optional(),
|
|
145437
|
+
activationCount: external_exports3.number().optional(),
|
|
145438
|
+
lastUsedAt: external_exports3.string().nullable().optional(),
|
|
145439
|
+
lastSuccessfullyRanAt: external_exports3.string().nullable().optional()
|
|
145440
|
+
});
|
|
145441
|
+
var resolveCapabilityResponseSchema = external_exports3.object({
|
|
145442
|
+
capabilityId: external_exports3.string(),
|
|
145443
|
+
capabilitySlug: external_exports3.string(),
|
|
145444
|
+
matchedVia: external_exports3.enum(["exact", "template"])
|
|
145445
|
+
});
|
|
145446
|
+
var Capabilities = class {
|
|
145447
|
+
constructor(client) {
|
|
145448
|
+
this.client = client;
|
|
145449
|
+
}
|
|
145450
|
+
get = (id, opts = {}) => request2(
|
|
145451
|
+
this.client,
|
|
145452
|
+
{
|
|
145453
|
+
method: "GET",
|
|
145454
|
+
path: `/v1/capabilities/${encodeURIComponent(id)}`,
|
|
145455
|
+
query: opts.searchId ? { searchId: opts.searchId } : void 0,
|
|
145456
|
+
signal: opts.signal
|
|
145457
|
+
},
|
|
145458
|
+
capabilityResponseSchema
|
|
145459
|
+
);
|
|
145460
|
+
// Resolve a raw endpoint URL + method back to the capability that owns it,
|
|
145461
|
+
// for the `zero fetch <url>` case where the client has no local search
|
|
145462
|
+
// context to match against (a memoized/cross-session URL). Returns null on
|
|
145463
|
+
// 404 — i.e. no match or an ambiguous multi-match, both of which the server
|
|
145464
|
+
// reports as 404 (resolveByUrl fails closed rather than mis-attribute).
|
|
145465
|
+
// The URL travels in the POST body so it stays out of access logs and is
|
|
145466
|
+
// never stored; the caller uses the returned capabilityId to record an
|
|
145467
|
+
// attributed run without the URL ever touching the run row (ZERO-335).
|
|
145468
|
+
resolveByUrl = async (url4, method, opts = {}) => {
|
|
145469
|
+
try {
|
|
145470
|
+
return await request2(
|
|
145471
|
+
this.client,
|
|
145472
|
+
{
|
|
145473
|
+
method: "POST",
|
|
145474
|
+
path: "/v1/capabilities/resolve",
|
|
145475
|
+
body: { url: url4, method },
|
|
145476
|
+
signal: opts.signal
|
|
145477
|
+
},
|
|
145478
|
+
resolveCapabilityResponseSchema
|
|
145479
|
+
);
|
|
145480
|
+
} catch (err) {
|
|
145481
|
+
if (err instanceof ZeroApiError && err.status === 404) return null;
|
|
145482
|
+
throw err;
|
|
145483
|
+
}
|
|
145484
|
+
};
|
|
145485
|
+
};
|
|
145486
|
+
var createRunResponseSchema = external_exports3.object({
|
|
145487
|
+
runId: external_exports3.string()
|
|
145488
|
+
});
|
|
145489
|
+
var runListItemSchema = external_exports3.object({
|
|
145490
|
+
uid: external_exports3.string(),
|
|
145491
|
+
capabilityUid: external_exports3.string(),
|
|
145492
|
+
capabilitySlug: external_exports3.string(),
|
|
145493
|
+
capabilityName: external_exports3.string(),
|
|
145494
|
+
status: external_exports3.number().nullable(),
|
|
145495
|
+
latencyMs: external_exports3.number().nullable(),
|
|
145496
|
+
cost: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string().nullable() }).nullable(),
|
|
145497
|
+
payment: external_exports3.object({
|
|
145498
|
+
protocol: external_exports3.string(),
|
|
145499
|
+
chain: external_exports3.string().nullable(),
|
|
145500
|
+
txHash: external_exports3.string().nullable(),
|
|
145501
|
+
mode: external_exports3.string().nullable()
|
|
145502
|
+
}).nullable(),
|
|
145503
|
+
createdAt: external_exports3.coerce.date(),
|
|
145504
|
+
reviewed: external_exports3.boolean()
|
|
145505
|
+
});
|
|
144876
145506
|
var listRunsResponseSchema = external_exports3.object({
|
|
144877
145507
|
runs: external_exports3.array(runListItemSchema),
|
|
144878
145508
|
nextCursor: external_exports3.string().nullable()
|
|
@@ -144955,866 +145585,251 @@ var Runs = class {
|
|
|
144955
145585
|
new ZeroApiError(
|
|
144956
145586
|
"runs.list({ limit: 0 }) requires a cursor \u2014 without one the empty page is indistinguishable from end-of-stream",
|
|
144957
145587
|
{ status: 0 }
|
|
144958
|
-
)
|
|
144959
|
-
);
|
|
144960
|
-
}
|
|
144961
|
-
return Promise.resolve({
|
|
144962
|
-
runs: [],
|
|
144963
|
-
nextCursor: params.cursor
|
|
144964
|
-
});
|
|
144965
|
-
}
|
|
144966
|
-
const query = {};
|
|
144967
|
-
if (params.capabilityId !== void 0)
|
|
144968
|
-
query.capabilityId = params.capabilityId;
|
|
144969
|
-
if (params.unreviewed !== void 0) query.unreviewed = params.unreviewed;
|
|
144970
|
-
if (params.limit !== void 0) query.limit = params.limit;
|
|
144971
|
-
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
144972
|
-
return request2(
|
|
144973
|
-
this.client,
|
|
144974
|
-
{
|
|
144975
|
-
method: "GET",
|
|
144976
|
-
path: "/v1/runs",
|
|
144977
|
-
query,
|
|
144978
|
-
signal: opts.signal
|
|
144979
|
-
},
|
|
144980
|
-
listRunsResponseSchema
|
|
144981
|
-
);
|
|
144982
|
-
};
|
|
144983
|
-
get = (runId, opts = {}) => request2(
|
|
144984
|
-
this.client,
|
|
144985
|
-
{
|
|
144986
|
-
method: "GET",
|
|
144987
|
-
path: `/v1/runs/${runId}`,
|
|
144988
|
-
signal: opts.signal
|
|
144989
|
-
},
|
|
144990
|
-
runDetailSchema
|
|
144991
|
-
);
|
|
144992
|
-
review = (input, opts = {}) => request2(
|
|
144993
|
-
this.client,
|
|
144994
|
-
{
|
|
144995
|
-
method: "POST",
|
|
144996
|
-
path: "/v1/reviews",
|
|
144997
|
-
body: input,
|
|
144998
|
-
signal: opts.signal
|
|
144999
|
-
},
|
|
145000
|
-
createReviewResponseSchema
|
|
145001
|
-
);
|
|
145002
|
-
// Bulk review submission. The CLI's bulk JSONL parser stays CLI-side —
|
|
145003
|
-
// SDK consumers pass already-parsed structured input.
|
|
145004
|
-
createReviewsBatch = (reviews, opts = {}) => request2(
|
|
145005
|
-
this.client,
|
|
145006
|
-
{
|
|
145007
|
-
method: "POST",
|
|
145008
|
-
path: "/v1/reviews/batch",
|
|
145009
|
-
body: { reviews },
|
|
145010
|
-
signal: opts.signal
|
|
145011
|
-
},
|
|
145012
|
-
batchReviewResponseSchema
|
|
145013
|
-
);
|
|
145014
|
-
};
|
|
145015
|
-
var USDC_BASE2 = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
145016
|
-
var USDC_TEMPO2 = "0x20c000000000000000000000b9537d11c60e8b50";
|
|
145017
|
-
var TEMPO_CHAIN_ID2 = 4217;
|
|
145018
|
-
var baseChain = base;
|
|
145019
|
-
var tempoChain2 = {
|
|
145020
|
-
id: TEMPO_CHAIN_ID2,
|
|
145021
|
-
name: "Tempo",
|
|
145022
|
-
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
145023
|
-
rpcUrls: {
|
|
145024
|
-
default: { http: ["https://rpc.tempo.xyz"] }
|
|
145025
|
-
}
|
|
145026
|
-
};
|
|
145027
|
-
var ERC20_BALANCE_ABI2 = [
|
|
145028
|
-
{
|
|
145029
|
-
inputs: [{ name: "account", type: "address" }],
|
|
145030
|
-
name: "balanceOf",
|
|
145031
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
145032
|
-
stateMutability: "view",
|
|
145033
|
-
type: "function"
|
|
145034
|
-
}
|
|
145035
|
-
];
|
|
145036
|
-
var USDC_DECIMALS = 6;
|
|
145037
|
-
var fundingUrlResponseSchema = external_exports3.object({ url: external_exports3.string() });
|
|
145038
|
-
var userWalletListSchema = external_exports3.array(userWalletDtoSchema);
|
|
145039
|
-
var migrateAuthorizationResponseSchema = external_exports3.object({
|
|
145040
|
-
transactionHash: external_exports3.string()
|
|
145041
|
-
});
|
|
145042
|
-
var errorMessage = (reason) => reason instanceof Error ? reason.message : String(reason);
|
|
145043
|
-
var Wallet = class {
|
|
145044
|
-
constructor(client) {
|
|
145045
|
-
this.client = client;
|
|
145046
|
-
}
|
|
145047
|
-
clients = {};
|
|
145048
|
-
// The configured wallet address, or null if the client wasn't constructed
|
|
145049
|
-
// with an account. Stable read — does not hit the network.
|
|
145050
|
-
get address() {
|
|
145051
|
-
const credentials = this.client.getCredentials();
|
|
145052
|
-
if (credentials.kind !== "account") return null;
|
|
145053
|
-
return credentials.account.address;
|
|
145054
|
-
}
|
|
145055
|
-
balance = async (opts = {}) => {
|
|
145056
|
-
const target = opts.address ?? this.address;
|
|
145057
|
-
if (!target) {
|
|
145058
|
-
throw new ZeroWalletError(
|
|
145059
|
-
"balance() requires either an `address` option or a client constructed with an account"
|
|
145060
|
-
);
|
|
145061
|
-
}
|
|
145062
|
-
const chain2 = opts.chain ?? "total";
|
|
145063
|
-
if (chain2 !== "total") {
|
|
145064
|
-
const raw = await this.readChainBalance(chain2, target);
|
|
145065
|
-
return { amount: formatUnits(raw, USDC_DECIMALS), asset: "USDC" };
|
|
145066
|
-
}
|
|
145067
|
-
const chains = ["base", "tempo"];
|
|
145068
|
-
const settled = await Promise.allSettled(
|
|
145069
|
-
chains.map((c) => this.readChainBalance(c, target))
|
|
145070
|
-
);
|
|
145071
|
-
let sum = 0n;
|
|
145072
|
-
const errors = [];
|
|
145073
|
-
for (let i = 0; i < settled.length; i++) {
|
|
145074
|
-
const result = settled[i];
|
|
145075
|
-
const chainName = chains[i];
|
|
145076
|
-
if (!result || !chainName) continue;
|
|
145077
|
-
if (result.status === "fulfilled") {
|
|
145078
|
-
sum += result.value;
|
|
145079
|
-
} else {
|
|
145080
|
-
errors.push({ chain: chainName, message: errorMessage(result.reason) });
|
|
145081
|
-
}
|
|
145082
|
-
}
|
|
145083
|
-
if (errors.length === settled.length) {
|
|
145084
|
-
throw new ZeroWalletError(
|
|
145085
|
-
`balance() failed for every chain: ${errors.map((e2) => `${e2.chain} (${e2.message})`).join(", ")}`
|
|
145086
|
-
);
|
|
145087
|
-
}
|
|
145088
|
-
const balance = {
|
|
145089
|
-
amount: formatUnits(sum, USDC_DECIMALS),
|
|
145090
|
-
asset: "USDC"
|
|
145091
|
-
};
|
|
145092
|
-
if (errors.length > 0) balance.errors = errors;
|
|
145093
|
-
return balance;
|
|
145094
|
-
};
|
|
145095
|
-
// All wallets linked to the authenticated session user. Session-only.
|
|
145096
|
-
list = (opts = {}) => request2(
|
|
145097
|
-
this.client,
|
|
145098
|
-
{
|
|
145099
|
-
method: "GET",
|
|
145100
|
-
path: "/v1/users/me/wallets",
|
|
145101
|
-
signal: opts.signal
|
|
145102
|
-
},
|
|
145103
|
-
userWalletListSchema
|
|
145104
|
-
);
|
|
145105
|
-
// Provision a managed (Privy-embedded) wallet for the session user.
|
|
145106
|
-
// Idempotent server-side — repeat calls return the existing wallet.
|
|
145107
|
-
provision = (opts = {}) => request2(
|
|
145108
|
-
this.client,
|
|
145109
|
-
{
|
|
145110
|
-
method: "POST",
|
|
145111
|
-
path: "/v1/users/me/wallets/provision",
|
|
145112
|
-
signal: opts.signal
|
|
145113
|
-
},
|
|
145114
|
-
userWalletDtoSchema
|
|
145115
|
-
);
|
|
145116
|
-
// Relays a BYO-wallet-signed EIP-3009 ReceiveWithAuthorization, sweeping
|
|
145117
|
-
// USDC from the BYO wallet to the user's Zero wallet on Base via the
|
|
145118
|
-
// gas-paying relayer. The SDK does not author the authorization (chain
|
|
145119
|
-
// nonce + EIP-712 domain coupling stays caller-side); it only forwards
|
|
145120
|
-
// the signed payload. Session-only.
|
|
145121
|
-
migrateAuthorization = (authorization, opts = {}) => request2(
|
|
145122
|
-
this.client,
|
|
145123
|
-
{
|
|
145124
|
-
method: "POST",
|
|
145125
|
-
path: "/v1/users/me/wallets/migrate",
|
|
145126
|
-
body: { authorization },
|
|
145127
|
-
signal: opts.signal
|
|
145128
|
-
},
|
|
145129
|
-
migrateAuthorizationResponseSchema
|
|
145130
|
-
);
|
|
145131
|
-
// Routes by identity: account mode signs EIP-191 against /v1/wallet/fund-url,
|
|
145132
|
-
// session mode hits /v1/users/me/fund-url (Bearer-authed, wallet resolved
|
|
145133
|
-
// server-side). Both honor `provider` (coinbase | stripe).
|
|
145134
|
-
fundingUrl = async (opts = {}) => {
|
|
145135
|
-
const credentials = this.client.getCredentials();
|
|
145136
|
-
const path3 = credentials.kind === "account" ? "/v1/wallet/fund-url" : credentials.kind === "session" ? "/v1/users/me/fund-url" : null;
|
|
145137
|
-
if (!path3) {
|
|
145138
|
-
throw new ZeroWalletError(
|
|
145139
|
-
"fundingUrl() requires a client constructed with an account or session credentials"
|
|
145140
|
-
);
|
|
145141
|
-
}
|
|
145142
|
-
const query = {
|
|
145143
|
-
provider: opts.provider ?? "coinbase"
|
|
145144
|
-
};
|
|
145145
|
-
if (opts.amount) query.amount = opts.amount;
|
|
145146
|
-
const { url: url4 } = await request2(
|
|
145147
|
-
this.client,
|
|
145148
|
-
{ method: "GET", path: path3, query, signal: opts.signal },
|
|
145149
|
-
fundingUrlResponseSchema
|
|
145150
|
-
);
|
|
145151
|
-
return url4;
|
|
145152
|
-
};
|
|
145153
|
-
getPublicClient = (chain2) => {
|
|
145154
|
-
if (chain2 === "base") {
|
|
145155
|
-
if (!this.clients.base) {
|
|
145156
|
-
this.clients.base = createPublicClient({
|
|
145157
|
-
chain: baseChain,
|
|
145158
|
-
transport: http()
|
|
145159
|
-
});
|
|
145160
|
-
}
|
|
145161
|
-
return this.clients.base;
|
|
145162
|
-
}
|
|
145163
|
-
if (!this.clients.tempo) {
|
|
145164
|
-
this.clients.tempo = createPublicClient({
|
|
145165
|
-
// biome-ignore lint/suspicious/noExplicitAny: tempo is a custom chain object that viem's stricter Chain type rejects shape-wise but accepts at runtime
|
|
145166
|
-
chain: tempoChain2,
|
|
145167
|
-
transport: http()
|
|
145168
|
-
});
|
|
145169
|
-
}
|
|
145170
|
-
return this.clients.tempo;
|
|
145171
|
-
};
|
|
145172
|
-
/**
|
|
145173
|
-
* @internal
|
|
145174
|
-
*
|
|
145175
|
-
* Per-chain USDC balance read. Exposed (rather than private) so unit
|
|
145176
|
-
* tests can stub it without standing up a real viem public client —
|
|
145177
|
-
* viem's `http()` transport doesn't go through `client.fetchImpl`, so
|
|
145178
|
-
* the standard mock-fetch trick doesn't cover this path.
|
|
145179
|
-
*/
|
|
145180
|
-
readChainBalance = async (chain2, address2) => {
|
|
145181
|
-
const publicClient = this.getPublicClient(chain2);
|
|
145182
|
-
const tokenAddress = chain2 === "base" ? USDC_BASE2 : USDC_TEMPO2;
|
|
145183
|
-
const balance = await publicClient.readContract({
|
|
145184
|
-
address: tokenAddress,
|
|
145185
|
-
abi: ERC20_BALANCE_ABI2,
|
|
145186
|
-
functionName: "balanceOf",
|
|
145187
|
-
args: [address2]
|
|
145188
|
-
});
|
|
145189
|
-
return balance;
|
|
145190
|
-
};
|
|
145191
|
-
};
|
|
145192
|
-
var DEFAULT_BASE_URL = "https://api.zero.xyz";
|
|
145193
|
-
var DEFAULT_TIMEOUT_MS = 18e4;
|
|
145194
|
-
var DEFAULT_MAX_RETRIES = 2;
|
|
145195
|
-
var noopRefresh = async () => {
|
|
145196
|
-
};
|
|
145197
|
-
var MAX_402_PROBE_BYTES = 1024 * 1024;
|
|
145198
|
-
var MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
145199
|
-
var TEXT_CONTENT_TYPES = [
|
|
145200
|
-
"application/json",
|
|
145201
|
-
"application/xml",
|
|
145202
|
-
"application/javascript",
|
|
145203
|
-
"application/ecmascript",
|
|
145204
|
-
"application/x-www-form-urlencoded",
|
|
145205
|
-
"text/",
|
|
145206
|
-
"+json",
|
|
145207
|
-
"+xml"
|
|
145208
|
-
];
|
|
145209
|
-
var MPP_SCHEME_TOKENS = /* @__PURE__ */ new Set(["payment", "mpp"]);
|
|
145210
|
-
var splitWwwAuthenticateChallenges = (header) => {
|
|
145211
|
-
const chunks = [];
|
|
145212
|
-
let buf = "";
|
|
145213
|
-
let inQuotes = false;
|
|
145214
|
-
for (let i = 0; i < header.length; i++) {
|
|
145215
|
-
const ch = header[i];
|
|
145216
|
-
if (inQuotes) {
|
|
145217
|
-
if (ch === "\\" && i + 1 < header.length) {
|
|
145218
|
-
buf += ch + header[i + 1];
|
|
145219
|
-
i++;
|
|
145220
|
-
continue;
|
|
145221
|
-
}
|
|
145222
|
-
if (ch === '"') inQuotes = false;
|
|
145223
|
-
buf += ch;
|
|
145224
|
-
continue;
|
|
145225
|
-
}
|
|
145226
|
-
if (ch === '"') {
|
|
145227
|
-
inQuotes = true;
|
|
145228
|
-
buf += ch;
|
|
145229
|
-
continue;
|
|
145230
|
-
}
|
|
145231
|
-
if (ch === ",") {
|
|
145232
|
-
chunks.push(buf);
|
|
145233
|
-
buf = "";
|
|
145234
|
-
continue;
|
|
145235
|
-
}
|
|
145236
|
-
buf += ch;
|
|
145237
|
-
}
|
|
145238
|
-
if (buf.length > 0) chunks.push(buf);
|
|
145239
|
-
return chunks;
|
|
145240
|
-
};
|
|
145241
|
-
var isTextContentType = (contentType) => {
|
|
145242
|
-
if (!contentType) return true;
|
|
145243
|
-
const lower = contentType.toLowerCase();
|
|
145244
|
-
return TEXT_CONTENT_TYPES.some((marker) => lower.includes(marker));
|
|
145245
|
-
};
|
|
145246
|
-
var redactUrl2 = (url4) => {
|
|
145247
|
-
try {
|
|
145248
|
-
const u2 = new URL(url4);
|
|
145249
|
-
return `${u2.origin}${u2.pathname}`;
|
|
145250
|
-
} catch {
|
|
145251
|
-
return "<invalid url>";
|
|
145252
|
-
}
|
|
145253
|
-
};
|
|
145254
|
-
var ECHO_DETECT_MIN_LEN = 16;
|
|
145255
|
-
var ECHO_DETECT_MAX_SCAN = 64 * 1024;
|
|
145256
|
-
var requestBodyEchoed = (candidate, requestBody) => {
|
|
145257
|
-
if (requestBody === void 0) return false;
|
|
145258
|
-
const asString = typeof requestBody === "string" ? requestBody : new TextDecoder("utf-8", { fatal: false }).decode(
|
|
145259
|
-
requestBody.byteLength > ECHO_DETECT_MAX_SCAN ? requestBody.subarray(0, ECHO_DETECT_MAX_SCAN) : requestBody
|
|
145260
|
-
);
|
|
145261
|
-
if (asString.length < ECHO_DETECT_MIN_LEN) return false;
|
|
145262
|
-
const scanLen = Math.min(asString.length, ECHO_DETECT_MAX_SCAN);
|
|
145263
|
-
for (let i = 0; i + ECHO_DETECT_MIN_LEN <= scanLen; i++) {
|
|
145264
|
-
if (candidate.includes(asString.slice(i, i + ECHO_DETECT_MIN_LEN))) {
|
|
145265
|
-
return true;
|
|
145266
|
-
}
|
|
145267
|
-
}
|
|
145268
|
-
return false;
|
|
145269
|
-
};
|
|
145270
|
-
var cancelBody2 = (response) => {
|
|
145271
|
-
try {
|
|
145272
|
-
response.body?.cancel().catch(() => {
|
|
145273
|
-
});
|
|
145274
|
-
} catch {
|
|
145275
|
-
}
|
|
145276
|
-
};
|
|
145277
|
-
var detectPaymentRequirement = async (response) => {
|
|
145278
|
-
if (response.status !== 402) return null;
|
|
145279
|
-
const x402Header = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
|
|
145280
|
-
if (x402Header) {
|
|
145281
|
-
cancelBody2(response);
|
|
145282
|
-
try {
|
|
145283
|
-
const decoded = JSON.parse(
|
|
145284
|
-
Buffer.from(x402Header, "base64").toString("utf8")
|
|
145285
|
-
);
|
|
145286
|
-
return { protocol: "x402", raw: decoded };
|
|
145287
|
-
} catch {
|
|
145288
|
-
return { protocol: "x402", raw: { encoded: x402Header } };
|
|
145289
|
-
}
|
|
145290
|
-
}
|
|
145291
|
-
const declaredLen = Number.parseInt(
|
|
145292
|
-
response.headers.get("content-length") ?? "",
|
|
145293
|
-
10
|
|
145294
|
-
);
|
|
145295
|
-
const bodyFits = !Number.isFinite(declaredLen) || declaredLen <= MAX_402_PROBE_BYTES;
|
|
145296
|
-
if (bodyFits) {
|
|
145297
|
-
try {
|
|
145298
|
-
const text = await readClippedText(response, MAX_402_PROBE_BYTES);
|
|
145299
|
-
if (text) {
|
|
145300
|
-
const parsed = JSON.parse(text);
|
|
145301
|
-
if (looksLikeX402Body(parsed)) {
|
|
145302
|
-
return { protocol: "x402", raw: parsed };
|
|
145303
|
-
}
|
|
145304
|
-
}
|
|
145305
|
-
} catch {
|
|
145306
|
-
}
|
|
145307
|
-
}
|
|
145308
|
-
const wwwAuth = response.headers.get("www-authenticate");
|
|
145309
|
-
if (wwwAuth) {
|
|
145310
|
-
const schemes = splitWwwAuthenticateChallenges(wwwAuth).map(
|
|
145311
|
-
(challenge2) => challenge2.trim().split(/\s+/)[0]?.toLowerCase() ?? ""
|
|
145312
|
-
);
|
|
145313
|
-
if (schemes.some((scheme) => MPP_SCHEME_TOKENS.has(scheme))) {
|
|
145314
|
-
cancelBody2(response);
|
|
145315
|
-
return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
|
|
145316
|
-
}
|
|
145317
|
-
}
|
|
145318
|
-
cancelBody2(response);
|
|
145319
|
-
return { protocol: "unknown", raw: {} };
|
|
145320
|
-
};
|
|
145321
|
-
var readClippedBytes = async (response, max) => {
|
|
145322
|
-
if (response.body === null) return new Uint8Array(0);
|
|
145323
|
-
const reader = response.body.getReader();
|
|
145324
|
-
const chunks = [];
|
|
145325
|
-
let total = 0;
|
|
145326
|
-
try {
|
|
145327
|
-
while (total < max) {
|
|
145328
|
-
const { done, value } = await reader.read();
|
|
145329
|
-
if (done) break;
|
|
145330
|
-
if (!value) continue;
|
|
145331
|
-
chunks.push(value);
|
|
145332
|
-
total += value.byteLength;
|
|
145333
|
-
}
|
|
145334
|
-
} finally {
|
|
145335
|
-
try {
|
|
145336
|
-
await reader.cancel();
|
|
145337
|
-
} catch {
|
|
145338
|
-
}
|
|
145339
|
-
}
|
|
145340
|
-
const merged = new Uint8Array(Math.min(total, max));
|
|
145341
|
-
let offset = 0;
|
|
145342
|
-
for (const c of chunks) {
|
|
145343
|
-
const take = Math.min(c.byteLength, max - offset);
|
|
145344
|
-
merged.set(c.subarray(0, take), offset);
|
|
145345
|
-
offset += take;
|
|
145346
|
-
if (offset >= max) break;
|
|
145347
|
-
}
|
|
145348
|
-
return merged;
|
|
145349
|
-
};
|
|
145350
|
-
var readClippedText = async (response, max) => {
|
|
145351
|
-
const bytes = await readClippedBytes(response, max);
|
|
145352
|
-
return new TextDecoder().decode(bytes);
|
|
145353
|
-
};
|
|
145354
|
-
var parseResponseBody = async (response, max) => {
|
|
145355
|
-
const contentType = response.headers.get("content-type");
|
|
145356
|
-
const bytes = await readClippedBytes(response, max + 1);
|
|
145357
|
-
const truncated = bytes.byteLength > max;
|
|
145358
|
-
const view = truncated ? bytes.subarray(0, max) : bytes;
|
|
145359
|
-
const buf = Buffer.from(view.buffer, view.byteOffset, view.byteLength);
|
|
145360
|
-
if (!isTextContentType(contentType)) {
|
|
145361
|
-
const base644 = buf.toString("base64");
|
|
145362
|
-
return {
|
|
145363
|
-
body: base644,
|
|
145364
|
-
bodyRaw: base644,
|
|
145365
|
-
bodyEncoding: "base64",
|
|
145366
|
-
truncated
|
|
145367
|
-
};
|
|
145368
|
-
}
|
|
145369
|
-
const text = buf.toString("utf8");
|
|
145370
|
-
if (contentType?.toLowerCase().includes("json")) {
|
|
145371
|
-
try {
|
|
145372
|
-
return { body: JSON.parse(text), bodyRaw: text, truncated };
|
|
145373
|
-
} catch {
|
|
145374
|
-
}
|
|
145375
|
-
}
|
|
145376
|
-
return { body: text, bodyRaw: text, truncated };
|
|
145377
|
-
};
|
|
145378
|
-
var UPSTREAM_ERROR_FIELDS = [
|
|
145379
|
-
"error",
|
|
145380
|
-
"message",
|
|
145381
|
-
"detail",
|
|
145382
|
-
"reason",
|
|
145383
|
-
"error_description"
|
|
145384
|
-
];
|
|
145385
|
-
var UPSTREAM_ERROR_MAX_LEN = 200;
|
|
145386
|
-
var ERROR_SNIPPET_BYTES = 500;
|
|
145387
|
-
var clampUpstreamMessage = (value) => {
|
|
145388
|
-
const trimmed = value.trim();
|
|
145389
|
-
if (!trimmed) return void 0;
|
|
145390
|
-
return trimmed.length > UPSTREAM_ERROR_MAX_LEN ? `${trimmed.slice(0, UPSTREAM_ERROR_MAX_LEN)}\u2026` : trimmed;
|
|
145391
|
-
};
|
|
145392
|
-
var tryParseJson = (text) => {
|
|
145393
|
-
try {
|
|
145394
|
-
return JSON.parse(text);
|
|
145395
|
-
} catch {
|
|
145396
|
-
return null;
|
|
145397
|
-
}
|
|
145398
|
-
};
|
|
145399
|
-
var extractUpstreamErrorMessage = (body) => {
|
|
145400
|
-
const parsed = tryParseJson(body);
|
|
145401
|
-
if (parsed === null || typeof parsed !== "object") {
|
|
145402
|
-
return clampUpstreamMessage(body);
|
|
145403
|
-
}
|
|
145404
|
-
const record3 = parsed;
|
|
145405
|
-
for (const field of UPSTREAM_ERROR_FIELDS) {
|
|
145406
|
-
const value = record3[field];
|
|
145407
|
-
if (typeof value === "string" && value.length > 0) {
|
|
145408
|
-
return clampUpstreamMessage(value);
|
|
145409
|
-
}
|
|
145410
|
-
if (value && typeof value === "object") {
|
|
145411
|
-
const nested = value.message;
|
|
145412
|
-
if (typeof nested === "string" && nested.length > 0) {
|
|
145413
|
-
return clampUpstreamMessage(nested);
|
|
145414
|
-
}
|
|
145415
|
-
}
|
|
145416
|
-
}
|
|
145417
|
-
return void 0;
|
|
145418
|
-
};
|
|
145419
|
-
var buildUpstreamError = (status, bodyRaw, bodyEncoding) => {
|
|
145420
|
-
if (status >= 200 && status < 300) return void 0;
|
|
145421
|
-
if (bodyRaw === null || bodyRaw.length === 0) return void 0;
|
|
145422
|
-
if (bodyEncoding === "base64") return void 0;
|
|
145423
|
-
const snippet = bodyRaw.slice(0, ERROR_SNIPPET_BYTES);
|
|
145424
|
-
return {
|
|
145425
|
-
status,
|
|
145426
|
-
message: extractUpstreamErrorMessage(bodyRaw),
|
|
145427
|
-
snippetHash: createHash("sha256").update(snippet).digest("hex"),
|
|
145428
|
-
snippetLength: snippet.length
|
|
145429
|
-
};
|
|
145430
|
-
};
|
|
145431
|
-
var computeOutcome = (status, payment, warnings) => {
|
|
145432
|
-
if (warnings.includes(FETCH_WARNINGS.mppSessionCloseFailed))
|
|
145433
|
-
return "payment_close_failed";
|
|
145434
|
-
if (status === 402 && payment !== null) return "payment_rejected";
|
|
145435
|
-
if (status === 402) return "payment_failed";
|
|
145436
|
-
if (status >= 400) return "server_error";
|
|
145437
|
-
return "success";
|
|
145438
|
-
};
|
|
145439
|
-
var errorFetchResult = (startedAt, error48, skipReason, capabilityIdRequested, outcome, status = null) => {
|
|
145440
|
-
const result = {
|
|
145441
|
-
runId: null,
|
|
145442
|
-
ok: false,
|
|
145443
|
-
status,
|
|
145444
|
-
latencyMs: Date.now() - startedAt,
|
|
145445
|
-
payment: null,
|
|
145446
|
-
outcome,
|
|
145447
|
-
body: null,
|
|
145448
|
-
bodyRaw: null,
|
|
145449
|
-
error: error48
|
|
145450
|
-
};
|
|
145451
|
-
if (capabilityIdRequested) result.runTrackingSkipped = [skipReason];
|
|
145452
|
-
return result;
|
|
145453
|
-
};
|
|
145454
|
-
var resolveRecordingClient = (client, opts) => {
|
|
145455
|
-
const credentials = client.getCredentials();
|
|
145456
|
-
const recordingClient = opts.account ? client.withAccount(opts.account) : client;
|
|
145457
|
-
const canRecord = opts.account !== void 0 || credentials.kind === "account" || credentials.kind === "session";
|
|
145458
|
-
return { recordingClient, canRecord };
|
|
145459
|
-
};
|
|
145460
|
-
var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) => {
|
|
145461
|
-
const effectiveCapId = opts.capabilityId;
|
|
145462
|
-
if (effectiveCapId === void 0) return;
|
|
145463
|
-
const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
|
|
145464
|
-
if (!canRecord) return;
|
|
145465
|
-
const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : opts.fetchOrigin;
|
|
145466
|
-
try {
|
|
145467
|
-
const created = await recordingClient.runs.create({
|
|
145468
|
-
capabilityId: effectiveCapId,
|
|
145469
|
-
...opts.searchId && { searchId: opts.searchId },
|
|
145470
|
-
...fetchOriginForRecord && { fetchOrigin: fetchOriginForRecord },
|
|
145471
|
-
...result.status !== null && { status: result.status },
|
|
145472
|
-
latencyMs: result.latencyMs,
|
|
145473
|
-
...opts.requestSchema && { requestSchema: opts.requestSchema }
|
|
145474
|
-
});
|
|
145475
|
-
result.runId = created.runId;
|
|
145476
|
-
delete result.runTrackingSkipped;
|
|
145477
|
-
} catch {
|
|
145478
|
-
}
|
|
145479
|
-
};
|
|
145480
|
-
var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested, capabilityIdOverride) => {
|
|
145481
|
-
const result = errorFetchResult(
|
|
145482
|
-
startedAt,
|
|
145483
|
-
err.message,
|
|
145484
|
-
"timeout",
|
|
145485
|
-
capabilityIdRequested,
|
|
145486
|
-
"network_error"
|
|
145487
|
-
);
|
|
145488
|
-
await recordErrorFetchRun(client, opts, result);
|
|
145489
|
-
};
|
|
145490
|
-
var sniffJsonShapeBytes = (buf) => {
|
|
145491
|
-
let i = 0;
|
|
145492
|
-
if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) {
|
|
145493
|
-
i = 3;
|
|
145494
|
-
}
|
|
145495
|
-
while (i < buf.length && (buf[i] === 32 || buf[i] === 9 || buf[i] === 10 || buf[i] === 13)) {
|
|
145496
|
-
i++;
|
|
145497
|
-
}
|
|
145498
|
-
if (i >= buf.length) return false;
|
|
145499
|
-
return buf[i] === 123 || buf[i] === 91;
|
|
145500
|
-
};
|
|
145501
|
-
var withDefaultContentType = (headers, body) => {
|
|
145502
|
-
if (!headers && body === void 0) return void 0;
|
|
145503
|
-
const next = headers ? { ...headers } : {};
|
|
145504
|
-
if (body === void 0) return next;
|
|
145505
|
-
const hasContentType = Object.keys(next).some(
|
|
145506
|
-
(k3) => k3.toLowerCase() === "content-type"
|
|
145507
|
-
);
|
|
145508
|
-
if (!hasContentType) {
|
|
145509
|
-
next["content-type"] = typeof body === "string" || sniffJsonShapeBytes(body) ? "application/json" : "application/octet-stream";
|
|
145510
|
-
}
|
|
145511
|
-
return next;
|
|
145512
|
-
};
|
|
145513
|
-
var clientFetch = async (client, url4, opts = {}) => {
|
|
145514
|
-
const startedAt = Date.now();
|
|
145515
|
-
const capabilityIdRequested = opts.capabilityId !== void 0;
|
|
145516
|
-
const normalized = normalizeTransportEnvelopeRequest(url4, {
|
|
145517
|
-
method: opts.method,
|
|
145518
|
-
body: opts.body
|
|
145519
|
-
});
|
|
145520
|
-
const requestUrl = normalized.url;
|
|
145521
|
-
const requestBody = normalized.body;
|
|
145522
|
-
const method = normalized.method ?? (requestBody !== void 0 ? "POST" : "GET");
|
|
145523
|
-
const { canRecord: canRecordForResolve } = resolveRecordingClient(
|
|
145524
|
-
client,
|
|
145525
|
-
opts
|
|
145526
|
-
);
|
|
145527
|
-
const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl2(requestUrl), method).catch(() => null) : Promise.resolve(null);
|
|
145528
|
-
const probeHeaders = withDefaultContentType(opts.headers, requestBody);
|
|
145529
|
-
const requestInit = {
|
|
145530
|
-
method,
|
|
145531
|
-
headers: probeHeaders,
|
|
145532
|
-
body: requestBody,
|
|
145533
|
-
signal: opts.signal
|
|
145534
|
-
};
|
|
145535
|
-
const configuredFetch = buildConfiguredFetch(client, {
|
|
145536
|
-
timeoutMs: opts.timeoutMs
|
|
145537
|
-
});
|
|
145538
|
-
let response;
|
|
145539
|
-
let payment = null;
|
|
145540
|
-
const skipReasons = [];
|
|
145541
|
-
const warnings = [];
|
|
145542
|
-
try {
|
|
145543
|
-
response = await configuredFetch(requestUrl, requestInit);
|
|
145544
|
-
} catch (err) {
|
|
145545
|
-
if (err instanceof ZeroTimeoutError) {
|
|
145546
|
-
await recordTimeoutRun(
|
|
145547
|
-
client,
|
|
145548
|
-
opts,
|
|
145549
|
-
err,
|
|
145550
|
-
startedAt,
|
|
145551
|
-
capabilityIdRequested
|
|
145552
|
-
);
|
|
145553
|
-
throw err;
|
|
145554
|
-
}
|
|
145555
|
-
if (err instanceof ZeroError) throw err;
|
|
145556
|
-
const errMessage = err instanceof Error ? err.message : String(err);
|
|
145557
|
-
const result2 = errorFetchResult(
|
|
145558
|
-
startedAt,
|
|
145559
|
-
errMessage,
|
|
145560
|
-
"fetch_failed_before_response",
|
|
145561
|
-
capabilityIdRequested,
|
|
145562
|
-
"network_error"
|
|
145563
|
-
);
|
|
145564
|
-
await recordErrorFetchRun(client, opts, result2);
|
|
145565
|
-
return result2;
|
|
145566
|
-
}
|
|
145567
|
-
if (response.status === 402) {
|
|
145568
|
-
const requirement = await detectPaymentRequirement(response);
|
|
145569
|
-
if (requirement?.protocol === "x402" || requirement?.protocol === "mpp") {
|
|
145570
|
-
const payCall = requirement.protocol === "x402" ? client.payments.pay : client.payments.payMpp;
|
|
145571
|
-
try {
|
|
145572
|
-
const paid = await payCall({
|
|
145573
|
-
url: requestUrl,
|
|
145574
|
-
method,
|
|
145575
|
-
// Fresh clone for the paid retry — same rationale as
|
|
145576
|
-
// the probe-side clone above. Re-derives the default
|
|
145577
|
-
// Content-Type so the paid leg matches the probe.
|
|
145578
|
-
headers: withDefaultContentType(opts.headers, requestBody),
|
|
145579
|
-
body: requestBody,
|
|
145580
|
-
maxPay: opts.maxPay,
|
|
145581
|
-
account: opts.account,
|
|
145582
|
-
signal: opts.signal,
|
|
145583
|
-
timeoutMs: opts.timeoutMs,
|
|
145584
|
-
...opts.displayCostAmount && {
|
|
145585
|
-
displayCostAmount: opts.displayCostAmount
|
|
145586
|
-
}
|
|
145587
|
-
});
|
|
145588
|
-
response = paid.response;
|
|
145589
|
-
payment = paid.payment;
|
|
145590
|
-
if (paid.warnings) warnings.push(...paid.warnings);
|
|
145591
|
-
} catch (err) {
|
|
145592
|
-
if (err instanceof ZeroSessionCloseFailedError) {
|
|
145593
|
-
response = err.response;
|
|
145594
|
-
payment = {
|
|
145595
|
-
protocol: "mpp",
|
|
145596
|
-
chain: tempoChainLabelFromId(err.session.chainId),
|
|
145597
|
-
txHash: null,
|
|
145598
|
-
amount: err.capturedAmount,
|
|
145599
|
-
asset: "USDC",
|
|
145600
|
-
session: err.session
|
|
145601
|
-
};
|
|
145602
|
-
warnings.push(FETCH_WARNINGS.mppSessionCloseFailed);
|
|
145603
|
-
} else if (err instanceof ZeroInsufficientFundsError) {
|
|
145604
|
-
return errorFetchResult(
|
|
145605
|
-
startedAt,
|
|
145606
|
-
err.message,
|
|
145607
|
-
FETCH_SKIP_REASONS.insufficientFunds,
|
|
145608
|
-
capabilityIdRequested,
|
|
145609
|
-
"insufficient_funds",
|
|
145610
|
-
null
|
|
145611
|
-
);
|
|
145612
|
-
} else if (err instanceof ZeroPaymentError || err instanceof ZeroAuthError) {
|
|
145613
|
-
const result2 = errorFetchResult(
|
|
145614
|
-
startedAt,
|
|
145615
|
-
err.message,
|
|
145616
|
-
"payment_failed",
|
|
145617
|
-
capabilityIdRequested,
|
|
145618
|
-
"payment_failed",
|
|
145619
|
-
402
|
|
145620
|
-
);
|
|
145621
|
-
await recordErrorFetchRun(client, opts, result2);
|
|
145622
|
-
return result2;
|
|
145623
|
-
} else if (err instanceof ZeroTimeoutError) {
|
|
145624
|
-
await recordTimeoutRun(
|
|
145625
|
-
client,
|
|
145626
|
-
opts,
|
|
145627
|
-
err,
|
|
145628
|
-
startedAt,
|
|
145629
|
-
capabilityIdRequested
|
|
145630
|
-
);
|
|
145631
|
-
throw err;
|
|
145632
|
-
} else {
|
|
145633
|
-
throw err;
|
|
145634
|
-
}
|
|
145588
|
+
)
|
|
145589
|
+
);
|
|
145635
145590
|
}
|
|
145636
|
-
|
|
145637
|
-
|
|
145638
|
-
|
|
145639
|
-
|
|
145640
|
-
"unrecognized_402_protocol",
|
|
145641
|
-
capabilityIdRequested,
|
|
145642
|
-
"payment_failed",
|
|
145643
|
-
402
|
|
145644
|
-
);
|
|
145645
|
-
await recordErrorFetchRun(client, opts, result2);
|
|
145646
|
-
return result2;
|
|
145591
|
+
return Promise.resolve({
|
|
145592
|
+
runs: [],
|
|
145593
|
+
nextCursor: params.cursor
|
|
145594
|
+
});
|
|
145647
145595
|
}
|
|
145596
|
+
const query = {};
|
|
145597
|
+
if (params.capabilityId !== void 0)
|
|
145598
|
+
query.capabilityId = params.capabilityId;
|
|
145599
|
+
if (params.unreviewed !== void 0) query.unreviewed = params.unreviewed;
|
|
145600
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
145601
|
+
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
145602
|
+
return request2(
|
|
145603
|
+
this.client,
|
|
145604
|
+
{
|
|
145605
|
+
method: "GET",
|
|
145606
|
+
path: "/v1/runs",
|
|
145607
|
+
query,
|
|
145608
|
+
signal: opts.signal
|
|
145609
|
+
},
|
|
145610
|
+
listRunsResponseSchema
|
|
145611
|
+
);
|
|
145612
|
+
};
|
|
145613
|
+
get = (runId, opts = {}) => request2(
|
|
145614
|
+
this.client,
|
|
145615
|
+
{
|
|
145616
|
+
method: "GET",
|
|
145617
|
+
path: `/v1/runs/${runId}`,
|
|
145618
|
+
signal: opts.signal
|
|
145619
|
+
},
|
|
145620
|
+
runDetailSchema
|
|
145621
|
+
);
|
|
145622
|
+
review = (input, opts = {}) => request2(
|
|
145623
|
+
this.client,
|
|
145624
|
+
{
|
|
145625
|
+
method: "POST",
|
|
145626
|
+
path: "/v1/reviews",
|
|
145627
|
+
body: input,
|
|
145628
|
+
signal: opts.signal
|
|
145629
|
+
},
|
|
145630
|
+
createReviewResponseSchema
|
|
145631
|
+
);
|
|
145632
|
+
// Bulk review submission. The CLI's bulk JSONL parser stays CLI-side —
|
|
145633
|
+
// SDK consumers pass already-parsed structured input.
|
|
145634
|
+
createReviewsBatch = (reviews, opts = {}) => request2(
|
|
145635
|
+
this.client,
|
|
145636
|
+
{
|
|
145637
|
+
method: "POST",
|
|
145638
|
+
path: "/v1/reviews/batch",
|
|
145639
|
+
body: { reviews },
|
|
145640
|
+
signal: opts.signal
|
|
145641
|
+
},
|
|
145642
|
+
batchReviewResponseSchema
|
|
145643
|
+
);
|
|
145644
|
+
};
|
|
145645
|
+
var USDC_BASE2 = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
145646
|
+
var USDC_TEMPO2 = "0x20c000000000000000000000b9537d11c60e8b50";
|
|
145647
|
+
var TEMPO_CHAIN_ID2 = 4217;
|
|
145648
|
+
var baseChain = base;
|
|
145649
|
+
var tempoChain2 = {
|
|
145650
|
+
id: TEMPO_CHAIN_ID2,
|
|
145651
|
+
name: "Tempo",
|
|
145652
|
+
nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
|
|
145653
|
+
rpcUrls: {
|
|
145654
|
+
default: { http: ["https://rpc.tempo.xyz"] }
|
|
145648
145655
|
}
|
|
145649
|
-
|
|
145650
|
-
|
|
145651
|
-
|
|
145652
|
-
|
|
145653
|
-
|
|
145654
|
-
|
|
145655
|
-
|
|
145656
|
-
|
|
145657
|
-
|
|
145658
|
-
|
|
145659
|
-
|
|
145660
|
-
|
|
145661
|
-
|
|
145662
|
-
|
|
145663
|
-
|
|
145664
|
-
|
|
145665
|
-
|
|
145656
|
+
};
|
|
145657
|
+
var ERC20_BALANCE_ABI2 = [
|
|
145658
|
+
{
|
|
145659
|
+
inputs: [{ name: "account", type: "address" }],
|
|
145660
|
+
name: "balanceOf",
|
|
145661
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
145662
|
+
stateMutability: "view",
|
|
145663
|
+
type: "function"
|
|
145664
|
+
}
|
|
145665
|
+
];
|
|
145666
|
+
var USDC_DECIMALS = 6;
|
|
145667
|
+
var fundingUrlResponseSchema = external_exports3.object({ url: external_exports3.string() });
|
|
145668
|
+
var userWalletListSchema = external_exports3.array(userWalletDtoSchema);
|
|
145669
|
+
var migrateAuthorizationResponseSchema = external_exports3.object({
|
|
145670
|
+
transactionHash: external_exports3.string()
|
|
145671
|
+
});
|
|
145672
|
+
var errorMessage = (reason) => reason instanceof Error ? reason.message : String(reason);
|
|
145673
|
+
var Wallet = class {
|
|
145674
|
+
constructor(client) {
|
|
145675
|
+
this.client = client;
|
|
145676
|
+
}
|
|
145677
|
+
clients = {};
|
|
145678
|
+
// The configured wallet address, or null if the client wasn't constructed
|
|
145679
|
+
// with an account. Stable read — does not hit the network.
|
|
145680
|
+
get address() {
|
|
145681
|
+
const credentials = this.client.getCredentials();
|
|
145682
|
+
if (credentials.kind !== "account") return null;
|
|
145683
|
+
return credentials.account.address;
|
|
145684
|
+
}
|
|
145685
|
+
balance = async (opts = {}) => {
|
|
145686
|
+
const target = opts.address ?? this.address;
|
|
145687
|
+
if (!target) {
|
|
145688
|
+
throw new ZeroWalletError(
|
|
145689
|
+
"balance() requires either an `address` option or a client constructed with an account"
|
|
145690
|
+
);
|
|
145666
145691
|
}
|
|
145667
|
-
const
|
|
145668
|
-
|
|
145669
|
-
|
|
145670
|
-
|
|
145671
|
-
warnings.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
145672
|
-
skips.push(FETCH_WARNINGS.paidButStill402NotRecorded);
|
|
145692
|
+
const chain2 = opts.chain ?? "total";
|
|
145693
|
+
if (chain2 !== "total") {
|
|
145694
|
+
const raw = await this.readChainBalance(chain2, target);
|
|
145695
|
+
return { amount: formatUnits(raw, USDC_DECIMALS), asset: "USDC" };
|
|
145673
145696
|
}
|
|
145674
|
-
|
|
145675
|
-
|
|
145676
|
-
|
|
145697
|
+
const chains = ["base", "tempo"];
|
|
145698
|
+
const settled = await Promise.allSettled(
|
|
145699
|
+
chains.map((c) => this.readChainBalance(c, target))
|
|
145700
|
+
);
|
|
145701
|
+
let sum = 0n;
|
|
145702
|
+
const errors = [];
|
|
145703
|
+
for (let i = 0; i < settled.length; i++) {
|
|
145704
|
+
const result = settled[i];
|
|
145705
|
+
const chainName = chains[i];
|
|
145706
|
+
if (!result || !chainName) continue;
|
|
145707
|
+
if (result.status === "fulfilled") {
|
|
145708
|
+
sum += result.value;
|
|
145709
|
+
} else {
|
|
145710
|
+
errors.push({ chain: chainName, message: errorMessage(result.reason) });
|
|
145711
|
+
}
|
|
145677
145712
|
}
|
|
145678
|
-
if (
|
|
145679
|
-
|
|
145713
|
+
if (errors.length === settled.length) {
|
|
145714
|
+
throw new ZeroWalletError(
|
|
145715
|
+
`balance() failed for every chain: ${errors.map((e2) => `${e2.chain} (${e2.message})`).join(", ")}`
|
|
145716
|
+
);
|
|
145680
145717
|
}
|
|
145681
|
-
|
|
145682
|
-
|
|
145683
|
-
|
|
145684
|
-
ok: false,
|
|
145685
|
-
status: response.status,
|
|
145686
|
-
latencyMs: Date.now() - startedAt,
|
|
145687
|
-
payment,
|
|
145688
|
-
outcome: computeOutcome(response.status, payment, warnings),
|
|
145689
|
-
body: null,
|
|
145690
|
-
bodyRaw: null,
|
|
145691
|
-
error: message2
|
|
145718
|
+
const balance = {
|
|
145719
|
+
amount: formatUnits(sum, USDC_DECIMALS),
|
|
145720
|
+
asset: "USDC"
|
|
145692
145721
|
};
|
|
145693
|
-
if (
|
|
145694
|
-
|
|
145695
|
-
|
|
145696
|
-
|
|
145697
|
-
|
|
145698
|
-
|
|
145699
|
-
|
|
145700
|
-
|
|
145701
|
-
|
|
145702
|
-
|
|
145703
|
-
|
|
145704
|
-
|
|
145705
|
-
}
|
|
145706
|
-
let runId = null;
|
|
145707
|
-
const closeFailed = warnings.includes(FETCH_WARNINGS.mppSessionCloseFailed);
|
|
145708
|
-
const upstreamErrorForRecord = buildUpstreamError(
|
|
145709
|
-
response.status,
|
|
145710
|
-
bodyRaw,
|
|
145711
|
-
bodyEncoding
|
|
145722
|
+
if (errors.length > 0) balance.errors = errors;
|
|
145723
|
+
return balance;
|
|
145724
|
+
};
|
|
145725
|
+
// All wallets linked to the authenticated session user. Session-only.
|
|
145726
|
+
list = (opts = {}) => request2(
|
|
145727
|
+
this.client,
|
|
145728
|
+
{
|
|
145729
|
+
method: "GET",
|
|
145730
|
+
path: "/v1/users/me/wallets",
|
|
145731
|
+
signal: opts.signal
|
|
145732
|
+
},
|
|
145733
|
+
userWalletListSchema
|
|
145712
145734
|
);
|
|
145713
|
-
|
|
145714
|
-
|
|
145715
|
-
|
|
145716
|
-
|
|
145717
|
-
|
|
145718
|
-
|
|
145719
|
-
|
|
145720
|
-
|
|
145721
|
-
|
|
145722
|
-
|
|
145723
|
-
|
|
145724
|
-
|
|
145725
|
-
|
|
145726
|
-
|
|
145727
|
-
|
|
145728
|
-
|
|
145729
|
-
|
|
145730
|
-
|
|
145731
|
-
|
|
145732
|
-
|
|
145733
|
-
|
|
145734
|
-
|
|
145735
|
-
|
|
145736
|
-
|
|
145737
|
-
|
|
145738
|
-
|
|
145739
|
-
|
|
145740
|
-
|
|
145741
|
-
|
|
145742
|
-
|
|
145743
|
-
|
|
145744
|
-
|
|
145745
|
-
|
|
145746
|
-
|
|
145747
|
-
|
|
145748
|
-
|
|
145749
|
-
|
|
145750
|
-
|
|
145751
|
-
|
|
145752
|
-
|
|
145753
|
-
|
|
145754
|
-
|
|
145755
|
-
|
|
145756
|
-
|
|
145757
|
-
|
|
145758
|
-
|
|
145759
|
-
|
|
145760
|
-
|
|
145761
|
-
|
|
145762
|
-
|
|
145763
|
-
|
|
145764
|
-
|
|
145765
|
-
|
|
145766
|
-
|
|
145767
|
-
paymentProtocol: payment.protocol,
|
|
145768
|
-
paymentChain: payment.chain,
|
|
145769
|
-
paymentTxHash: payment.txHash ?? void 0,
|
|
145770
|
-
paymentMode: payment.session ? "session" : "charge"
|
|
145771
|
-
}
|
|
145772
|
-
});
|
|
145773
|
-
runId = result2.runId;
|
|
145774
|
-
} catch (err) {
|
|
145775
|
-
const errorMessage22 = err instanceof Error ? err.message : String(err);
|
|
145776
|
-
const code = err instanceof ZeroError ? err.code : void 0;
|
|
145777
|
-
const skipMsg = code ? `run_create_failed:${code}: ${errorMessage22}` : `run_create_failed: ${errorMessage22}`;
|
|
145778
|
-
skipReasons.push(skipMsg);
|
|
145779
|
-
client.logger?.({
|
|
145780
|
-
level: "warn",
|
|
145781
|
-
message: "Failed to record run for fetch",
|
|
145782
|
-
meta: {
|
|
145783
|
-
url: redactUrl2(url4),
|
|
145784
|
-
capabilityId: effectiveCapabilityId,
|
|
145785
|
-
error: errorMessage22,
|
|
145786
|
-
errorCode: code
|
|
145787
|
-
}
|
|
145735
|
+
// Provision a managed (Privy-embedded) wallet for the session user.
|
|
145736
|
+
// Idempotent server-side — repeat calls return the existing wallet.
|
|
145737
|
+
provision = (opts = {}) => request2(
|
|
145738
|
+
this.client,
|
|
145739
|
+
{
|
|
145740
|
+
method: "POST",
|
|
145741
|
+
path: "/v1/users/me/wallets/provision",
|
|
145742
|
+
signal: opts.signal
|
|
145743
|
+
},
|
|
145744
|
+
userWalletDtoSchema
|
|
145745
|
+
);
|
|
145746
|
+
// Relays a BYO-wallet-signed EIP-3009 ReceiveWithAuthorization, sweeping
|
|
145747
|
+
// USDC from the BYO wallet to the user's Zero wallet on Base via the
|
|
145748
|
+
// gas-paying relayer. The SDK does not author the authorization (chain
|
|
145749
|
+
// nonce + EIP-712 domain coupling stays caller-side); it only forwards
|
|
145750
|
+
// the signed payload. Session-only.
|
|
145751
|
+
migrateAuthorization = (authorization, opts = {}) => request2(
|
|
145752
|
+
this.client,
|
|
145753
|
+
{
|
|
145754
|
+
method: "POST",
|
|
145755
|
+
path: "/v1/users/me/wallets/migrate",
|
|
145756
|
+
body: { authorization },
|
|
145757
|
+
signal: opts.signal
|
|
145758
|
+
},
|
|
145759
|
+
migrateAuthorizationResponseSchema
|
|
145760
|
+
);
|
|
145761
|
+
// Routes by identity: account mode signs EIP-191 against /v1/wallet/fund-url,
|
|
145762
|
+
// session mode hits /v1/users/me/fund-url (Bearer-authed, wallet resolved
|
|
145763
|
+
// server-side). Both honor `provider` (coinbase | stripe).
|
|
145764
|
+
fundingUrl = async (opts = {}) => {
|
|
145765
|
+
const credentials = this.client.getCredentials();
|
|
145766
|
+
const path3 = credentials.kind === "account" ? "/v1/wallet/fund-url" : credentials.kind === "session" ? "/v1/users/me/fund-url" : null;
|
|
145767
|
+
if (!path3) {
|
|
145768
|
+
throw new ZeroWalletError(
|
|
145769
|
+
"fundingUrl() requires a client constructed with an account or session credentials"
|
|
145770
|
+
);
|
|
145771
|
+
}
|
|
145772
|
+
const query = {
|
|
145773
|
+
provider: opts.provider ?? "coinbase"
|
|
145774
|
+
};
|
|
145775
|
+
if (opts.amount) query.amount = opts.amount;
|
|
145776
|
+
const { url: url4 } = await request2(
|
|
145777
|
+
this.client,
|
|
145778
|
+
{ method: "GET", path: path3, query, signal: opts.signal },
|
|
145779
|
+
fundingUrlResponseSchema
|
|
145780
|
+
);
|
|
145781
|
+
return url4;
|
|
145782
|
+
};
|
|
145783
|
+
getPublicClient = (chain2) => {
|
|
145784
|
+
if (chain2 === "base") {
|
|
145785
|
+
if (!this.clients.base) {
|
|
145786
|
+
this.clients.base = createPublicClient({
|
|
145787
|
+
chain: baseChain,
|
|
145788
|
+
transport: http()
|
|
145788
145789
|
});
|
|
145789
145790
|
}
|
|
145791
|
+
return this.clients.base;
|
|
145790
145792
|
}
|
|
145791
|
-
|
|
145792
|
-
|
|
145793
|
-
|
|
145794
|
-
|
|
145795
|
-
|
|
145796
|
-
|
|
145797
|
-
|
|
145798
|
-
|
|
145799
|
-
body,
|
|
145800
|
-
bodyRaw
|
|
145793
|
+
if (!this.clients.tempo) {
|
|
145794
|
+
this.clients.tempo = createPublicClient({
|
|
145795
|
+
// biome-ignore lint/suspicious/noExplicitAny: tempo is a custom chain object that viem's stricter Chain type rejects shape-wise but accepts at runtime
|
|
145796
|
+
chain: tempoChain2,
|
|
145797
|
+
transport: http()
|
|
145798
|
+
});
|
|
145799
|
+
}
|
|
145800
|
+
return this.clients.tempo;
|
|
145801
145801
|
};
|
|
145802
|
-
|
|
145803
|
-
|
|
145804
|
-
|
|
145805
|
-
|
|
145806
|
-
|
|
145807
|
-
|
|
145808
|
-
|
|
145809
|
-
|
|
145810
|
-
|
|
145811
|
-
|
|
145812
|
-
|
|
145813
|
-
|
|
145814
|
-
|
|
145802
|
+
/**
|
|
145803
|
+
* @internal
|
|
145804
|
+
*
|
|
145805
|
+
* Per-chain USDC balance read. Exposed (rather than private) so unit
|
|
145806
|
+
* tests can stub it without standing up a real viem public client —
|
|
145807
|
+
* viem's `http()` transport doesn't go through `client.fetchImpl`, so
|
|
145808
|
+
* the standard mock-fetch trick doesn't cover this path.
|
|
145809
|
+
*/
|
|
145810
|
+
readChainBalance = async (chain2, address2) => {
|
|
145811
|
+
const publicClient = this.getPublicClient(chain2);
|
|
145812
|
+
const tokenAddress = chain2 === "base" ? USDC_BASE2 : USDC_TEMPO2;
|
|
145813
|
+
const balance = await publicClient.readContract({
|
|
145814
|
+
address: tokenAddress,
|
|
145815
|
+
abi: ERC20_BALANCE_ABI2,
|
|
145816
|
+
functionName: "balanceOf",
|
|
145817
|
+
args: [address2]
|
|
145818
|
+
});
|
|
145819
|
+
return balance;
|
|
145820
|
+
};
|
|
145821
|
+
};
|
|
145822
|
+
var DEFAULT_BASE_URL = "https://api.zero.xyz";
|
|
145823
|
+
var DEFAULT_TIMEOUT_MS = 18e4;
|
|
145824
|
+
var DEFAULT_MAX_RETRIES = 2;
|
|
145825
|
+
var noopRefresh = async () => {
|
|
145815
145826
|
};
|
|
145816
145827
|
var searchResultSchema = external_exports3.object({
|
|
145817
145828
|
id: external_exports3.string(),
|
|
145829
|
+
// Opaque attribution token (format: `z_{shortId}.{position}`). Optional
|
|
145830
|
+
// so old API deploys that don't emit it still parse cleanly. Pass as
|
|
145831
|
+
// capabilityId to client.fetch() for exact search attribution.
|
|
145832
|
+
token: external_exports3.string().nullable().optional(),
|
|
145818
145833
|
position: external_exports3.number(),
|
|
145819
145834
|
slug: external_exports3.string(),
|
|
145820
145835
|
name: external_exports3.string(),
|
|
@@ -146316,7 +146331,7 @@ Categories the classifier picks from:
|
|
|
146316
146331
|
).action(
|
|
146317
146332
|
async (description, options) => {
|
|
146318
146333
|
try {
|
|
146319
|
-
const { analyticsService, client,
|
|
146334
|
+
const { analyticsService, client, walletAddress } = appContext.services;
|
|
146320
146335
|
if (!walletAddress) {
|
|
146321
146336
|
console.error(
|
|
146322
146337
|
"Wallet auth required \u2014 run `zero auth login`, or `zero wallet set <key>` / set ZERO_PRIVATE_KEY."
|
|
@@ -146397,12 +146412,6 @@ Bulk bug-report complete: ${ok} ok, ${failed} failed`
|
|
|
146397
146412
|
let { capability, run, search } = options;
|
|
146398
146413
|
const useAutoContext = options.context !== false;
|
|
146399
146414
|
if (useAutoContext) {
|
|
146400
|
-
const lastSearch = stateService.loadLastSearch();
|
|
146401
|
-
if (lastSearch) {
|
|
146402
|
-
search = search ?? lastSearch.searchId;
|
|
146403
|
-
const recent = lastSearch.capabilities[0];
|
|
146404
|
-
capability = capability ?? recent?.id;
|
|
146405
|
-
}
|
|
146406
146415
|
if (!run) {
|
|
146407
146416
|
try {
|
|
146408
146417
|
const list2 = await client.runs.list({ limit: 1 });
|
|
@@ -146610,11 +146619,6 @@ var sniffJsonShape = (buf) => {
|
|
|
146610
146619
|
if (i >= buf.length) return false;
|
|
146611
146620
|
return buf[i] === 123 || buf[i] === 91;
|
|
146612
146621
|
};
|
|
146613
|
-
var urlMatchesTemplate = (url4, template) => {
|
|
146614
|
-
const escaped = template.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
146615
|
-
const withCaptures = escaped.replace(/\\\{[^/\\}]+\\\}/g, "[^/]+");
|
|
146616
|
-
return new RegExp(`^${withCaptures}$`).test(url4);
|
|
146617
|
-
};
|
|
146618
146622
|
var resolveRequestBody = (rawData, readStdin2) => {
|
|
146619
146623
|
const fromFile = (spec) => {
|
|
146620
146624
|
if (spec === "@-") return readFileSync(0);
|
|
@@ -146681,27 +146685,25 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146681
146685
|
).action(
|
|
146682
146686
|
async (url4, options) => {
|
|
146683
146687
|
try {
|
|
146684
|
-
const {
|
|
146685
|
-
|
|
146686
|
-
|
|
146687
|
-
stateService,
|
|
146688
|
-
walletAddress,
|
|
146689
|
-
lowBalanceWarning
|
|
146690
|
-
} = appContext.services;
|
|
146688
|
+
const { analyticsService, client, walletAddress, lowBalanceWarning } = appContext.services;
|
|
146689
|
+
const fromToken = options.capability ? isShortToken(options.capability) : false;
|
|
146690
|
+
const effectiveCapRef = options.capability;
|
|
146691
146691
|
let resolvedUrl;
|
|
146692
146692
|
let resolvedMethodFromCapability;
|
|
146693
|
+
let capFromNoUrl;
|
|
146693
146694
|
if (!url4) {
|
|
146694
146695
|
if (!options.capability) {
|
|
146695
146696
|
console.error(
|
|
146696
|
-
"Missing URL. Pass a URL argument or --capability <uid|slug> so the URL can be resolved from the capability."
|
|
146697
|
+
"Missing URL. Pass a URL argument or --capability <uid|slug|token> so the URL can be resolved from the capability."
|
|
146697
146698
|
);
|
|
146698
146699
|
process.exitCode = 1;
|
|
146699
146700
|
return;
|
|
146700
146701
|
}
|
|
146701
146702
|
try {
|
|
146702
|
-
const cap = await client.capabilities.get(
|
|
146703
|
+
const cap = await client.capabilities.get(effectiveCapRef ?? "");
|
|
146703
146704
|
resolvedUrl = cap.url;
|
|
146704
146705
|
resolvedMethodFromCapability = cap.method;
|
|
146706
|
+
capFromNoUrl = cap;
|
|
146705
146707
|
} catch (err) {
|
|
146706
146708
|
console.error(
|
|
146707
146709
|
`Failed to resolve --capability ${options.capability}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -146758,24 +146760,31 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146758
146760
|
}
|
|
146759
146761
|
const log2 = (msg) => console.error(` ${msg}`);
|
|
146760
146762
|
const method = options.method ? options.method.toUpperCase() : resolvedMethodFromCapability ? resolvedMethodFromCapability.toUpperCase() : resolvedBody ? "POST" : "GET";
|
|
146761
|
-
|
|
146762
|
-
|
|
146763
|
-
|
|
146764
|
-
|
|
146765
|
-
|
|
146766
|
-
|
|
146767
|
-
|
|
146768
|
-
|
|
146769
|
-
|
|
146770
|
-
|
|
146771
|
-
|
|
146772
|
-
|
|
146773
|
-
|
|
146774
|
-
|
|
146775
|
-
|
|
146776
|
-
|
|
146777
|
-
|
|
146778
|
-
|
|
146763
|
+
let capabilityId = null;
|
|
146764
|
+
let capabilityUid = null;
|
|
146765
|
+
let capabilitySlug = null;
|
|
146766
|
+
let searchId;
|
|
146767
|
+
let displayCostAmount;
|
|
146768
|
+
let fetchOrigin;
|
|
146769
|
+
if (fromToken) {
|
|
146770
|
+
capabilityUid = capFromNoUrl?.uid ?? null;
|
|
146771
|
+
capabilityId = options.capability ?? "";
|
|
146772
|
+
capabilitySlug = capFromNoUrl?.slug ?? null;
|
|
146773
|
+
displayCostAmount = capFromNoUrl?.displayCostAmount;
|
|
146774
|
+
fetchOrigin = "from_search";
|
|
146775
|
+
} else if (options.capability) {
|
|
146776
|
+
capabilityUid = capFromNoUrl?.uid ?? null;
|
|
146777
|
+
capabilitySlug = capFromNoUrl?.slug ?? null;
|
|
146778
|
+
capabilityId = options.capability;
|
|
146779
|
+
displayCostAmount = capFromNoUrl?.displayCostAmount;
|
|
146780
|
+
fetchOrigin = "direct_slug";
|
|
146781
|
+
} else {
|
|
146782
|
+
const resolved = await client.capabilities.resolveByUrl(resolvedUrl, options.method ?? "GET").catch(() => null);
|
|
146783
|
+
capabilityUid = resolved?.capabilityId ?? null;
|
|
146784
|
+
capabilityId = capabilityUid;
|
|
146785
|
+
fetchOrigin = "direct_url";
|
|
146786
|
+
}
|
|
146787
|
+
const resultRank = void 0;
|
|
146779
146788
|
const cliSkipReasons = [];
|
|
146780
146789
|
if (!walletAddress) {
|
|
146781
146790
|
cliSkipReasons.push(
|
|
@@ -146811,16 +146820,17 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146811
146820
|
// Adaptive MPP channel prefund: when the seller sends no
|
|
146812
146821
|
// suggestedDeposit and the caller didn't pass --max-pay,
|
|
146813
146822
|
// the SDK scales the channel to 10× displayCostAmount so
|
|
146814
|
-
// an expensive single call doesn't under-fund.
|
|
146815
|
-
//
|
|
146816
|
-
|
|
146817
|
-
|
|
146818
|
-
},
|
|
146823
|
+
// an expensive single call doesn't under-fund. Derived from
|
|
146824
|
+
// the capability details when available (token or direct-slug
|
|
146825
|
+
// paths that triggered a capabilities.get).
|
|
146826
|
+
...displayCostAmount && { displayCostAmount },
|
|
146819
146827
|
// Only attach the capability when wallet auth is available;
|
|
146820
146828
|
// recording without a wallet would skip server-side anyway,
|
|
146821
146829
|
// and omitting here keeps result.runTrackingSkipped clean.
|
|
146822
146830
|
...capabilityId && walletAddress && { capabilityId },
|
|
146823
|
-
|
|
146831
|
+
// searchId intentionally omitted: server derives attribution
|
|
146832
|
+
// via SearchAttributor (wallet + capId + 30-min window) so
|
|
146833
|
+
// parallel fetches are race-free without shared client state.
|
|
146824
146834
|
// Stamp how the agent arrived (from_search | direct_slug |
|
|
146825
146835
|
// direct_url) onto the run's metadata so direct execution is
|
|
146826
146836
|
// distinguishable from search-driven runs server-side. Only
|
|
@@ -146947,19 +146957,12 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
146947
146957
|
} else {
|
|
146948
146958
|
if (walletAddress && !runId) {
|
|
146949
146959
|
cliSkipReasons.push(
|
|
146950
|
-
"no capability resolved \u2014 pass --capability <uid|slug> or run `zero search` first so the URL can be matched"
|
|
146960
|
+
"no capability resolved \u2014 pass --capability <uid|slug|token> or run `zero search` first so the URL can be matched"
|
|
146951
146961
|
);
|
|
146952
146962
|
}
|
|
146953
|
-
const lastSearch = stateService.loadLastSearch();
|
|
146954
|
-
const cached2 = lastSearch?.capabilities ?? [];
|
|
146955
146963
|
analyticsService.capture("capability_resolution_missed", {
|
|
146956
146964
|
url: redactUrl(resolvedUrl),
|
|
146957
|
-
method
|
|
146958
|
-
hasLastSearch: lastSearch !== null,
|
|
146959
|
-
lastSearchSize: cached2.length,
|
|
146960
|
-
lastSearchHasTemplates: cached2.some(
|
|
146961
|
-
(c) => Boolean(c.urlTemplate)
|
|
146962
|
-
)
|
|
146965
|
+
method
|
|
146963
146966
|
});
|
|
146964
146967
|
}
|
|
146965
146968
|
}
|
|
@@ -147078,28 +147081,35 @@ var fetchCommand = (appContext) => new Command("fetch").description(
|
|
|
147078
147081
|
})
|
|
147079
147082
|
);
|
|
147080
147083
|
} else if (runId && outcomeInfo.reviewable) {
|
|
147084
|
+
const isTTY = process.stderr.isTTY;
|
|
147081
147085
|
console.error(`
|
|
147082
147086
|
Run ID: ${runId}`);
|
|
147083
|
-
|
|
147084
|
-
|
|
147085
|
-
|
|
147086
|
-
|
|
147087
|
-
|
|
147088
|
-
|
|
147089
|
-
|
|
147090
|
-
|
|
147091
|
-
|
|
147092
|
-
|
|
147093
|
-
|
|
147094
|
-
|
|
147095
|
-
|
|
147096
|
-
|
|
147097
|
-
|
|
147098
|
-
|
|
147099
|
-
|
|
147100
|
-
|
|
147101
|
-
|
|
147102
|
-
|
|
147087
|
+
if (isTTY) {
|
|
147088
|
+
console.error(
|
|
147089
|
+
` Leave a review to help other agents discover great capabilities:`
|
|
147090
|
+
);
|
|
147091
|
+
console.error(
|
|
147092
|
+
` zero review ${runId} --success --accuracy 5 --value 4 --reliability 5 --content "your feedback"`
|
|
147093
|
+
);
|
|
147094
|
+
console.error(
|
|
147095
|
+
[
|
|
147096
|
+
``,
|
|
147097
|
+
` Tips for a great review:`,
|
|
147098
|
+
` --success / --no-success Did the API return the result you expected?`,
|
|
147099
|
+
` --accuracy 1-5 How correct was the response? (1 = wrong, 5 = perfect)`,
|
|
147100
|
+
` --value 1-5 Was it worth the price? (1 = overpriced, 5 = great deal)`,
|
|
147101
|
+
` --reliability 1-5 Did it respond quickly and without errors? (1 = flaky, 5 = rock solid)`,
|
|
147102
|
+
` --content Free-text is optional but helps other agents pick the best capability.`,
|
|
147103
|
+
` Published publicly \u2014 do not include personal or identifying`,
|
|
147104
|
+
` information (names, emails, phone numbers, addresses, keys, SSNs).`,
|
|
147105
|
+
``
|
|
147106
|
+
].join("\n")
|
|
147107
|
+
);
|
|
147108
|
+
} else {
|
|
147109
|
+
console.error(
|
|
147110
|
+
` zero review ${runId} --success --accuracy 5 --value 4 --reliability 5`
|
|
147111
|
+
);
|
|
147112
|
+
}
|
|
147103
147113
|
} else if (!runId && cliSkipReasons.length > 0) {
|
|
147104
147114
|
console.error(
|
|
147105
147115
|
`
|
|
@@ -147410,7 +147420,11 @@ var buildTryItExample = (capability) => {
|
|
|
147410
147420
|
if (method === "GET" || queryParams && !body) {
|
|
147411
147421
|
const qpProps = queryParams ? asNode(queryParams.properties) : null;
|
|
147412
147422
|
const qs = qpProps ? Object.entries(qpProps).map(
|
|
147413
|
-
|
|
147423
|
+
// Key is always an identifier — safe to encode. Value is
|
|
147424
|
+
// left unencoded so `<FIELD>` placeholders stay readable
|
|
147425
|
+
// (encodeURIComponent would produce %3CFIELD%3E, which
|
|
147426
|
+
// agents copy verbatim and get a charged 400).
|
|
147427
|
+
([k3, schema]) => `${encodeURIComponent(k3)}=${placeholderFor(k3, schema)}`
|
|
147414
147428
|
).join("&") : "";
|
|
147415
147429
|
const url4 = qs ? `${capability.url}?${qs}` : capability.url;
|
|
147416
147430
|
const urlLine = ` zero fetch --capability ${capability.slug} "${url4}"`;
|
|
@@ -147458,6 +147472,12 @@ var formatCapability = (capability) => {
|
|
|
147458
147472
|
lines.push(
|
|
147459
147473
|
` Last successful run: ${formatRelativeTimestamp(capability.lastSuccessfullyRanAt)}`
|
|
147460
147474
|
);
|
|
147475
|
+
if (capability.instructions?.trim()) {
|
|
147476
|
+
lines.push("", "Instructions:");
|
|
147477
|
+
for (const line of capability.instructions.trim().split("\n")) {
|
|
147478
|
+
lines.push(` ${line}`);
|
|
147479
|
+
}
|
|
147480
|
+
}
|
|
147461
147481
|
if (capability.exampleAgentPrompt?.trim()) {
|
|
147462
147482
|
lines.push(" Example prompt:");
|
|
147463
147483
|
for (const promptLine of capability.exampleAgentPrompt.split("\n")) {
|
|
@@ -147474,66 +147494,26 @@ var formatCapability = (capability) => {
|
|
|
147474
147494
|
lines.push(...buildTryItExample(capability));
|
|
147475
147495
|
return lines.join("\n");
|
|
147476
147496
|
};
|
|
147477
|
-
var getCommand = (appContext) => new Command("get").description(
|
|
147478
|
-
"Get details for a capability by position from last search, or by slug"
|
|
147479
|
-
).argument(
|
|
147497
|
+
var getCommand = (appContext) => new Command("get").description("Get details for a capability by token, slug, or uid").argument(
|
|
147480
147498
|
"<identifier>",
|
|
147481
|
-
"
|
|
147499
|
+
"Attribution token (z_xxx.N from search results), capability slug, or uid"
|
|
147482
147500
|
).option("--formatted", "Output formatted capability details").option("--json", "Output raw JSON to stdout (default)").option(
|
|
147483
147501
|
"--agent <name>",
|
|
147484
147502
|
"Identify your agent host for this invocation. Overrides auto-detect for this call only."
|
|
147485
147503
|
).action(async (identifier, options) => {
|
|
147486
147504
|
try {
|
|
147487
|
-
const { analyticsService, client
|
|
147488
|
-
const
|
|
147489
|
-
const isPosition = !Number.isNaN(position) && position >= 1;
|
|
147490
|
-
let capabilityId;
|
|
147491
|
-
let searchId;
|
|
147492
|
-
if (isPosition) {
|
|
147493
|
-
const lastSearch = stateService.loadLastSearch();
|
|
147494
|
-
if (!lastSearch) {
|
|
147495
|
-
console.error("No recent search found. Run `zero search` first.");
|
|
147496
|
-
process.exitCode = 1;
|
|
147497
|
-
return;
|
|
147498
|
-
}
|
|
147499
|
-
const entry = lastSearch.capabilities.find(
|
|
147500
|
-
(c) => c.position === position
|
|
147501
|
-
);
|
|
147502
|
-
if (!entry) {
|
|
147503
|
-
console.error(
|
|
147504
|
-
`No capability at position ${position}. Positions: ${lastSearch.capabilities.map((c) => c.position).join(", ")}`
|
|
147505
|
-
);
|
|
147506
|
-
process.exitCode = 1;
|
|
147507
|
-
return;
|
|
147508
|
-
}
|
|
147509
|
-
capabilityId = entry.id;
|
|
147510
|
-
searchId = lastSearch.searchId;
|
|
147511
|
-
} else {
|
|
147512
|
-
capabilityId = identifier;
|
|
147513
|
-
const ctx = stateService.findSearchContextByCapability(identifier);
|
|
147514
|
-
if (ctx) searchId = ctx.searchId;
|
|
147515
|
-
}
|
|
147516
|
-
const capability = await client.capabilities.get(capabilityId, {
|
|
147517
|
-
searchId
|
|
147518
|
-
});
|
|
147505
|
+
const { analyticsService, client } = appContext.services;
|
|
147506
|
+
const capability = await client.capabilities.get(identifier);
|
|
147519
147507
|
if (options.formatted && !options.json) {
|
|
147520
147508
|
console.log(formatCapability(capability));
|
|
147521
147509
|
} else {
|
|
147522
147510
|
console.log(JSON.stringify(capability, null, 2));
|
|
147523
147511
|
}
|
|
147524
147512
|
analyticsService.capture("capability_viewed", {
|
|
147525
|
-
|
|
147526
|
-
// resolved to uid via the last-search cache). Preserved
|
|
147527
|
-
// for back-compat with existing dashboards.
|
|
147528
|
-
capabilityId,
|
|
147529
|
-
// New canonical identifier fields read off the API response,
|
|
147530
|
-
// so they are always populated regardless of how the user
|
|
147531
|
-
// referenced the capability.
|
|
147513
|
+
capabilityRef: identifier,
|
|
147532
147514
|
capabilityUid: capability.uid,
|
|
147533
147515
|
capabilitySlug: capability.slug,
|
|
147534
|
-
|
|
147535
|
-
...isPosition ? { position } : {},
|
|
147536
|
-
...searchId ? { searchId } : {}
|
|
147516
|
+
fromToken: isShortToken(identifier)
|
|
147537
147517
|
});
|
|
147538
147518
|
} catch (err) {
|
|
147539
147519
|
console.error(err instanceof Error ? err.message : "Get failed");
|
|
@@ -148610,7 +148590,7 @@ var formatDetail = (r2) => {
|
|
|
148610
148590
|
}
|
|
148611
148591
|
return lines.join("\n");
|
|
148612
148592
|
};
|
|
148613
|
-
var runsDetailCommand = (appContext) => new Command("detail").description("Show full metadata for a single run").argument("<runId>", "Run ID (run_\u2026)").option("--json", "Output raw JSON to stdout").action(async (runId, _opts, cmd) => {
|
|
148593
|
+
var runsDetailCommand = (appContext) => new Command("detail").description("Show full metadata for a single run (from server)").argument("<runId>", "Run ID (run_\u2026)").option("--json", "Output raw JSON to stdout").action(async (runId, _opts, cmd) => {
|
|
148614
148594
|
const { json: json3 } = cmd.opts();
|
|
148615
148595
|
try {
|
|
148616
148596
|
const { client } = appContext.services;
|
|
@@ -148625,9 +148605,10 @@ var runsDetailCommand = (appContext) => new Command("detail").description("Show
|
|
|
148625
148605
|
process.exitCode = 1;
|
|
148626
148606
|
}
|
|
148627
148607
|
});
|
|
148628
|
-
var runsCommand = (appContext) =>
|
|
148629
|
-
"
|
|
148630
|
-
|
|
148608
|
+
var runsCommand = (appContext) => {
|
|
148609
|
+
const cmd = new Command("runs").description("List your recent capability runs").addHelpText(
|
|
148610
|
+
"after",
|
|
148611
|
+
`
|
|
148631
148612
|
View your recent capability runs \u2014 status, latency, cost, and payment info.
|
|
148632
148613
|
A leading [\u2713] means the run already has a review; [ ] means it does not.
|
|
148633
148614
|
|
|
@@ -148636,52 +148617,55 @@ Examples:
|
|
|
148636
148617
|
zero runs --unreviewed # filter to runs without a review
|
|
148637
148618
|
zero runs --capability translate-en # filter to one capability (uid or slug)
|
|
148638
148619
|
zero runs --json # full structured output for scripts
|
|
148639
|
-
zero runs detail <runId> # full metadata for a
|
|
148640
|
-
).
|
|
148641
|
-
|
|
148642
|
-
|
|
148643
|
-
|
|
148644
|
-
).option("--json", "Output raw JSON to stdout").option(
|
|
148645
|
-
|
|
148646
|
-
|
|
148647
|
-
).action(
|
|
148648
|
-
|
|
148649
|
-
|
|
148650
|
-
|
|
148651
|
-
|
|
148652
|
-
|
|
148653
|
-
|
|
148654
|
-
|
|
148655
|
-
|
|
148656
|
-
|
|
148657
|
-
|
|
148658
|
-
|
|
148659
|
-
|
|
148660
|
-
|
|
148661
|
-
|
|
148662
|
-
|
|
148663
|
-
|
|
148664
|
-
|
|
148665
|
-
|
|
148666
|
-
|
|
148667
|
-
|
|
148668
|
-
|
|
148669
|
-
|
|
148670
|
-
|
|
148671
|
-
|
|
148672
|
-
|
|
148673
|
-
|
|
148674
|
-
|
|
148675
|
-
|
|
148676
|
-
|
|
148620
|
+
zero runs detail <runId> # full server-side metadata for a run`
|
|
148621
|
+
).option("--capability <id>", "Filter by capability uid or slug").option("--unreviewed", "Only show runs without a review").option(
|
|
148622
|
+
"--limit <n>",
|
|
148623
|
+
"Max rows (1-100, default 25)",
|
|
148624
|
+
(v) => Number.parseInt(v, 10)
|
|
148625
|
+
).option("--json", "Output raw JSON to stdout").option(
|
|
148626
|
+
"--agent <name>",
|
|
148627
|
+
"Identify your agent host for this invocation. Overrides auto-detect for this call only."
|
|
148628
|
+
).action(
|
|
148629
|
+
async (options) => {
|
|
148630
|
+
try {
|
|
148631
|
+
const { client } = appContext.services;
|
|
148632
|
+
const result = await client.runs.list({
|
|
148633
|
+
capabilityId: options.capability,
|
|
148634
|
+
unreviewed: options.unreviewed,
|
|
148635
|
+
limit: options.limit
|
|
148636
|
+
});
|
|
148637
|
+
if (options.json) {
|
|
148638
|
+
console.log(JSON.stringify(result, null, 2));
|
|
148639
|
+
return;
|
|
148640
|
+
}
|
|
148641
|
+
if (result.runs.length === 0) {
|
|
148642
|
+
console.log("No runs found.");
|
|
148643
|
+
return;
|
|
148644
|
+
}
|
|
148645
|
+
for (const r2 of result.runs) {
|
|
148646
|
+
const when = r2.createdAt.toISOString().replace("T", " ").slice(0, 19);
|
|
148647
|
+
const mark = r2.reviewed ? "\u2713" : " ";
|
|
148648
|
+
const status = r2.status ?? "\u2014";
|
|
148649
|
+
const latency = r2.latencyMs != null ? `${r2.latencyMs}ms` : "\u2014";
|
|
148650
|
+
const cost = formatCost2(r2.cost);
|
|
148651
|
+
const payment = formatPayment(r2.payment);
|
|
148652
|
+
console.log(
|
|
148653
|
+
`[${mark}] ${r2.uid} ${r2.capabilitySlug} status=${status} ${latency} ${cost} ${payment} ${when}`
|
|
148654
|
+
);
|
|
148655
|
+
}
|
|
148656
|
+
if (result.nextCursor) {
|
|
148657
|
+
console.log(`
|
|
148677
148658
|
(more available \u2014 use --limit to see more)`);
|
|
148659
|
+
}
|
|
148660
|
+
} catch (err) {
|
|
148661
|
+
console.error(err instanceof Error ? err.message : "Failed");
|
|
148662
|
+
process.exitCode = 1;
|
|
148678
148663
|
}
|
|
148679
|
-
} catch (err) {
|
|
148680
|
-
console.error(err instanceof Error ? err.message : "Failed");
|
|
148681
|
-
process.exitCode = 1;
|
|
148682
148664
|
}
|
|
148683
|
-
|
|
148684
|
-
);
|
|
148665
|
+
);
|
|
148666
|
+
cmd.addCommand(runsDetailCommand(appContext));
|
|
148667
|
+
return cmd;
|
|
148668
|
+
};
|
|
148685
148669
|
|
|
148686
148670
|
// src/commands/search-command.ts
|
|
148687
148671
|
init_esm_shims();
|
|
@@ -148720,7 +148704,8 @@ var formatSearchResults = (results) => {
|
|
|
148720
148704
|
const ratingBadge = formatRatingBadge(r2.rating);
|
|
148721
148705
|
const statusBadge = formatStatusBadge(r2.availabilityStatus);
|
|
148722
148706
|
const costLabel = r2.cost.amount === "0" ? "Free" : r2.cost.amount === "unknown" ? "variable pricing" : `$${r2.cost.amount}/call`;
|
|
148723
|
-
|
|
148707
|
+
const tokenHint = r2.token ? ` [${r2.token}]` : "";
|
|
148708
|
+
return ` ${r2.position}.${tokenHint} ${displayName} \u2014 ${costLabel} \u2014 ${ratingBadge}${statusBadge}
|
|
148724
148709
|
"${displayDescription}"`;
|
|
148725
148710
|
}).join("\n");
|
|
148726
148711
|
};
|
|
@@ -148742,7 +148727,7 @@ var searchCommand = (appContext) => new Command("search").description("Search fo
|
|
|
148742
148727
|
).action(
|
|
148743
148728
|
async (query, options) => {
|
|
148744
148729
|
try {
|
|
148745
|
-
const { analyticsService, client
|
|
148730
|
+
const { analyticsService, client } = appContext.services;
|
|
148746
148731
|
if (options.protocol && !["x402", "mpp"].includes(options.protocol)) {
|
|
148747
148732
|
console.error(
|
|
148748
148733
|
`Invalid protocol "${options.protocol}". Must be x402 or mpp.`
|
|
@@ -148811,17 +148796,6 @@ var searchCommand = (appContext) => new Command("search").description("Search fo
|
|
|
148811
148796
|
);
|
|
148812
148797
|
return;
|
|
148813
148798
|
}
|
|
148814
|
-
stateService.saveLastSearch({
|
|
148815
|
-
searchId: result.searchId,
|
|
148816
|
-
capabilities: result.capabilities.map((c) => ({
|
|
148817
|
-
position: c.position,
|
|
148818
|
-
id: c.id,
|
|
148819
|
-
slug: c.slug,
|
|
148820
|
-
url: c.url,
|
|
148821
|
-
urlTemplate: c.urlTemplate ?? null,
|
|
148822
|
-
displayCostAmount: c.cost.amount
|
|
148823
|
-
}))
|
|
148824
|
-
});
|
|
148825
148799
|
console.log(formatSearchResults(result.capabilities));
|
|
148826
148800
|
if (result.hasMore) {
|
|
148827
148801
|
console.error(
|
|
@@ -148831,7 +148805,7 @@ var searchCommand = (appContext) => new Command("search").description("Search fo
|
|
|
148831
148805
|
}
|
|
148832
148806
|
if (result.capabilities.length > 0) {
|
|
148833
148807
|
console.error(
|
|
148834
|
-
"\n Run `zero get
|
|
148808
|
+
"\n Run `zero get <token>` (or `zero get <slug>`) to view a capability.\n"
|
|
148835
148809
|
);
|
|
148836
148810
|
}
|
|
148837
148811
|
} catch (err) {
|
|
@@ -154114,105 +154088,6 @@ var AnalyticsService = class {
|
|
|
154114
154088
|
}
|
|
154115
154089
|
};
|
|
154116
154090
|
|
|
154117
|
-
// src/services/state-service.ts
|
|
154118
|
-
init_esm_shims();
|
|
154119
|
-
var RECENT_SEARCH_LIMIT = 10;
|
|
154120
|
-
var StateService = class {
|
|
154121
|
-
constructor(zeroDir) {
|
|
154122
|
-
this.zeroDir = zeroDir;
|
|
154123
|
-
this.lastSearchPath = join(zeroDir, "last_search.json");
|
|
154124
|
-
this.recentSearchesPath = join(zeroDir, "recent_searches.json");
|
|
154125
|
-
}
|
|
154126
|
-
lastSearchPath;
|
|
154127
|
-
recentSearchesPath;
|
|
154128
|
-
saveLastSearch = (data) => {
|
|
154129
|
-
mkdirSync(this.zeroDir, { recursive: true });
|
|
154130
|
-
writeFileSync(this.lastSearchPath, JSON.stringify(data, null, 2));
|
|
154131
|
-
const recent = this.loadRecentSearches();
|
|
154132
|
-
const filtered = recent.searches.filter(
|
|
154133
|
-
(s) => s.searchId !== data.searchId
|
|
154134
|
-
);
|
|
154135
|
-
const next = [data, ...filtered].slice(0, RECENT_SEARCH_LIMIT);
|
|
154136
|
-
writeFileSync(
|
|
154137
|
-
this.recentSearchesPath,
|
|
154138
|
-
JSON.stringify({ searches: next }, null, 2)
|
|
154139
|
-
);
|
|
154140
|
-
};
|
|
154141
|
-
loadLastSearch = () => {
|
|
154142
|
-
try {
|
|
154143
|
-
if (!existsSync(this.lastSearchPath)) return null;
|
|
154144
|
-
const raw = readFileSync(this.lastSearchPath, "utf8");
|
|
154145
|
-
return JSON.parse(raw);
|
|
154146
|
-
} catch {
|
|
154147
|
-
return null;
|
|
154148
|
-
}
|
|
154149
|
-
};
|
|
154150
|
-
loadRecentSearches = () => {
|
|
154151
|
-
try {
|
|
154152
|
-
if (!existsSync(this.recentSearchesPath)) {
|
|
154153
|
-
const last = this.loadLastSearch();
|
|
154154
|
-
return { searches: last ? [last] : [] };
|
|
154155
|
-
}
|
|
154156
|
-
const raw = readFileSync(this.recentSearchesPath, "utf8");
|
|
154157
|
-
const parsed = JSON.parse(raw);
|
|
154158
|
-
return { searches: parsed.searches ?? [] };
|
|
154159
|
-
} catch {
|
|
154160
|
-
return { searches: [] };
|
|
154161
|
-
}
|
|
154162
|
-
};
|
|
154163
|
-
// Walk recent searches newest-first, returning the first one whose
|
|
154164
|
-
// results contain `capabilityRef` (matches against uid OR slug).
|
|
154165
|
-
// Preferred over "loadLastSearch" for attributing rank — handles the
|
|
154166
|
-
// parallel-search case where the most recent search isn't the one being
|
|
154167
|
-
// fetched.
|
|
154168
|
-
findSearchContextByCapability = (capabilityRef) => {
|
|
154169
|
-
const recent = this.loadRecentSearches();
|
|
154170
|
-
for (const search of recent.searches) {
|
|
154171
|
-
const entry = search.capabilities.find(
|
|
154172
|
-
(c) => c.id === capabilityRef || c.slug === capabilityRef
|
|
154173
|
-
);
|
|
154174
|
-
if (entry) {
|
|
154175
|
-
return {
|
|
154176
|
-
searchId: search.searchId,
|
|
154177
|
-
resultRank: entry.position,
|
|
154178
|
-
capabilityId: entry.id,
|
|
154179
|
-
capabilityUid: entry.id,
|
|
154180
|
-
capabilitySlug: entry.slug ?? null,
|
|
154181
|
-
url: entry.url,
|
|
154182
|
-
displayCostAmount: entry.displayCostAmount
|
|
154183
|
-
};
|
|
154184
|
-
}
|
|
154185
|
-
}
|
|
154186
|
-
return null;
|
|
154187
|
-
};
|
|
154188
|
-
// URL-based attribution for `zero fetch <url>`. Matches by URL prefix
|
|
154189
|
-
// (some capabilities accept query params or path tails the agent appends)
|
|
154190
|
-
// across the recent ring, newest match wins. Falls back to a caller-
|
|
154191
|
-
// supplied urlTemplate matcher (ADS-509 path-parameterized URLs).
|
|
154192
|
-
findSearchContextByUrl = (url4, options) => {
|
|
154193
|
-
const recent = this.loadRecentSearches();
|
|
154194
|
-
for (const search of recent.searches) {
|
|
154195
|
-
const prefixHit = search.capabilities.find((c) => url4.startsWith(c.url));
|
|
154196
|
-
const templateHit = prefixHit ?? search.capabilities.find(
|
|
154197
|
-
(c) => c.urlTemplate && options?.matchTemplate ? options.matchTemplate(c.urlTemplate) : false
|
|
154198
|
-
);
|
|
154199
|
-
const entry = templateHit;
|
|
154200
|
-
if (entry) {
|
|
154201
|
-
return {
|
|
154202
|
-
searchId: search.searchId,
|
|
154203
|
-
resultRank: entry.position,
|
|
154204
|
-
capabilityId: entry.id,
|
|
154205
|
-
capabilityUid: entry.id,
|
|
154206
|
-
capabilitySlug: entry.slug ?? null,
|
|
154207
|
-
url: entry.url,
|
|
154208
|
-
displayCostAmount: entry.displayCostAmount
|
|
154209
|
-
};
|
|
154210
|
-
}
|
|
154211
|
-
}
|
|
154212
|
-
return null;
|
|
154213
|
-
};
|
|
154214
|
-
};
|
|
154215
|
-
|
|
154216
154091
|
// src/services/wallet-migration-service.ts
|
|
154217
154092
|
init_esm_shims();
|
|
154218
154093
|
var USDC_BASE3 = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
|
|
@@ -154496,7 +154371,6 @@ var getServices = async (env) => {
|
|
|
154496
154371
|
const walletMigrationService = new WalletMigrationService(
|
|
154497
154372
|
byoAccount ?? legacyAccount
|
|
154498
154373
|
);
|
|
154499
|
-
const stateService = new StateService(zeroDir);
|
|
154500
154374
|
const analyticsService = new AnalyticsService({
|
|
154501
154375
|
walletAddress: account?.address ?? null,
|
|
154502
154376
|
configPath,
|
|
@@ -154509,7 +154383,6 @@ var getServices = async (env) => {
|
|
|
154509
154383
|
analyticsService,
|
|
154510
154384
|
client,
|
|
154511
154385
|
walletMigrationService,
|
|
154512
|
-
stateService,
|
|
154513
154386
|
lowBalanceWarning,
|
|
154514
154387
|
// Canonical resolved wallet address across the CLI — covers BYO,
|
|
154515
154388
|
// managed (Privy embedded) and legacy paths via the precedence above.
|