@absol-labs/agent 0.7.3 → 0.9.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.
Files changed (80) hide show
  1. package/README.md +19 -4
  2. package/dist/discovery/registry.d.ts +110 -305
  3. package/dist/discovery/registry.d.ts.map +1 -1
  4. package/dist/discovery/registry.js +141 -318
  5. package/dist/discovery/registry.js.map +1 -1
  6. package/dist/frameworks/agentkit.d.ts.map +1 -1
  7. package/dist/frameworks/agentkit.js +23 -6
  8. package/dist/frameworks/agentkit.js.map +1 -1
  9. package/dist/gateway/caller-auth-gateway.d.ts +103 -2
  10. package/dist/gateway/caller-auth-gateway.d.ts.map +1 -1
  11. package/dist/gateway/caller-auth-gateway.js +176 -19
  12. package/dist/gateway/caller-auth-gateway.js.map +1 -1
  13. package/dist/gateway/http-server.d.ts +12 -0
  14. package/dist/gateway/http-server.d.ts.map +1 -1
  15. package/dist/gateway/http-server.js +45 -1
  16. package/dist/gateway/http-server.js.map +1 -1
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +3 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/wallet/autonomous-wallet-store.d.ts +123 -0
  22. package/dist/wallet/autonomous-wallet-store.d.ts.map +1 -0
  23. package/dist/wallet/autonomous-wallet-store.js +318 -0
  24. package/dist/wallet/autonomous-wallet-store.js.map +1 -0
  25. package/dist/wallet/autonomous-wallet.d.ts +14 -39
  26. package/dist/wallet/autonomous-wallet.d.ts.map +1 -1
  27. package/dist/wallet/autonomous-wallet.js +12 -145
  28. package/dist/wallet/autonomous-wallet.js.map +1 -1
  29. package/dist/wallet/cdp-sdk.d.ts +23 -0
  30. package/dist/wallet/cdp-sdk.d.ts.map +1 -0
  31. package/dist/wallet/cdp-sdk.js +27 -0
  32. package/dist/wallet/cdp-sdk.js.map +1 -0
  33. package/dist/wallet/encrypted-file-credential-store.d.ts +41 -0
  34. package/dist/wallet/encrypted-file-credential-store.d.ts.map +1 -0
  35. package/dist/wallet/encrypted-file-credential-store.js +221 -0
  36. package/dist/wallet/encrypted-file-credential-store.js.map +1 -0
  37. package/dist/wallet/provider.d.ts +1 -1
  38. package/dist/wallet/provider.d.ts.map +1 -1
  39. package/dist/wallet/provider.js +8 -3
  40. package/dist/wallet/provider.js.map +1 -1
  41. package/dist/wallet/secret-service-probe.d.ts +56 -0
  42. package/dist/wallet/secret-service-probe.d.ts.map +1 -0
  43. package/dist/wallet/secret-service-probe.js +407 -0
  44. package/dist/wallet/secret-service-probe.js.map +1 -0
  45. package/dist/zktls/reclaim-js-sdk.d.ts +24 -0
  46. package/dist/zktls/reclaim-js-sdk.d.ts.map +1 -0
  47. package/dist/zktls/reclaim-js-sdk.js +29 -0
  48. package/dist/zktls/reclaim-js-sdk.js.map +1 -0
  49. package/dist/zktls/reclaim.d.ts +14 -2
  50. package/dist/zktls/reclaim.d.ts.map +1 -1
  51. package/dist/zktls/reclaim.js +29 -6
  52. package/dist/zktls/reclaim.js.map +1 -1
  53. package/dist/zktls/t2-delivery-proof.d.ts +8 -1
  54. package/dist/zktls/t2-delivery-proof.d.ts.map +1 -1
  55. package/dist/zktls/t2-delivery-proof.js +22 -6
  56. package/dist/zktls/t2-delivery-proof.js.map +1 -1
  57. package/docs/agent-layer.md +150 -0
  58. package/docs/autonomous-privy-wallet.md +133 -0
  59. package/docs/crewai.md +70 -0
  60. package/docs/eliza.md +109 -0
  61. package/docs/langchain.md +63 -0
  62. package/docs/mcp-hosted.md +137 -0
  63. package/docs/privy-embedded-wallet.md +102 -0
  64. package/docs/quickstart.md +370 -0
  65. package/docs/threat-model.md +160 -0
  66. package/package.json +19 -6
  67. package/src/discovery/registry.ts +242 -414
  68. package/src/frameworks/agentkit.ts +24 -5
  69. package/src/gateway/caller-auth-gateway.ts +281 -15
  70. package/src/gateway/http-server.ts +64 -0
  71. package/src/index.ts +24 -0
  72. package/src/wallet/autonomous-wallet-store.ts +487 -0
  73. package/src/wallet/autonomous-wallet.ts +57 -224
  74. package/src/wallet/cdp-sdk.ts +33 -0
  75. package/src/wallet/encrypted-file-credential-store.ts +341 -0
  76. package/src/wallet/provider.ts +16 -9
  77. package/src/wallet/secret-service-probe.ts +487 -0
  78. package/src/zktls/reclaim-js-sdk.ts +50 -0
  79. package/src/zktls/reclaim.ts +57 -23
  80. package/src/zktls/t2-delivery-proof.ts +28 -10
