AlgoVoi is available for acquisition -- docs.algovoi.co.uk/acquisition
algovoi-pef
Payment Evidence Frame (PEF) v1 -- a canonical wrapper format for
AlgoVoi payment-lifecycle receipts. Each frame carries a byte-deterministic
frame_id (SHA-256 of the JCS-canonical preimage) and an optional detached
RFC 9421 signature field.
Normative spec: draft-hopley-x402-payment-evidence-frame-00 (IETF I-D, published 2026-05-30).
Canonicalisation pin: urn:x402:canonicalisation:jcs-rfc8785-v1.
Install
pip install algovoi-pef # Python
npm install @algovoi/pef # TypeScript / JavaScript
Quick start
from algovoi_pef import build_pef, verify_pef
# Wrap a compliance receipt in a PEF frame
frame = build_pef(
claim_type="payment_admission",
receipt={
"canon_version": "urn:x402:canonicalisation:jcs-rfc8785-v1",
"jurisdiction_flags": ["EU", "UK"],
"payer_ref": "sha256:abc123...",
"prev_hash": None,
"screen_provider_did": "did:web:api.algovoi.co.uk",
"screen_result": "ALLOW",
"screen_timestamp_ms": 1748534600000,
},
frame_provider_did="did:web:api.algovoi.co.uk",
frame_timestamp_ms=1748534600000,
)
result = verify_pef(frame)
assert result["valid"]
print(frame["frame_id"])
# sha256:09929082c83d5006f61f06bb12eb58cc2c21acebd70a31bca3cb26169c11b6bf
import { buildPef, verifyPef } from "@algovoi/pef";
const frame = buildPef({
claim_type: "payment_settlement",
receipt: {
canon_version: "urn:x402:canonicalisation:jcs-rfc8785-v1",
settled_payment_ref: "sha256:abc123...",
settlement_chain: "ethereum:84532",
settlement_provider_did: "did:web:api.algovoi.co.uk",
settlement_result: "SETTLED",
settlement_timestamp_ms: 1748534700000,
},
frame_provider_did: "did:web:api.algovoi.co.uk",
frame_timestamp_ms: 1748534700000,
});
const result = verifyPef(frame);
console.log(result.valid); // true
console.log(frame.frame_id); // sha256:...
Claim types
PEF defines five claim types, each mapping to an IETF I-D-anchored receipt format:
claim_type |
receipt_format |
IETF I-D | Platform source |
|---|---|---|---|
payment_admission |
compliance-receipt-v1 |
draft-hopley-x402-compliance-receipt |
/compliance/screen |
payment_settlement |
settlement-attestation-v1 |
draft-hopley-x402-settlement-attestation |
/checkout/{t}/verify |
payment_cancellation |
cancellation-receipt-v1 |
draft-hopley-x402-cancellation-receipt |
mandate cancel endpoints |
payment_refund |
refund-receipt-v1 |
draft-hopley-x402-refund-receipt |
refund endpoints |
composite_verdict |
composite-trust-query-v1 |
draft-hopley-x402-composite-trust-query |
/compliance/trust-query |
Frame structure
{
"canon_version": "urn:x402:canonicalisation:jcs-rfc8785-v1",
"claim_type": "payment_admission",
"frame_id": "sha256:<64-hex-chars>",
"frame_provider_did": "did:web:api.algovoi.co.uk",
"frame_timestamp_ms": 1748534600000,
"pef_version": "1",
"receipt": { "..." : "..." },
"receipt_format": "compliance-receipt-v1",
"receipt_hash": "sha256:<64-hex-chars>",
"signature": "<RFC 9421 detached JWS -- optional>"
}
frame_id derivation
receipt_hash = "sha256:" + hex(sha256(JCS(receipt)))
preimage = {
canon_version, claim_type, frame_provider_did,
frame_timestamp_ms, pef_version, receipt,
receipt_format, receipt_hash
}
frame_id = "sha256:" + hex(sha256(JCS(preimage)))
signature is appended after frame_id is set and is excluded from both
hash inputs. Signing the frame_id (rather than the full frame body) keeps
the signature stable across re-serialisations.
API
Python
from algovoi_pef import build_pef, verify_pef, pef_frame_id, CLAIM_TYPES
# Build a frame
frame = build_pef(
claim_type="payment_admission", # str -- must be in CLAIM_TYPES
receipt={...}, # dict
frame_provider_did="did:...", # str
frame_timestamp_ms=1748534600000, # int, epoch-ms
signature="...", # str, optional RFC 9421 JWS
)
# Verify structural integrity (does NOT verify the RFC 9421 signature)
result = verify_pef(frame)
# {"valid": True, "errors": []}
# Re-derive frame_id from an existing frame
fid = pef_frame_id(frame)
# Inspect the closed enum
print(CLAIM_TYPES)
# {"payment_admission": "compliance-receipt-v1", ...}
TypeScript
import {
buildPef, verifyPef, pefFrameId,
CLAIM_TYPES, PEF_VERSION, CANON_VERSION,
type BuildPefOptions, type Pef, type VerifyResult,
} from "@algovoi/pef";
const frame: Pef = buildPef({ claim_type, receipt, frame_provider_did, frame_timestamp_ms });
const result: VerifyResult = verifyPef(frame);
const fid: string = pefFrameId(frame);
Platform integration
shared.utils.pef_wrapper in the AlgoVoi gateway provides soft-import helpers
so each router can emit PEF-wrapped receipts alongside existing fields:
from shared.utils.pef_wrapper import (
wrap_compliance_receipt, # payment_admission
wrap_settlement_attestation, # payment_settlement
wrap_cancellation_receipt, # payment_cancellation
wrap_refund_receipt, # payment_refund
wrap_trust_query_response, # composite_verdict
)
# compliance_gate.py -- returns None gracefully if algovoi-pef not installed
pef_frame = wrap_compliance_receipt(
compliance_receipt_dict,
screen_timestamp_ms=screen_ts,
)
All wrappers use pef_or_none() -- they return None during a rolling deploy
before algovoi-pef is added to the platform requirements, so existing API
responses are unaffected.
Cross-implementation validation
frame_id derivation has been independently validated across eight JCS
implementations in eight programming languages -- 64/64 byte-for-byte
agreements across all five claim types (both receipt_hash and frame_id
layers per vector):
| Language | Runtime | JCS library | Author |
|---|---|---|---|
| Python | CPython 3.12 | rfc8785 0.1.4 |
Trail of Bits |
| JavaScript | Node.js v24 | canonicalize 1.0.8 |
Samuel Erdtman |
| Ruby | Ruby 3.4 | json-canonicalization 1.0.0 |
RubyGems community |
| PHP | PHP 8.4 | inline pure-stdlib JCS | AlgoVoi |
| Go | Go 1.26 | gowebpki/jcs v1.0.1 |
Web PKI Working Group |
| Rust | Rust 1.95 | serde_jcs 0.2.0 |
l1h3r |
| Java | JDK 17 | erdtman/java-json-canonicalization 1.1 |
Anders Rundgren (RFC 8785 author) + Samuel Erdtman |
| .NET | .NET 9 | Baqhub.Packages.JsonCanonicalization 1.0.1 |
Baqhub |
Full attestation record and reproducible runner harnesses:
_attestations/2026-05-30-8-impl-pef-v1.md
in chopmob-cloud/algovoi-jcs-conformance-vectors.
The same corpus now has 576/576 cumulative byte-for-byte agreements across eight vector sets covering the full AlgoVoi agentic-payment receipt stack (admission, settlement, cancellation, refund, composite verdict, PEF).
Tests
# Unit tests (24 tests)
python -m pytest tests/test_pef.py -v
# Integration smoke tests -- platform-realistic receipt shapes + JS parity (32 tests)
python -m pytest tests/test_smoke_pef_platform.py -v
# Full suite (56 tests)
python -m pytest tests/ -v
# Live API integration test (requires network access to api.algovoi.co.uk)
python -m pytest tests/test_smoke_pef_platform.py -v -m live
# TypeScript tests (20 tests)
npm run build && npm test
Specification
- Normative spec:
draft-hopley-x402-payment-evidence-frame-00(IETF I-D, published 2026-05-30) - Canonicalisation pin:
draft-hopley-x402-canonicalisation-jcs-v1 - Receipt format I-Ds:
- Upstream x402 PRs: #2493 / #2494 / #2495 / #2524 / #2525
- Conformance vectors:
pef_v1inchopmob-cloud/algovoi-jcs-conformance-vectors
Acknowledgments
Cross-implementation validation is possible because of the independent JCS
libraries listed in the matrix above. AlgoVoi acknowledges with thanks:
Trail of Bits (rfc8785), Samuel Erdtman (canonicalize and
java-json-canonicalization), Anders Rundgren (RFC 8785 author, Java
implementation), Web PKI Working Group (gowebpki/jcs), l1h3r (serde_jcs),
Baqhub (Baqhub.Packages.JsonCanonicalization), and the RubyGems community
(json-canonicalization).
Licence
Apache 2.0. See LICENSE.
Author
AlgoVoi (Christopher Hopley, chopmob-cloud)
Attribution
This package is Apache-2.0. Use it freely and build whatever you are building on top of it. The only ask is the one the licence already makes: keep the NOTICE, and name who authored the substrate. To attribute it in your own product, add this to your NOTICE file:
This product includes the AlgoVoi substrate,
authored by Christopher Hopley / AlgoVoi (chopmob-cloud), Apache-2.0.
https://docs.algovoi.co.uk/canonicalisation-substrate
The full invitation is at https://docs.algovoi.co.uk/canonicalisation-substrate#adopt-the-substrate
Metadata
Release files for algovoi-pef 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| algovoi_pef-0.1.2.tar.gz | 21.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| algovoi_pef-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.2 kB
Release files / algovoi_pef-0.1.2.tar.gz
| Download URL | algovoi_pef-0.1.2.tar.gz |
|---|---|
| Size | 21.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2e1f7c7dbd887670e68fdfd38f15203aff73b7c41e10e724e44e6d8b9a2bc7f
|
|
BLAKE2b-256 checksum How to use checksums |
b173d8e96bb03de2dd2e69eb43ceb4663f0691e39e5147b64befff322e922710
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / algovoi_pef-0.1.2-py3-none-any.whl
| Download URL | algovoi_pef-0.1.2-py3-none-any.whl |
|---|---|
| Size | 12.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e4e16772864271e8e965aed3eb0478a08914bf9ba1a0606f652e8a0da9c5b2f
|
|
BLAKE2b-256 checksum How to use checksums |
2496679077acd1c4f25881d02272f0deea2dfd3795116bb4cb3b55558eb106cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for algovoi-pef 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.