@zeroxyz/sdk 0.4.0 → 0.6.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.
@@ -128,6 +128,78 @@ var ZeroConfigurationError = class extends ZeroError {
128
128
  }
129
129
  };
130
130
 
131
+ // src/input-envelope.ts
132
+ var asSchemaNode = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : null;
133
+ var extractInputEnvelope = (bodySchema, method) => {
134
+ const root = asSchemaNode(bodySchema);
135
+ if (!root) return {};
136
+ const props = asSchemaNode(root.properties);
137
+ if (!props) return {};
138
+ const inputProps = asSchemaNode(asSchemaNode(props.input)?.properties);
139
+ if (inputProps) {
140
+ return {
141
+ queryParams: asSchemaNode(inputProps.queryParams) ?? void 0,
142
+ body: asSchemaNode(inputProps.body) ?? void 0
143
+ };
144
+ }
145
+ const upperMethod = method.toUpperCase();
146
+ const isGetLike = upperMethod === "GET" || upperMethod === "DELETE";
147
+ return isGetLike ? { queryParams: root } : { body: root };
148
+ };
149
+ var unwrapTransportEnvelope = (request2) => {
150
+ const input = asSchemaNode(asSchemaNode(request2)?.input);
151
+ if (!input || input.type !== "http") return request2;
152
+ const body = input.body;
153
+ const hasBody = body !== void 0 && body !== null && !(typeof body === "object" && Object.keys(body).length === 0);
154
+ if (hasBody) return body;
155
+ const qp = asSchemaNode(input.queryParams);
156
+ if (qp && Object.keys(qp).length > 0) return qp;
157
+ return null;
158
+ };
159
+ var GET_LIKE = /* @__PURE__ */ new Set(["GET", "HEAD", "DELETE"]);
160
+ var appendQueryParams = (url, params) => {
161
+ const entries = Object.entries(params).filter(([, v]) => v != null);
162
+ if (entries.length === 0) return url;
163
+ try {
164
+ const u = new URL(url);
165
+ for (const [k, v] of entries) u.searchParams.set(k, String(v));
166
+ return u.toString();
167
+ } catch {
168
+ const qs = entries.map(
169
+ ([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
170
+ ).join("&");
171
+ return url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
172
+ }
173
+ };
174
+ var normalizeTransportEnvelopeRequest = (url, opts) => {
175
+ const { method, body } = opts;
176
+ if (typeof body !== "string") return { url, method, body };
177
+ let parsed;
178
+ try {
179
+ parsed = JSON.parse(body);
180
+ } catch {
181
+ return { url, method, body };
182
+ }
183
+ const input = asSchemaNode(asSchemaNode(parsed)?.input);
184
+ if (!input || input.type !== "http") return { url, method, body };
185
+ const innerBody = input.body;
186
+ const hasInnerBody = innerBody !== void 0 && innerBody !== null && !(typeof innerBody === "object" && Object.keys(innerBody).length === 0);
187
+ const verb = (method ?? (typeof input.method === "string" ? input.method : void 0) ?? (hasInnerBody ? "POST" : "GET")).toUpperCase();
188
+ if (GET_LIKE.has(verb)) {
189
+ const qp = asSchemaNode(input.queryParams);
190
+ return {
191
+ url: qp ? appendQueryParams(url, qp) : url,
192
+ method: verb,
193
+ body: void 0
194
+ };
195
+ }
196
+ return {
197
+ url,
198
+ method: verb,
199
+ body: hasInnerBody ? JSON.stringify(innerBody) : void 0
200
+ };
201
+ };
202
+
131
203
  // src/chains/eip712.ts
132
204
  var KNOWN_EIP712_DOMAINS = {
133
205
  // Base mainnet USDC. On-chain `name()` is "USD Coin" (NOT "USDC")
@@ -1146,7 +1218,7 @@ var Payments = class {
1146
1218
 
1147
1219
  // package.json
1148
1220
  var package_default = {
1149
- version: "0.4.0"};
1221
+ version: "0.6.0"};
1150
1222
 
1151
1223
  // src/version.ts
1152
1224
  var SDK_VERSION = package_default.version;
@@ -1803,6 +1875,11 @@ var capabilityResponseSchema = zod.z.object({
1803
1875
  lastUsedAt: zod.z.string().nullable().optional(),
1804
1876
  lastSuccessfullyRanAt: zod.z.string().nullable().optional()
1805
1877
  });
1878
+ var resolveCapabilityResponseSchema = zod.z.object({
1879
+ capabilityId: zod.z.string(),
1880
+ capabilitySlug: zod.z.string(),
1881
+ matchedVia: zod.z.enum(["exact", "template"])
1882
+ });
1806
1883
 
1807
1884
  // src/namespaces/capabilities.ts
1808
1885
  var Capabilities = class {
@@ -1819,6 +1896,31 @@ var Capabilities = class {
1819
1896
  },
1820
1897
  capabilityResponseSchema
1821
1898
  );
1899
+ // Resolve a raw endpoint URL + method back to the capability that owns it,
1900
+ // for the `zero fetch <url>` case where the client has no local search
1901
+ // context to match against (a memoized/cross-session URL). Returns null on
1902
+ // 404 — i.e. no match or an ambiguous multi-match, both of which the server
1903
+ // reports as 404 (resolveByUrl fails closed rather than mis-attribute).
1904
+ // The URL travels in the POST body so it stays out of access logs and is
1905
+ // never stored; the caller uses the returned capabilityId to record an
1906
+ // attributed run without the URL ever touching the run row (ZERO-335).
1907
+ resolveByUrl = async (url, method, opts = {}) => {
1908
+ try {
1909
+ return await request(
1910
+ this.client,
1911
+ {
1912
+ method: "POST",
1913
+ path: "/v1/capabilities/resolve",
1914
+ body: { url, method },
1915
+ signal: opts.signal
1916
+ },
1917
+ resolveCapabilityResponseSchema
1918
+ );
1919
+ } catch (err) {
1920
+ if (err instanceof ZeroApiError && err.status === 404) return null;
1921
+ throw err;
1922
+ }
1923
+ };
1822
1924
  };
1823
1925
  var createRunResponseSchema = zod.z.object({
1824
1926
  runId: zod.z.string()
@@ -1844,6 +1946,30 @@ var listRunsResponseSchema = zod.z.object({
1844
1946
  runs: zod.z.array(runListItemSchema),
1845
1947
  nextCursor: zod.z.string().nullable()
1846
1948
  });
1949
+ var runDetailSchema = zod.z.object({
1950
+ runId: zod.z.string(),
1951
+ status: zod.z.number().nullable(),
1952
+ latencyMs: zod.z.number().nullable(),
1953
+ errorClass: zod.z.string().nullable(),
1954
+ createdAt: zod.z.coerce.date(),
1955
+ cost: zod.z.object({ amount: zod.z.string(), asset: zod.z.string().nullable() }).nullable(),
1956
+ payment: zod.z.object({
1957
+ protocol: zod.z.string(),
1958
+ chain: zod.z.string().nullable(),
1959
+ txHash: zod.z.string().nullable(),
1960
+ mode: zod.z.string().nullable()
1961
+ }).nullable(),
1962
+ capability: zod.z.object({
1963
+ uid: zod.z.string(),
1964
+ slug: zod.z.string(),
1965
+ name: zod.z.string(),
1966
+ url: zod.z.string(),
1967
+ method: zod.z.string(),
1968
+ whatItDoes: zod.z.string().nullable(),
1969
+ tags: zod.z.array(zod.z.string())
1970
+ }),
1971
+ reviewed: zod.z.boolean()
1972
+ });
1847
1973
  var createReviewResponseSchema = zod.z.object({
1848
1974
  reviewId: zod.z.string(),
1849
1975
  recorded: zod.z.boolean(),
@@ -1925,6 +2051,15 @@ var Runs = class {
1925
2051
  listRunsResponseSchema
1926
2052
  );
1927
2053
  };
2054
+ get = (runId, opts = {}) => request(
2055
+ this.client,
2056
+ {
2057
+ method: "GET",
2058
+ path: `/v1/runs/${runId}`,
2059
+ signal: opts.signal
2060
+ },
2061
+ runDetailSchema
2062
+ );
1928
2063
  review = (input, opts = {}) => request(
1929
2064
  this.client,
1930
2065
  {
@@ -2399,14 +2534,17 @@ var resolveRecordingClient = (client, opts) => {
2399
2534
  const canRecord = opts.account !== void 0 || credentials.kind === "account" || credentials.kind === "session";
2400
2535
  return { recordingClient, canRecord };
2401
2536
  };
2402
- var recordErrorFetchRun = async (client, opts, result) => {
2403
- if (opts.capabilityId === void 0) return;
2537
+ var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) => {
2538
+ const effectiveCapId = opts.capabilityId;
2539
+ if (effectiveCapId === void 0) return;
2404
2540
  const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
2405
2541
  if (!canRecord) return;
2542
+ const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : opts.fetchOrigin;
2406
2543
  try {
2407
2544
  const created = await recordingClient.runs.create({
2408
- capabilityId: opts.capabilityId,
2545
+ capabilityId: effectiveCapId,
2409
2546
  ...opts.searchId && { searchId: opts.searchId },
2547
+ ...fetchOriginForRecord && { fetchOrigin: fetchOriginForRecord },
2410
2548
  ...result.status !== null && { status: result.status },
2411
2549
  latencyMs: result.latencyMs,
2412
2550
  ...opts.requestSchema && { requestSchema: opts.requestSchema }
@@ -2416,7 +2554,7 @@ var recordErrorFetchRun = async (client, opts, result) => {
2416
2554
  } catch {
2417
2555
  }
2418
2556
  };
2419
- var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested) => {
2557
+ var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested, capabilityIdOverride) => {
2420
2558
  const result = errorFetchResult(
2421
2559
  startedAt,
2422
2560
  err.message,
@@ -2452,12 +2590,23 @@ var withDefaultContentType = (headers, body) => {
2452
2590
  var clientFetch = async (client, url, opts = {}) => {
2453
2591
  const startedAt = Date.now();
2454
2592
  const capabilityIdRequested = opts.capabilityId !== void 0;
2455
- const method = opts.method ?? (opts.body !== void 0 ? "POST" : "GET");
2456
- const probeHeaders = withDefaultContentType(opts.headers, opts.body);
2593
+ const normalized = normalizeTransportEnvelopeRequest(url, {
2594
+ method: opts.method,
2595
+ body: opts.body
2596
+ });
2597
+ const requestUrl = normalized.url;
2598
+ const requestBody = normalized.body;
2599
+ const method = normalized.method ?? (requestBody !== void 0 ? "POST" : "GET");
2600
+ const { canRecord: canRecordForResolve } = resolveRecordingClient(
2601
+ client,
2602
+ opts
2603
+ );
2604
+ const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl(requestUrl), method).catch(() => null) : Promise.resolve(null);
2605
+ const probeHeaders = withDefaultContentType(opts.headers, requestBody);
2457
2606
  const requestInit = {
2458
2607
  method,
2459
2608
  headers: probeHeaders,
2460
- body: opts.body,
2609
+ body: requestBody,
2461
2610
  signal: opts.signal
2462
2611
  };
2463
2612
  const configuredFetch = buildConfiguredFetch(client, {
@@ -2468,7 +2617,7 @@ var clientFetch = async (client, url, opts = {}) => {
2468
2617
  const skipReasons = [];
2469
2618
  const warnings = [];
2470
2619
  try {
2471
- response = await configuredFetch(url, requestInit);
2620
+ response = await configuredFetch(requestUrl, requestInit);
2472
2621
  } catch (err) {
2473
2622
  if (err instanceof ZeroTimeoutError) {
2474
2623
  await recordTimeoutRun(
@@ -2498,13 +2647,13 @@ var clientFetch = async (client, url, opts = {}) => {
2498
2647
  const payCall = requirement.protocol === "x402" ? client.payments.pay : client.payments.payMpp;
2499
2648
  try {
2500
2649
  const paid = await payCall({
2501
- url,
2650
+ url: requestUrl,
2502
2651
  method,
2503
2652
  // Fresh clone for the paid retry — same rationale as
2504
2653
  // the probe-side clone above. Re-derives the default
2505
2654
  // Content-Type so the paid leg matches the probe.
2506
- headers: withDefaultContentType(opts.headers, opts.body),
2507
- body: opts.body,
2655
+ headers: withDefaultContentType(opts.headers, requestBody),
2656
+ body: requestBody,
2508
2657
  maxPay: opts.maxPay,
2509
2658
  account: opts.account,
2510
2659
  signal: opts.signal,
@@ -2644,7 +2793,15 @@ var clientFetch = async (client, url, opts = {}) => {
2644
2793
  else if (closeFailed)
2645
2794
  skipReasons.push(FETCH_SKIP_REASONS.mppSessionCloseFailedNotRecorded);
2646
2795
  }
2647
- if (opts.capabilityId !== void 0 && !paidButStill402 && !closeFailed) {
2796
+ const resolvedCap = await resolvePromise;
2797
+ const effectiveCapabilityId = opts.capabilityId ?? resolvedCap?.capabilityId;
2798
+ const capabilityResolution = !capabilityIdRequested && canRecordForResolve ? resolvedCap !== null ? {
2799
+ resolved: true,
2800
+ capabilityId: resolvedCap.capabilityId,
2801
+ capabilitySlug: resolvedCap.capabilitySlug,
2802
+ matchedVia: resolvedCap.matchedVia
2803
+ } : { resolved: false } : void 0;
2804
+ if (effectiveCapabilityId !== void 0 && !paidButStill402 && !closeFailed) {
2648
2805
  const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
2649
2806
  if (!canRecord) {
2650
2807
  skipReasons.push("no_credentials");
@@ -2664,8 +2821,11 @@ var clientFetch = async (client, url, opts = {}) => {
2664
2821
  }
2665
2822
  }
2666
2823
  const result2 = await recordingClient.runs.create({
2667
- capabilityId: opts.capabilityId,
2824
+ capabilityId: effectiveCapabilityId,
2668
2825
  searchId: opts.searchId,
2826
+ // Auto-resolved runs are always direct_url — they only fire when
2827
+ // no capabilityId was supplied (the direct_url path by definition).
2828
+ ...opts.capabilityId === void 0 ? { fetchOrigin: "direct_url" } : opts.fetchOrigin && { fetchOrigin: opts.fetchOrigin },
2669
2829
  status: response.status,
2670
2830
  latencyMs,
2671
2831
  ...opts.requestSchema && { requestSchema: opts.requestSchema },
@@ -2698,7 +2858,7 @@ var clientFetch = async (client, url, opts = {}) => {
2698
2858
  message: "Failed to record run for fetch",
2699
2859
  meta: {
2700
2860
  url: redactUrl(url),
2701
- capabilityId: opts.capabilityId,
2861
+ capabilityId: effectiveCapabilityId,
2702
2862
  error: errorMessage2,
2703
2863
  errorCode: code
2704
2864
  }
@@ -2726,6 +2886,8 @@ var clientFetch = async (client, url, opts = {}) => {
2726
2886
  result.runTrackingSkipped = skipReasons;
2727
2887
  }
2728
2888
  if (warnings.length > 0) result.warnings = warnings;
2889
+ if (capabilityResolution !== void 0)
2890
+ result.capabilityResolution = capabilityResolution;
2729
2891
  return result;
2730
2892
  };
2731
2893
  var searchResultSchema = zod.z.object({
@@ -3165,9 +3327,13 @@ exports.ZeroSessionCloseFailedError = ZeroSessionCloseFailedError;
3165
3327
  exports.ZeroTimeoutError = ZeroTimeoutError;
3166
3328
  exports.ZeroValidationError = ZeroValidationError;
3167
3329
  exports.ZeroWalletError = ZeroWalletError;
3330
+ exports.asSchemaNode = asSchemaNode;
3168
3331
  exports.coerceTempoChainId = coerceTempoChainId;
3169
3332
  exports.createManagedAccount = createManagedAccount;
3333
+ exports.extractInputEnvelope = extractInputEnvelope;
3334
+ exports.normalizeTransportEnvelopeRequest = normalizeTransportEnvelopeRequest;
3170
3335
  exports.paymentHasAnchor = paymentHasAnchor;
3171
3336
  exports.tempoChainLabelFromId = tempoChainLabelFromId;
3172
- //# sourceMappingURL=chunk-5ZVIL7AZ.cjs.map
3173
- //# sourceMappingURL=chunk-5ZVIL7AZ.cjs.map
3337
+ exports.unwrapTransportEnvelope = unwrapTransportEnvelope;
3338
+ //# sourceMappingURL=chunk-UIK7QKNQ.cjs.map
3339
+ //# sourceMappingURL=chunk-UIK7QKNQ.cjs.map