Repository navigation
feat: add fractalaiReceipts action provider - #1549
Open
johnInarti wants to merge 3 commits into
Open
johnInarti wants to merge 3 commits into
johnInarti wants to merge 3 commits into
Conversation
Agents that pay for x402 resources get a settlement transaction but no verifiable record of what the paid service committed to. This provider adds two actions so any AgentKit agent can check and obtain signed receipts: - verify_x402_receipt: verifies post-quantum (ML-DSA-65, FIPS 204) receipts and reports integrity / authentic / trusted / settlement / delivery as separate levels with reason codes. It supports receipts of the proposed x402 `delivery-receipt` extension from any issuer (issuer key directory fetched from /.well-known/x402-receipt-keys, trust basis reported as "tls" unless a governance key is pinned in the config) and FractalAI's notary seals, served proofs and MIDAS alerts, which are checked against a governance key and an epoch-3 directory checkpoint pinned in the provider (rollback and equivocation are refused). The signed message is always rebuilt from the kind's fixed domain; unsigned copies of signed content must match exactly; keys are checked for use, status and validity window at the signed time (reserved and revoked keys never authorize). JSON input is parsed strictly (duplicate keys, lone surrogates, trailing data refused) and untrusted strings are sanitized before they reach the model. - request_x402_receipt: asks the FractalAI notary for an independent seal of an x402 payment that already settled on Base, pays its 0.005 USDC fee through @x402/fetch with the agent's EVM wallet (a payment policy only accepts USDC on Base to the notary's pinned address, up to the configured cap), then verifies the returned seal and compares it with the request. @noble/post-quantum is pinned to ^0.4.1 because AgentKit compiles to CommonJS and later majors are ESM-only; its verify argument order (publicKey, message, signature) is pinned by a known-answer test on a production receipt. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The provider makes trust decisions, so the tests pin them against real artefacts instead of only self-generated ones: - fixtures are FractalAI's published epoch-3 key directory, its pinned trust roots and a production MIDAS alert receipt (fe62b072...) signed by the active key 86c139c960bb274c; a known-answer test fixes the ML-DSA-65 argument order of @noble/post-quantum 0.4.x; - negative vectors: a signed digit changed in the canonical (signature fails even with consistent unsigned copies), unsigned facts or ids that disagree with signed content, duplicate JSON keys, ambiguous kinds, reserved routes, self-attested seals, a directory signed by another governance key, a tampered production directory, unlisted, reserved, revoked and out-of-window keys, rollback, equivocation, chain gaps and non-append-only epochs; - delivery-receipt: TLS vs pinned trust, settlement and body mismatches, altered payload, issuer authorization; - request_x402_receipt with fetch and payment fully mocked: exact seal_body, the payment policy and pre-payment hook, notary refusal, bad-signature and unlisted-key seals, and the trusted path with test trust roots swapped in an isolated module registry. No test touches the network or moves funds. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds the provider README (actions, verification levels, trust bases, configuration) with an explicit scope-and-limits section, so users know what a valid receipt does and does not prove: it shows that a trusted key signed the bytes at the signed time, not that the content is true; the FractalAI roots are trust-on-first-use pinned on 2026-10-07; revoked keys are never trusted because time anchors are not verified here; delivery-receipt is a proposed x402 extension; @noble/post-quantum is not a CMVP-validated module. Also lists the provider in the package README and adds the patch changeset required by CONTRIBUTING-TYPESCRIPT.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🟡 Heimdall Review Status
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR adds a
fractalaiReceiptsaction provider with two actions that give any AgentKit agent signed, offline-verifiable evidence about x402 payments.verify_x402_receiptverifies an ML-DSA-65 (NIST FIPS 204) signed receipt and reports each level separately, with reason codes:integrityauthentictrustedreserved/revokednever)settlementdeliverySupported receipts:
delivery-receiptx402 extension (a draft proposed to coinbase/x402, not merged there yet: signed payload binding the settlement locator, the paid terms and the SHA-256 of the served body), from any issuer. The issuer's key directory is fetched from<issuer>/.well-known/x402-receipt-keys; trust is reported astls(trust on first use) unless the governance key is pinned in the provider config (pinned);pinned-root): older epochs are refused as rollback, a different epoch-3 root as equivocation.The kind is chosen by the caller when known (a document of another kind is refused); otherwise it is inferred from shape, never from a field that claims a domain. JSON is parsed strictly (duplicate keys, lone surrogates and trailing data are refused) and strings from receipts are sanitized before they reach the model, in the spirit of #1480.
request_x402_receiptasks the FractalAI notary for an independent seal of an x402 payment that already settled on Base. The notary re-derives the transfer from Base before asking for payment and answers 422 (nothing charged) if it does not match. Otherwise the action pays the 0.005 USDC fee through@x402/fetchwith the agent's EVM wallet, using the same signer setup as the existingx402provider. A payment policy and a pre-payment hook only acceptexactUSDC on Base to the notary's pinned address, up tomaxPaymentUsdc(default 0.005). The returned seal is verified and compared with the request.What a receipt does not prove
A valid receipt proves that a trusted key signed these bytes at the signed time. It does not prove that the content is true or correct, and unless
settlementis checked it does not prove the payment happened (this provider does not query the chain). The FractalAI roots are trust-on-first-use pinned on 2026-10-07. Revoked keys are never trusted because consensus time anchors are not verified here.@noble/post-quantumis not a CMVP / FIPS 140-3 validated module. These limits are listed in the provider README.Dependency
Adds
@noble/post-quantum@^0.4.1(pure JS, depends only on@noble/hashes, which is already in the tree). AgentKit compiles to CommonJS and later majors of@noble/post-quantumare ESM-only, so 0.4.x is used. Itsverify(publicKey, message, signature)argument order is pinned by a known-answer test on a production receipt. The lockfile change is limited to this package.Authorship
Contributed by FractalAI (FRACTAL AI S.A.S.), which operates the notary and maintains the FractalAI receipt formats and the
delivery-receiptextension draft. The code was written with AI assistance (Claude Code).Tests
Unit tests only (
src/action-providers/fractalaiReceipts/fractalaiReceiptsActionProvider.test.ts, 36 tests). No network access, no payment:fe62b072…, signed by the active key86c139c960bb274c) verified against the published epoch-3 directory (fixtures copied fromhttps://fractalai.net.co/.well-known/x402-receipt-keys);delivery-receipt: TLS vs pinned trust, settlement and body mismatches, altered payload, issuer authorization;request_x402_receiptwith@x402/fetchmocked: exactseal_body, the payment policy and hook, notary refusal, invalid-signature and unlisted-key seals, and the success path with test trust roots.Not yet done: a manual run with an example chatbot on Base mainnet (it would spend 0.005 USDC per notary call). We can add a transcript before review if maintainers want one.
Checklist
🤖 Generated with Claude Code