@absol-labs/agent 0.9.1 → 0.11.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 (293) hide show
  1. package/README.md +184 -26
  2. package/dist/capability/invocation-capability.d.ts +18 -6
  3. package/dist/capability/invocation-capability.d.ts.map +1 -1
  4. package/dist/capability/invocation-capability.js.map +1 -1
  5. package/dist/cli/amounts.d.ts +26 -0
  6. package/dist/cli/amounts.d.ts.map +1 -0
  7. package/dist/cli/amounts.js +71 -0
  8. package/dist/cli/amounts.js.map +1 -0
  9. package/dist/cli/args.d.ts +32 -0
  10. package/dist/cli/args.d.ts.map +1 -0
  11. package/dist/cli/args.js +119 -0
  12. package/dist/cli/args.js.map +1 -0
  13. package/dist/cli/attesters.d.ts +51 -0
  14. package/dist/cli/attesters.d.ts.map +1 -0
  15. package/dist/cli/attesters.js +58 -0
  16. package/dist/cli/attesters.js.map +1 -0
  17. package/dist/cli/bin.d.ts +3 -0
  18. package/dist/cli/bin.d.ts.map +1 -0
  19. package/dist/cli/bin.js +5 -0
  20. package/dist/cli/bin.js.map +1 -0
  21. package/dist/cli/commands/claim.d.ts +13 -0
  22. package/dist/cli/commands/claim.d.ts.map +1 -0
  23. package/dist/cli/commands/claim.js +102 -0
  24. package/dist/cli/commands/claim.js.map +1 -0
  25. package/dist/cli/commands/close.d.ts +3 -0
  26. package/dist/cli/commands/close.d.ts.map +1 -0
  27. package/dist/cli/commands/close.js +55 -0
  28. package/dist/cli/commands/close.js.map +1 -0
  29. package/dist/cli/commands/discover.d.ts +3 -0
  30. package/dist/cli/commands/discover.d.ts.map +1 -0
  31. package/dist/cli/commands/discover.js +183 -0
  32. package/dist/cli/commands/discover.js.map +1 -0
  33. package/dist/cli/commands/invoke.d.ts +3 -0
  34. package/dist/cli/commands/invoke.d.ts.map +1 -0
  35. package/dist/cli/commands/invoke.js +142 -0
  36. package/dist/cli/commands/invoke.js.map +1 -0
  37. package/dist/cli/commands/mcp.d.ts +3 -0
  38. package/dist/cli/commands/mcp.d.ts.map +1 -0
  39. package/dist/cli/commands/mcp.js +113 -0
  40. package/dist/cli/commands/mcp.js.map +1 -0
  41. package/dist/cli/commands/open.d.ts +3 -0
  42. package/dist/cli/commands/open.d.ts.map +1 -0
  43. package/dist/cli/commands/open.js +331 -0
  44. package/dist/cli/commands/open.js.map +1 -0
  45. package/dist/cli/commands/reclaim-unverified.d.ts +3 -0
  46. package/dist/cli/commands/reclaim-unverified.d.ts.map +1 -0
  47. package/dist/cli/commands/reclaim-unverified.js +172 -0
  48. package/dist/cli/commands/reclaim-unverified.js.map +1 -0
  49. package/dist/cli/commands/reclaim.d.ts +33 -0
  50. package/dist/cli/commands/reclaim.d.ts.map +1 -0
  51. package/dist/cli/commands/reclaim.js +308 -0
  52. package/dist/cli/commands/reclaim.js.map +1 -0
  53. package/dist/cli/commands/status.d.ts +3 -0
  54. package/dist/cli/commands/status.d.ts.map +1 -0
  55. package/dist/cli/commands/status.js +43 -0
  56. package/dist/cli/commands/status.js.map +1 -0
  57. package/dist/cli/commands/streams.d.ts +3 -0
  58. package/dist/cli/commands/streams.d.ts.map +1 -0
  59. package/dist/cli/commands/streams.js +257 -0
  60. package/dist/cli/commands/streams.js.map +1 -0
  61. package/dist/cli/commands/watch.d.ts +3 -0
  62. package/dist/cli/commands/watch.d.ts.map +1 -0
  63. package/dist/cli/commands/watch.js +55 -0
  64. package/dist/cli/commands/watch.js.map +1 -0
  65. package/dist/cli/config.d.ts +61 -0
  66. package/dist/cli/config.d.ts.map +1 -0
  67. package/dist/cli/config.js +140 -0
  68. package/dist/cli/config.js.map +1 -0
  69. package/dist/cli/context.d.ts +29 -0
  70. package/dist/cli/context.d.ts.map +1 -0
  71. package/dist/cli/context.js +2 -0
  72. package/dist/cli/context.js.map +1 -0
  73. package/dist/cli/deps.d.ts +191 -0
  74. package/dist/cli/deps.d.ts.map +1 -0
  75. package/dist/cli/deps.js +277 -0
  76. package/dist/cli/deps.js.map +1 -0
  77. package/dist/cli/descriptor.d.ts +61 -0
  78. package/dist/cli/descriptor.d.ts.map +1 -0
  79. package/dist/cli/descriptor.js +78 -0
  80. package/dist/cli/descriptor.js.map +1 -0
  81. package/dist/cli/errors.d.ts +48 -0
  82. package/dist/cli/errors.d.ts.map +1 -0
  83. package/dist/cli/errors.js +129 -0
  84. package/dist/cli/errors.js.map +1 -0
  85. package/dist/cli/escape-hatch.d.ts +50 -0
  86. package/dist/cli/escape-hatch.d.ts.map +1 -0
  87. package/dist/cli/escape-hatch.js +45 -0
  88. package/dist/cli/escape-hatch.js.map +1 -0
  89. package/dist/cli/index.d.ts +8 -0
  90. package/dist/cli/index.d.ts.map +1 -0
  91. package/dist/cli/index.js +7 -0
  92. package/dist/cli/index.js.map +1 -0
  93. package/dist/cli/listings.d.ts +15 -0
  94. package/dist/cli/listings.d.ts.map +1 -0
  95. package/dist/cli/listings.js +56 -0
  96. package/dist/cli/listings.js.map +1 -0
  97. package/dist/cli/mandate.d.ts +66 -0
  98. package/dist/cli/mandate.d.ts.map +1 -0
  99. package/dist/cli/mandate.js +61 -0
  100. package/dist/cli/mandate.js.map +1 -0
  101. package/dist/cli/output.d.ts +33 -0
  102. package/dist/cli/output.d.ts.map +1 -0
  103. package/dist/cli/output.js +34 -0
  104. package/dist/cli/output.js.map +1 -0
  105. package/dist/cli/preflight.d.ts +38 -0
  106. package/dist/cli/preflight.d.ts.map +1 -0
  107. package/dist/cli/preflight.js +72 -0
  108. package/dist/cli/preflight.js.map +1 -0
  109. package/dist/cli/privy.d.ts +83 -0
  110. package/dist/cli/privy.d.ts.map +1 -0
  111. package/dist/cli/privy.js +230 -0
  112. package/dist/cli/privy.js.map +1 -0
  113. package/dist/cli/progress.d.ts +36 -0
  114. package/dist/cli/progress.d.ts.map +1 -0
  115. package/dist/cli/progress.js +40 -0
  116. package/dist/cli/progress.js.map +1 -0
  117. package/dist/cli/run.d.ts +25 -0
  118. package/dist/cli/run.d.ts.map +1 -0
  119. package/dist/cli/run.js +173 -0
  120. package/dist/cli/run.js.map +1 -0
  121. package/dist/cli/scan-range.d.ts +55 -0
  122. package/dist/cli/scan-range.d.ts.map +1 -0
  123. package/dist/cli/scan-range.js +57 -0
  124. package/dist/cli/scan-range.js.map +1 -0
  125. package/dist/cli/spend-policy.d.ts +60 -0
  126. package/dist/cli/spend-policy.d.ts.map +1 -0
  127. package/dist/cli/spend-policy.js +65 -0
  128. package/dist/cli/spend-policy.js.map +1 -0
  129. package/dist/cli/status.d.ts +90 -0
  130. package/dist/cli/status.d.ts.map +1 -0
  131. package/dist/cli/status.js +252 -0
  132. package/dist/cli/status.js.map +1 -0
  133. package/dist/cli/timeout.d.ts +30 -0
  134. package/dist/cli/timeout.d.ts.map +1 -0
  135. package/dist/cli/timeout.js +55 -0
  136. package/dist/cli/timeout.js.map +1 -0
  137. package/dist/cli/version.d.ts +12 -0
  138. package/dist/cli/version.d.ts.map +1 -0
  139. package/dist/cli/version.js +22 -0
  140. package/dist/cli/version.js.map +1 -0
  141. package/dist/cli/wallet.d.ts +164 -0
  142. package/dist/cli/wallet.d.ts.map +1 -0
  143. package/dist/cli/wallet.js +234 -0
  144. package/dist/cli/wallet.js.map +1 -0
  145. package/dist/frameworks/crewai.d.ts +10 -0
  146. package/dist/frameworks/crewai.d.ts.map +1 -1
  147. package/dist/frameworks/crewai.js +12 -2
  148. package/dist/frameworks/crewai.js.map +1 -1
  149. package/dist/gateway/caller-auth-gateway.d.ts +38 -3
  150. package/dist/gateway/caller-auth-gateway.d.ts.map +1 -1
  151. package/dist/gateway/caller-auth-gateway.js +25 -1
  152. package/dist/gateway/caller-auth-gateway.js.map +1 -1
  153. package/dist/gateway/http-server.d.ts +53 -0
  154. package/dist/gateway/http-server.d.ts.map +1 -1
  155. package/dist/gateway/http-server.js +189 -4
  156. package/dist/gateway/http-server.js.map +1 -1
  157. package/dist/gateway/server-entry.d.ts +1 -0
  158. package/dist/gateway/server-entry.js +1 -0
  159. package/dist/gateway/server-entry.js.map +1 -1
  160. package/dist/gateway/x402-mode.d.ts +123 -0
  161. package/dist/gateway/x402-mode.d.ts.map +1 -0
  162. package/dist/gateway/x402-mode.js +212 -0
  163. package/dist/gateway/x402-mode.js.map +1 -0
  164. package/dist/index.d.ts +6 -4
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +8 -3
  167. package/dist/index.js.map +1 -1
  168. package/dist/mandates/env.d.ts +3 -2
  169. package/dist/mandates/env.d.ts.map +1 -1
  170. package/dist/mandates/env.js +3 -2
  171. package/dist/mandates/env.js.map +1 -1
  172. package/dist/mcp/http-server.d.ts +1 -0
  173. package/dist/mcp/http-server.js +1 -0
  174. package/dist/mcp/http-server.js.map +1 -1
  175. package/dist/mcp/server.d.ts +49 -0
  176. package/dist/mcp/server.d.ts.map +1 -1
  177. package/dist/mcp/server.js +533 -25
  178. package/dist/mcp/server.js.map +1 -1
  179. package/dist/mcp/service-invoker.d.ts +97 -0
  180. package/dist/mcp/service-invoker.d.ts.map +1 -0
  181. package/dist/mcp/service-invoker.js +167 -0
  182. package/dist/mcp/service-invoker.js.map +1 -0
  183. package/dist/mcp/stdio.d.ts +1 -0
  184. package/dist/mcp/stdio.js +1 -0
  185. package/dist/mcp/stdio.js.map +1 -1
  186. package/dist/sdk/client.d.ts +25 -1
  187. package/dist/sdk/client.d.ts.map +1 -1
  188. package/dist/sdk/client.js +20 -1
  189. package/dist/sdk/client.js.map +1 -1
  190. package/dist/sdk/invoke.d.ts +19 -4
  191. package/dist/sdk/invoke.d.ts.map +1 -1
  192. package/dist/sdk/invoke.js +69 -5
  193. package/dist/sdk/invoke.js.map +1 -1
  194. package/dist/x402/delivery-oracle.d.ts +108 -0
  195. package/dist/x402/delivery-oracle.d.ts.map +1 -0
  196. package/dist/x402/delivery-oracle.js +174 -0
  197. package/dist/x402/delivery-oracle.js.map +1 -0
  198. package/dist/x402/facilitator-server-entry.d.ts +3 -0
  199. package/dist/x402/facilitator-server-entry.d.ts.map +1 -0
  200. package/dist/x402/facilitator-server-entry.js +27 -0
  201. package/dist/x402/facilitator-server-entry.js.map +1 -0
  202. package/dist/x402/facilitator-server.d.ts +73 -0
  203. package/dist/x402/facilitator-server.d.ts.map +1 -0
  204. package/dist/x402/facilitator-server.js +305 -0
  205. package/dist/x402/facilitator-server.js.map +1 -0
  206. package/dist/x402/facilitator.d.ts +69 -17
  207. package/dist/x402/facilitator.d.ts.map +1 -1
  208. package/dist/x402/facilitator.js +76 -33
  209. package/dist/x402/facilitator.js.map +1 -1
  210. package/dist/x402/payment-requirements.d.ts +106 -0
  211. package/dist/x402/payment-requirements.d.ts.map +1 -0
  212. package/dist/x402/payment-requirements.js +138 -0
  213. package/dist/x402/payment-requirements.js.map +1 -0
  214. package/dist/x402/relayer.d.ts +41 -0
  215. package/dist/x402/relayer.d.ts.map +1 -0
  216. package/dist/x402/relayer.js +64 -0
  217. package/dist/x402/relayer.js.map +1 -0
  218. package/dist/x402/resource-index.d.ts +75 -0
  219. package/dist/x402/resource-index.d.ts.map +1 -0
  220. package/dist/x402/resource-index.js +126 -0
  221. package/dist/x402/resource-index.js.map +1 -0
  222. package/dist/x402/verified-delivery-facilitator.d.ts +285 -0
  223. package/dist/x402/verified-delivery-facilitator.d.ts.map +1 -0
  224. package/dist/x402/verified-delivery-facilitator.js +423 -0
  225. package/dist/x402/verified-delivery-facilitator.js.map +1 -0
  226. package/dist/zktls/t2-delivery-proof.d.ts +6 -6
  227. package/docs/agent-layer.md +14 -9
  228. package/docs/cli.md +705 -0
  229. package/docs/crewai.md +6 -2
  230. package/docs/eliza.md +6 -1
  231. package/docs/mcp-hosted.md +7 -5
  232. package/docs/mcp-reference.md +175 -0
  233. package/docs/quickstart.md +36 -9
  234. package/docs/threat-model.md +4 -3
  235. package/docs/x402.md +648 -0
  236. package/package.json +33 -10
  237. package/src/capability/invocation-capability.ts +17 -1
  238. package/src/cli/amounts.ts +102 -0
  239. package/src/cli/args.ts +150 -0
  240. package/src/cli/attesters.ts +86 -0
  241. package/src/cli/bin.ts +5 -0
  242. package/src/cli/commands/claim.ts +126 -0
  243. package/src/cli/commands/close.ts +69 -0
  244. package/src/cli/commands/discover.ts +228 -0
  245. package/src/cli/commands/invoke.ts +178 -0
  246. package/src/cli/commands/mcp.ts +135 -0
  247. package/src/cli/commands/open.ts +397 -0
  248. package/src/cli/commands/reclaim-unverified.ts +218 -0
  249. package/src/cli/commands/reclaim.ts +377 -0
  250. package/src/cli/commands/status.ts +56 -0
  251. package/src/cli/commands/streams.ts +344 -0
  252. package/src/cli/commands/watch.ts +70 -0
  253. package/src/cli/config.ts +208 -0
  254. package/src/cli/context.ts +30 -0
  255. package/src/cli/deps.ts +528 -0
  256. package/src/cli/descriptor.ts +133 -0
  257. package/src/cli/errors.ts +162 -0
  258. package/src/cli/escape-hatch.ts +92 -0
  259. package/src/cli/index.ts +27 -0
  260. package/src/cli/listings.ts +77 -0
  261. package/src/cli/mandate.ts +126 -0
  262. package/src/cli/output.ts +63 -0
  263. package/src/cli/preflight.ts +88 -0
  264. package/src/cli/privy.ts +396 -0
  265. package/src/cli/progress.ts +75 -0
  266. package/src/cli/run.ts +209 -0
  267. package/src/cli/scan-range.ts +76 -0
  268. package/src/cli/spend-policy.ts +139 -0
  269. package/src/cli/status.ts +381 -0
  270. package/src/cli/timeout.ts +64 -0
  271. package/src/cli/version.ts +21 -0
  272. package/src/cli/wallet.ts +372 -0
  273. package/src/frameworks/crewai.ts +13 -2
  274. package/src/gateway/caller-auth-gateway.ts +77 -6
  275. package/src/gateway/http-server.ts +280 -6
  276. package/src/gateway/server-entry.ts +1 -0
  277. package/src/gateway/x402-mode.ts +350 -0
  278. package/src/index.ts +40 -5
  279. package/src/mandates/env.ts +3 -2
  280. package/src/mcp/http-server.ts +1 -0
  281. package/src/mcp/server.ts +706 -30
  282. package/src/mcp/service-invoker.ts +285 -0
  283. package/src/mcp/stdio.ts +1 -0
  284. package/src/sdk/client.ts +33 -1
  285. package/src/sdk/invoke.ts +90 -12
  286. package/src/x402/delivery-oracle.ts +285 -0
  287. package/src/x402/facilitator-server-entry.ts +35 -0
  288. package/src/x402/facilitator-server.ts +445 -0
  289. package/src/x402/facilitator.ts +125 -46
  290. package/src/x402/payment-requirements.ts +231 -0
  291. package/src/x402/relayer.ts +122 -0
  292. package/src/x402/resource-index.ts +228 -0
  293. package/src/x402/verified-delivery-facilitator.ts +744 -0