package/README.md CHANGED
@@ -74,7 +74,9 @@ For a fresh autonomous agent, the default headless path is
74
74
  stores it in the host OS credential manager, and asks the public Metrik broker to create a
75
75
  policy-bound Privy EOA owned by that key. No Privy secret, OTP, browser, clipboard, or
76
76
  plaintext key file is required, and every later write is signed locally over the exact
77
- prepared Privy request. See
77
+ prepared Privy request. Provisioning refuses a credential store that would not survive a
78
+ host reboot — including the Linux kernel keyring a headless host silently falls back to —
79
+ and ships `EncryptedFileCredentialStore` as the durable headless option. See
78
80
  [`docs/autonomous-privy-wallet.md`](./docs/autonomous-privy-wallet.md). The authenticated
79
81
  user-owned Privy flow remains available as an optional recoverable mode.
80
82
 
@@ -288,7 +290,9 @@ await server.listen(8787);
288
290
  Or run the ready-made standalone server from env (`METRIK_GATEWAY_ESCROW_ADDRESS`,
289
291
  `METRIK_GATEWAY_RPC_URL`, `METRIK_GATEWAY_SERVICE_REF`, `METRIK_GATEWAY_UPSTREAM_URL`,
290
292
  optional comma-separated `METRIK_GATEWAY_SERVICE_REFS` migration aliases,
291
- optional `METRIK_GATEWAY_CHAIN_ID` / `METRIK_GATEWAY_PORT` / `METRIK_GATEWAY_HOST`):
293
+ optional `METRIK_GATEWAY_CHAIN_ID` / `METRIK_GATEWAY_PORT` / `METRIK_GATEWAY_HOST`,
294
+ optional `METRIK_GATEWAY_CORROBORATING_RPC_URLS` /
295
+ `METRIK_GATEWAY_MAX_STATE_STALENESS_SECONDS`):
292
296
 
