@absol-labs/agent 0.10.0 → 0.12.0-rc.1
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/README.md +106 -30
- package/dist/capability/invocation-capability.d.ts +20 -8
- package/dist/capability/invocation-capability.d.ts.map +1 -1
- package/dist/capability/invocation-capability.js.map +1 -1
- package/dist/capability/probe-capability.d.ts +225 -0
- package/dist/capability/probe-capability.d.ts.map +1 -0
- package/dist/capability/probe-capability.js +248 -0
- package/dist/capability/probe-capability.js.map +1 -0
- package/dist/cli/args.d.ts +11 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +23 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/claim.d.ts.map +1 -1
- package/dist/cli/commands/claim.js +21 -5
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.d.ts.map +1 -1
- package/dist/cli/commands/close.js +51 -7
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/invoke.d.ts +2 -0
- package/dist/cli/commands/invoke.d.ts.map +1 -1
- package/dist/cli/commands/invoke.js +3 -2
- package/dist/cli/commands/invoke.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +15 -2
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/open.d.ts.map +1 -1
- package/dist/cli/commands/open.js +121 -15
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/pay.d.ts +19 -0
- package/dist/cli/commands/pay.d.ts.map +1 -0
- package/dist/cli/commands/pay.js +355 -0
- package/dist/cli/commands/pay.js.map +1 -0
- package/dist/cli/commands/reclaim-unverified.d.ts.map +1 -1
- package/dist/cli/commands/reclaim-unverified.js +15 -6
- package/dist/cli/commands/reclaim-unverified.js.map +1 -1
- package/dist/cli/commands/reclaim.d.ts +23 -2
- package/dist/cli/commands/reclaim.d.ts.map +1 -1
- package/dist/cli/commands/reclaim.js +200 -21
- package/dist/cli/commands/reclaim.js.map +1 -1
- package/dist/cli/commands/refund.d.ts +13 -0
- package/dist/cli/commands/refund.d.ts.map +1 -0
- package/dist/cli/commands/refund.js +224 -0
- package/dist/cli/commands/refund.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +10 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/streams.js +9 -13
- package/dist/cli/commands/streams.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +2 -1
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/config.d.ts +44 -26
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +88 -38
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/deps.d.ts +86 -7
- package/dist/cli/deps.d.ts.map +1 -1
- package/dist/cli/deps.js +102 -16
- package/dist/cli/deps.js.map +1 -1
- package/dist/cli/errors.d.ts.map +1 -1
- package/dist/cli/errors.js +21 -1
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/escape-hatch.d.ts +6 -4
- package/dist/cli/escape-hatch.d.ts.map +1 -1
- package/dist/cli/escape-hatch.js +6 -2
- package/dist/cli/escape-hatch.js.map +1 -1
- package/dist/cli/listings.d.ts +18 -0
- package/dist/cli/listings.d.ts.map +1 -1
- package/dist/cli/listings.js +22 -12
- package/dist/cli/listings.js.map +1 -1
- package/dist/cli/preflight.d.ts +20 -14
- package/dist/cli/preflight.d.ts.map +1 -1
- package/dist/cli/preflight.js +34 -20
- package/dist/cli/preflight.js.map +1 -1
- package/dist/cli/privy.d.ts +83 -0
- package/dist/cli/privy.d.ts.map +1 -0
- package/dist/cli/privy.js +232 -0
- package/dist/cli/privy.js.map +1 -0
- package/dist/cli/reclaimability.d.ts +82 -0
- package/dist/cli/reclaimability.d.ts.map +1 -0
- package/dist/cli/reclaimability.js +80 -0
- package/dist/cli/reclaimability.js.map +1 -0
- package/dist/cli/run.d.ts +2 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +40 -11
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/scan-range.d.ts +2 -2
- package/dist/cli/scan-range.js +2 -2
- package/dist/cli/spend-policy.d.ts +60 -0
- package/dist/cli/spend-policy.d.ts.map +1 -0
- package/dist/cli/spend-policy.js +65 -0
- package/dist/cli/spend-policy.js.map +1 -0
- package/dist/cli/status.d.ts +3 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +15 -3
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/wallet.d.ts +109 -40
- package/dist/cli/wallet.d.ts.map +1 -1
- package/dist/cli/wallet.js +109 -44
- package/dist/cli/wallet.js.map +1 -1
- package/dist/discovery/rate-band.d.ts +74 -0
- package/dist/discovery/rate-band.d.ts.map +1 -0
- package/dist/discovery/rate-band.js +114 -0
- package/dist/discovery/rate-band.js.map +1 -0
- package/dist/escrow-generation.d.ts +81 -0
- package/dist/escrow-generation.d.ts.map +1 -0
- package/dist/escrow-generation.js +76 -0
- package/dist/escrow-generation.js.map +1 -0
- package/dist/frameworks/agentkit.d.ts +8 -4
- package/dist/frameworks/agentkit.d.ts.map +1 -1
- package/dist/frameworks/agentkit.js +27 -10
- package/dist/frameworks/agentkit.js.map +1 -1
- package/dist/frameworks/eliza.d.ts +3 -3
- package/dist/frameworks/eliza.d.ts.map +1 -1
- package/dist/frameworks/eliza.js +15 -6
- package/dist/frameworks/eliza.js.map +1 -1
- package/dist/frameworks/langchain.d.ts.map +1 -1
- package/dist/frameworks/langchain.js +8 -0
- package/dist/frameworks/langchain.js.map +1 -1
- package/dist/gateway/caller-auth-gateway.d.ts +91 -4
- package/dist/gateway/caller-auth-gateway.d.ts.map +1 -1
- package/dist/gateway/caller-auth-gateway.js +184 -7
- package/dist/gateway/caller-auth-gateway.js.map +1 -1
- package/dist/gateway/http-server.d.ts +121 -1
- package/dist/gateway/http-server.d.ts.map +1 -1
- package/dist/gateway/http-server.js +474 -5
- package/dist/gateway/http-server.js.map +1 -1
- package/dist/gateway/probe-auth.d.ts +112 -0
- package/dist/gateway/probe-auth.d.ts.map +1 -0
- package/dist/gateway/probe-auth.js +127 -0
- package/dist/gateway/probe-auth.js.map +1 -0
- package/dist/gateway/signed-rate-bounds.d.ts +51 -0
- package/dist/gateway/signed-rate-bounds.d.ts.map +1 -0
- package/dist/gateway/signed-rate-bounds.js +94 -0
- package/dist/gateway/signed-rate-bounds.js.map +1 -0
- package/dist/gateway/x402-opener-mode.d.ts +215 -0
- package/dist/gateway/x402-opener-mode.d.ts.map +1 -0
- package/dist/gateway/x402-opener-mode.js +639 -0
- package/dist/gateway/x402-opener-mode.js.map +1 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/mandates/env.d.ts +3 -2
- package/dist/mandates/env.d.ts.map +1 -1
- package/dist/mandates/env.js +3 -2
- package/dist/mandates/env.js.map +1 -1
- package/dist/mcp/server.d.ts +100 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +719 -39
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/service-invoker.d.ts +97 -0
- package/dist/mcp/service-invoker.d.ts.map +1 -0
- package/dist/mcp/service-invoker.js +167 -0
- package/dist/mcp/service-invoker.js.map +1 -0
- package/dist/mcp/x402-tools.d.ts +104 -0
- package/dist/mcp/x402-tools.d.ts.map +1 -0
- package/dist/mcp/x402-tools.js +434 -0
- package/dist/mcp/x402-tools.js.map +1 -0
- package/dist/network.d.ts +119 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +199 -0
- package/dist/network.js.map +1 -0
- package/dist/sdk/invoke.d.ts +23 -4
- package/dist/sdk/invoke.d.ts.map +1 -1
- package/dist/sdk/invoke.js +71 -10
- package/dist/sdk/invoke.js.map +1 -1
- package/dist/wallet/autonomous-wallet-broker.d.ts +3 -0
- package/dist/wallet/autonomous-wallet-broker.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet-broker.js +27 -23
- package/dist/wallet/autonomous-wallet-broker.js.map +1 -1
- package/dist/wallet/autonomous-wallet-protocol.d.ts +8 -2
- package/dist/wallet/autonomous-wallet-protocol.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet-protocol.js +9 -2
- package/dist/wallet/autonomous-wallet-protocol.js.map +1 -1
- package/dist/wallet/autonomous-wallet.d.ts.map +1 -1
- package/dist/wallet/autonomous-wallet.js +3 -2
- package/dist/wallet/autonomous-wallet.js.map +1 -1
- package/dist/wallet/broker-escrows.d.ts +222 -0
- package/dist/wallet/broker-escrows.d.ts.map +1 -0
- package/dist/wallet/broker-escrows.js +36 -0
- package/dist/wallet/broker-escrows.js.map +1 -0
- package/dist/wallet/lifecycle.d.ts +21 -5
- package/dist/wallet/lifecycle.d.ts.map +1 -1
- package/dist/wallet/lifecycle.js +32 -12
- package/dist/wallet/lifecycle.js.map +1 -1
- package/dist/wallet/privy-broker-server.d.ts.map +1 -1
- package/dist/wallet/privy-broker-server.js +31 -26
- package/dist/wallet/privy-broker-server.js.map +1 -1
- package/dist/wallet/privy-session-broker.d.ts +14 -5
- package/dist/wallet/privy-session-broker.d.ts.map +1 -1
- package/dist/wallet/privy-session-broker.js +29 -17
- package/dist/wallet/privy-session-broker.js.map +1 -1
- package/dist/wallet/privy-session-provider.d.ts +3 -1
- package/dist/wallet/privy-session-provider.d.ts.map +1 -1
- package/dist/wallet/privy-session-provider.js +5 -3
- package/dist/wallet/privy-session-provider.js.map +1 -1
- package/dist/wallet/provider.d.ts.map +1 -1
- package/dist/wallet/provider.js +15 -8
- package/dist/wallet/provider.js.map +1 -1
- package/dist/x402/facilitator.d.ts +42 -17
- package/dist/x402/facilitator.d.ts.map +1 -1
- package/dist/x402/facilitator.js +49 -33
- package/dist/x402/facilitator.js.map +1 -1
- package/dist/x402-buyer/guarded-fetch.d.ts +51 -0
- package/dist/x402-buyer/guarded-fetch.d.ts.map +1 -0
- package/dist/x402-buyer/guarded-fetch.js +147 -0
- package/dist/x402-buyer/guarded-fetch.js.map +1 -0
- package/dist/x402-buyer/index.d.ts +10 -0
- package/dist/x402-buyer/index.d.ts.map +1 -0
- package/dist/x402-buyer/index.js +10 -0
- package/dist/x402-buyer/index.js.map +1 -0
- package/dist/x402-buyer/pay.d.ts +135 -0
- package/dist/x402-buyer/pay.d.ts.map +1 -0
- package/dist/x402-buyer/pay.js +336 -0
- package/dist/x402-buyer/pay.js.map +1 -0
- package/dist/x402-opener/abi.d.ts +684 -0
- package/dist/x402-opener/abi.d.ts.map +1 -0
- package/dist/x402-opener/abi.js +880 -0
- package/dist/x402-opener/abi.js.map +1 -0
- package/dist/x402-opener/facilitator-entry.d.ts +3 -0
- package/dist/x402-opener/facilitator-entry.d.ts.map +1 -0
- package/dist/x402-opener/facilitator-entry.js +37 -0
- package/dist/x402-opener/facilitator-entry.js.map +1 -0
- package/dist/x402-opener/facilitator-server.d.ts +180 -0
- package/dist/x402-opener/facilitator-server.d.ts.map +1 -0
- package/dist/x402-opener/facilitator-server.js +696 -0
- package/dist/x402-opener/facilitator-server.js.map +1 -0
- package/dist/x402-opener/index.d.ts +14 -0
- package/dist/x402-opener/index.d.ts.map +1 -0
- package/dist/x402-opener/index.js +14 -0
- package/dist/x402-opener/index.js.map +1 -0
- package/dist/x402-opener/listing-resolver.d.ts +55 -0
- package/dist/x402-opener/listing-resolver.d.ts.map +1 -0
- package/dist/x402-opener/listing-resolver.js +125 -0
- package/dist/x402-opener/listing-resolver.js.map +1 -0
- package/dist/x402-opener/refund-relay.d.ts +240 -0
- package/dist/x402-opener/refund-relay.d.ts.map +1 -0
- package/dist/x402-opener/refund-relay.js +1240 -0
- package/dist/x402-opener/refund-relay.js.map +1 -0
- package/dist/x402-opener/relayer-queue.d.ts +14 -0
- package/dist/x402-opener/relayer-queue.d.ts.map +1 -0
- package/dist/x402-opener/relayer-queue.js +18 -0
- package/dist/x402-opener/relayer-queue.js.map +1 -0
- package/dist/x402-opener/scheme.d.ts +217 -0
- package/dist/x402-opener/scheme.d.ts.map +1 -0
- package/dist/x402-opener/scheme.js +749 -0
- package/dist/x402-opener/scheme.js.map +1 -0
- package/dist/x402-opener/terms.d.ts +105 -0
- package/dist/x402-opener/terms.d.ts.map +1 -0
- package/dist/x402-opener/terms.js +212 -0
- package/dist/x402-opener/terms.js.map +1 -0
- package/dist/zktls/reclaim.d.ts +2 -2
- package/docs/agent-layer.md +13 -8
- package/docs/autonomous-privy-wallet.md +188 -0
- package/docs/cli.md +342 -53
- package/docs/langchain.md +5 -0
- package/docs/mcp-hosted.md +4 -3
- package/docs/mcp-reference.md +245 -0
- package/docs/probe-capability.md +191 -0
- package/docs/quickstart.md +54 -5
- package/docs/threat-model.md +24 -3
- package/docs/x402.md +681 -0
- package/package.json +19 -6
- package/src/capability/invocation-capability.ts +17 -1
- package/src/capability/probe-capability.ts +355 -0
- package/src/cli/args.ts +29 -0
- package/src/cli/commands/claim.ts +31 -5
- package/src/cli/commands/close.ts +56 -7
- package/src/cli/commands/invoke.ts +6 -2
- package/src/cli/commands/mcp.ts +18 -2
- package/src/cli/commands/open.ts +151 -14
- package/src/cli/commands/pay.ts +442 -0
- package/src/cli/commands/reclaim-unverified.ts +24 -6
- package/src/cli/commands/reclaim.ts +274 -19
- package/src/cli/commands/refund.ts +277 -0
- package/src/cli/commands/status.ts +17 -1
- package/src/cli/commands/streams.ts +11 -15
- package/src/cli/commands/watch.ts +7 -1
- package/src/cli/config.ts +139 -52
- package/src/cli/deps.ts +189 -25
- package/src/cli/errors.ts +24 -1
- package/src/cli/escape-hatch.ts +19 -5
- package/src/cli/listings.ts +43 -10
- package/src/cli/preflight.ts +36 -21
- package/src/cli/privy.ts +398 -0
- package/src/cli/reclaimability.ts +154 -0
- package/src/cli/run.ts +54 -11
- package/src/cli/scan-range.ts +2 -2
- package/src/cli/spend-policy.ts +139 -0
- package/src/cli/status.ts +14 -1
- package/src/cli/wallet.ts +189 -58
- package/src/discovery/rate-band.ts +172 -0
- package/src/escrow-generation.ts +135 -0
- package/src/frameworks/agentkit.ts +45 -11
- package/src/frameworks/eliza.ts +27 -5
- package/src/frameworks/langchain.ts +14 -0
- package/src/gateway/caller-auth-gateway.ts +336 -13
- package/src/gateway/http-server.ts +690 -7
- package/src/gateway/probe-auth.ts +191 -0
- package/src/gateway/signed-rate-bounds.ts +164 -0
- package/src/gateway/x402-opener-mode.ts +974 -0
- package/src/index.ts +112 -14
- package/src/mandates/env.ts +3 -2
- package/src/mcp/server.ts +973 -44
- package/src/mcp/service-invoker.ts +285 -0
- package/src/mcp/x402-tools.ts +621 -0
- package/src/network.ts +302 -0
- package/src/sdk/invoke.ts +96 -17
- package/src/wallet/autonomous-wallet-broker.ts +46 -20
- package/src/wallet/autonomous-wallet-protocol.ts +11 -2
- package/src/wallet/autonomous-wallet.ts +4 -2
- package/src/wallet/broker-escrows.ts +66 -0
- package/src/wallet/lifecycle.ts +53 -18
- package/src/wallet/privy-broker-server.ts +35 -25
- package/src/wallet/privy-session-broker.ts +58 -25
- package/src/wallet/privy-session-provider.ts +7 -3
- package/src/wallet/provider.ts +20 -15
- package/src/x402/facilitator.ts +85 -46
- package/src/x402-buyer/guarded-fetch.ts +213 -0
- package/src/x402-buyer/index.ts +9 -0
- package/src/x402-buyer/pay.ts +517 -0
- package/src/x402-opener/abi.ts +881 -0
- package/src/x402-opener/facilitator-entry.ts +45 -0
- package/src/x402-opener/facilitator-server.ts +1014 -0
- package/src/x402-opener/index.ts +13 -0
- package/src/x402-opener/listing-resolver.ts +202 -0
- package/src/x402-opener/refund-relay.ts +1743 -0
- package/src/x402-opener/relayer-queue.ts +18 -0
- package/src/x402-opener/scheme.ts +1133 -0
- package/src/x402-opener/terms.ts +300 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@absol-labs/agent/x402-opener` — x402 v2 `exact` payments settled into a
|
|
3
|
+
* `StreamEscrowV2` stream through the ownerless `X402StreamOpenerFactory`
|
|
4
|
+
* (metrik-agent#116). Kept out of the root barrel so consumers that never use
|
|
5
|
+
* x402 do not load `@x402/*`. See docs/x402.md.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./abi.js";
|
|
8
|
+
export * from "./terms.js";
|
|
9
|
+
export * from "./listing-resolver.js";
|
|
10
|
+
export * from "./scheme.js";
|
|
11
|
+
export * from "./facilitator-server.js";
|
|
12
|
+
export * from "./refund-relay.js";
|
|
13
|
+
export * from "./relayer-queue.js";
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_METRIK_PUBLIC_REGISTRY_URL,
|
|
3
|
+
discoverServicesDetailed,
|
|
4
|
+
type DiscoveredService,
|
|
5
|
+
} from "../discovery/registry.js";
|
|
6
|
+
import type { OpenerTerms } from "./terms.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolves opener terms to exactly ONE operator-signed Metrik listing.
|
|
10
|
+
*
|
|
11
|
+
* The trust decision is the existing discovery verification, reused verbatim
|
|
12
|
+
* ({@link discoverServicesDetailed} → `@absol-labs/sdk`): every registry row is
|
|
13
|
+
* schema-validated, its `serviceRef` is re-derived from the signed content, and
|
|
14
|
+
* its operator EIP-712 signature is recovered and matched. Only then is it
|
|
15
|
+
* compared with the terms. An unsigned registry column, or anything a request
|
|
16
|
+
* carries, is never consulted — `serviceRef` and `operator` come out of the
|
|
17
|
+
* verified signed record.
|
|
18
|
+
*
|
|
19
|
+
* Fail closed: an unreachable registry, zero matches, or more than one match is
|
|
20
|
+
* a refusal, never a pass.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export type ListingResolution =
|
|
24
|
+
| {
|
|
25
|
+
readonly ok: true;
|
|
26
|
+
readonly listing: DiscoveredService;
|
|
27
|
+
}
|
|
28
|
+
| {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly reason:
|
|
31
|
+
| "listing-registry-unavailable"
|
|
32
|
+
| "listing-not-found"
|
|
33
|
+
| "listing-ambiguous"
|
|
34
|
+
| "listing-rate-out-of-bounds";
|
|
35
|
+
readonly message: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export interface OperatorSignedListingResolver {
|
|
39
|
+
resolve(
|
|
40
|
+
terms: Pick<OpenerTerms, "operator" | "serviceRef" | "ratePerSecond">,
|
|
41
|
+
): Promise<ListingResolution>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RegistryListingResolverOptions {
|
|
45
|
+
/** Default {@link DEFAULT_METRIK_PUBLIC_REGISTRY_URL}. */
|
|
46
|
+
readonly registryUrl?: string;
|
|
47
|
+
/**
|
|
48
|
+
* How long a SUCCESSFUL registry read is reused, in seconds. Failures are
|
|
49
|
+
* never cached. Default 60. `0` disables caching.
|
|
50
|
+
*/
|
|
51
|
+
readonly cacheSeconds?: number;
|
|
52
|
+
readonly timeoutMs?: number;
|
|
53
|
+
readonly fetch?: typeof fetch;
|
|
54
|
+
readonly now?: () => number;
|
|
55
|
+
readonly logger?: { warn: (...args: unknown[]) => void };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const DEFAULT_LISTING_CACHE_SECONDS = 60;
|
|
59
|
+
|
|
60
|
+
export class RegistryListingResolver implements OperatorSignedListingResolver {
|
|
61
|
+
private readonly registryUrl: string;
|
|
62
|
+
private readonly cacheSeconds: number;
|
|
63
|
+
private readonly now: () => number;
|
|
64
|
+
private cache:
|
|
65
|
+
| { readonly at: number; readonly services: readonly DiscoveredService[] }
|
|
66
|
+
| undefined;
|
|
67
|
+
private inFlight: Promise<readonly DiscoveredService[]> | undefined;
|
|
68
|
+
|
|
69
|
+
constructor(private readonly options: RegistryListingResolverOptions = {}) {
|
|
70
|
+
this.registryUrl =
|
|
71
|
+
options.registryUrl ?? DEFAULT_METRIK_PUBLIC_REGISTRY_URL;
|
|
72
|
+
// eslint-disable-next-line no-new -- validates the URL is well-formed.
|
|
73
|
+
new URL(this.registryUrl);
|
|
74
|
+
const cacheSeconds = options.cacheSeconds ?? DEFAULT_LISTING_CACHE_SECONDS;
|
|
75
|
+
if (!Number.isFinite(cacheSeconds) || cacheSeconds < 0) {
|
|
76
|
+
throw new Error("cacheSeconds must be a non-negative number");
|
|
77
|
+
}
|
|
78
|
+
this.cacheSeconds = cacheSeconds;
|
|
79
|
+
this.now = options.now ?? (() => Math.floor(Date.now() / 1000));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async resolve(
|
|
83
|
+
terms: Pick<OpenerTerms, "operator" | "serviceRef" | "ratePerSecond">,
|
|
84
|
+
): Promise<ListingResolution> {
|
|
85
|
+
let services: readonly DiscoveredService[];
|
|
86
|
+
try {
|
|
87
|
+
services = await this.services();
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
ok: false,
|
|
91
|
+
reason: "listing-registry-unavailable",
|
|
92
|
+
message: error instanceof Error ? error.message : String(error),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const serviceRef = terms.serviceRef.toLowerCase();
|
|
96
|
+
const operator = terms.operator.toLowerCase();
|
|
97
|
+
const matches = services.filter(
|
|
98
|
+
(service) =>
|
|
99
|
+
service.serviceRef.toLowerCase() === serviceRef &&
|
|
100
|
+
service.operator.toLowerCase() === operator,
|
|
101
|
+
);
|
|
102
|
+
if (matches.length === 0) {
|
|
103
|
+
return {
|
|
104
|
+
ok: false,
|
|
105
|
+
reason: "listing-not-found",
|
|
106
|
+
message: `no operator-signed listing for serviceRef ${terms.serviceRef} signed by ${terms.operator}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (matches.length > 1) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
reason: "listing-ambiguous",
|
|
113
|
+
message: `${matches.length} listings match serviceRef ${terms.serviceRef}`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const listing = matches[0] as DiscoveredService;
|
|
117
|
+
const bounds = signedRateBounds(listing);
|
|
118
|
+
if (
|
|
119
|
+
(bounds.min !== undefined && terms.ratePerSecond < bounds.min) ||
|
|
120
|
+
(bounds.max !== undefined && terms.ratePerSecond > bounds.max)
|
|
121
|
+
) {
|
|
122
|
+
return {
|
|
123
|
+
ok: false,
|
|
124
|
+
reason: "listing-rate-out-of-bounds",
|
|
125
|
+
message: `ratePerSecond ${terms.ratePerSecond} is outside the listing's signed bounds [${bounds.min ?? "-"}, ${bounds.max ?? "-"}]`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return { ok: true, listing };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private async services(): Promise<readonly DiscoveredService[]> {
|
|
132
|
+
const nowSeconds = this.now();
|
|
133
|
+
if (
|
|
134
|
+
this.cache !== undefined &&
|
|
135
|
+
this.cacheSeconds > 0 &&
|
|
136
|
+
nowSeconds - this.cache.at < this.cacheSeconds
|
|
137
|
+
) {
|
|
138
|
+
return this.cache.services;
|
|
139
|
+
}
|
|
140
|
+
if (this.inFlight !== undefined) {
|
|
141
|
+
return this.inFlight;
|
|
142
|
+
}
|
|
143
|
+
const read = discoverServicesDetailed({
|
|
144
|
+
registryUrl: this.registryUrl,
|
|
145
|
+
// An explicit empty key pins the credential-free public read: the
|
|
146
|
+
// METRIK_AGENT_REGISTRY_APIKEY env override must not switch transports.
|
|
147
|
+
apiKey: "",
|
|
148
|
+
...(this.options.fetch === undefined
|
|
149
|
+
? {}
|
|
150
|
+
: { fetch: this.options.fetch }),
|
|
151
|
+
...(this.options.timeoutMs === undefined
|
|
152
|
+
? {}
|
|
153
|
+
: { timeoutMs: this.options.timeoutMs }),
|
|
154
|
+
...(this.options.logger === undefined
|
|
155
|
+
? {}
|
|
156
|
+
: { logger: this.options.logger }),
|
|
157
|
+
}).then((result) => {
|
|
158
|
+
if (!result.registryAvailable) {
|
|
159
|
+
throw new Error("registry reported itself unavailable");
|
|
160
|
+
}
|
|
161
|
+
this.cache = { at: this.now(), services: result.services };
|
|
162
|
+
return result.services;
|
|
163
|
+
});
|
|
164
|
+
this.inFlight = read;
|
|
165
|
+
try {
|
|
166
|
+
return await read;
|
|
167
|
+
} finally {
|
|
168
|
+
this.inFlight = undefined;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Rate bounds from the SIGNED descriptor's `commercial` block, when present.
|
|
175
|
+
* A legacy binding carries none.
|
|
176
|
+
*/
|
|
177
|
+
function signedRateBounds(listing: DiscoveredService): {
|
|
178
|
+
readonly min?: bigint;
|
|
179
|
+
readonly max?: bigint;
|
|
180
|
+
} {
|
|
181
|
+
const signed = listing.signed as { readonly descriptor?: unknown };
|
|
182
|
+
const descriptor = signed.descriptor as
|
|
183
|
+
| {
|
|
184
|
+
readonly commercial?: {
|
|
185
|
+
minRatePerSecond?: string;
|
|
186
|
+
maxRatePerSecond?: string;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
| undefined;
|
|
190
|
+
const commercial = descriptor?.commercial;
|
|
191
|
+
if (commercial === undefined) {
|
|
192
|
+
return {};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...(commercial.minRatePerSecond === undefined
|
|
196
|
+
? {}
|
|
197
|
+
: { min: BigInt(commercial.minRatePerSecond) }),
|
|
198
|
+
...(commercial.maxRatePerSecond === undefined
|
|
199
|
+
? {}
|
|
200
|
+
: { max: BigInt(commercial.maxRatePerSecond) }),
|
|
201
|
+
};
|
|
202
|
+
}
|