npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@receipt-graph/agent-collector

v0.1.0

Published

Agent-side collector (HTTP/x402 client wrapper, partial-trust receipts).

Downloads

152

Readme

@receipt-graph/agent-collector

Agent-side fetch wrapper that observes x402 payment flow from the client perspective and emits lifecycle events to the ReceiptGraph HTTP API with source: "agent". Works against any x402-capable provider without requiring provider middleware to be installed.

Partial-trust contract: the collector records what the HTTP client can observe through TLS termination — request URL, the x402 challenge, the payment-signature header hash, and the client-observed response body hash. These are never co-signed by the provider. After Kitescan on-chain verification, trustLevel resolves to agent_observed, never provider_verified, unless provider middleware also contributes delivery events.

Quick start — with settlement

Use receiptGraphAgentCollector when your payment client can provide txHash after a successful paid call:

import { receiptGraphAgentCollector } from "@receipt-graph/agent-collector";
import { wrapWithX402 } from "@x402/client"; // or your x402 payment wrapper

const collector = receiptGraphAgentCollector(fetch, {
  agentId:         process.env.AGENT_ID!,
  sessionId:       process.env.SESSION_ID!,
  receiptGraphUrl: process.env.RECEIPTGRAPH_URL!,
  apiKey:          process.env.RECEIPTGRAPH_API_KEY!,
});

// Pass collector.fetch as the underlying transport for your x402 payment client.
// Both the initial 402 and the paid retry must go through the wrapper.
const paidFetch = wrapWithX402(collector.fetch, paymentOptions);
const response  = await paidFetch("https://example.com/api/resource");

// Emit settlement when the payment client provides txHash:
const txHash    = paymentClient.lastTxHash();
const receiptId = "...";  // returned from the 402 step via onError ctx, or computed independently
await collector.settle(txHash, receiptId);

Quick start — fetch-only (no settlement)

Use receiptGraphAgentFetch when you do not need to emit settlement. Returns a plain typeof fetch — no settle handle:

import { receiptGraphAgentFetch } from "@receipt-graph/agent-collector";

const paidFetch = receiptGraphAgentFetch(fetch, {
  agentId:         process.env.AGENT_ID!,
  sessionId:       process.env.SESSION_ID!,
  receiptGraphUrl: process.env.RECEIPTGRAPH_URL!,
});

const response = await paidFetch("https://example.com/api/resource");

Configuration

All keys are typed on AgentCollectorConfig (exported from the package entry).

| Field | Required | Purpose | |---|---|---| | agentId | yes | Stable agent identifier; stored as SHA-256(agentId) — raw value never persisted. | | sessionId | yes | Correlates multiple paid calls in one run; stored as SHA-256(sessionId). | | receiptGraphUrl | yes | ReceiptGraph API base URL (no trailing slash; normalized at runtime). | | apiKey | no | Authorization: Bearer <apiKey> on ReceiptGraph writes. Defaults to RECEIPTGRAPH_API_KEY env var. | | emitMode | no | "best_effort" (default) or "strict". In best_effort, ReceiptGraph failures never block the paid response. | | verifySettlement | no | Default true: call POST /api/verify-settlement after settle(). Set false to defer on-chain verification to a background worker. | | onError | no | (ctx: AgentCollectorOnErrorContext) => void — called on any failed emit. Must not throw in best_effort mode. |

txHash availability matrix

| Situation | What to do | |---|---| | txHash known right after fetch returns | await collector.settle(txHash, receiptId) immediately | | txHash arrives later (async callback, event, polling) | call await collector.settle(txHash, receiptId) when it arrives; internal state is retained | | txHash is never available to the agent | do not call settle; the receipt stays at delivered for Phase 5 reconciliation |

When settle is never called, the receipt already contains the fields the Phase 5 reconciler needs to find the on-chain transfer:

  • payTo — normalized EVM address of the payment recipient
  • asset — EVM address of the payment token
  • maxAmountRequired — token amount in atomic units
  • network — chain id (e.g. eip155:84532)
  • requestedUrl — canonicalized URL of the paid endpoint
  • paymentHeaderHash — SHA-256 of the payment-signature header
  • agentIdHash / sessionIdHash — hashed identities for correlation

Observation hooks

Each hook documents which ReceiptGraph HTTP route it calls and which ReceiptEventType it produces. The canonical table is AGENT_OBSERVATION_HOOK_SPECS in src/observation-hooks.ts.

| Hook | ReceiptGraph HTTP | Resulting ReceiptEventType | |---|---|---| | request_start | (none — local capture for pending) | — | | pending | POST /api/receipts/pending | pending_created | | payment_seen | POST /api/receipts/:receiptId/payment-seen | payment_seen | | delivery | POST /api/receipts/:receiptId/delivery | delivered or delivery_failed | | settlement | POST /api/receipts/:receiptId/settlement then POST /api/verify-settlement | settled + (on verify) verified |

payment_seen is emitted before the paid retry goes out; delivery is emitted after the final response arrives. Both run through runAgentCollectorEmit so emitMode and onError stay consistent.

Hashing

All hash functions are re-exported from @receipt-graph/provider-middleware to guarantee bit-identical receiptId values across agent and provider paths. Golden-vector alignment is enforced by tests/hashing-alignment.test.ts.

| Function | Role | |---|---| | computeRequestHash(method, url) | SHA-256(method + normalizedUrl + sortedQueryParams) | | computeReceiptId(input) | Deterministic receipt identity — same inputs always produce the same id | | computePaymentHeaderHash(headerValue) | SHA-256 of the raw payment-signature header bytes | | computeResponseBodyHash(body) | SHA-256 of stable-JSON-stringified body (or raw UTF-8 for strings) | | sha256HexUtf8(s) | General-purpose UTF-8 SHA-256 used for agentIdHash / sessionIdHash |

Scripts

  • npm run typechecktsc --noEmit
  • npm test — Vitest unit tests (no network, no Postgres, no real API keys)
  • npm run release:dry-run — run the full npm publish dry run
  • npm run release — publish to npm