293
297
  ```bash
294
298
  pnpm gateway
@@ -298,8 +302,19 @@ Every request must carry a valid capability; every failure mode (missing header,
298
302
  signature, wrong buyer, closed/expired/underfunded stream, replayed nonce, wrong
299
303
  method/path, wrong `serviceRef`) is rejected with a distinct machine-readable `reason`
300
304
  and a `402`/`403` - the real upstream is never touched on a rejection. Access is revoked
301
- automatically: once a stream is closed, expired, or reclaimed, the next on-chain read
302
- fails closed with no extra bookkeeping.
305
+ automatically: once a stream is closed, expired, or reclaimed, the on-chain read fails
306
+ closed with no extra bookkeeping.
307
+
308
+ Stream state is never trusted from a single unverified view. Every configured RPC view is
309
+ read per request (in parallel, at most one read each) and a request is authorized only if
310
+ **every** view authorizes - so a stale view cannot keep serving a stream the buyer just
311
+ closed. A view reporting a chain head older than
312
+ `METRIK_GATEWAY_MAX_STATE_STALENESS_SECONDS` (default 30) is rejected outright
313
+ (`stream-state-stale`), and because `close`/expiry/full-claim are irreversible on-chain,
314
+ an observed terminal state is remembered for the process lifetime - a later stale
315
+ `active` read can never re-authorize. Set
316
+ `METRIK_GATEWAY_CORROBORATING_RPC_URLS` to one or more **independent** providers to
317
+ collapse the post-close window to the freshest of them.
303
318
 
304
319
  **Buyer side** - after `hireVerifiedService`/`open()`, call the purchased service
305
320
  directly:
@@ -1,28 +1,44 @@
1
- import { type SignedServiceBinding, type SignedServiceDescriptor } from "@absol-labs/shared";
1
+ import { RegistryUnavailableError, type DiscoverResult, type DiscoveredService } from "@absol-labs/sdk";
2
+ import type { SignedServiceBinding, SignedServiceDescriptor } from "@absol-labs/shared";
2
3
  /**
3
4
  * Service discovery for the Metrik verified-service marketplace.
4
5
  *
5
- * Before this module every agent surface (SDK, MCP, framework tools) assumed the
6
- * caller already knew a seller's `operator` + `serviceRef`. There was no way to
7
- * DISCOVER a service. {@link discoverServices} closes that gap: it reads the same
8
- * Supabase `listings` registry the oracle reads and returns typed, VERIFIED
9
- * listings an agent can hire directly.
6
+ * ## One implementation, two shapes
7
+ * The verification and transport logic lives in ONE place: `@absol-labs/sdk`'s
8
+ * {@link sdkDiscoverServices}. This module is a thin, documented adapter over it
9
+ * that projects the SDK's richer {@link DiscoveredService} onto the agent layer's
10
+ * {@link ServiceListing}. Previously both packages shipped their own
11
+ * `discoverServices` with different defaults and OPPOSITE failure semantics —
12
+ * the SDK threw on an unreachable registry while this one silently returned a
13
+ * hardcoded listing. There is now a single trust decision, a single default
14
+ * endpoint, and a single error type ({@link RegistryUnavailableError}) across
15
+ * both packages. Need the SDK's full result (tier, verification summary,
16
+ * `registryAvailable`, `source`, filter notes)? Call
17
+ * {@link discoverServicesDetailed}, which returns it verbatim.
10
18
  *
11
- * ## Fail-closed trust model
12
- * The security-critical envelope lives entirely inside each row's `signed_binding`
13
- * (`{ binding, signature, serviceRef, targetMetadata }`). The flat `service_ref` /
14
- * `operator` / `public_url` columns are UNSIGNED denormalised copies for querying
15
- * only never trusted. A row is DROPPED (and logged) unless BOTH hold:
16
- * 1. its EIP-712 signature recovers to `binding.operator`; and
17
- * 2. `deriveServiceRef(binding)` equals the envelope's own `serviceRef`.
18
- * `discoverServices` therefore NEVER returns an unverifiable listing.
19
+ * ## Zero configuration
20
+ * The default read source is {@link DEFAULT_METRIK_PUBLIC_REGISTRY_URL} the
21
+ * oracle's public, credential-free, CORS-enabled listings endpoint. A
22
+ * third-party developer needs no Supabase key and no configuration. (The old
23
+ * default was a raw Supabase PostgREST URL that `401`s for anyone without
24
+ * Metrik's anon key.)
19
25
  *
20
- * The unsigned `category` column is carried through as informational metadata only
21
- * (used for the optional client-side category filter); it is never part of the
22
- * trust decision.
26
+ * ## Untrusted transport
27
+ * The oracle is a TRANSPORT, not an authority. Every row it serves is treated as
28
+ * an untrusted envelope: schema-validated, its `serviceRef` re-derived from the
29
+ * signed content, and its operator EIP-712 signature recovered and matched.
30
+ * Anything that fails is DROPPED, so a compromised registry or oracle can
31
+ * neither inject a listing nor redirect an invocation URL. Rows dropped this way
32
+ * are reported through {@link DiscoverServicesOptions.logger}.
33
+ *
34
+ * ## Loud failure
35
+ * An unreachable registry throws {@link RegistryUnavailableError}. It never
36
+ * degrades to embedded seed data: a hardcoded listing outlives the service it
37
+ * points at and cannot be revoked without a release, and a caller that reads
38
+ * "one service" and invokes it has been actively misled.
23
39
  */
24
40
  /** A verified, hireable service listing. `serviceRef`/`operator`/`publicUrl` are
25
- * derived from the SIGNED binding, not the unsigned flat columns. */
41
+ * derived from the SIGNED record, never from unsigned envelope columns. */
26
42
  export interface ServiceListing {
27
43
  readonly serviceRef: `0x${string}`;
28
44
  readonly operator: `0x${string}`;
@@ -32,25 +48,47 @@ export interface ServiceListing {
32
48
  readonly accessUrl: string;
33
49
  /** The schema-validated and cryptographically verified signed record. */
34
50
  readonly signed: SignedServiceBinding | SignedServiceDescriptor;
35
- /** Unsigned informational category from the listings row (may be absent). */
51
+ /** Unsigned informational category from the registry row (may be absent). */
36
52
  readonly category: string | null;
37
- /** Optional unsigned operator-supplied resolver hints; never used for invocation. */
53
+ /**
54
+ * @deprecated No longer populated. The signed-record schema is strict, and the
55
+ * public discovery endpoint carries no unsigned resolver hints. Retained so
56
+ * existing code compiles.
57
+ */
38
58
  readonly targetMetadata?: Record<string, string>;
39
59
  }
40
60
  export interface DiscoverServicesOptions {
41
- /** Registry endpoint. Defaults to {@link DEFAULT_METRIK_REGISTRY_URL} (env override:
42
- * `METRIK_AGENT_REGISTRY_URL`). Pass the full PostgREST `?select=...&order=...` URL. */
61
+ /**
62
+ * Registry endpoint. Defaults to {@link DEFAULT_METRIK_PUBLIC_REGISTRY_URL}
63
+ * (env override: `METRIK_AGENT_REGISTRY_URL`).
64
+ *
65
+ * With no {@link DiscoverServicesOptions.apiKey} this is read as a plain
66
+ * credential-free `GET` against exactly this URL.
67
+ *
68
+ * With an `apiKey` it is read as Supabase/PostgREST, and this must be either a
69
+ * project base URL (`https://<ref>.supabase.co`, to which `/rest/v1/listings`
70
+ * is appended) or a URL already ending in `/rest/v1` or `/rest/v1/listings`.
71
+ * Any query string is stripped — the SDK appends its own `select`/`order`.
72
+ * Supplying an `apiKey` without setting this explicitly is a configuration
73
+ * error and throws: the public default is not a PostgREST base, and silently
74
+ * appending to it would produce a 404 on every read.
75
+ */
43
76
  readonly registryUrl?: string;
44
- /** Append the built-in {@link DEMO_SEED_LISTING} when the registry does not already
45
- * surface it (empty / unreachable / 401 / just missing), so a zero-config newcomer
46
- * still discovers one hireable, verified service. The seed is NOT trusted blindly —
47
- * it flows through the SAME fail-closed {@link verifyRow} path as any registry row.
48
- * Defaults to `true`. Pass `false` to get only what the registry itself returns. */
77
+ /**
78
+ * @deprecated No-op. Discovery no longer ships an embedded seed listing: an
79
+ * unreachable registry throws {@link RegistryUnavailableError} instead of
80
+ * quietly serving stale local data.
81
+ */
49
82
  readonly includeDemoSeed?: boolean;
50
- /** PostgREST apikey (Supabase anon key). Env override: `METRIK_AGENT_REGISTRY_APIKEY`.
51
- * Sent as both the `apikey` header and `Authorization: Bearer`. */
83
+ /** PostgREST apikey (Supabase anon key) for an authenticated read. Env override:
84
+ * `METRIK_AGENT_REGISTRY_APIKEY`. Not required the default endpoint is public. */
52
85
  readonly apiKey?: string;
53
- /** Optional client-side filter on the unsigned `category` column. */
86
+ /**
87
+ * Optional filter on the unsigned `category` column (case-insensitive).
88
+ * The public discovery endpoint serves signed records only and carries no
89
+ * category column, so this filter matches nothing there; use it against an
90
+ * authenticated PostgREST read.
91
+ */
54
92
  readonly category?: string;
55
93
  /** Optional cap on the number of verified listings returned. */
56
94
  readonly limit?: number;
