Evidence helpers
Evidence is the network’s own proof, attached to an event. The helpers in @halvorai/ingest/evidence do two things only:
put each proof into the right shape, and compute its SHA-256 digest. They do not verify anything. Verification happens on the
server, so it is the same for every producer. See evidence and verification.
import { ap2, vi, tap } from '@halvorai/ingest/evidence';AP2 mandates
Section titled “AP2 mandates”halvor.emit({ type: 'payment.authorized', payment: { /* ... */ }, payee: { /* ... */ }, evidence: [ap2.paymentMandate(paymentMandateSdJwt), ap2.checkoutMandate(checkoutMandateSdJwt)],});ap2.paymentMandate(sdJwt) returns { kind: 'ap2.payment_mandate', format, value, sha256 }. The format is kb-sd-jwt when the
string ends with a key-binding token and sd-jwt otherwise. ap2.checkoutMandate does the same for checkout mandates.
Pass the whole tilde-separated string exactly as you received it.
Mastercard Verifiable Intent
Section titled “Mastercard Verifiable Intent”evidence: [vi.chain(presentationString)]Pass the full chain of layers as one string. Do not split or reorder it, because the digest and the signatures depend on the exact bytes.
Visa Trusted Agent Protocol
Section titled “Visa Trusted Agent Protocol”app.post('/checkout', (req, res) => { halvor.emit({ type: 'payment.authorized', payment: { /* ... */ }, payee: { /* ... */ }, evidence: [tap.fromRequest(req)], });});tap.fromRequest(req) reads the Signature-Input and Signature headers and the signed components, such as the authority
and the path, from the incoming request. It builds the evidence object that the verifier needs to check the signature
against Visa’s key directory.
Why packaging matters
Section titled “Why packaging matters”The digest on an evidence item is over its exact bytes. A bank can recompute it from the pack and see that the value you stored
is the value you sent. If you reformat a credential before sending it, the digest still matches the new bytes, but the
credential’s own signature no longer verifies, and the item becomes invalid. Send credentials untouched.
Attaching other evidence
Section titled “Attaching other evidence”For other kinds, such as x402 payloads and Stripe snapshots, the rail adapters attach the evidence for you. To attach your own
JSON, set kind, format: 'json', the value, and a sha256 computed over its RFC 8785 canonical form. The SDK recomputes the
digest after it redacts personal data from JSON evidence.
Signed credentials (sd-jwt, kb-sd-jwt, jws) are never redacted, so their signatures stay valid.