@absol-labs/agent 0.4.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.
Files changed (57) hide show
  1. package/README.md +187 -0
  2. package/dist/capability/invocation-capability.d.ts +184 -0
  3. package/dist/capability/invocation-capability.d.ts.map +1 -0
  4. package/dist/capability/invocation-capability.js +183 -0
  5. package/dist/capability/invocation-capability.js.map +1 -0
  6. package/dist/discovery/registry.d.ts +260 -15
  7. package/dist/discovery/registry.d.ts.map +1 -1
  8. package/dist/discovery/registry.js +174 -31
  9. package/dist/discovery/registry.js.map +1 -1
  10. package/dist/frameworks/agentkit.js +3 -3
  11. package/dist/frameworks/agentkit.js.map +1 -1
  12. package/dist/frameworks/crewai.js +1 -1
  13. package/dist/frameworks/crewai.js.map +1 -1
  14. package/dist/frameworks/eliza.js +2 -2
  15. package/dist/frameworks/eliza.js.map +1 -1
  16. package/dist/frameworks/langchain.js +2 -2
  17. package/dist/frameworks/langchain.js.map +1 -1
  18. package/dist/gateway/caller-auth-gateway.d.ts +108 -0
  19. package/dist/gateway/caller-auth-gateway.d.ts.map +1 -0
  20. package/dist/gateway/caller-auth-gateway.js +191 -0
  21. package/dist/gateway/caller-auth-gateway.js.map +1 -0
  22. package/dist/gateway/http-server.d.ts +51 -0
  23. package/dist/gateway/http-server.d.ts.map +1 -0
  24. package/dist/gateway/http-server.js +241 -0
  25. package/dist/gateway/http-server.js.map +1 -0
  26. package/dist/gateway/server-entry.d.ts +2 -0
  27. package/dist/gateway/server-entry.d.ts.map +1 -0
  28. package/dist/gateway/server-entry.js +30 -0
  29. package/dist/gateway/server-entry.js.map +1 -0
  30. package/dist/index.d.ts +6 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +6 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/mcp/server.js +4 -2
  35. package/dist/mcp/server.js.map +1 -1
  36. package/dist/sdk/invoke.d.ts +136 -0
  37. package/dist/sdk/invoke.d.ts.map +1 -0
  38. package/dist/sdk/invoke.js +274 -0
  39. package/dist/sdk/invoke.js.map +1 -0
  40. package/dist/wallet/lifecycle.d.ts +101 -0
  41. package/dist/wallet/lifecycle.d.ts.map +1 -0
  42. package/dist/wallet/lifecycle.js +57 -0
  43. package/dist/wallet/lifecycle.js.map +1 -0
  44. package/package.json +6 -3
  45. package/src/capability/invocation-capability.ts +255 -0
  46. package/src/discovery/registry.ts +213 -35
  47. package/src/frameworks/agentkit.ts +3 -3
  48. package/src/frameworks/crewai.ts +1 -1
  49. package/src/frameworks/eliza.ts +2 -2
  50. package/src/frameworks/langchain.ts +2 -2
  51. package/src/gateway/caller-auth-gateway.ts +332 -0
  52. package/src/gateway/http-server.ts +342 -0
  53. package/src/gateway/server-entry.ts +38 -0
  54. package/src/index.ts +86 -0
  55. package/src/mcp/server.ts +4 -2
  56. package/src/sdk/invoke.ts +495 -0
  57. package/src/wallet/lifecycle.ts +158 -0
@@ -0,0 +1,136 @@
1
+ import { type DeliveryReceiptDomainInput } from "@absol-labs/shared";
2
+ import type { Address, Hex, LocalAccount } from "viem";
3
+ import type { ServiceListing } from "../discovery/registry.js";
4
+ import { type BuildT2DeliveryProofResult, type DeliveryProofAttestor, type PaidRouteRequestSpec } from "../zktls/t2-delivery-proof.js";
5
+ import { type HttpMethod, type InvocationCapabilityDomainInput, type SignedInvocationCapability } from "../capability/invocation-capability.js";
6
+ /**
7
+ * Buyer half of the pay -> use loop (metrik-agent#64, impl of #62 part 2/2).
8
+ *
9
+ * After `hire()`/`openStream()`, an agent calls the purchased service directly
10
+ * with no out-of-band credentials: `invoke()` loads the stream, builds+signs
11
+ * a minimal-scope `InvocationCapability`, attaches it, and calls the
12
+ * gateway-fronted service (`../gateway/caller-auth-gateway.ts`).
13
+ */
14
+ /** The subset of `MetrikClient.getStreamV2` this module needs. Duck-typed so any real SDK client satisfies it. */
15
+ export interface InvokeStreamView {
16
+ readonly buyer: Address;
17
+ readonly operator: Address;
18
+ readonly serviceRef: Hex;
19
+ readonly status: "active" | "closed";
20
+ readonly expiresAt: number;
21
+ }
22
+ export interface InvokeStreamReader {
23
+ getStreamV2(streamId: Hex): Promise<InvokeStreamView>;
24
+ }
25
+ /** Default `InvokeStreamReader`: a real, read-only `MetrikClient` (no wallet, no writes). */
26
+ export declare function createSdkInvokeStreamReader(options: {
27
+ readonly escrowAddress: Address;
28
+ readonly rpcUrl: string;
29
+ }): InvokeStreamReader;
30
+ export declare class InvokeStreamNotActiveError extends Error {
31
+ constructor(streamId: Hex, status: string);
32
+ }
33
+ export declare class InvokeStreamExpiredError extends Error {
34
+ constructor(streamId: Hex, expiresAt: number);
35
+ }
36
+ export declare class InvokeBuyerMismatchError extends Error {
37
+ constructor(streamId: Hex, streamBuyer: Address, signer: Address);
38
+ }
39
+ export declare class InvokeServiceRefMismatchError extends Error {
40
+ constructor(streamRef: Hex, listingRef: Hex);
41
+ }
42
+ export declare class InvokeAccessUrlError extends Error {
43
+ constructor(message: string);
44
+ }
45
+ export declare class InvokePathError extends Error {
46
+ constructor(path: string);
47
+ }
48
+ export interface CapabilityForOptions {
49
+ readonly buyer: LocalAccount;
50
+ readonly domain: InvocationCapabilityDomainInput;
51
+ readonly serviceRef: Hex;
52
+ /** Default {@link DEFAULT_CAPABILITY_TTL_SECONDS}. */
53
+ readonly ttlSeconds?: number;
54
+ /** Default a fresh random nonce. */
55
+ readonly nonce?: Hex;
56
+ /** Default `Math.floor(Date.now() / 1000)`. Injectable for tests. */
57
+ readonly nowSeconds?: number;
58
+ }
59
+ /**
60
+ * Builds and signs a minimal-scope `InvocationCapability` for one
61
+ * `method`+`path` call against `streamId`, WITHOUT touching the network.
62
+ */
63
+ export declare function capabilityFor(streamId: Hex, request: {
64
+ readonly method: HttpMethod;
65
+ readonly path: string;
66
+ }, options: CapabilityForOptions): Promise<SignedInvocationCapability>;
67
+ export interface InvokeServiceInput {
68
+ readonly method: HttpMethod;
69
+ readonly path: string;
70
+ readonly headers?: Readonly<Record<string, string>>;
71
+ readonly body?: NonNullable<RequestInit["body"]>;
72
+ }
73
+ export interface InvokeOptions {
74
+ /** Reads the stream's current serviceRef/operator/status/expiry. Real default: a `MetrikClient` instance. */
75
+ readonly streamReader: InvokeStreamReader;
76
+ /** The buyer's own wallet - signs the capability, never broadcasts a transaction. */
77
+ readonly buyer: LocalAccount;
78
+ /** `{chainId, verifyingContract}` - the `StreamEscrowV2` the stream settles on. */
79
+ readonly domain: InvocationCapabilityDomainInput;
80
+ /** Preferred: a cryptographically verified result from discoverServices(). */
81
+ readonly listing?: ServiceListing;
82
+ /** @deprecated Manual escape hatch. Verified listing routing is safer. */
83
+ readonly serviceBaseUrl?: string;
84
+ readonly ttlSeconds?: number;
85
+ readonly nonce?: Hex;
86
+ readonly nowSeconds?: number;
87
+ /** Injectable `fetch` implementation, for tests. Default: global `fetch`. */
88
+ readonly fetchImpl?: typeof fetch;
89
+ }
90
+ export interface InvokeResult {
91
+ readonly response: Response;
92
+ readonly capability: SignedInvocationCapability;
93
+ readonly stream: InvokeStreamView;
94
+ }
95
+ /**
96
+ * `open()` -> `invoke()`: loads the stream, builds+signs a capability scoped
97
+ * to exactly this `method`+`path`, and calls the gateway-fronted service.
98
+ * Fails closed BEFORE any network call to the service if the stream is not
99
+ * active, is expired, or does not belong to the signing account.
100
+ */
101
+ export declare function invoke(streamId: Hex, request: InvokeServiceInput, options: InvokeOptions): Promise<InvokeResult>;
102
+ export interface InvokeWithT2DeliveryProofOptions {
103
+ readonly streamReader: InvokeStreamReader;
104
+ readonly buyer: LocalAccount;
105
+ readonly domain: DeliveryReceiptDomainInput;
106
+ /** The T2 paid-route spec (absolute `url`, `responseMatches`, nonce injection point, ...). */
107
+ readonly request: PaidRouteRequestSpec;
108
+ /** Verified listing. Gated T2 is rejected until proof-target pinning supports it. */
109
+ readonly listing?: ServiceListing;
110
+ /** Which billing interval this delivery proof covers. */
111
+ readonly intervalIndex: bigint;
112
+ /** Oracle-issued anti-replay nonce, from `GET /delivery/nonce`. */
113
+ readonly nonce: Hex;
114
+ readonly issuedAt?: number;
115
+ readonly mandateId?: string;
116
+ readonly attestor?: DeliveryProofAttestor;
117
+ readonly capabilityTtlSeconds?: number;
118
+ readonly capabilityNonce?: Hex;
119
+ readonly nowSeconds?: number;
120
+ }
121
+ export interface InvokeWithT2DeliveryProofResult {
122
+ readonly capability: SignedInvocationCapability;
123
+ readonly stream: InvokeStreamView;
124
+ readonly t2: BuildT2DeliveryProofResult;
125
+ }
126
+ /**
127
+ * The T2 variant of `invoke()`: the SAME capability-authorized call the
128
+ * gateway serves is what the buyer's Reclaim attestor proves, so usage and
129
+ * delivery proof are one action (issue #63's "the invocation IS the
130
+ * delivery"). Attaches the `InvocationCapability` header to the exact request
131
+ * `buildT2DeliveryProofSubmission` proves via zkTLS, then signs the resulting
132
+ * `DeliveryReceipt` - identical evidence chain as the plain T2 flow, just
133
+ * capability-gated at the gateway.
134
+ */
135
+ export declare function invokeWithT2DeliveryProof(streamId: Hex, options: InvokeWithT2DeliveryProofOptions): Promise<InvokeWithT2DeliveryProofResult>;
136
+ //# sourceMappingURL=invoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/sdk/invoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,274 @@
1
+ import { deriveServiceRef, recoverServiceBindingSigner, recoverServiceDescriptorSigner, signedServiceBindingSchema, signedServiceDescriptorSchema, } from "@absol-labs/shared";
2
+ import { MetrikClient } from "@absol-labs/sdk";
3
+ import { buildT2DeliveryProofSubmission, } from "../zktls/t2-delivery-proof.js";
4
+ import { CAPABILITY_HEADER_NAME, encodeCapabilityHeader, generateCapabilityNonce, hashInvocationPath, signInvocationCapability, DEFAULT_CAPABILITY_TTL_SECONDS, } from "../capability/invocation-capability.js";
5
+ /** Default `InvokeStreamReader`: a real, read-only `MetrikClient` (no wallet, no writes). */
6
+ export function createSdkInvokeStreamReader(options) {
7
+ const metrik = MetrikClient.baseSepolia({
8
+ escrow: options.escrowAddress,
9
+ rpcUrl: options.rpcUrl,
10
+ });
11
+ return {
12
+ async getStreamV2(streamId) {
13
+ const stream = await metrik.getStreamV2(streamId);
14
+ return {
15
+ buyer: stream.buyer,
16
+ operator: stream.operator,
17
+ serviceRef: stream.serviceRef,
18
+ status: stream.status,
19
+ expiresAt: stream.expiresAt,
20
+ };
21
+ },
22
+ };
23
+ }
24
+ export class InvokeStreamNotActiveError extends Error {
25
+ constructor(streamId, status) {
26
+ super(`stream ${streamId} is not active (status=${status})`);
27
+ this.name = "InvokeStreamNotActiveError";
28
+ }
29
+ }
30
+ export class InvokeStreamExpiredError extends Error {
31
+ constructor(streamId, expiresAt) {
32
+ super(`stream ${streamId} expired at ${expiresAt}`);
33
+ this.name = "InvokeStreamExpiredError";
34
+ }
35
+ }
36
+ export class InvokeBuyerMismatchError extends Error {
37
+ constructor(streamId, streamBuyer, signer) {
38
+ super(`stream ${streamId} buyer ${streamBuyer} does not match the signing account ${signer}`);
39
+ this.name = "InvokeBuyerMismatchError";
40
+ }
41
+ }
42
+ export class InvokeServiceRefMismatchError extends Error {
43
+ constructor(streamRef, listingRef) {
44
+ super(`stream serviceRef ${streamRef} does not match listing serviceRef ${listingRef}`);
45
+ this.name = "InvokeServiceRefMismatchError";
46
+ }
47
+ }
48
+ export class InvokeAccessUrlError extends Error {
49
+ constructor(message) {
50
+ super(message);
51
+ this.name = "InvokeAccessUrlError";
52
+ }
53
+ }
54
+ export class InvokePathError extends Error {
55
+ constructor(path) {
56
+ super(`invocation path must be origin-relative and start with one slash: ${path}`);
57
+ this.name = "InvokePathError";
58
+ }
59
+ }
60
+ /**
61
+ * Builds and signs a minimal-scope `InvocationCapability` for one
62
+ * `method`+`path` call against `streamId`, WITHOUT touching the network.
63
+ */
64
+ export async function capabilityFor(streamId, request, options) {
65
+ const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1000);
66
+ const capability = {
67
+ streamId,
68
+ buyer: options.buyer.address,
69
+ serviceRef: options.serviceRef,
70
+ method: request.method,
71
+ pathHash: hashInvocationPath(request.path),
72
+ nonce: options.nonce ?? generateCapabilityNonce(),
73
+ expiry: nowSeconds + (options.ttlSeconds ?? DEFAULT_CAPABILITY_TTL_SECONDS),
74
+ };
75
+ const signature = await signInvocationCapability(capability, options.domain, options.buyer);
76
+ return { ...capability, signature };
77
+ }
78
+ /**
79
+ * `open()` -> `invoke()`: loads the stream, builds+signs a capability scoped
80
+ * to exactly this `method`+`path`, and calls the gateway-fronted service.
81
+ * Fails closed BEFORE any network call to the service if the stream is not
82
+ * active, is expired, or does not belong to the signing account.
83
+ */
84
+ export async function invoke(streamId, request, options) {
85
+ assertOriginRelativePath(request.path);
86
+ const stream = await options.streamReader.getStreamV2(streamId);
87
+ const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1000);
88
+ if (stream.buyer.toLowerCase() !== options.buyer.address.toLowerCase()) {
89
+ throw new InvokeBuyerMismatchError(streamId, stream.buyer, options.buyer.address);
90
+ }
91
+ if (stream.status !== "active") {
92
+ throw new InvokeStreamNotActiveError(streamId, stream.status);
93
+ }
94
+ if (nowSeconds >= stream.expiresAt) {
95
+ throw new InvokeStreamExpiredError(streamId, stream.expiresAt);
96
+ }
97
+ const serviceBaseUrl = await resolveInvocationBaseUrl(stream.serviceRef, options);
98
+ const capability = await capabilityFor(streamId, request, {
99
+ buyer: options.buyer,
100
+ domain: options.domain,
101
+ serviceRef: stream.serviceRef,
102
+ ...(options.ttlSeconds === undefined
103
+ ? {}
104
+ : { ttlSeconds: options.ttlSeconds }),
105
+ ...(options.nonce === undefined ? {} : { nonce: options.nonce }),
106
+ nowSeconds,
107
+ });
108
+ const header = encodeCapabilityHeader(capability);
109
+ const url = new URL(request.path, ensureTrailingSlash(serviceBaseUrl)).toString();
110
+ const fetchImpl = options.fetchImpl ?? fetch;
111
+ const response = await fetchImpl(url, {
112
+ method: request.method,
113
+ headers: {
114
+ ...(request.headers ?? {}),
115
+ [CAPABILITY_HEADER_NAME]: header,
116
+ },
117
+ ...(request.body === undefined ? {} : { body: request.body }),
118
+ });
119
+ return { response, capability, stream };
120
+ }
121
+ /**
122
+ * The T2 variant of `invoke()`: the SAME capability-authorized call the
123
+ * gateway serves is what the buyer's Reclaim attestor proves, so usage and
124
+ * delivery proof are one action (issue #63's "the invocation IS the
125
+ * delivery"). Attaches the `InvocationCapability` header to the exact request
126
+ * `buildT2DeliveryProofSubmission` proves via zkTLS, then signs the resulting
127
+ * `DeliveryReceipt` - identical evidence chain as the plain T2 flow, just
128
+ * capability-gated at the gateway.
129
+ */
130
+ export async function invokeWithT2DeliveryProof(streamId, options) {
131
+ const stream = await options.streamReader.getStreamV2(streamId);
132
+ const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1000);
133
+ if (stream.buyer.toLowerCase() !== options.buyer.address.toLowerCase()) {
134
+ throw new InvokeBuyerMismatchError(streamId, stream.buyer, options.buyer.address);
135
+ }
136
+ if (stream.status !== "active") {
137
+ throw new InvokeStreamNotActiveError(streamId, stream.status);
138
+ }
139
+ if (nowSeconds >= stream.expiresAt) {
140
+ throw new InvokeStreamExpiredError(streamId, stream.expiresAt);
141
+ }
142
+ if (options.listing !== undefined) {
143
+ const route = await verifyListingRoute(stream.serviceRef, options.listing);
144
+ if (route.access === "gated") {
145
+ throw new InvokeAccessUrlError("consumer-attested T2 invocation is not supported for gated listings");
146
+ }
147
+ const requestOrigin = new URL(options.request.url).origin;
148
+ const signedOrigin = new URL(route.url).origin;
149
+ if (requestOrigin !== signedOrigin) {
150
+ throw new InvokeAccessUrlError(`T2 request origin ${requestOrigin} does not match signed listing origin ${signedOrigin}`);
151
+ }
152
+ }
153
+ const path = new URL(options.request.url).pathname;
154
+ const capability = await capabilityFor(streamId, { method: options.request.method ?? "GET", path }, {
155
+ buyer: options.buyer,
156
+ domain: options.domain,
157
+ serviceRef: stream.serviceRef,
158
+ ...(options.capabilityTtlSeconds === undefined
159
+ ? {}
160
+ : { ttlSeconds: options.capabilityTtlSeconds }),
161
+ ...(options.capabilityNonce === undefined
162
+ ? {}
163
+ : { nonce: options.capabilityNonce }),
164
+ nowSeconds,
165
+ });
166
+ const requestWithCapability = {
167
+ ...options.request,
168
+ headers: {
169
+ ...(options.request.headers ?? {}),
170
+ [CAPABILITY_HEADER_NAME]: encodeCapabilityHeader(capability),
171
+ },
172
+ };
173
+ const t2 = await buildT2DeliveryProofSubmission({
174
+ streamId,
175
+ operator: stream.operator,
176
+ serviceRef: stream.serviceRef,
177
+ intervalIndex: options.intervalIndex,
178
+ nonce: options.nonce,
179
+ buyer: options.buyer,
180
+ domain: options.domain,
181
+ request: requestWithCapability,
182
+ ...(options.issuedAt === undefined ? {} : { issuedAt: options.issuedAt }),
183
+ ...(options.mandateId === undefined
184
+ ? {}
185
+ : { mandateId: options.mandateId }),
186
+ ...(options.attestor === undefined ? {} : { attestor: options.attestor }),
187
+ });
188
+ return { capability, stream, t2 };
189
+ }
190
+ async function resolveInvocationBaseUrl(streamRef, options) {
191
+ if (options.listing !== undefined) {
192
+ return (await verifyListingRoute(streamRef, options.listing)).url;
193
+ }
194
+ if (options.serviceBaseUrl === undefined) {
195
+ throw new InvokeAccessUrlError("a verified listing is required (or pass deprecated serviceBaseUrl explicitly)");
196
+ }
197
+ return requireHttpUrl(options.serviceBaseUrl, "serviceBaseUrl");
198
+ }
199
+ async function verifyListingRoute(streamRef, listing) {
200
+ if (streamRef.toLowerCase() !== listing.serviceRef.toLowerCase()) {
201
+ throw new InvokeServiceRefMismatchError(streamRef, listing.serviceRef);
202
+ }
203
+ const descriptor = signedServiceDescriptorSchema.safeParse(listing.signed);
204
+ if (descriptor.success) {
205
+ const signed = descriptor.data;
206
+ const derived = deriveServiceRef(signed.descriptor);
207
+ const signer = await recoverServiceDescriptorSigner(signed.descriptor, signed.signature);
208
+ const access = signed.descriptor.access ?? "public";
209
+ const url = access === "gated"
210
+ ? signed.descriptor.callerAuth?.accessUrl
211
+ : (signed.descriptor.interface?.baseUrl ?? signed.descriptor.publicUrl);
212
+ if (derived.toLowerCase() !== listing.serviceRef.toLowerCase() ||
213
+ signed.serviceRef.toLowerCase() !== listing.serviceRef.toLowerCase() ||
214
+ signer === null ||
215
+ signer.toLowerCase() !== signed.descriptor.operator.toLowerCase() ||
216
+ listing.operator.toLowerCase() !==
217
+ signed.descriptor.operator.toLowerCase() ||
218
+ listing.publicUrl !== signed.descriptor.publicUrl ||
219
+ listing.access !== access ||
220
+ url === undefined ||
221
+ listing.accessUrl !== url) {
222
+ throw new InvokeAccessUrlError("listing does not match its verified signed descriptor");
223
+ }
224
+ const verifiedUrl = requireHttpUrl(url, "signed listing access URL");
225
+ if (access === "gated" && new URL(verifiedUrl).protocol !== "https:") {
226
+ throw new InvokeAccessUrlError("signed gated listing access URL must use HTTPS");
227
+ }
228
+ return { access, url: verifiedUrl };
229
+ }
230
+ const binding = signedServiceBindingSchema.safeParse(listing.signed);
231
+ if (binding.success) {
232
+ const signed = binding.data;
233
+ const derived = deriveServiceRef(signed.binding);
234
+ const signer = await recoverServiceBindingSigner(signed.binding, signed.signature);
235
+ if (derived.toLowerCase() !== listing.serviceRef.toLowerCase() ||
236
+ signed.serviceRef.toLowerCase() !== listing.serviceRef.toLowerCase() ||
237
+ signer === null ||
238
+ signer.toLowerCase() !== signed.binding.operator.toLowerCase() ||
239
+ listing.operator.toLowerCase() !==
240
+ signed.binding.operator.toLowerCase() ||
241
+ listing.publicUrl !== signed.binding.publicUrl ||
242
+ listing.access !== "public" ||
243
+ listing.accessUrl !== signed.binding.publicUrl) {
244
+ throw new InvokeAccessUrlError("listing does not match its verified signed binding");
245
+ }
246
+ return {
247
+ access: "public",
248
+ url: requireHttpUrl(signed.binding.publicUrl, "signed listing access URL"),
249
+ };
250
+ }
251
+ throw new InvokeAccessUrlError("listing signed record is invalid");
252
+ }
253
+ function requireHttpUrl(value, label) {
254
+ let parsed;
255
+ try {
256
+ parsed = new URL(value);
257
+ }
258
+ catch {
259
+ throw new InvokeAccessUrlError(`${label} must be an absolute HTTP(S) URL`);
260
+ }
261
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
262
+ throw new InvokeAccessUrlError(`${label} must be an absolute HTTP(S) URL`);
263
+ }
264
+ return parsed.toString();
265
+ }
266
+ function assertOriginRelativePath(path) {
267
+ if (!path.startsWith("/") || path.startsWith("//") || path.includes("#")) {
268
+ throw new InvokePathError(path);
269
+ }
270
+ }
271
+ function ensureTrailingSlash(value) {
272
+ return value.endsWith("/") ? value : `${value}/`;
273
+ }
274
+ //# sourceMappingURL=invoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/sdk/invoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { erc20Abi, type Address } from "viem";
2
+ /**
3
+ * Agent wallet lifecycle helpers (metrik-agent#65).
4
+ *
5
+ * `../wallet/provider.ts` already resolves a wallet (injected key or a
6
+ * Coinbase CDP Server Wallet v2 account) and hands back a viem `Account` that
7
+ * can sign directly — `resolveAgentWallet()`'s CDP path is create-OR-restore
8
+ * by construction (`cdp.evm.getOrCreateAccount({ name })` is idempotent: the
9
+ * same `ownerName` always resolves to the same on-chain address, so a second
10
+ * run with the same env "restores" rather than creates a new wallet).
11
+ *
12
+ * This module adds the remaining thin, non-custodial lifecycle pieces the
13
+ * issue asks for: reading balances, a testnet faucet hint, and requesting
14
+ * funds from the CDP faucet. It deliberately does NOT wrap signing — a
15
+ * `ResolvedAgentWallet.account` is already a plain viem `Account`
16
+ * (`signMessage` / `signTypedData` / `signTransaction` all work as-is), and
17
+ * adding a second signing surface here would be exactly the "second wallet
18
+ * system" AGENTS.md warns against.
19
+ */
20
+ /** Native gas balance + USDC balance for one address. */
21
+ export interface WalletBalances {
22
+ /** Native token balance (ETH on Base/Base Sepolia), in wei. */
23
+ readonly nativeWei: bigint;
24
+ /** USDC balance, in atomic units (6 decimals). */
25
+ readonly usdcAtomic: bigint;
26
+ }
27
+ /** The subset of a viem `PublicClient` balance reads need. Duck-typed so any real client satisfies it. */
28
+ export interface BalanceReader {
29
+ getBalance(args: {
30
+ readonly address: Address;
31
+ }): Promise<bigint>;
32
+ readContract(args: {
33
+ readonly address: Address;
34
+ readonly abi: typeof erc20Abi;
35
+ readonly functionName: "balanceOf";
36
+ readonly args: readonly [Address];
37
+ }): Promise<unknown>;
38
+ }
39
+ export interface GetWalletBalancesOptions {
40
+ readonly publicClient: BalanceReader;
41
+ readonly address: Address;
42
+ /** The USDC token contract to read the ERC-20 balance from. */
43
+ readonly usdc: Address;
44
+ }
45
+ /** Reads a wallet's native gas balance and USDC balance in one call. Read-only — no signing, no writes. */
46
+ export declare function getWalletBalances(options: GetWalletBalancesOptions): Promise<WalletBalances>;
47
+ /** Human-facing pointers to fund a freshly created/restored testnet wallet. */
48
+ export interface FaucetHint {
49
+ readonly network: string;
50
+ /** Coinbase CDP faucet — funds native ETH (and, on some networks, USDC) for a CDP-managed address. */
51
+ readonly cdpFaucetUrl: string;
52
+ /** Circle's own Base Sepolia USDC faucet — an alternative USDC source that doesn't require a CDP account. */
53
+ readonly usdcFaucetUrl: string;
54
+ /** How to request the same funds programmatically from a CDP wallet — see {@link requestCdpFaucet}. */
55
+ readonly programmaticHint: string;
56
+ }
57
+ export declare class UnsupportedFaucetChainError extends Error {
58
+ constructor(chainId: number);
59
+ }
60
+ /** A faucet hint for the given chain. Only Base Sepolia (84532) is supported — Metrik is testnet-only, single-chain. */
61
+ export declare function faucetHint(chainId: number): FaucetHint;
62
+ export type FaucetToken = "eth" | "usdc";
63
+ /** The subset of the Coinbase CDP client the faucet request needs. Duck-typed for testability. */
64
+ export interface CdpFaucetClientLike {
65
+ readonly evm: {
66
+ requestFaucet(options: {
67
+ readonly address: Address;
68
+ readonly network: string;
69
+ readonly token: FaucetToken;
70
+ }): Promise<{
71
+ readonly transactionHash: string;
72
+ }>;
73
+ };
74
+ }
75
+ export interface RequestCdpFaucetOptions {
76
+ readonly cdp: CdpFaucetClientLike;
77
+ readonly address: Address;
78
+ readonly token: FaucetToken;
79
+ /** Default `"base-sepolia"`. */
80
+ readonly network?: string;
81
+ }
82
+ export interface FaucetRequestResult {
83
+ /** `true` iff the faucet accepted the request (a tx hash was returned). */
84
+ readonly requested: boolean;
85
+ readonly txHash?: string;
86
+ /**
87
+ * Set when `requested` is `false`. The CDP faucet enforces a 24h per-address
88
+ * rate limit, so a failure here is an EXPECTED, non-fatal outcome — never
89
+ * thrown. Callers should log this and fall back to checking whether the
90
+ * balance is already sufficient.
91
+ */
92
+ readonly error?: string;
93
+ }
94
+ /**
95
+ * Requests testnet funds from the Coinbase CDP faucet for a CDP-managed
96
+ * address. Tolerates the faucet's 24h rate limit and any other request
97
+ * failure by returning `{ requested: false, error }` — it never throws, so a
98
+ * caller can always fall through to reading the current balance instead.
99
+ */
100
+ export declare function requestCdpFaucet(options: RequestCdpFaucetOptions): Promise<FaucetRequestResult>;
101
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/wallet/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AAEH,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,0GAA0G;AAC1G,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,YAAY,CAAC,IAAI,EAAE;QACjB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,GAAG,EAAE,OAAO,QAAQ,CAAC;QAC9B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC;QACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;KACnC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,2GAA2G;AAC3G,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sGAAsG;IACtG,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6GAA6G;IAC7G,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uGAAuG;IACvG,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAM5B;AAYD,wHAAwH;AACxH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAKtD;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzC,kGAAkG;AAClG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE;QACZ,aAAa,CAAC,OAAO,EAAE;YACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;YAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;SAC7B,GAAG,OAAO,CAAC;YAAE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnD,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,mBAAmB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,gCAAgC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CAc9B"}
@@ -0,0 +1,57 @@
1
+ import { erc20Abi } from "viem";
2
+ /** Reads a wallet's native gas balance and USDC balance in one call. Read-only — no signing, no writes. */
3
+ export async function getWalletBalances(options) {
4
+ const [nativeWei, usdcAtomic] = await Promise.all([
5
+ options.publicClient.getBalance({ address: options.address }),
6
+ options.publicClient.readContract({
7
+ address: options.usdc,
8
+ abi: erc20Abi,
9
+ functionName: "balanceOf",
10
+ args: [options.address],
11
+ }),
12
+ ]);
13
+ return { nativeWei, usdcAtomic: usdcAtomic };
14
+ }
15
+ export class UnsupportedFaucetChainError extends Error {
16
+ constructor(chainId) {
17
+ super(`no known testnet faucet for chainId ${chainId} (Metrik is Base Sepolia (84532) only)`);
18
+ this.name = "UnsupportedFaucetChainError";
19
+ }
20
+ }
21
+ const BASE_SEPOLIA_CHAIN_ID = 84532;
22
+ const BASE_SEPOLIA_FAUCET_HINT = {
23
+ network: "base-sepolia",
24
+ cdpFaucetUrl: "https://portal.cdp.coinbase.com/products/faucet",
25
+ usdcFaucetUrl: "https://faucet.circle.com",
26
+ programmaticHint: "requestCdpFaucet({ cdp, address, token: 'eth' | 'usdc' }) — subject to a 24h per-address rate limit",
27
+ };
28
+ /** A faucet hint for the given chain. Only Base Sepolia (84532) is supported — Metrik is testnet-only, single-chain. */
29
+ export function faucetHint(chainId) {
30
+ if (chainId !== BASE_SEPOLIA_CHAIN_ID) {
31
+ throw new UnsupportedFaucetChainError(chainId);
32
+ }
33
+ return BASE_SEPOLIA_FAUCET_HINT;
34
+ }
35
+ /**
36
+ * Requests testnet funds from the Coinbase CDP faucet for a CDP-managed
37
+ * address. Tolerates the faucet's 24h rate limit and any other request
38
+ * failure by returning `{ requested: false, error }` — it never throws, so a
39
+ * caller can always fall through to reading the current balance instead.
40
+ */
41
+ export async function requestCdpFaucet(options) {
42
+ try {
43
+ const result = await options.cdp.evm.requestFaucet({
44
+ address: options.address,
45
+ network: options.network ?? "base-sepolia",
46
+ token: options.token,
47
+ });
48
+ return { requested: true, txHash: result.transactionHash };
49
+ }
50
+ catch (error) {
51
+ return {
52
+ requested: false,
53
+ error: error instanceof Error ? error.message : String(error),
54
+ };
55
+ }
56
+ }
57
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/wallet/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAgB,MAAM,MAAM,CAAC;AA+C9C,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAiC;IAEjC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7D,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC;YAChC,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,GAAG,EAAE,QAAQ;YACb,YAAY,EAAE,WAAW;YACzB,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;SACxB,CAAC;KACH,CAAC,CAAC;IACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAoB,EAAE,CAAC;AACzD,CAAC;AAaD,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,OAAe;QACzB,KAAK,CACH,uCAAuC,OAAO,wCAAwC,CACvF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAEpC,MAAM,wBAAwB,GAAe;IAC3C,OAAO,EAAE,cAAc;IACvB,YAAY,EAAE,iDAAiD;IAC/D,aAAa,EAAE,2BAA2B;IAC1C,gBAAgB,EACd,qGAAqG;CACxG,CAAC;AAEF,wHAAwH;AACxH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,IAAI,OAAO,KAAK,qBAAqB,EAAE,CAAC;QACtC,MAAM,IAAI,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAoCD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC;YACjD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc;YAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absol-labs/agent",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Metrik agent layer: x402 verified-streaming payments, an MCP server, framework tools, and spend mandates so AI agents can hire and pay verified services safely.",
5
5
  "license": "MIT",