@@ -58,295 +96,62 @@ export interface DiscoverServicesOptions {
58
96
  readonly fetch?: typeof fetch;
59
97
  /** Request timeout in milliseconds. Defaults to 5000. */
60
98
  readonly timeoutMs?: number;
61
- /** Warning sink for dropped rows / registry failures. Defaults to `console`. */
99
+ /** Warning sink for dropped rows / filter notes. Defaults to `console`. */
62
100
  readonly logger?: {
63
101
  warn: (...args: unknown[]) => void;
64
102
  };
65
103
  }
66
104
  /**
67
- * Default Metrik listings registry (Supabase PostgREST). Selects the columns the
68
- * oracle and the agent both need and orders newest-first.
105
+ * The oracle's public, credential-free, CORS-enabled discovery endpoint. Serves
106
+ * operator-signed envelopes verbatim so they can be verified client-side, and
107
+ * answers an unreachable upstream with `503` and NO `listings` key — precisely so
108
+ * it cannot be misread as "zero services".
109
+ */
110
+ export declare const DEFAULT_METRIK_PUBLIC_REGISTRY_URL = "https://oracle.metrik.live/listings";
111
+ /**
112
+ * @deprecated Renamed to {@link DEFAULT_METRIK_PUBLIC_REGISTRY_URL}. The value
113
+ * changed in 0.9.0: it used to be a raw Supabase PostgREST URL that `401`s
114
+ * without Metrik's anon key.
69
115
  */
70
- export declare const DEFAULT_METRIK_REGISTRY_URL = "https://pzvnacjolaipeobmptsb.supabase.co/rest/v1/listings?select=service_ref,operator,public_url,category,signed_binding&order=created_at.desc";
116
+ export declare const DEFAULT_METRIK_REGISTRY_URL = "https://oracle.metrik.live/listings";
71
117
  /**
72
- * `serviceRef` of the built-in verified live-data listing. Kept as a named constant so
73
- * callers can recognise (and dedupe against) the seeded row.
118
+ * @deprecated Removed in 0.9.0. The embedded seed listing is gone: it was
119
+ * unrevocable without a release, and masking an unreachable registry with stale
120
+ * local data is exactly the bug this package now refuses to ship. Kept as an
121
+ * empty object so existing imports still compile.
74
122
  */
75
- export declare const LIVE_DATA_SEED_SERVICE_REF: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
76
- /** @deprecated Use {@link LIVE_DATA_SEED_SERVICE_REF}. */
77
- export declare const DEMO_SEED_SERVICE_REF: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
123
+ export declare const LIVE_DATA_SEED_LISTING: Record<string, never>;
124
+ /** @deprecated Removed in 0.9.0. See {@link LIVE_DATA_SEED_LISTING}. */
125
+ export declare const DEMO_SEED_LISTING: Record<string, never>;
126
+ /** @deprecated Removed in 0.9.0. There is no seeded listing to identify. */
127
+ export declare const LIVE_DATA_SEED_SERVICE_REF: null;
128
+ /** @deprecated Removed in 0.9.0. See {@link LIVE_DATA_SEED_SERVICE_REF}. */
129
+ export declare const DEMO_SEED_SERVICE_REF: null;
130
+ export { RegistryUnavailableError };
131
+ export type { DiscoverResult, DiscoveredService };
78
132
  /**
79
- * A real, operator-signed live-data listing row embedded so `discoverServices()` returns
80
- * something hireable with ZERO configuration (no Supabase anon key, no registry URL).
133
+ * Discover verified services and return the SDK's full {@link DiscoverResult}
134
+ * (typed listings plus `registryAvailable`, `source`, `matched`, `filteredOut`
135
+ * and an explanatory `note` when a non-empty source was filtered to nothing).
81
136
  *
82
- * This is PUBLIC data a signed {@link https://github.com/Absol-Labs | Metrik}
83
- * ServiceBinding safe to ship in source. It is **NOT** a trust bypass: when seeded
84
- * it is fed through the exact same fail-closed {@link verifyRow} path as any registry
85
- * row, so it only ever surfaces if BOTH its EIP-712 signature recovers to
86
- * `binding.operator` AND `deriveServiceRef(binding)` equals its `serviceRef`. Tamper
87
- * with any field here and the seed silently drops itself, identically to a bad
88
- * registry row. The `category` column is unsigned informational metadata only.
137
+ * Throws {@link RegistryUnavailableError} when the configured read source cannot
138
+ * be read at all.
89
139
  */
