Skip to content

feat!: async Signer interface, unified OID policy — release 4.0.0 - #47

Merged
chtitux merged 3 commits into
mainfrom
claude/signature-retrieval-method-8mplxb
Sep 20, 2026
Merged

chtitux merged 3 commits into
mainfrom
claude/signature-retrieval-method-8mplxb

Conversation

@chtitux

@chtitux chtitux commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • New async Signer interface — the signing-side counterpart of Level1KeyProvider: { curve, sign(data), getPublicKey?() }. localSigner(privateKey, curve) covers raw in-memory keys; WebCrypto/HSM/KMS backends implement Signer without the private key ever entering the library. signAndEncodeTicket(ticket, { level1, level2? }), signLevel1(ticket, signer) and signLevel2(ticket, signer) are async.
  • Unified algorithm-OID policy, aligned with the verifier's "a disagreement is an error" rule: signAndEncodeTicket writes OIDs and the Level 2 public key from the signers (always self-consistent output); signLevel1/signLevel2 sign the ticket's data exactly as given — contradictory OIDs are an error, absent OIDs stay absent, which makes out-of-band-algorithm barcodes producible for the first time.
  • signLevel1/signLevel2 rebuilt on the composable primitives (no more placeholder signatures and triple encode).
  • getPublicKey (key derivation) renamed derivePublicKey, ending the collision with Level1KeyProvider.getPublicKey.
  • controlTicket accepts raw bytes as well as hex (string | Uint8Array) — it was the last hex-only entry point.
  • Full exported-API audit: all types.ts types re-exported (verified by diff), internal oids.ts helpers stay private, README now documents every export (getOpenTicketValidityWindow, derivePublicKey, signPayload, getSigningAlgorithm/getKeyAlgorithm, signatureKey).
  • Release prep: version bumped to 4.0.0; CHANGELOG carries a "Migrating from 3.0.0" guide (call-by-call mapping table and the four behavioral changes to review).

The website/ app depends on the published npm dosipas-ts@^3.0.0 and keeps building; its signing calls migrate when it bumps to 4.x.

Test plan

  • npx tsc --noEmit and npm run build pass
  • Full Vitest suite: 186 tests pass, including new coverage for the OID-mismatch errors, OID-less (out-of-band) signing verified end-to-end, an HSM-style custom Signer, the required getPublicKey on Level 2 signers, and controlTicket bytes input

🤖 Generated with Claude Code

https://claude.ai/code/session_01BMYUez7fcvaL34RUjxKZRJ


Generated by Claude Code

Signing now goes through the Signer interface — the signing-side
counterpart of Level1KeyProvider. localSigner(privateKey, curve) wraps a
raw in-memory key; any backend that produces DER ECDSA signatures
(WebCrypto, HSM, cloud KMS) can implement Signer without the private key
ever entering the library.

signAndEncodeTicket(ticket, { level1, level2? }) is authoritative for the
header's security claims (OIDs and Level 2 public key written from the
signers); signLevel1/signLevel2 sign the ticket's data exactly as given,
erroring on contradictory OIDs and leaving absent OIDs absent — which
makes out-of-band-algorithm barcodes producible for the first time — and
no longer triple-encode via placeholder signatures. getPublicKey (key
derivation) is renamed derivePublicKey to end the collision with
Level1KeyProvider.getPublicKey.

BREAKING CHANGE: signing functions take Signers and are async;
SigningKeyPair is only generateKeyPair's return type; getPublicKey is
renamed derivePublicKey. Migration guide from 3.0.0 in CHANGELOG.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMYUez7fcvaL34RUjxKZRJ
API surface audit: every type defined in types.ts is exported, internal
oids helpers (resolveAlgorithms & co) stay private, and naming/input
conventions are consistent — except controlTicket, the last hex-only
entry point, which now accepts string | Uint8Array like the rest of the
pipeline. README gains the previously undocumented exports:
getOpenTicketValidityWindow, derivePublicKey, signPayload,
getSigningAlgorithm/getKeyAlgorithm and signatureKey.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMYUez7fcvaL34RUjxKZRJ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMYUez7fcvaL34RUjxKZRJ
@chtitux
chtitux merged commit f6e37cc into main Sep 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants