@absol-labs/agent 0.12.0-rc.1 → 0.12.0-rc.2
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 +1 -1
- package/dist/cli/commands/claim.d.ts +32 -0
- package/dist/cli/commands/claim.d.ts.map +1 -1
- package/dist/cli/commands/claim.js +115 -27
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/pay.d.ts +15 -0
- package/dist/cli/commands/pay.d.ts.map +1 -1
- package/dist/cli/commands/pay.js +131 -7
- package/dist/cli/commands/pay.js.map +1 -1
- package/dist/cli/commands/reclaim.d.ts.map +1 -1
- package/dist/cli/commands/reclaim.js +20 -4
- package/dist/cli/commands/reclaim.js.map +1 -1
- package/dist/cli/commands/refund.d.ts +19 -1
- package/dist/cli/commands/refund.d.ts.map +1 -1
- package/dist/cli/commands/refund.js +200 -27
- package/dist/cli/commands/refund.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +11 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +2 -0
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/context.d.ts +19 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/deps.d.ts +20 -0
- package/dist/cli/deps.d.ts.map +1 -1
- package/dist/cli/deps.js +14 -0
- package/dist/cli/deps.js.map +1 -1
- package/dist/cli/progress.d.ts +13 -1
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +7 -1
- package/dist/cli/progress.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +26 -14
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/status.d.ts +103 -0
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +310 -41
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/wallet.d.ts +1 -1
- package/dist/cli/wallet.d.ts.map +1 -1
- package/dist/cli/wallet.js +28 -4
- package/dist/cli/wallet.js.map +1 -1
- package/dist/gateway/http-server.d.ts +17 -0
- package/dist/gateway/http-server.d.ts.map +1 -1
- package/dist/gateway/http-server.js +76 -9
- package/dist/gateway/http-server.js.map +1 -1
- package/dist/gateway/x402-opener-mode.d.ts +39 -2
- package/dist/gateway/x402-opener-mode.d.ts.map +1 -1
- package/dist/gateway/x402-opener-mode.js +169 -36
- package/dist/gateway/x402-opener-mode.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +28 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/x402-tools.d.ts +8 -3
- package/dist/mcp/x402-tools.d.ts.map +1 -1
- package/dist/mcp/x402-tools.js +126 -6
- package/dist/mcp/x402-tools.js.map +1 -1
- package/dist/sdk/client.d.ts +13 -0
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/client.js +15 -0
- package/dist/sdk/client.js.map +1 -1
- package/dist/x402-buyer/pay.d.ts +22 -0
- package/dist/x402-buyer/pay.d.ts.map +1 -1
- package/dist/x402-buyer/pay.js +33 -3
- package/dist/x402-buyer/pay.js.map +1 -1
- package/dist/x402-opener/facilitator-entry.js +4 -1
- package/dist/x402-opener/facilitator-entry.js.map +1 -1
- package/dist/x402-opener/facilitator-server.d.ts +29 -0
- package/dist/x402-opener/facilitator-server.d.ts.map +1 -1
- package/dist/x402-opener/facilitator-server.js +67 -1
- package/dist/x402-opener/facilitator-server.js.map +1 -1
- package/dist/x402-opener/refund-relay.d.ts +30 -4
- package/dist/x402-opener/refund-relay.d.ts.map +1 -1
- package/dist/x402-opener/refund-relay.js +123 -22
- package/dist/x402-opener/refund-relay.js.map +1 -1
- package/dist/x402-opener/scheme.d.ts +79 -0
- package/dist/x402-opener/scheme.d.ts.map +1 -1
- package/dist/x402-opener/scheme.js +326 -40
- package/dist/x402-opener/scheme.js.map +1 -1
- package/dist/x402-opener/terms.d.ts +61 -1
- package/dist/x402-opener/terms.d.ts.map +1 -1
- package/dist/x402-opener/terms.js +94 -2
- package/dist/x402-opener/terms.js.map +1 -1
- package/docs/cli.md +87 -9
- package/docs/mcp-reference.md +18 -2
- package/docs/quickstart.md +3 -3
- package/docs/x402.md +150 -10
- package/package.json +3 -3
- package/src/cli/commands/claim.ts +167 -32
- package/src/cli/commands/pay.ts +150 -8
- package/src/cli/commands/reclaim.ts +25 -5
- package/src/cli/commands/refund.ts +231 -33
- package/src/cli/commands/status.ts +11 -1
- package/src/cli/commands/watch.ts +4 -0
- package/src/cli/context.ts +16 -0
- package/src/cli/deps.ts +37 -0
- package/src/cli/progress.ts +21 -2
- package/src/cli/run.ts +26 -13
- package/src/cli/status.ts +440 -43
- package/src/cli/wallet.ts +44 -7
- package/src/gateway/http-server.ts +96 -8
- package/src/gateway/x402-opener-mode.ts +234 -37
- package/src/mcp/server.ts +43 -11
- package/src/mcp/x402-tools.ts +171 -7
- package/src/sdk/client.ts +25 -0
- package/src/x402-buyer/pay.ts +41 -3
- package/src/x402-opener/facilitator-entry.ts +4 -1
- package/src/x402-opener/facilitator-server.ts +101 -1
- package/src/x402-opener/refund-relay.ts +150 -20
- package/src/x402-opener/scheme.ts +459 -41
- package/src/x402-opener/terms.ts +155 -2
package/src/x402-opener/terms.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InvalidUpfrontTermsError,
|
|
3
|
+
validateUpfrontTerms,
|
|
4
|
+
} from "@absol-labs/shared";
|
|
1
5
|
import { getAddress, isAddress, isHex, type Address, type Hex } from "viem";
|
|
2
6
|
|
|
3
7
|
/**
|
|
@@ -51,6 +55,96 @@ export interface OpenerTerms {
|
|
|
51
55
|
readonly maxDuration: bigint;
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Which opener contract a factory deploys: `"stream"` (`X402StreamOpener`,
|
|
60
|
+
* 4-field terms, the whole payment funds a stream) or `"upfront"`
|
|
61
|
+
* (`X402UpfrontStreamOpener`, 6-field terms: a fixed `price` whose
|
|
62
|
+
* non-refundable `upfrontAmount` is paid to the seller at settlement and whose
|
|
63
|
+
* remainder funds a stream). Decided by WHICH configured factory a quote names,
|
|
64
|
+
* never by the wire fields alone.
|
|
65
|
+
*/
|
|
66
|
+
export type OpenerKind = "stream" | "upfront";
|
|
67
|
+
|
|
68
|
+
/** `termsVersion` of each opener kind's `extra.metrikStreamOpener` (as the SDK checks it). */
|
|
69
|
+
export const OPENER_TERMS_VERSION = {
|
|
70
|
+
stream: "stream-1",
|
|
71
|
+
upfront: "upfront-1",
|
|
72
|
+
} as const satisfies Record<OpenerKind, string>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The 6-field terms of an `X402UpfrontStreamOpener` (metrik-contracts#54),
|
|
76
|
+
* mirroring the Solidity struct. Every field is committed by the `payTo`.
|
|
77
|
+
*/
|
|
78
|
+
export interface UpfrontOpenerTerms extends OpenerTerms {
|
|
79
|
+
/** The exact x402 amount: the opener accepts this value and nothing else. */
|
|
80
|
+
readonly price: bigint;
|
|
81
|
+
/** NON-REFUNDABLE part paid to the seller (net of the protocol fee) at settlement. `<= price`. */
|
|
82
|
+
readonly upfrontAmount: bigint;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The refundable, metered part of an upfront opener's price (the stream deposit). */
|
|
86
|
+
export function upfrontRefundable(terms: UpfrontOpenerTerms): bigint {
|
|
87
|
+
return terms.price - terms.upfrontAmount;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** True when an upfront opener opens no stream at all (`upfrontAmount == price`). */
|
|
91
|
+
export function isUpfrontOnly(terms: UpfrontOpenerTerms): boolean {
|
|
92
|
+
return terms.price > 0n && terms.upfrontAmount === terms.price;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The upfront terms a gateway may quote: exactly the factory's
|
|
97
|
+
* `validateTerms` (via `@absol-labs/shared`'s `validateUpfrontTerms`, so a
|
|
98
|
+
* `payTo` no transaction can deploy is never quoted), a fixed non-zero price,
|
|
99
|
+
* and a metered part (`price - upfrontAmount`) the stream can actually earn
|
|
100
|
+
* (`<= ratePerSecond * maxDuration`) — the SDK buyer refuses anything else.
|
|
101
|
+
*/
|
|
102
|
+
export function assertValidUpfrontTerms(terms: UpfrontOpenerTerms): void {
|
|
103
|
+
assertValidTerms(terms);
|
|
104
|
+
try {
|
|
105
|
+
validateUpfrontTerms({
|
|
106
|
+
operator: getAddress(terms.operator),
|
|
107
|
+
serviceRef: terms.serviceRef.toLowerCase() as Hex,
|
|
108
|
+
ratePerSecond: terms.ratePerSecond,
|
|
109
|
+
maxDuration: terms.maxDuration,
|
|
110
|
+
price: terms.price,
|
|
111
|
+
upfrontAmount: terms.upfrontAmount,
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw new InvalidOpenerTermsError(
|
|
115
|
+
error instanceof InvalidUpfrontTermsError || error instanceof Error
|
|
116
|
+
? error.message
|
|
117
|
+
: String(error),
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
if (terms.price <= 0n) {
|
|
121
|
+
throw new InvalidOpenerTermsError(
|
|
122
|
+
"an upfront opener needs a fixed price > 0",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (upfrontRefundable(terms) > maxEarnable(terms)) {
|
|
126
|
+
throw new InvalidOpenerTermsError(
|
|
127
|
+
`the metered part ${upfrontRefundable(terms)} (price - upfrontAmount) exceeds ratePerSecond * maxDuration (${maxEarnable(terms)})`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Solidity-tuple view of 6-field upfront terms for viem contract calls. */
|
|
133
|
+
export function upfrontTermsTuple(terms: UpfrontOpenerTerms): {
|
|
134
|
+
readonly operator: Address;
|
|
135
|
+
readonly serviceRef: Hex;
|
|
136
|
+
readonly ratePerSecond: bigint;
|
|
137
|
+
readonly maxDuration: bigint;
|
|
138
|
+
readonly price: bigint;
|
|
139
|
+
readonly upfrontAmount: bigint;
|
|
140
|
+
} {
|
|
141
|
+
return {
|
|
142
|
+
...termsTuple(terms),
|
|
143
|
+
price: terms.price,
|
|
144
|
+
upfrontAmount: terms.upfrontAmount,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
54
148
|
/** JSON-safe projection of {@link OpenerTerms} plus the factory that prices them. */
|
|
55
149
|
export interface OpenerTermsExtra {
|
|
56
150
|
readonly factory: Address;
|
|
@@ -58,6 +152,12 @@ export interface OpenerTermsExtra {
|
|
|
58
152
|
readonly serviceRef: Hex;
|
|
59
153
|
readonly ratePerSecond: string;
|
|
60
154
|
readonly maxDuration: string;
|
|
155
|
+
/** Upfront openers only: the exact price (base units). */
|
|
156
|
+
readonly price?: string;
|
|
157
|
+
/** Upfront openers only: the non-refundable per-call part (base units). */
|
|
158
|
+
readonly upfrontAmount?: string;
|
|
159
|
+
/** `stream-1` / `upfront-1`; optional, must match the factory's kind when present. */
|
|
160
|
+
readonly termsVersion?: string;
|
|
61
161
|
/**
|
|
62
162
|
* Informational only (metrik-agent#119): where the payer gets unearned money
|
|
63
163
|
* back without ETH, as a template containing `{streamId}`. Never used for
|
|
@@ -158,14 +258,38 @@ export function termsToExtra(
|
|
|
158
258
|
};
|
|
159
259
|
}
|
|
160
260
|
|
|
261
|
+
/** The 402 `extra.metrikStreamOpener` terms of an upfront opener quote. */
|
|
262
|
+
export function upfrontTermsToExtra(
|
|
263
|
+
factory: Address,
|
|
264
|
+
terms: UpfrontOpenerTerms,
|
|
265
|
+
): OpenerTermsExtra {
|
|
266
|
+
return {
|
|
267
|
+
factory: getAddress(factory),
|
|
268
|
+
termsVersion: OPENER_TERMS_VERSION.upfront,
|
|
269
|
+
operator: getAddress(terms.operator),
|
|
270
|
+
serviceRef: terms.serviceRef.toLowerCase() as Hex,
|
|
271
|
+
ratePerSecond: terms.ratePerSecond.toString(),
|
|
272
|
+
maxDuration: terms.maxDuration.toString(),
|
|
273
|
+
price: terms.price.toString(),
|
|
274
|
+
upfrontAmount: terms.upfrontAmount.toString(),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
161
278
|
/**
|
|
162
279
|
* Reads opener terms from an untrusted `PaymentRequirements.extra`. Every field
|
|
163
280
|
* is re-validated; unknown keys under the opener object are rejected so the
|
|
164
|
-
* wire shape cannot drift silently.
|
|
281
|
+
* wire shape cannot drift silently. `price` / `upfrontAmount` are returned as
|
|
282
|
+
* `upfront` when present (both or neither); whether they are REQUIRED or
|
|
283
|
+
* FORBIDDEN depends on the factory's kind, which only the caller knows.
|
|
165
284
|
*/
|
|
166
285
|
export function termsFromExtra(extra: unknown): {
|
|
167
286
|
readonly factory: Address;
|
|
168
287
|
readonly terms: OpenerTerms;
|
|
288
|
+
readonly upfront?: {
|
|
289
|
+
readonly price: bigint;
|
|
290
|
+
readonly upfrontAmount: bigint;
|
|
291
|
+
};
|
|
292
|
+
readonly termsVersion?: string;
|
|
169
293
|
} {
|
|
170
294
|
if (typeof extra !== "object" || extra === null) {
|
|
171
295
|
throw new InvalidOpenerTermsError("requirements.extra is missing");
|
|
@@ -183,6 +307,9 @@ export function termsFromExtra(extra: unknown): {
|
|
|
183
307
|
"serviceRef",
|
|
184
308
|
"ratePerSecond",
|
|
185
309
|
"maxDuration",
|
|
310
|
+
"price",
|
|
311
|
+
"upfrontAmount",
|
|
312
|
+
"termsVersion",
|
|
186
313
|
"refundUrl",
|
|
187
314
|
"docsUrl",
|
|
188
315
|
]);
|
|
@@ -217,7 +344,33 @@ export function termsFromExtra(extra: unknown): {
|
|
|
217
344
|
maxDuration: parseUintString(record.maxDuration, "maxDuration"),
|
|
218
345
|
};
|
|
219
346
|
assertValidTerms(terms);
|
|
220
|
-
|
|
347
|
+
const termsVersion = record.termsVersion;
|
|
348
|
+
if (
|
|
349
|
+
termsVersion !== undefined &&
|
|
350
|
+
(typeof termsVersion !== "string" || termsVersion.length > 64)
|
|
351
|
+
) {
|
|
352
|
+
throw new InvalidOpenerTermsError("termsVersion must be a short string");
|
|
353
|
+
}
|
|
354
|
+
if ((record.price === undefined) !== (record.upfrontAmount === undefined)) {
|
|
355
|
+
throw new InvalidOpenerTermsError(
|
|
356
|
+
"price and upfrontAmount must be given together (an upfront opener's terms) or not at all",
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
const upfront =
|
|
360
|
+
record.price === undefined
|
|
361
|
+
? undefined
|
|
362
|
+
: {
|
|
363
|
+
price: parseUintString(record.price, "price"),
|
|
364
|
+
upfrontAmount: parseUintString(record.upfrontAmount, "upfrontAmount"),
|
|
365
|
+
};
|
|
366
|
+
return {
|
|
367
|
+
factory: getAddress(factory),
|
|
368
|
+
terms,
|
|
369
|
+
...(upfront === undefined ? {} : { upfront }),
|
|
370
|
+
...(termsVersion === undefined
|
|
371
|
+
? {}
|
|
372
|
+
: { termsVersion: termsVersion as string }),
|
|
373
|
+
};
|
|
221
374
|
}
|
|
222
375
|
|
|
223
376
|
/** Chain id encoded in an `eip155:<id>` CAIP-2 identifier. Throws otherwise. */
|