@zeroxyz/sdk 0.2.0 → 0.3.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 +10 -0
- package/README.md +59 -5
- package/dist/{chunk-SLXRHGE4.js → chunk-FH6C6TXR.js} +10 -3
- package/dist/chunk-FH6C6TXR.js.map +1 -0
- package/dist/{chunk-LHS7KBN7.cjs → chunk-LVK77C6A.cjs} +10 -3
- package/dist/chunk-LVK77C6A.cjs.map +1 -0
- package/dist/{client-BpYZibrw.d.cts → client-CEC0IuN3.d.cts} +4 -0
- package/dist/{client-BpYZibrw.d.ts → client-CEC0IuN3.d.ts} +4 -0
- package/dist/index.cjs +31 -31
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- 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-LHS7KBN7.cjs.map +0 -1
- package/dist/chunk-SLXRHGE4.js.map +0 -1
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.3.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `SearchResult` now carries `method` (the capability's HTTP verb) and `brandName`. Both are already returned by the search API but were previously stripped by the SDK's response schema. Surfacing `method` lets a caller tell GET from POST straight from a search result — enough to `fetch()` a no-body GET without a `capabilities.get()` round-trip. Both fields are optional, so a response that omits them still parses. (#593)
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- Expanded the README with a **Wallet & funding** section (`wallet.balance()` / `wallet.fundingUrl()`), the full `FetchResult` shape, the `runId`-requires-`capabilityId` precondition, and search → get → fetch guidance. (#593)
|
|
16
|
+
|
|
7
17
|
## 0.2.0
|
|
8
18
|
|
|
9
19
|
### Changed
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ const client = new ZeroClient();
|
|
|
25
25
|
|
|
26
26
|
const { capabilities } = await client.search("current weather in tokyo");
|
|
27
27
|
for (const cap of capabilities) {
|
|
28
|
-
console.log(cap.id, cap.name, cap.url, cap.availabilityStatus);
|
|
28
|
+
console.log(cap.id, cap.name, cap.method, cap.url, cap.availabilityStatus);
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -102,6 +102,8 @@ 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.
|
|
106
|
+
|
|
105
107
|
```ts
|
|
106
108
|
const result = await client.fetch(url, {
|
|
107
109
|
method: "POST",
|
|
@@ -142,12 +144,65 @@ for (const warning of result.warnings ?? []) {
|
|
|
142
144
|
}
|
|
143
145
|
```
|
|
144
146
|
|
|
147
|
+
### The `FetchResult`
|
|
148
|
+
|
|
149
|
+
`fetch()` always resolves to one object — it doesn't reject for expected runtime failures (those come back as an `outcome`; see [Errors](#errors)). The full shape:
|
|
150
|
+
|
|
151
|
+
| Field | Type | Notes |
|
|
152
|
+
| --- | --- | --- |
|
|
153
|
+
| `outcome` | `FetchOutcome` | The closed enum above — branch on this first. |
|
|
154
|
+
| `ok` | `boolean` | `true` iff `status` is 2xx. Convenience for the HTTP-success check; `outcome === "success"` is the same signal at the payment-and-HTTP level. |
|
|
155
|
+
| `status` | `number \| null` | Upstream HTTP status; `null` if the request never reached the server. |
|
|
156
|
+
| `body` | `unknown` | Parsed JSON when the response is JSON, otherwise the text (base64 for binary). |
|
|
157
|
+
| `bodyRaw` | `string \| null` | The exact response text, for hashing/forwarding. `bodyEncoding: "base64"` is set when binary. |
|
|
158
|
+
| `payment` | `PaymentResult \| null` | `{ protocol, chain, txHash, amount, asset, … }` when a payment settled; `null` on a free call. |
|
|
159
|
+
| `runId` | `string \| null` | The recorded run, for `runs.review()`. **`null` unless you pass `capabilityId`** (and a wallet is configured). |
|
|
160
|
+
| `latencyMs` | `number` | End-to-end call latency. |
|
|
161
|
+
| `upstreamError` | `UpstreamError?` | Present on `server_error` — the capability's own 4xx/5xx detail. |
|
|
162
|
+
| `warnings` | `string[]?` | Non-fatal notes (truncated body, MPP close failure, …) — keyed by `FETCH_WARNINGS`. |
|
|
163
|
+
| `runTrackingSkipped` | `string[]?` | Why a run wasn't recorded (e.g. no `capabilityId`) — keyed by `FETCH_SKIP_REASONS`. |
|
|
164
|
+
|
|
165
|
+
`capabilityId` accepts the capability's `uid` (`cap_…`) or `slug` — i.e. the `id`/`slug` from a `search()` result or the `uid`/`slug` from `capabilities.get()`.
|
|
166
|
+
|
|
145
167
|
### `maxPay`
|
|
146
168
|
|
|
147
169
|
`maxPay` is your hard per-call ceiling, in USDC. The challenge amount is checked against it **before** anything is signed; an over-cap challenge aborts with `outcome: "payment_failed"` and no on-chain spend. Set it on every paid call — it's the guardrail that keeps a mispriced or hostile endpoint from draining the wallet.
|
|
148
170
|
|
|
149
171
|
To put a human in the loop before any spend, read the price up front (`cost.amount` is on every search result and on `capabilities.get()`), show it to your user, and only call `fetch()` with `maxPay` once they approve.
|
|
150
172
|
|
|
173
|
+
## Wallet & funding
|
|
174
|
+
|
|
175
|
+
The wallet you construct the client with **is** the agent's identity — paid calls draw USDC from it, and there are no per-service API keys to provision. Keeping it funded is the only operational task. Two funding models, both first-class:
|
|
176
|
+
|
|
177
|
+
- **Partner-funded shared wallet** *(the common default).* You hold one wallet on behalf of all your users, keep it topped up as a backend cost, and recoup it through your own billing. Per-user spend tracking and caps live in your app — `maxPay` is the per-call guard.
|
|
178
|
+
- **End-user top-up.** Each user funds the wallet directly; you surface a funding link when their balance runs low. Pairs with a per-user wallet.
|
|
179
|
+
|
|
180
|
+
The same two primitives serve both:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// The configured address (null in session mode until the first paid call resolves it).
|
|
184
|
+
client.wallet.address;
|
|
185
|
+
|
|
186
|
+
// Balance in USDC. Sums Base + Tempo by default; pass a chain for just one.
|
|
187
|
+
const { amount } = await client.wallet.balance(); // e.g. "12.50"
|
|
188
|
+
const onBase = await client.wallet.balance({ chain: "base" });
|
|
189
|
+
|
|
190
|
+
// A one-time hosted top-up link — Coinbase by default, or provider: "stripe".
|
|
191
|
+
// USDC settles on Base.
|
|
192
|
+
const url = await client.wallet.fundingUrl({ amount: "10" });
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Poll `balance()` to decide when to top up. Then either open `fundingUrl()` yourself to refill the shared wallet — from an ops dashboard, a low-balance alert, or alongside a direct USDC transfer to `wallet.address` — or hand the link to the end user. Either way the link is **single-use** and burns when opened, so generate it at the moment of funding and don't pre-open one you intend to give to someone else.
|
|
196
|
+
|
|
197
|
+
In **session mode** (acting for a Zero user) the wallet is Zero-managed, and a couple more methods apply:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
await client.wallet.list(); // every wallet linked to the session user
|
|
201
|
+
await client.wallet.provision(); // create the user's managed wallet (idempotent)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
To move funds from a user's own (BYO) wallet into their Zero-managed wallet, sign an EIP-3009 `ReceiveWithAuthorization` and relay it with `client.wallet.migrateAuthorization(authorization)` — Zero pays the gas and sweeps the USDC to Base.
|
|
205
|
+
|
|
151
206
|
## Namespaces
|
|
152
207
|
|
|
153
208
|
Beyond `search()` and `fetch()`, the client groups the rest of the API into resource namespaces:
|
|
@@ -162,10 +217,9 @@ const { capabilities } = await client.search("translate text to french", {
|
|
|
162
217
|
// Capabilities — full detail for one capability by id
|
|
163
218
|
const cap = await client.capabilities.get("cap_abc");
|
|
164
219
|
|
|
165
|
-
// Wallet
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
const fundUrl = await client.wallet.fundingUrl({ amount: "10" }); // onramp link
|
|
220
|
+
// Wallet — balance + one-time funding URL. See "Wallet & funding" above.
|
|
221
|
+
const { amount } = await client.wallet.balance();
|
|
222
|
+
const fundUrl = await client.wallet.fundingUrl({ amount: "10" });
|
|
169
223
|
|
|
170
224
|
// Runs — fetch() records these for you on paid calls; reach for them
|
|
171
225
|
// directly when you want to log or review a call yourself
|
|
@@ -1098,7 +1098,7 @@ var Payments = class {
|
|
|
1098
1098
|
|
|
1099
1099
|
// package.json
|
|
1100
1100
|
var package_default = {
|
|
1101
|
-
version: "0.
|
|
1101
|
+
version: "0.3.0"};
|
|
1102
1102
|
|
|
1103
1103
|
// src/version.ts
|
|
1104
1104
|
var SDK_VERSION = package_default.version;
|
|
@@ -2677,8 +2677,15 @@ var searchResultSchema = z.object({
|
|
|
2677
2677
|
slug: z.string(),
|
|
2678
2678
|
name: z.string(),
|
|
2679
2679
|
canonicalName: z.string().nullable().optional(),
|
|
2680
|
+
brandName: z.string().nullable().optional(),
|
|
2680
2681
|
description: z.string(),
|
|
2681
2682
|
whatItDoes: z.string().nullable().optional(),
|
|
2683
|
+
// HTTP verb the capability expects. Surfaced on the search row so a caller
|
|
2684
|
+
// can tell GET from POST without a `capabilities.get()` round-trip — enough
|
|
2685
|
+
// to `fetch()` a no-body GET directly. POST bodies still need `get()` for
|
|
2686
|
+
// the `bodySchema`. Optional (not required) so a response that omits it —
|
|
2687
|
+
// an older API deploy — still parses rather than failing the whole search.
|
|
2688
|
+
method: z.string().optional(),
|
|
2682
2689
|
url: z.string(),
|
|
2683
2690
|
urlTemplate: z.string().nullable().optional(),
|
|
2684
2691
|
cost: z.object({ amount: z.string(), asset: z.string() }),
|
|
@@ -3076,5 +3083,5 @@ var ZeroClient = class _ZeroClient {
|
|
|
3076
3083
|
};
|
|
3077
3084
|
|
|
3078
3085
|
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 };
|
|
3079
|
-
//# sourceMappingURL=chunk-
|
|
3080
|
-
//# sourceMappingURL=chunk-
|
|
3086
|
+
//# sourceMappingURL=chunk-FH6C6TXR.js.map
|
|
3087
|
+
//# sourceMappingURL=chunk-FH6C6TXR.js.map
|