@zeroxyz/sdk 0.5.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.
- package/CHANGELOG.md +14 -0
- package/README.md +12 -0
- package/dist/{chunk-RY3VFSIE.js → chunk-3YKWO4B2.js} +123 -12
- package/dist/chunk-3YKWO4B2.js.map +1 -0
- package/dist/{chunk-ED754B5U.cjs → chunk-UIK7QKNQ.cjs} +126 -11
- package/dist/chunk-UIK7QKNQ.cjs.map +1 -0
- package/dist/{client-BKAiYZYS.d.cts → client-CDk1PVU-.d.cts} +32 -1
- package/dist/{client-BKAiYZYS.d.ts → client-CDk1PVU-.d.ts} +32 -1
- package/dist/index.cjs +47 -31
- package/dist/index.d.cts +58 -3
- package/dist/index.d.ts +58 -3
- package/dist/index.js +1 -1
- package/dist/testing.cjs +2 -2
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-ED754B5U.cjs.map +0 -1
- package/dist/chunk-RY3VFSIE.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ 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.6.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Envelope-aware `client.fetch()` routing.** When a request body is Zero's HTTP-transport envelope (`{ input: { type:"http", method, queryParams, body } }` — how many caps store their request contract), `fetch()` now normalizes it into a real wire request: the verb is **carried** (explicit `method` → the envelope's `input.method` → body-presence, in that order) rather than inferred from body-presence, and a GET's `queryParams` are moved onto the URL query string with the body dropped. This stops the SDK from POSTing the ~6,614 indexed GET capabilities that store an MPP-style envelope on an x402 GET endpoint (which 404'd with "Cannot POST"). The envelope is never a wire format, so the normalization is unconditional and protocol-agnostic. (#677)
|
|
12
|
+
- New pure exports for envelope/schema handling, lifted out of the CLI so SDK-direct consumers get them too: `extractInputEnvelope`, `unwrapTransportEnvelope`, `normalizeTransportEnvelopeRequest`, `asSchemaNode`, and the `JsonSchemaNode` type. (#677)
|
|
13
|
+
- **`client.runs.get(runId)`** — fetch a single run's detail. New exports `RunDetail` and `runDetailSchema`. (#667)
|
|
14
|
+
|
|
15
|
+
## 0.5.0
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Direct-URL `client.fetch()` calls now record a run via a server-side URL→capability resolve, so a bare URL that missed the local cache is still attributable without the caller supplying a `capabilityId`. The resolve runs concurrently with the probe (no added latency) and is fail-open. (#558, ZERO-335)
|
|
20
|
+
|
|
7
21
|
## 0.4.0
|
|
8
22
|
|
|
9
23
|
### Added
|
package/README.md
CHANGED
|
@@ -104,6 +104,18 @@ Endpoints that don't charge pass straight through: a `200` on the first request
|
|
|
104
104
|
|
|
105
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.
|
|
106
106
|
|
|
107
|
+
**The HTTP-transport envelope.** Some capabilities store their request contract as Zero's HTTP-transport envelope — `{ input: { type: "http", method, queryParams, body } }` — rather than a bare body. You don't have to special-case it: `fetch()` detects an envelope body and normalizes it to the real wire request — it **carries the method** (from the envelope's `input.method`, never inferring `POST` from body-presence) and moves a `GET`'s `queryParams` onto the URL query string. So passing the envelope straight through works:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// A GET capability whose schema is the envelope — fetch() routes it to
|
|
111
|
+
// GET https://…/weather/current?city=tokyo (not a POST).
|
|
112
|
+
await client.fetch(cap.url, {
|
|
113
|
+
body: JSON.stringify({ input: { type: "http", method: "GET", queryParams: { city: "tokyo" } } }),
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If you'd rather inspect the schema yourself, the SDK exports the pure helpers it uses: `extractInputEnvelope(bodySchema, method)` (the query-param / body schema nodes), `unwrapTransportEnvelope(exampleRequest)` (the inner request from a stored example), and `normalizeTransportEnvelopeRequest(url, { method, body })` (the `{ url, method, body }` the wire request should use).
|
|
118
|
+
|
|
107
119
|
```ts
|
|
108
120
|
const result = await client.fetch(url, {
|
|
109
121
|
method: "POST",
|
|
@@ -126,6 +126,78 @@ var ZeroConfigurationError = class extends ZeroError {
|
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
+
// src/input-envelope.ts
|
|
130
|
+
var asSchemaNode = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
131
|
+
var extractInputEnvelope = (bodySchema, method) => {
|
|
132
|
+
const root = asSchemaNode(bodySchema);
|
|
133
|
+
if (!root) return {};
|
|
134
|
+
const props = asSchemaNode(root.properties);
|
|
135
|
+
if (!props) return {};
|
|
136
|
+
const inputProps = asSchemaNode(asSchemaNode(props.input)?.properties);
|
|
137
|
+
if (inputProps) {
|
|
138
|
+
return {
|
|
139
|
+
queryParams: asSchemaNode(inputProps.queryParams) ?? void 0,
|
|
140
|
+
body: asSchemaNode(inputProps.body) ?? void 0
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const upperMethod = method.toUpperCase();
|
|
144
|
+
const isGetLike = upperMethod === "GET" || upperMethod === "DELETE";
|
|
145
|
+
return isGetLike ? { queryParams: root } : { body: root };
|
|
146
|
+
};
|
|
147
|
+
var unwrapTransportEnvelope = (request2) => {
|
|
148
|
+
const input = asSchemaNode(asSchemaNode(request2)?.input);
|
|
149
|
+
if (!input || input.type !== "http") return request2;
|
|
150
|
+
const body = input.body;
|
|
151
|
+
const hasBody = body !== void 0 && body !== null && !(typeof body === "object" && Object.keys(body).length === 0);
|
|
152
|
+
if (hasBody) return body;
|
|
153
|
+
const qp = asSchemaNode(input.queryParams);
|
|
154
|
+
if (qp && Object.keys(qp).length > 0) return qp;
|
|
155
|
+
return null;
|
|
156
|
+
};
|
|
157
|
+
var GET_LIKE = /* @__PURE__ */ new Set(["GET", "HEAD", "DELETE"]);
|
|
158
|
+
var appendQueryParams = (url, params) => {
|
|
159
|
+
const entries = Object.entries(params).filter(([, v]) => v != null);
|
|
160
|
+
if (entries.length === 0) return url;
|
|
161
|
+
try {
|
|
162
|
+
const u = new URL(url);
|
|
163
|
+
for (const [k, v] of entries) u.searchParams.set(k, String(v));
|
|
164
|
+
return u.toString();
|
|
165
|
+
} catch {
|
|
166
|
+
const qs = entries.map(
|
|
167
|
+
([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
|
|
168
|
+
).join("&");
|
|
169
|
+
return url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
var normalizeTransportEnvelopeRequest = (url, opts) => {
|
|
173
|
+
const { method, body } = opts;
|
|
174
|
+
if (typeof body !== "string") return { url, method, body };
|
|
175
|
+
let parsed;
|
|
176
|
+
try {
|
|
177
|
+
parsed = JSON.parse(body);
|
|
178
|
+
} catch {
|
|
179
|
+
return { url, method, body };
|
|
180
|
+
}
|
|
181
|
+
const input = asSchemaNode(asSchemaNode(parsed)?.input);
|
|
182
|
+
if (!input || input.type !== "http") return { url, method, body };
|
|
183
|
+
const innerBody = input.body;
|
|
184
|
+
const hasInnerBody = innerBody !== void 0 && innerBody !== null && !(typeof innerBody === "object" && Object.keys(innerBody).length === 0);
|
|
185
|
+
const verb = (method ?? (typeof input.method === "string" ? input.method : void 0) ?? (hasInnerBody ? "POST" : "GET")).toUpperCase();
|
|
186
|
+
if (GET_LIKE.has(verb)) {
|
|
187
|
+
const qp = asSchemaNode(input.queryParams);
|
|
188
|
+
return {
|
|
189
|
+
url: qp ? appendQueryParams(url, qp) : url,
|
|
190
|
+
method: verb,
|
|
191
|
+
body: void 0
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
url,
|
|
196
|
+
method: verb,
|
|
197
|
+
body: hasInnerBody ? JSON.stringify(innerBody) : void 0
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
|
|
129
201
|
// src/chains/eip712.ts
|
|
130
202
|
var KNOWN_EIP712_DOMAINS = {
|
|
131
203
|
// Base mainnet USDC. On-chain `name()` is "USD Coin" (NOT "USDC")
|
|
@@ -1144,7 +1216,7 @@ var Payments = class {
|
|
|
1144
1216
|
|
|
1145
1217
|
// package.json
|
|
1146
1218
|
var package_default = {
|
|
1147
|
-
version: "0.
|
|
1219
|
+
version: "0.6.0"};
|
|
1148
1220
|
|
|
1149
1221
|
// src/version.ts
|
|
1150
1222
|
var SDK_VERSION = package_default.version;
|
|
@@ -1872,6 +1944,30 @@ var listRunsResponseSchema = z.object({
|
|
|
1872
1944
|
runs: z.array(runListItemSchema),
|
|
1873
1945
|
nextCursor: z.string().nullable()
|
|
1874
1946
|
});
|
|
1947
|
+
var runDetailSchema = z.object({
|
|
1948
|
+
runId: z.string(),
|
|
1949
|
+
status: z.number().nullable(),
|
|
1950
|
+
latencyMs: z.number().nullable(),
|
|
1951
|
+
errorClass: z.string().nullable(),
|
|
1952
|
+
createdAt: z.coerce.date(),
|
|
1953
|
+
cost: z.object({ amount: z.string(), asset: z.string().nullable() }).nullable(),
|
|
1954
|
+
payment: z.object({
|
|
1955
|
+
protocol: z.string(),
|
|
1956
|
+
chain: z.string().nullable(),
|
|
1957
|
+
txHash: z.string().nullable(),
|
|
1958
|
+
mode: z.string().nullable()
|
|
1959
|
+
}).nullable(),
|
|
1960
|
+
capability: z.object({
|
|
1961
|
+
uid: z.string(),
|
|
1962
|
+
slug: z.string(),
|
|
1963
|
+
name: z.string(),
|
|
1964
|
+
url: z.string(),
|
|
1965
|
+
method: z.string(),
|
|
1966
|
+
whatItDoes: z.string().nullable(),
|
|
1967
|
+
tags: z.array(z.string())
|
|
1968
|
+
}),
|
|
1969
|
+
reviewed: z.boolean()
|
|
1970
|
+
});
|
|
1875
1971
|
var createReviewResponseSchema = z.object({
|
|
1876
1972
|
reviewId: z.string(),
|
|
1877
1973
|
recorded: z.boolean(),
|
|
@@ -1953,6 +2049,15 @@ var Runs = class {
|
|
|
1953
2049
|
listRunsResponseSchema
|
|
1954
2050
|
);
|
|
1955
2051
|
};
|
|
2052
|
+
get = (runId, opts = {}) => request(
|
|
2053
|
+
this.client,
|
|
2054
|
+
{
|
|
2055
|
+
method: "GET",
|
|
2056
|
+
path: `/v1/runs/${runId}`,
|
|
2057
|
+
signal: opts.signal
|
|
2058
|
+
},
|
|
2059
|
+
runDetailSchema
|
|
2060
|
+
);
|
|
1956
2061
|
review = (input, opts = {}) => request(
|
|
1957
2062
|
this.client,
|
|
1958
2063
|
{
|
|
@@ -2483,17 +2588,23 @@ var withDefaultContentType = (headers, body) => {
|
|
|
2483
2588
|
var clientFetch = async (client, url, opts = {}) => {
|
|
2484
2589
|
const startedAt = Date.now();
|
|
2485
2590
|
const capabilityIdRequested = opts.capabilityId !== void 0;
|
|
2486
|
-
const
|
|
2591
|
+
const normalized = normalizeTransportEnvelopeRequest(url, {
|
|
2592
|
+
method: opts.method,
|
|
2593
|
+
body: opts.body
|
|
2594
|
+
});
|
|
2595
|
+
const requestUrl = normalized.url;
|
|
2596
|
+
const requestBody = normalized.body;
|
|
2597
|
+
const method = normalized.method ?? (requestBody !== void 0 ? "POST" : "GET");
|
|
2487
2598
|
const { canRecord: canRecordForResolve } = resolveRecordingClient(
|
|
2488
2599
|
client,
|
|
2489
2600
|
opts
|
|
2490
2601
|
);
|
|
2491
|
-
const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl(
|
|
2492
|
-
const probeHeaders = withDefaultContentType(opts.headers,
|
|
2602
|
+
const resolvePromise = !capabilityIdRequested && canRecordForResolve ? client.capabilities.resolveByUrl(redactUrl(requestUrl), method).catch(() => null) : Promise.resolve(null);
|
|
2603
|
+
const probeHeaders = withDefaultContentType(opts.headers, requestBody);
|
|
2493
2604
|
const requestInit = {
|
|
2494
2605
|
method,
|
|
2495
2606
|
headers: probeHeaders,
|
|
2496
|
-
body:
|
|
2607
|
+
body: requestBody,
|
|
2497
2608
|
signal: opts.signal
|
|
2498
2609
|
};
|
|
2499
2610
|
const configuredFetch = buildConfiguredFetch(client, {
|
|
@@ -2504,7 +2615,7 @@ var clientFetch = async (client, url, opts = {}) => {
|
|
|
2504
2615
|
const skipReasons = [];
|
|
2505
2616
|
const warnings = [];
|
|
2506
2617
|
try {
|
|
2507
|
-
response = await configuredFetch(
|
|
2618
|
+
response = await configuredFetch(requestUrl, requestInit);
|
|
2508
2619
|
} catch (err) {
|
|
2509
2620
|
if (err instanceof ZeroTimeoutError) {
|
|
2510
2621
|
await recordTimeoutRun(
|
|
@@ -2534,13 +2645,13 @@ var clientFetch = async (client, url, opts = {}) => {
|
|
|
2534
2645
|
const payCall = requirement.protocol === "x402" ? client.payments.pay : client.payments.payMpp;
|
|
2535
2646
|
try {
|
|
2536
2647
|
const paid = await payCall({
|
|
2537
|
-
url,
|
|
2648
|
+
url: requestUrl,
|
|
2538
2649
|
method,
|
|
2539
2650
|
// Fresh clone for the paid retry — same rationale as
|
|
2540
2651
|
// the probe-side clone above. Re-derives the default
|
|
2541
2652
|
// Content-Type so the paid leg matches the probe.
|
|
2542
|
-
headers: withDefaultContentType(opts.headers,
|
|
2543
|
-
body:
|
|
2653
|
+
headers: withDefaultContentType(opts.headers, requestBody),
|
|
2654
|
+
body: requestBody,
|
|
2544
2655
|
maxPay: opts.maxPay,
|
|
2545
2656
|
account: opts.account,
|
|
2546
2657
|
signal: opts.signal,
|
|
@@ -3188,6 +3299,6 @@ var ZeroClient = class _ZeroClient {
|
|
|
3188
3299
|
};
|
|
3189
3300
|
};
|
|
3190
3301
|
|
|
3191
|
-
export { Auth, 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_ID, TEMPO_TESTNET_CHAIN_ID, Wallet, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, coerceTempoChainId, createManagedAccount, paymentHasAnchor, tempoChainLabelFromId };
|
|
3192
|
-
//# sourceMappingURL=chunk-
|
|
3193
|
-
//# sourceMappingURL=chunk-
|
|
3302
|
+
export { Auth, 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_ID, TEMPO_TESTNET_CHAIN_ID, Wallet, ZeroApiError, ZeroAuthError, ZeroClient, ZeroConfigurationError, ZeroError, ZeroPaymentError, ZeroSessionCloseFailedError, ZeroTimeoutError, ZeroValidationError, ZeroWalletError, asSchemaNode, coerceTempoChainId, createManagedAccount, extractInputEnvelope, normalizeTransportEnvelopeRequest, paymentHasAnchor, tempoChainLabelFromId, unwrapTransportEnvelope };
|
|
3303
|
+
//# sourceMappingURL=chunk-3YKWO4B2.js.map
|
|
3304
|
+
//# sourceMappingURL=chunk-3YKWO4B2.js.map
|