feat: add TypeScript port (@verifiable-intent/core) - #31
Open
miguelvelasquezdev wants to merge 7 commits into
Open
feat: add TypeScript port (@verifiable-intent/core)#31miguelvelasquezdev wants to merge 7 commits into
miguelvelasquezdev wants to merge 7 commits into
Conversation
Relocate the Python package (src, tests, examples, conftest, pyproject) from the repo root into python/ to make room for sibling language implementations in a polyglot monorepo layout. All moves are pure renames with no content changes. CI lint/test jobs now run with working-directory: python, a package-level README documents the Python implementation's new home, and CONTRIBUTING.md's setup instructions point at the new location. Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
verify_chain now fails closed when the same disclosure digest appears more than once in an _sd array, at every layer (L1, L2, L3a/L3b). RFC 9901 section 7.1 forbids repeated digests; a duplicate is an ambiguity/smuggling vector that valid credentials never produce. Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
test-vectors/vectors.json snapshots one Immediate and one Autonomous
flow from the Python implementation with deterministic demo keys and
fixed timestamps, nonces, and salts. ECDSA P-256 signatures are
randomized, so the vectors record every deterministic artifact
(disclosure encodings, hashes, payload JSON, _sd arrays, sd_hash
inputs/outputs) plus the exact salts consumed, letting ports replay
issuance byte-for-byte without depending on signature bytes.
python/scripts/generate_vectors.py regenerates the file:
uv run --no-project --with "cryptography>=42" python scripts/generate_vectors.py
Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
AP2 0.2.0 (28 April 2026) introduced an SD-JWT-based Human-Not-Present model with Open Checkout / Open Payment Mandates and cnf-based agent key binding, natively covering much of the delegation mechanism VI was positioned to fill. Update the version baseline, re-map L2 Autonomous to the Open mandates (same VCTs, cnf binding, and constraints array), clarify that the Intent Mandate is a separate upstream human-present artifact, and flag the recurrence vocabulary mismatch (ISO 20022 frequency codes vs AP2 V2's named enum; only ON_DEMAND overlaps). Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
Byte-compatible TypeScript implementation of the Verifiable Intent credential format, ported from the Python reference: SD-JWT issuance (issuer/user/agent), full chain verification, constraint checking, and selective disclosure, with fail-closed behavior on every verification path. Parity with the reference implementation is enforced to the byte: - Issuance replays the shared conformance vectors in test-vectors/ byte-for-byte (disclosure encodings, digests, payload JSON, _sd ordering, sd_hash inputs). - Verification re-encodes signed segments with Python json.dumps number semantics (int/float distinction, float repr, arbitrary- precision integers), so credentials issued by the Python implementation verify without false failures while tampering is still detected. - base64url handling, disclosure resolution order, and error strings match the reference exactly, keeping accept/reject decisions and reported errors identical across both implementations. The test suite (180 tests) covers chain verification, fail-closed rejection of tampered, expired, and mis-bound credentials, cnf key-binding hardening, issue/verify round trips, and vector replay. CI gains a typescript job (lint, typecheck, tests, build), and the root README documents the monorepo layout. Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
…ero deps) Replace Node-specific primitives with Web standards: crypto.subtle for ES256/SHA-256, crypto.getRandomValues for salts, hand-rolled base64url over Uint8Array instead of Buffer. Signature bytes are unchanged and the decoder is fuzz-verified against Node's, so Python vector replay and parity tests pass unmodified. The package now runs on Node >= 20 and browsers with zero runtime dependencies. Hashing APIs are now async (WebCrypto is promise-based); ASCII validation still throws synchronously to preserve parity assertions. Also drops the unused unrun devDependency and gitignores npm pack tarballs. Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
… result budget/recurrence/agent_recurrence are spec-assigned to the payment network (stateful), so the stateless verifier never evaluates them. ChainVerificationResult.networkEnforced now lists them per mandate pair so callers know what remains to be enforced. Additive only; Python verdict parity unchanged. Also expands the package README. Signed-off-by: Miguel Velasquez <veruiz.miguel@gmail.com>
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.
Summary
Byte-compatible TypeScript implementation of the Verifiable Intent
credential format (
@verifiable-intent/core), ported from the Pythonreference, plus the monorepo restructure and shared conformance vectors
that support it.
Related: #24, #30 (prior community interest in a TypeScript implementation).
Motivation
A TypeScript SDK makes the format usable from Node.js services, browsers,
and the JS agent tooling ecosystem, and a second implementation validates
the spec's portability. Issuance and verification are byte-compatible with
the Python reference, so credentials interoperate across implementations.
What's included
python/(pure renames) and shared goldenvectors in
test-vectors/so ports replay issuance byte-for-byte._sddigests (RFC 9901 §7.1), mirroredin both implementations.
verification with aud/nonce replay protection, and constraint checking —
with byte-level parity (vectors, Python
json.dumpsnumber semantics,exact error strings).
verifyChainsurfaces network-enforced constraints (budget/recurrence)explicitly, since the spec assigns them to the payment network.
runtime dependencies.
typescriptjob; docs updated (AP2 0.2.0 mapping, READMEs).Test plan
byte-for-byte vector replay; isomorphic check runs issue→verify through
both ESM and CJS bundles with
Bufferdeleted.immediate + autonomous flows plus tamper/expiry/audience negatives.
Notes
spec/changes. All commits carry DCOSigned-off-by.