90
- export declare const LIVE_DATA_SEED_LISTING: {
91
- readonly service_ref: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
92
- readonly operator: "0xB3e162711920dFD8933609019Dc35C73cC1a09F0";
93
- readonly public_url: "https://livedata.137.23.50.249.sslip.io";
94
- readonly category: "live-data";
95
- readonly signed_binding: {
96
- readonly serviceRef: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
97
- readonly descriptor: {
98
- readonly version: 3;
99
- readonly operator: "0xB3e162711920dFD8933609019Dc35C73cC1a09F0";
100
- readonly publicUrl: "https://livedata.137.23.50.249.sslip.io";
101
- readonly issuedAt: 1787772057;
102
- readonly interface: {
103
- readonly baseUrl: "https://livedata.137.23.50.249.sslip.io";
104
- readonly healthPath: "/health";
105
- readonly endpoints: readonly [{
106
- readonly name: "health";
107
- readonly path: "/health";
108
- readonly method: "GET";
109
- readonly description: "Liveness probe.";
110
- }, {
111
- readonly name: "readiness";
112
- readonly path: "/readiness";
113
- readonly method: "GET";
114
- readonly description: "Non-value dependency readiness backed by the same real BTC cache policy.";
115
- }, {
116
- readonly name: "price";
117
- readonly path: "/price";
118
- readonly method: "GET";
119
- readonly description: "Real live crypto spot price (?symbol=BTC|ETH|SOL) from CoinGecko's public API.";
120
- }];
121
- readonly authModel: "caller-auth";
122
- readonly example: {
123
- readonly endpoint: "price";
124
- readonly request: {
125
- readonly symbol: "BTC";
126
- };
127
- readonly response: {
128
- readonly symbol: "BTC";
129
- readonly source: "coingecko-public-api";
130
- };
131
- readonly description: "Real, nondeterministic live price — no re-execution guarantee.";
132
- };
133
- readonly expectedStatuses: readonly [200];
134
- };
135
- readonly verification: {
136
- readonly canaries: readonly [{
137
- readonly path: "/readiness";
138
- readonly method: "GET";
139
- readonly matcher: {
140
- readonly type: "json-field-equals";
141
- readonly field: "source";
142
- readonly expected: "coingecko-public-api";
143
- };
144
- readonly nonce: {
145
- readonly inject: {
146
- readonly in: "query";
147
- readonly name: "nonce";
148
- };
149
- readonly echo: {
150
- readonly from: "json-path";
151
- readonly path: "nonce";
152
- };
153
- };
154
- }, {
155
- readonly path: "/canary";
156
- readonly method: "GET";
157
- readonly matcher: {
158
- readonly type: "includes";
159
- readonly expected: "metrik-canary:live-data:";
160
- };
161
- readonly nonce: {
162
- readonly inject: {
163
- readonly in: "query";
164
- readonly name: "nonce";
165
- };
166
- readonly echo: {
167
- readonly from: "json-path";
168
- readonly path: "nonce";
169
- };
170
- };
171
- }];
172
- readonly schema: {
173
- readonly path: "/readiness?nonce=metrik-schema";
174
- readonly required: readonly [{
175
- readonly pointer: "ready";
176
- readonly type: "boolean";
177
- }, {
178
- readonly pointer: "source";
179
- readonly type: "string";
180
- readonly nonEmpty: true;
181
- }, {
182
- readonly pointer: "fetchedAt";
183
- readonly type: "string";
184
- readonly nonEmpty: true;
185
- }, {
186
- readonly pointer: "priceAgeMs";
187
- readonly type: "number";
188
- }, {
189
- readonly pointer: "freshness";
190
- readonly type: "string";
191
- readonly nonEmpty: true;
192
- }];
193
- };
194
- readonly sla: {
195
- readonly maxLatencyMs: 5000;
196
- readonly freshnessSeconds: 60;
197
- };
198
- };
199
- readonly commercial: {
200
- readonly minRatePerSecond: "100";
201
- readonly maxRatePerSecond: "10000";
202
- readonly currency: "USDC";
203
- readonly slaDescription: "Failed or unproven intervals do not advance verified cumulative entitlement; the stream remains active until buyer close or expiry.";
204
- readonly refundPolicy: "The buyer reclaims unspent escrow using the latest checkpoint after close/expiry, or the unverified escape path after its grace window.";
205
- };
206
- readonly access: "gated";
207
- readonly callerAuth: {
208
- readonly mechanism: "on-chain";
209
- readonly role: "buyer";
210
- readonly accessUrl: "https://gateway.137.23.50.249.sslip.io";
211
- };
212
- };
213
- readonly signature: "0x2f4d2784eb40b1542517bc19f12534fb2e97da4ade5a3ff56193fcfb97fbef921309f77af3445e336cb07a4379011b080bba700033a098f672b0b2f096197f161b";
214
- };
215
- };
216
- /** @deprecated Use {@link LIVE_DATA_SEED_LISTING}. */
217
- export declare const DEMO_SEED_LISTING: {
218
- readonly service_ref: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
219
- readonly operator: "0xB3e162711920dFD8933609019Dc35C73cC1a09F0";
220
- readonly public_url: "https://livedata.137.23.50.249.sslip.io";
221
- readonly category: "live-data";
222
- readonly signed_binding: {
223
- readonly serviceRef: "0x79e57358e98a35273c1cd9d5f1bf9ae1e0af8705db432eb706459dc4f88b6fe0";
224
- readonly descriptor: {
225
- readonly version: 3;
226
- readonly operator: "0xB3e162711920dFD8933609019Dc35C73cC1a09F0";
227
- readonly publicUrl: "https://livedata.137.23.50.249.sslip.io";
228
- readonly issuedAt: 1787772057;
229
- readonly interface: {
230
- readonly baseUrl: "https://livedata.137.23.50.249.sslip.io";
231
- readonly healthPath: "/health";
232
- readonly endpoints: readonly [{
233
- readonly name: "health";
234
- readonly path: "/health";
235
- readonly method: "GET";
236
- readonly description: "Liveness probe.";
237
- }, {
238
- readonly name: "readiness";
239
- readonly path: "/readiness";
240
- readonly method: "GET";
241
- readonly description: "Non-value dependency readiness backed by the same real BTC cache policy.";
242
- }, {
243
- readonly name: "price";
244
- readonly path: "/price";
245
- readonly method: "GET";
246
- readonly description: "Real live crypto spot price (?symbol=BTC|ETH|SOL) from CoinGecko's public API.";
247
- }];
248
- readonly authModel: "caller-auth";
249
- readonly example: {
250
- readonly endpoint: "price";
251
- readonly request: {
252
- readonly symbol: "BTC";
253
- };
254
- readonly response: {
255
- readonly symbol: "BTC";
256
- readonly source: "coingecko-public-api";
257
- };
258
- readonly description: "Real, nondeterministic live price — no re-execution guarantee.";
259
- };
260
- readonly expectedStatuses: readonly [200];
261
- };
262
- readonly verification: {
263
- readonly canaries: readonly [{
264
- readonly path: "/readiness";
265
- readonly method: "GET";
266
- readonly matcher: {
267
- readonly type: "json-field-equals";
268
- readonly field: "source";
269
- readonly expected: "coingecko-public-api";
270
- };
271
- readonly nonce: {
272
- readonly inject: {
273
- readonly in: "query";
274
- readonly name: "nonce";
275
- };
276
- readonly echo: {
277
- readonly from: "json-path";
278
- readonly path: "nonce";
279
- };
280
- };
281
- }, {
282
- readonly path: "/canary";
283
- readonly method: "GET";
284
- readonly matcher: {
285
- readonly type: "includes";
286
- readonly expected: "metrik-canary:live-data:";
287
- };
288
- readonly nonce: {
289
- readonly inject: {
290
- readonly in: "query";
291
- readonly name: "nonce";
292
- };
293
- readonly echo: {
294
- readonly from: "json-path";
295
- readonly path: "nonce";
296
- };
297
- };
298
- }];
299
- readonly schema: {
300
- readonly path: "/readiness?nonce=metrik-schema";
301
- readonly required: readonly [{
302
- readonly pointer: "ready";
303
- readonly type: "boolean";
304
- }, {
305
- readonly pointer: "source";
306
- readonly type: "string";
307
- readonly nonEmpty: true;
308
- }, {
309
- readonly pointer: "fetchedAt";
310
- readonly type: "string";
311
- readonly nonEmpty: true;
312
- }, {
313
- readonly pointer: "priceAgeMs";
314
- readonly type: "number";
315
- }, {
316
- readonly pointer: "freshness";
317
- readonly type: "string";
318
- readonly nonEmpty: true;
319
- }];
320
- };
321
- readonly sla: {
322
- readonly maxLatencyMs: 5000;
323
- readonly freshnessSeconds: 60;
324
- };
325
- };
326
- readonly commercial: {
327
- readonly minRatePerSecond: "100";
328
- readonly maxRatePerSecond: "10000";
329
- readonly currency: "USDC";
330
- readonly slaDescription: "Failed or unproven intervals do not advance verified cumulative entitlement; the stream remains active until buyer close or expiry.";
331
- readonly refundPolicy: "The buyer reclaims unspent escrow using the latest checkpoint after close/expiry, or the unverified escape path after its grace window.";
332
- };
333
- readonly access: "gated";
334
- readonly callerAuth: {
335
- readonly mechanism: "on-chain";
336
- readonly role: "buyer";
337
- readonly accessUrl: "https://gateway.137.23.50.249.sslip.io";
338
- };
339
- };
340
- readonly signature: "0x2f4d2784eb40b1542517bc19f12534fb2e97da4ade5a3ff56193fcfb97fbef921309f77af3445e336cb07a4379011b080bba700033a098f672b0b2f096197f161b";
341
- };
342
- };
140
+ export declare function discoverServicesDetailed(opts?: DiscoverServicesOptions): Promise<DiscoverResult>;
343
141
  /**
344
142
  * Discover verified services from the Metrik listings registry.
345
143
  *
346
- * Fail-closed: any row whose signed binding is malformed, whose signature does not
347
- * recover to its operator, or whose `serviceRef` does not match `deriveServiceRef`
348
- * is dropped and logged. Degrades gracefully: any network/registry failure returns
349
- * `[]` (with a logged warning) rather than throwing to the caller.
144
+ * Zero configuration: reads {@link DEFAULT_METRIK_PUBLIC_REGISTRY_URL}, the
145
+ * oracle's credential-free public endpoint.
146
+ *
147
+ * Fail-closed: every row is schema-validated, its `serviceRef` re-derived and
148
+ * its operator signature recovered; anything that fails is dropped and logged,
149
+ * so an unverifiable listing is never returned.
150
+ *
151
+ * LOUD, not silent: an unreachable / erroring / non-200 registry throws
152
+ * {@link RegistryUnavailableError} rather than returning `[]` or embedded seed
153
+ * data. Catch it if your caller can genuinely handle "the marketplace was never
154
+ * reached" — but do not confuse it with an empty marketplace.
350
155
  */
351
156
  export declare function discoverServices(opts?: DiscoverServicesOptions): Promise<ServiceListing[]>;
352
157
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAI5B;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;qEACqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,uBAAuB,CAAC;IAChE,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qFAAqF;IACrF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC;4FACwF;IACxF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;wFAIoF;IACpF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;uEACmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;KAAE,CAAC;CAC1D;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,mJAC0G,CAAC;AAInJ;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EACrC,oEAA6E,CAAC;AAChF,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,sEAA6B,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0GzB,CAAC;AACX,sDAAsD;AACtD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAyB,CAAC;AA+CxD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,cAAc,EAAE,CAAC,CA6E3B"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EAExB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EAGvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;2EAC2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,uBAAuB,CAAC;IAChE,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;wFACoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;KAAE,CAAC;CAC1D;AAED;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,wCACR,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,wCAAqC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAqB,CAAC;AAC/E,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAA0B,CAAC;AAC/E,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,EAAE,IAAW,CAAC;AACrD,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,EAAE,IAAW,CAAC;AAIhD,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC;AAElD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,cAAc,CAAC,CAoBzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,cAAc,EAAE,CAAC,CAqB3B"}