@@ -0,0 +1,423 @@
1
+ import { getAddress } from "viem";
2
+ import { PaymentPayloadSchema, PaymentRequirementsSchema, } from "x402/types";
3
+ import { X402_NETWORK_BY_CHAIN_ID, X402_USDC_BY_CHAIN_ID, X402_VERSION, } from "./payment-requirements.js";
4
+ export const SETTLEMENT_REFUSAL_DETAIL = Object.freeze({
5
+ "asset-not-allowed": "the settlement asset is not on this facilitator's allowlist. The relayer signs a call to " +
6
+ "`asset`, so an unrestricted asset would let a caller choose which contract the operator's " +
7
+ "key calls and pays gas for.",
8
+ "network-mismatch": "the payload or the requirements name a chain this facilitator does not settle on",
9
+ "zero-amount": "a zero-value settlement moves nothing and would only burn the relayer's gas",
10
+ "resource-not-tracked": "this relayer only pays gas for resources Metrik tracks, and this resource did not resolve " +
11
+ "to exactly one signed Metrik listing. The payment is not refused — any other facilitator " +
12
+ "can settle it; Metrik is declining to spend its own gas on it.",
13
+ });
14
+ export const DEFAULT_SETTLEMENT_SCOPE = "tracked-resources";
15
+ /**
16
+ * The `invalidReason` used when the delivery gate refuses.
17
+ *
18
+ * The enum has no member for "the resource is not delivering", so the choice is
19
+ * between members that are all imperfect. Every payer-side member
20
+ * (`invalid_payload`, `invalid_exact_evm_payload_signature`,
21
+ * `insufficient_funds`) would be an active lie: it sends the developer to debug
22
+ * a wallet that is working correctly. `unexpected_verify_error` is also false —
23
+ * this refusal is deliberate and expected, not an error.
24
+ *
25
+ * `invalid_payment_requirements` is the only member that points at the
26
+ * REQUIREMENTS side of the exchange, which is exactly where the problem is:
27
+ * Metrik will not settle a payment quoted for THIS resource to THIS payee right
28
+ * now. It is the honest member, and the `metrik.detail` string carries the rest.
29
+ */
30
+ export const DELIVERY_REFUSAL_REASON = "invalid_payment_requirements";
31
+ /**
32
+ * Default: `allow`.
33
+ *
34
+ * The standing Metrik rule is buyer-favouring, and it still is — but it applies
35
+ * where Metrik HOLDS the buyer's money and must decide whether to release it.
36
+ * Here Metrik holds nothing, so refusing does not protect a buyer's funds; it
37
+ * only denies them a service they asked to buy, on a rail that works fine
38
+ * without Metrik. Four things make `allow` the right default:
39
+ *
40
+ * 1. **Absent evidence is the normal case, not the exception.** The oracle's
41
+ * `/services` projection is built from ACTIVE STREAMS. A service with no live
42
+ * Metrik stream has no row at all — on the live oracle today that is every
43
+ * service. Failing closed would refuse 100% of payments, which is a broken
44
+ * facilitator rather than a careful one.
45
+ * 2. **Fail-closed is a censorship lever.** If "oracle down" meant "no payments",
46
+ * anyone who could degrade Metrik's oracle could block payments to a
47
+ * competitor listed on it. `allow` removes that lever entirely.
48
+ * 3. **The harms are asymmetric.** A wrong refusal denies a service outright. A
49
+ * wrong allowance passes one `exact` payment, at a price the buyer already
50
+ * agreed to, which by construction is one call's worth.
51
+ * 4. **A pass never claims anything.** `isValid: true` with
52
+ * `gate: "indeterminate"` says "no fresh evidence", and the annotation says
53
+ * so in the response. Nobody has to infer an endorsement that was not made.
54
+ *
55
+ * Set `indeterminatePolicy: "deny"` for a deployment that would rather refuse
56
+ * than proceed without positive fresh evidence. That is a real, supported
57
+ * choice — it is just not a safe default.
58
+ */
59
+ export const DEFAULT_INDETERMINATE_POLICY = "allow";
60
+ export class RelayerNotConfiguredError extends Error {
61
+ constructor() {
62
+ super("this facilitator has no settlement relayer configured, so /settle cannot broadcast. " +
63
+ "Set METRIK_X402_RELAYER_PRIVATE_KEY (and METRIK_X402_RPC_URL) to enable settlement. " +
64
+ "Refusing rather than silently returning a fake success.");
65
+ this.name = "RelayerNotConfiguredError";
66
+ }
67
+ }
68
+ export class MetrikVerifiedDeliveryFacilitator {
69
+ paymentVerifier;
70
+ paymentSettler;
71
+ resourceIndex;
72
+ deliveryOracle;
73
+ indeterminatePolicy;
74
+ network;
75
+ settlementAssets;
76
+ settlementScope;
77
+ constructor(options) {
78
+ const chainId = options.chainId ?? 84532;
79
+ const network = X402_NETWORK_BY_CHAIN_ID[chainId];
80
+ if (network === undefined) {
81
+ throw new Error(`x402 v1 has no network name for chain ${chainId} (Metrik settles on Base: 8453, 84532)`);
82
+ }
83
+ this.paymentVerifier = options.paymentVerifier;
84
+ this.paymentSettler = options.paymentSettler;
85
+ this.resourceIndex = options.resourceIndex;
86
+ this.deliveryOracle = options.deliveryOracle;
87
+ this.indeterminatePolicy =
88
+ options.indeterminatePolicy ?? DEFAULT_INDETERMINATE_POLICY;
89
+ this.network = network;
90
+ const defaultAsset = X402_USDC_BY_CHAIN_ID[chainId]?.address;
91
+ const allowlist = options.settlementAssetAllowlist ??
92
+ (defaultAsset === undefined ? [] : [defaultAsset]);
93
+ if (allowlist.length === 0) {
94
+ throw new Error(`no settlement asset allowlist for chain ${chainId} and none supplied. ` +
95
+ "Refusing to construct a facilitator that would either settle nothing or, " +
96
+ "worse, broadcast to a caller-chosen contract.");
97
+ }
98
+ const normalized = new Set();
99
+ for (const candidate of allowlist) {
100
+ let checksummed;
101
+ try {
102
+ checksummed = getAddress(candidate);
103
+ }
104
+ catch {
105
+ throw new Error(`settlementAssetAllowlist entry is not an EVM address: ${candidate}`);
106
+ }
107
+ normalized.add(checksummed);
108
+ }
109
+ this.settlementAssets = normalized;
110
+ this.settlementScope = options.settlementScope ?? DEFAULT_SETTLEMENT_SCOPE;
111
+ }
112
+ /** The assets this relayer may be asked to call, for logging at startup. */
113
+ get allowedSettlementAssets() {
114
+ return [...this.settlementAssets];
115
+ }
116
+ supported() {
117
+ return {
118
+ x402Version: X402_VERSION,
119
+ kind: [{ scheme: "exact", networkId: this.network, extra: {} }],
120
+ };
121
+ }
122
+ /** `POST /verify`. Takes an unvalidated body; never throws on bad input. */
123
+ async verify(body) {
124
+ const parsed = parseFacilitatorRequest(body);
125
+ if (parsed === undefined) {
126
+ return {
127
+ isValid: false,
128
+ invalidReason: "invalid_payload",
129
+ metrik: {
130
+ gate: "not-applicable",
131
+ settleable: false,
132
+ detail: "request body is not a valid x402 {paymentPayload, paymentRequirements} pair",
133
+ },
134
+ };
135
+ }
136
+ return this.evaluate(parsed.paymentPayload, parsed.paymentRequirements);
137
+ }
138
+ /**
139
+ * `POST /settle`. Re-runs the full gate before broadcasting: a facilitator
140
+ * must never settle something it would not verify, and `/settle` is reachable
141
+ * without `/verify` ever having been called.
142
+ */
143
+ async settle(body) {
144
+ const parsed = parseFacilitatorRequest(body);
145
+ if (parsed === undefined) {
146
+ return {
147
+ success: false,
148
+ errorReason: "invalid_payload",
149
+ transaction: "",
150
+ network: this.network,
151
+ metrik: {
152
+ gate: "not-applicable",
153
+ settleable: false,
154
+ detail: "request body is not a valid x402 {paymentPayload, paymentRequirements} pair",
155
+ },
156
+ };
157
+ }
158
+ // Settlement constraints that need no network round trip run FIRST, so a
159
+ // hostile body never reaches the RPC, the registry or the oracle — let
160
+ // alone the relayer.
161
+ const preflight = this.settlementPreflight(parsed.paymentPayload, parsed.paymentRequirements);
162
+ if (preflight !== undefined) {
163
+ return this.refuseSettlement(parsed.paymentPayload, preflight, undefined);
164
+ }
165
+ const gate = await this.evaluate(parsed.paymentPayload, parsed.paymentRequirements);
166
+ if (!gate.isValid) {
167
+ return {
168
+ success: false,
169
+ ...(gate.invalidReason === undefined
170
+ ? {}
171
+ : { errorReason: gate.invalidReason }),
172
+ transaction: "",
173
+ network: parsed.paymentPayload.network,
174
+ ...(gate.payer === undefined ? {} : { payer: gate.payer }),
175
+ metrik: gate.metrik,
176
+ };
177
+ }
178
+ if (!gate.metrik.settleable) {
179
+ return this.refuseSettlement(parsed.paymentPayload, gate.metrik.settlementRefusal ?? "resource-not-tracked", gate.metrik);
180
+ }
181
+ if (this.paymentSettler === undefined) {
182
+ throw new RelayerNotConfiguredError();
183
+ }
184
+ const settled = await this.paymentSettler.settle(parsed.paymentPayload, parsed.paymentRequirements);
185
+ return { ...settled, metrik: gate.metrik };
186
+ }
187
+ /**
188
+ * Settlement constraints checkable from the request alone — no RPC, no
189
+ * registry, no oracle. Returns the refusal, or `undefined` if the request
190
+ * clears them.
191
+ */
192
+ settlementPreflight(payload, requirements) {
193
+ if (payload.network !== this.network ||
194
+ requirements.network !== this.network) {
195
+ return "network-mismatch";
196
+ }
197
+ // THE control. Without it the relayer signs a call to whatever contract
198
+ // address the caller puts here. See `SettlementRefusalReason`.
199
+ let asset;
200
+ try {
201
+ asset = getAddress(requirements.asset);
202
+ }
203
+ catch {
204
+ return "asset-not-allowed";
205
+ }
206
+ if (!this.settlementAssets.has(asset)) {
207
+ return "asset-not-allowed";
208
+ }
209
+ let amount;
210
+ try {
211
+ amount = BigInt(requirements.maxAmountRequired);
212
+ }
213
+ catch {
214
+ return "zero-amount";
215
+ }
216
+ if (amount <= 0n) {
217
+ return "zero-amount";
218
+ }
219
+ return undefined;
220
+ }
221
+ /** Builds the standard-shaped refusal for a settlement the relayer declines. */
222
+ refuseSettlement(payload, reason, gate) {
223
+ return {
224
+ success: false,
225
+ errorReason: reason === "network-mismatch"
226
+ ? "invalid_network"
227
+ : "invalid_payment_requirements",
228
+ transaction: "",
229
+ network: this.network,
230
+ metrik: {
231
+ ...(gate ?? { gate: "not-applicable", detail: "" }),
232
+ settleable: false,
233
+ settlementRefusal: reason,
234
+ detail: SETTLEMENT_REFUSAL_DETAIL[reason],
235
+ },
236
+ };
237
+ }
238
+ async evaluate(payload, requirements) {
239
+ const evaluated = await this.evaluateGate(payload, requirements);
240
+ // `settleable` is computed once, here, from the same facts `/settle`
241
+ // enforces — so a resource server reading `/verify` learns BEFORE it does
242
+ // any work whether this relayer will actually broadcast.
243
+ const refusal = this.settlementPreflight(payload, requirements) ??
244
+ (evaluated.isValid
245
+ ? this.scopeRefusal(evaluated.metrik.gate)
246
+ : "resource-not-tracked");
247
+ return {
248
+ ...evaluated,
249
+ metrik: {
250
+ ...evaluated.metrik,
251
+ settleable: refusal === undefined,
252
+ ...(refusal === undefined ? {} : { settlementRefusal: refusal }),
253
+ },
254
+ };
255
+ }
256
+ /** Does this gate outcome name a resource the relayer will pay gas for? */
257
+ scopeRefusal(gate) {
258
+ if (this.settlementScope === "any-resource") {
259
+ return undefined;
260
+ }
261
+ // Only an origin that resolved to exactly one signed listing counts.
262
+ // "not-applicable" (not ours), "ambiguous" (two claimants) and
263
+ // "registry-unavailable" (cannot tell) are all "we do not know this is
264
+ // ours", and the relayer does not spend gas on that.
265
+ return gate === "passed" ||
266
+ gate === "indeterminate" ||
267
+ gate === "refused" ||
268
+ gate === "payee-mismatch"
269
+ ? undefined
270
+ : "resource-not-tracked";
271
+ }
272
+ async evaluateGate(payload, requirements) {
273
+ // 1. Ordinary payment validity first. A malformed or unfunded payment is
274
+ // rejected on its own merits, and never reaches — or leaks — the
275
+ // delivery record of a service.
276
+ const payment = await this.paymentVerifier.verify(payload, requirements);
277
+ if (!payment.isValid) {
278
+ return {
279
+ ...payment,
280
+ metrik: {
281
+ gate: "not-applicable",
282
+ detail: "payment rejected on ordinary x402 grounds; the Metrik delivery gate did not run",
283
+ },
284
+ };
285
+ }
286
+ // 2. Is this resource one of ours? Resolved from Metrik's own verified
287
+ // registry view, keyed on the resource URL's origin.
288
+ const lookup = await this.resourceIndex.lookup(requirements.resource);
289
+ if (lookup.status === "registry-unavailable") {
290
+ return this.applyIndeterminate(payment, {
291
+ gate: "registry-unavailable",
292
+ detail: "Metrik could not read its service registry, so it cannot tell whether this resource is one it tracks",
293
+ });
294
+ }
295
+ if (lookup.status !== "resolved" || lookup.resource === undefined) {
296
+ // Not a Metrik listing. Behave exactly like any other facilitator.
297
+ return {
298
+ ...payment,
299
+ metrik: {
300
+ gate: "not-applicable",
301
+ detail: "resource is not a Metrik-listed service; Metrik has no delivery opinion and applied no gate",
302
+ },
303
+ };
304
+ }
305
+ const resolved = lookup.resource;
306
+ // 3. The payee must be the operator who SIGNED the listing. This is the one
307
+ // check that protects the payer rather than the seller: without it,
308
+ // anyone could quote a Metrik-listed resource and redirect its payment to
309
+ // their own address.
310
+ if (!addressesEqual(requirements.payTo, resolved.operator)) {
311
+ return {
312
+ isValid: false,
313
+ invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
314
+ ...(payment.payer === undefined ? {} : { payer: payment.payer }),
315
+ metrik: {
316
+ gate: "payee-mismatch",
317
+ serviceRef: resolved.serviceRef,
318
+ detail: `payTo ${requirements.payTo} is not the operator ${resolved.operator} who signed the listing ` +
319
+ `for ${resolved.matchedOrigin}; refusing to settle a payment for a Metrik-listed resource to a different address`,
320
+ },
321
+ };
322
+ }
323
+ // 4. The differentiator.
324
+ const assessment = await this.deliveryOracle.verdictFor(resolved.serviceRef);
325
+ if (assessment.verdict === "failing") {
326
+ return {
327
+ isValid: false,
328
+ invalidReason: DELIVERY_REFUSAL_REASON,
329
+ ...(payment.payer === undefined ? {} : { payer: payment.payer }),
330
+ metrik: {
331
+ gate: "refused",
332
+ detail: `Metrik's oracle reports this service as FAILING its delivery checks ` +
333
+ `(verdict recorded ${assessment.ageSeconds ?? "?"}s ago, within the ` +
334
+ `${assessment.freshnessWindowSeconds}s freshness window). The payment itself is valid; ` +
335
+ `Metrik is refusing to settle it. This prevents a payment — it does not recover one.`,
336
+ ...assessmentFields(assessment, resolved.serviceRef),
337
+ },
338
+ };
339
+ }
340
+ if (assessment.verdict === "indeterminate") {
341
+ return this.applyIndeterminate(payment, {
342
+ gate: "indeterminate",
343
+ detail: `Metrik has no fresh delivery evidence for this service (${assessment.reason}; ` +
344
+ `freshness window ${assessment.freshnessWindowSeconds}s). ` +
345
+ `Policy is "${this.indeterminatePolicy}".`,
346
+ ...assessmentFields(assessment, resolved.serviceRef),
347
+ });
348
+ }
349
+ return {
350
+ ...payment,
351
+ metrik: {
352
+ gate: "passed",
353
+ detail: `Metrik's oracle recorded a passing delivery check for this service ` +
354
+ `${assessment.ageSeconds ?? "?"}s ago. This is not an endorsement of output correctness — ` +
355
+ `Metrik verifies delivery, not correctness.`,
356
+ ...assessmentFields(assessment, resolved.serviceRef),
357
+ },
358
+ };
359
+ }
360
+ applyIndeterminate(payment, annotation) {
361
+ if (this.indeterminatePolicy === "deny") {
362
+ return {
363
+ isValid: false,
364
+ invalidReason: DELIVERY_REFUSAL_REASON,
365
+ ...(payment.payer === undefined ? {} : { payer: payment.payer }),
366
+ metrik: {
367
+ ...annotation,
368
+ detail: `${annotation.detail} Refusing because this facilitator is configured to require positive fresh evidence.`,
369
+ },
370
+ };
371
+ }
372
+ return {
373
+ ...payment,
374
+ metrik: {
375
+ ...annotation,
376
+ detail: `${annotation.detail} Allowing: Metrik holds none of this money, so refusing would deny the ` +
377
+ `service without protecting anyone. "isValid: true" here asserts only that the payment is ` +
378
+ `well-formed — it is NOT a statement that the service is delivering.`,
379
+ },
380
+ };
381
+ }
382
+ }
383
+ function assessmentFields(assessment, serviceRef) {
384
+ return {
385
+ serviceRef,
386
+ deliveryVerdict: assessment.verdict,
387
+ deliveryReason: assessment.reason,
388
+ lastCheckedAt: assessment.lastCheckedAt,
389
+ verdictAgeSeconds: assessment.ageSeconds,
390
+ freshnessWindowSeconds: assessment.freshnessWindowSeconds,
391
+ };
392
+ }
393
+ function addressesEqual(a, b) {
394
+ try {
395
+ return getAddress(a) === getAddress(b);
396
+ }
397
+ catch {
398
+ return false;
399
+ }
400
+ }
401
+ /**
402
+ * Parses the facilitator wire body with the REAL x402 schemas. Both `/verify`
403
+ * and `/settle` take the same `{paymentPayload, paymentRequirements}` pair.
404
+ */
405
+ export function parseFacilitatorRequest(body) {
406
+ if (typeof body !== "object" || body === null) {
407
+ return undefined;
408
+ }
409
+ const candidate = body;
410
+ const payload = PaymentPayloadSchema.safeParse(candidate.paymentPayload);
411
+ if (!payload.success) {
412
+ return undefined;
413
+ }
414
+ const requirements = PaymentRequirementsSchema.safeParse(candidate.paymentRequirements);
415
+ if (!requirements.success) {
416
+ return undefined;
417
+ }
418
+ return {
419
+ paymentPayload: payload.data,
420
+ paymentRequirements: requirements.data,
421
+ };
422
+ }
423
+ //# sourceMappingURL=verified-delivery-facilitator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-delivery-facilitator.js","sourceRoot":"","sources":["../../src/x402/verified-delivery-facilitator.ts"],"names":[],"mappings":"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"}
@@ -161,17 +161,17 @@ export declare const deliveryProofRequestBodySchema: z.ZodObject<{
161
161
  identifier: z.ZodString;
162
162
  }, "strict", z.ZodTypeAny, {
163
163
  owner: string;
164
- parameters: string;
165
164
  context: string;
166
165
  provider: string;
166
+ parameters: string;
167
167
  timestampS: number;
168
168
  epoch: number;
169
169
  identifier: string;
170
170
  }, {
171
171
  owner: string;
172
- parameters: string;
173
172
  context: string;
174
173
  provider: string;
174
+ parameters: string;
175
175
  timestampS: number;
176
176
  epoch: number;
177
177
  identifier: string;
@@ -181,9 +181,9 @@ export declare const deliveryProofRequestBodySchema: z.ZodObject<{
181
181
  identifier: string;
182
182
  claimData: {
183
183
  owner: string;
184
- parameters: string;
185
184
  context: string;
186
185
  provider: string;
186
+ parameters: string;
187
187
  timestampS: number;
188
188
  epoch: number;
189
189
  identifier: string;
@@ -193,9 +193,9 @@ export declare const deliveryProofRequestBodySchema: z.ZodObject<{
193
193
  identifier: string;
194
194
  claimData: {
195
195
  owner: string;
196
- parameters: string;
197
196
  context: string;
198
197
  provider: string;
198
+ parameters: string;
199
199
  timestampS: number;
200
200
  epoch: number;
201
201
  identifier: string;
@@ -208,9 +208,9 @@ export declare const deliveryProofRequestBodySchema: z.ZodObject<{
208
208
  identifier: string;
209
209
  claimData: {
210
210
  owner: string;
211
- parameters: string;
212
211
  context: string;
213
212
  provider: string;
213
+ parameters: string;
214
214
  timestampS: number;
215
215
  epoch: number;
216
216
  identifier: string;
@@ -236,9 +236,9 @@ export declare const deliveryProofRequestBodySchema: z.ZodObject<{
236
236
  identifier: string;
237
237
  claimData: {
238
238
  owner: string;
239
- parameters: string;
240
239
  context: string;
241
240
  provider: string;
241
+ parameters: string;
242
242
  timestampS: number;
243
243
  epoch: number;
244
244
  identifier: string;
@@ -15,14 +15,18 @@ fills exactly that gap, and the agent layer is where an agent experiences it.
15
15
 
16
16
  ## The four components
17
17
 
18
- ### 1. x402 verified-streaming scheme
18
+ ### 1. Metrik verified-streaming `402` flow
19
19
 
20
- A StreamProof-flavored x402 scheme/facilitator: an agent hits an HTTP `402`, receives
21
- a _verified-streaming_ requirement (operator, serviceRef, rate, budget, settlement
20
+ A Metrik-native HTTP `402` challenge flow: an agent hits a `402`, receives a
21
+ _verified-streaming_ requirement (operator, serviceRef, rate, budget, settlement
22
22
  chain/escrow), responds with a signed-mandate payload, and a stream opens through the
23
- SDK — paying only for oracle-verified delivery, pausing on failure. The integration
24
- reuses the `402` challenge/response shape and the protocol's existing settlement path.
25
- (`src/x402/`)
23
+ SDK — paying only for oracle-verified delivery. It borrows the _shape_ of an x402
24
+ challenge/response and reuses the protocol's existing settlement path. (`src/x402/`)
25
+
26
+ It is **not the x402 protocol**: its scheme string, challenge body, payload and
27
+ `X-METRIK-PAYMENT` header are all Metrik's own, and it does not interoperate with
28
+ `x402-fetch`, `x402-axios`, or `x402-express`. See [docs/x402.md](./x402.md) for the
29
+ evidence and for what real x402 support would require.
26
30
 
27
31
  ### 2. MCP server
28
32
 
@@ -32,7 +36,8 @@ Every fund-moving tool is gated by a spend mandate, with JSON-serializable manda
32
36
  payloads and env-driven settlement config. The server also keeps a local stream
33
37
  registry so agents can list and reclaim the streams they opened. (`src/mcp/`)
34
38
 
35
- The server runs locally over stdio (`pnpm mcp:stdio`) or as a hosted,
39
+ The server runs locally over stdio (the published `metrik-mcp` executable, or
40
+ `pnpm mcp:stdio` in-repo) or as a hosted,
36
41
  multi-tenant, per-caller-authenticated endpoint over Streamable HTTP
37
42
  (`pnpm mcp:http`) — see [docs/mcp-hosted.md](./mcp-hosted.md).
38
43
 
@@ -124,7 +129,7 @@ proven live. Tracked separately if/when a paymaster is provisioned.
124
129
 
125
130
  ```mermaid
126
131
  flowchart LR
127
- AGENT[AI agent] -->|MCP tool / x402 402| AL[Agent layer]
132
+ AGENT[AI agent] -->|MCP tool / Metrik 402| AL[Agent layer]
128
133
  AL -->|checkMandate| MND[Spend mandate]
129
134
  MND -->|allowed| SDK[@absol-labs/sdk]
130
135
  SDK --> ESC[Escrow on settlement chain]
@@ -146,5 +151,5 @@ flowchart LR
146
151
 
147
152
  ## Roadmap (see issues)
148
153
 
149
- x402 scheme → MCP server → framework adapters → example agents
154
+ Metrik `402` flow → MCP server → framework adapters → example agents
150
155
  (hire + monitor + close on verification gaps) → wallet/provider integration.