@zeroxyz/sdk 0.11.0 → 0.12.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/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ All notable changes to `@zeroxyz/sdk` will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — with the pre-1.0 caveat that minor versions may include breaking changes.
6
6
 
7
+ ## 0.12.0
8
+
9
+ ### Added
10
+
11
+ - **`exampleRequest` on capability responses** (`capabilities.get()`) — the bare, ready-to-send request body an agent should copy: `.request` unwrapped from the stored `{request,response}` transcript **and** the HTTP-transport envelope, validated against the current `bodySchema`. `null` when there's no usable example or the stored one is stale (missing a now-required field); the raw `example` is retained for the response sample. Prefer `exampleRequest` over `example` when building a fetch body. (ZERO-393, #757)
12
+
13
+ ### Fixed
14
+
15
+ - **MPP session close honors a metered zero receipt** — a no-result metered call now closes the channel at `$0` instead of throwing an orphan `close-failed`. An ambiguous zero close (no explicit metered receipt) still refuses, as before. (#761)
16
+
7
17
  ## 0.11.0
8
18
 
9
19
  ### Added
package/README.md CHANGED
@@ -102,7 +102,7 @@ The SDK refreshes the access token automatically after a `401`, and every refres
102
102
 
103
103
  Endpoints that don't charge pass straight through: a `200` on the first request returns with `payment: null` and `outcome: "success"`. No payment is attempted.
104
104
 
105
- **Building the request — search → get → fetch.** A `search()` result carries the `url` and `method`, so a no-body `GET` capability can go straight to `fetch()`. For anything that takes a request body, call `capabilities.get()` first: its `bodySchema`, `method`, and `headers` are what tell you how to construct the call. Don't guess the body from the search summary.
105
+ **Building the request — search → get → fetch.** A `search()` result carries the `url` and `method`, so a no-body `GET` capability can go straight to `fetch()`. For anything that takes a request body, call `capabilities.get()` first: its `bodySchema`, `method`, and `headers` are what tell you how to construct the call. Don't guess the body from the search summary. When present, **`exampleRequest`** is the single best artifact to copy — the bare, ready-to-send request body from a real successful call, already unwrapped from the stored transcript and validated against the current schema (it's `null` when there's no example or the stored one is stale, so fall back to `bodySchema`). The raw `example` (`{ request, response }`) is retained for the response sample.
106
106
 
107
107
  Each search result also carries a `token` field (format: `z_xxx.N`) — a short server-issued attribution token that encodes the search context and the result's position. Pass it as `capabilityId` to `fetch()` (or as the `id` to `capabilities.get()`) instead of the raw uid/slug; the server uses it to attribute the run back to the originating search for ranking and analytics. Tokens expire when the session rolls, so use them within the same search session.
108
108
 
@@ -589,6 +589,7 @@ var pickSessionCloseAmount = (receipt, openTimeCumulative) => {
589
589
  if (receipt.metered === true) return fromReceipt;
590
590
  return fromReceipt > openTimeCumulative ? fromReceipt : openTimeCumulative;
591
591
  };
592
+ var isMeteredZeroReceipt = (receipt) => receipt?.metered === true && BigInt(receipt.acceptedCumulative) === 0n && BigInt(receipt.spent) === 0n;
592
593
  var raceWithSignal = (p, signal, client) => {
593
594
  if (!signal) return p;
594
595
  if (signal.aborted) {
@@ -1162,7 +1163,7 @@ var Payments = class {
1162
1163
  }
1163
1164
  const receipt = readSessionReceipt(response);
1164
1165
  let closeAmount = pickSessionCloseAmount(receipt, openTimeCumulative);
1165
- if (closeAmount === 0n && channelEntry.cumulativeAmount > 0n) {
1166
+ if (closeAmount === 0n && channelEntry.cumulativeAmount > 0n && !isMeteredZeroReceipt(receipt)) {
1166
1167
  closeAmount = channelEntry.cumulativeAmount;
1167
1168
  }
1168
1169
  const reconcileAmount = receipt && isUintString(receipt.acceptedCumulative) ? receipt.acceptedCumulative : closeAmount.toString();
@@ -1179,7 +1180,7 @@ var Payments = class {
1179
1180
  capturedAmount,
1180
1181
  cause
1181
1182
  });
1182
- if (closeAmount === 0n) {
1183
+ if (closeAmount === 0n && !isMeteredZeroReceipt(receipt)) {
1183
1184
  throw closeFailed(
1184
1185
  `Refusing to sign zero close credential for channel ${channelId} \u2014 neither receipt nor channelEntry produced a nonzero cumulativeAmount. Query escrow directly to recover; check logger for an earlier 'non-bigint cumulativeAmount' warning.`
1185
1186
  );
@@ -1950,7 +1951,7 @@ var clientFetch = async (client, url, opts = {}) => {
1950
1951
 
1951
1952
  // package.json
1952
1953
  var package_default = {
1953
- version: "0.11.0"};
1954
+ version: "0.12.0"};
1954
1955
 
1955
1956
  // src/version.ts
1956
1957
  var SDK_VERSION = package_default.version;
@@ -2840,6 +2841,12 @@ var capabilityResponseSchema = z.object({
2840
2841
  bodySchema: z.record(z.string(), z.unknown()).nullable(),
2841
2842
  responseSchema: z.record(z.string(), z.unknown()).nullable(),
2842
2843
  example: z.object({ request: z.unknown(), response: z.unknown() }).nullable(),
2844
+ // The bare, schema-validated request body to send — `.request` unwrapped
2845
+ // from the transcript envelope and checked against the current bodySchema.
2846
+ // Null when there's no usable example or it's stale vs the schema; `example`
2847
+ // is retained for the response sample. Optional for back-compat with older
2848
+ // servers that don't emit it.
2849
+ exampleRequest: z.record(z.string(), z.unknown()).nullable().optional(),
2843
2850
  tags: z.array(z.string()).nullable(),
2844
2851
  exampleAgentPrompt: z.string().nullable().optional(),
2845
2852
  whatItDoes: z.string().nullable().optional(),
@@ -3787,5 +3794,5 @@ var ZeroClient = class _ZeroClient {
3787
3794
  };
3788
3795
 
3789
3796
  export { Auth, AuthAgent, AuthDevice, BUG_REPORT_CATEGORIES, BugReports, Capabilities, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, FETCH_SKIP_REASONS, FETCH_WARNINGS, Payments, Runs, SDK_VERSION, TEMPO_CHAIN_ID2 as TEMPO_CHAIN_ID, TEMPO_TESTNET_CHAIN_ID, USDC_BASE, USDC_DECIMALS, USDC_TEMPO, Wallet, ZeroAgentAuthError, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, isShortToken, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope };
3790
- //# sourceMappingURL=chunk-T77VVLOM.js.map
3791
- //# sourceMappingURL=chunk-T77VVLOM.js.map
3797
+ //# sourceMappingURL=chunk-KDWESC42.js.map
3798
+ //# sourceMappingURL=chunk-KDWESC42.js.map