6
6
  "author": "Absol Labs",
@@ -66,8 +66,8 @@
66
66
  "pnpm": "9.15.x"
67
67
  },
68
68
  "dependencies": {
69
- "@absol-labs/sdk": "^0.4.0",
70
- "@absol-labs/shared": "^0.11.0",
69
+ "@absol-labs/sdk": "^0.7.0",
70
+ "@absol-labs/shared": "^0.12.1",
71
71
  "@coinbase/cdp-sdk": "^1.51.2",
72
72
  "@modelcontextprotocol/sdk": "^1.29.0",
73
73
  "@reclaimprotocol/js-sdk": "^5.6.0",
@@ -108,9 +108,12 @@
108
108
  "build:e2e": "tsc -p tsconfig.e2e.build.json",
109
109
  "mcp:stdio": "tsx src/mcp/stdio.ts",
110
110
  "mcp:http": "tsx src/mcp/http-server.ts",
111
+ "gateway": "tsx src/gateway/server-entry.ts",
111
112
  "e2e:cdp": "node dist-e2e/scripts/e2e-cdp.js",
113
+ "e2e:hire": "tsx scripts/e2e-hire.ts",
112
114
  "l2:proof": "node scripts/l2-proof.mjs",
113
115
  "test": "vitest run",
116
+ "test:package": "node scripts/test-packed-package.mjs",
114
117
  "typecheck": "tsc -p tsconfig.json --noEmit",
115
118
  "typecheck:e2e": "tsc -p tsconfig.e2e.json --noEmit",
116
119
  "lint": "tsc -p tsconfig.json --noEmit",