vet-sdk-core-ts 0.4.20 → 0.4.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,20 @@ UHC SDK packages and must not import them.
9
9
  The SDK consumes governed browser-safe values from `vet-data-utils-ts` and
10
10
  owns gateway request construction. GW VET remains the policy authority.
11
11
 
12
+ ## Veterinary health-card issuance
13
+
14
+ `issueVeterinaryHealthCardCredential(...)` accepts only an authoritative
15
+ readback Bundle, creates the standard ES256 SHC signing input, and asks each
16
+ attester for an independent RFC 7797 ML-DSA proof over the exact uncompressed
17
+ payload. `pqcQr.qrCount` configures the number of numeric companion labels; it
18
+ defaults to two and never copies the payload into those labels.
19
+
20
+ The result contains printable vaccination data plus both
21
+ `payloadReferences.multihashUrn` for an exact blockchain-index lookup and
22
+ `payloadReferences.cidV1` for content-addressed retrieval. The issuer supplies
23
+ the validity interval explicitly; FHIR `Immunization.expirationDate` remains
24
+ the vaccine-batch expiry.
25
+
12
26
  ## USDC payment quotes
13
27
 
14
28
  `vet-sdk-core-ts/payment` separates the payment provider, asset and EVM network
@@ -0,0 +1,69 @@
1
+ import { type PostQuantumCompanionProofQrOptions, type SmartHealthCardPayloadReferences } from 'vet-data-utils-ts/shc';
2
+ import { type InternationalHealthCardPrintData } from 'vet-data-utils-ts/international-health-card';
3
+ import { type ClinicalBundleReaderOptions } from 'vet-data-utils-ts/clinical-bundle-reader';
4
+ import type { SmartHealthCardPayload } from 'vet-data-utils-ts/shc';
5
+ export type VeterinaryHealthCardAttester = Readonly<{
6
+ /** Signs the exact uncompressed, deterministic SHC payload as RFC 7797 JWS. */
7
+ signDetachedPqc(payloadBytes: Uint8Array): Promise<string>;
8
+ }>;
9
+ export type IssuedVeterinaryHealthCardCredential = Readonly<{
10
+ compactJws: string;
11
+ shcQr: readonly string[];
12
+ pqcCompanionProofs: readonly string[];
13
+ pqcQr: readonly (readonly string[])[];
14
+ payloadBytes: Uint8Array;
15
+ payloadReferences: SmartHealthCardPayloadReferences;
16
+ printData: InternationalHealthCardPrintData;
17
+ }>;
18
+ /**
19
+ * Issues transport values only after the caller supplies GW's authoritative
20
+ * readback Bundle. The tenant issuer owns the standard ES256 signature. Every
21
+ * authenticated attester independently owns one detached ML-DSA signature.
22
+ */
23
+ export declare function issueVeterinaryHealthCardCredential(input: Readonly<{
24
+ authoritativeBundle: Record<string, unknown>;
25
+ issuer: string;
26
+ notBefore: number;
27
+ keyId: string;
28
+ fhirVersion: string;
29
+ signEs256(signingBytes: Uint8Array): Promise<string>;
30
+ attesters: readonly VeterinaryHealthCardAttester[];
31
+ print: Readonly<{
32
+ validFrom: string;
33
+ validUntil: string;
34
+ authorOrganizationUrn: string;
35
+ }>;
36
+ pqcQr?: PostQuantumCompanionProofQrOptions;
37
+ }>): Promise<IssuedVeterinaryHealthCardCredential>;
38
+ /** Verifies the standard credential and all scanned companion proofs offline through caller-owned trust resolvers. */
39
+ export declare function verifyVeterinaryHealthCardCredential(input: Readonly<{
40
+ shcQr: readonly string[];
41
+ pqcQr: readonly (readonly string[])[];
42
+ verifyEs256(compactJws: string): Promise<boolean>;
43
+ verifyDetachedPqc(payloadBytes: Uint8Array, detachedJws: string): Promise<boolean>;
44
+ }>): Promise<Readonly<{
45
+ shc: boolean;
46
+ pqcCompanionProofs: readonly boolean[];
47
+ valid: boolean;
48
+ }>>;
49
+ /**
50
+ * Verifies every scanned proof before exposing the SHC Bundle to the shared
51
+ * IPS reader. Terminology enrichment runs only on a presentation copy after
52
+ * verification, so neither signature bytes nor payload hashes can change.
53
+ */
54
+ export declare function readVerifiedVeterinaryHealthCardCredential(input: Readonly<{
55
+ shcQr: readonly string[];
56
+ pqcQr: readonly (readonly string[])[];
57
+ language: string;
58
+ verifyEs256(compactJws: string): Promise<boolean>;
59
+ verifyDetachedPqc(payloadBytes: Uint8Array, detachedJws: string): Promise<boolean>;
60
+ resolveTerminology: ClinicalBundleReaderOptions['resolveTerminology'];
61
+ }>): Promise<Readonly<{
62
+ verification: Readonly<{
63
+ shc: boolean;
64
+ pqcCompanionProofs: readonly boolean[];
65
+ valid: boolean;
66
+ }>;
67
+ payload: SmartHealthCardPayload;
68
+ bundle: Record<string, unknown>;
69
+ }>>;
@@ -0,0 +1,78 @@
1
+ import { assembleSmartHealthCardJws, buildSmartHealthCardPayloadReferences, decodePostQuantumCompanionProofQr, decodeSmartHealthCardPayloadBytes, decodeSmartHealthCardQr, encodePostQuantumCompanionProofUri, encodePostQuantumCompanionProofQr, encodeSmartHealthCardQr, prepareSmartHealthCard, } from 'vet-data-utils-ts/shc';
2
+ import { buildInternationalHealthCardPrintData, } from 'vet-data-utils-ts/international-health-card';
3
+ import { projectClinicalBundleForReading, } from 'vet-data-utils-ts/clinical-bundle-reader';
4
+ /**
5
+ * Issues transport values only after the caller supplies GW's authoritative
6
+ * readback Bundle. The tenant issuer owns the standard ES256 signature. Every
7
+ * authenticated attester independently owns one detached ML-DSA signature.
8
+ */
9
+ export async function issueVeterinaryHealthCardCredential(input) {
10
+ if (input.authoritativeBundle?.resourceType !== 'Bundle'
11
+ || !Array.isArray(input.authoritativeBundle.entry)
12
+ || input.authoritativeBundle.entry.length === 0) {
13
+ throw new TypeError('veterinary_health_card_authoritative_bundle_required');
14
+ }
15
+ if (!Array.isArray(input.attesters) || input.attesters.length === 0) {
16
+ throw new TypeError('veterinary_health_card_attester_required');
17
+ }
18
+ const prepared = prepareSmartHealthCard({
19
+ issuer: input.issuer,
20
+ notBefore: input.notBefore,
21
+ kid: input.keyId,
22
+ fhirVersion: input.fhirVersion,
23
+ fhirBundle: input.authoritativeBundle,
24
+ additionalTypes: ['https://smarthealth.cards#immunization'],
25
+ });
26
+ const signature = await input.signEs256(prepared.signingBytes);
27
+ const compactJws = assembleSmartHealthCardJws(prepared, signature);
28
+ const detached = await Promise.all(input.attesters.map(attester => attester.signDetachedPqc(prepared.payloadBytes)));
29
+ const payloadReferences = buildSmartHealthCardPayloadReferences(prepared.payloadBytes);
30
+ return {
31
+ compactJws,
32
+ shcQr: encodeSmartHealthCardQr(compactJws),
33
+ pqcCompanionProofs: detached.map(encodePostQuantumCompanionProofUri),
34
+ pqcQr: detached.map(proof => encodePostQuantumCompanionProofQr(proof, input.pqcQr)),
35
+ payloadBytes: prepared.payloadBytes,
36
+ payloadReferences,
37
+ printData: buildInternationalHealthCardPrintData({
38
+ authoritativeBundle: input.authoritativeBundle,
39
+ validFrom: input.print.validFrom,
40
+ validUntil: input.print.validUntil,
41
+ authorOrganizationUrn: input.print.authorOrganizationUrn,
42
+ payloadBytes: prepared.payloadBytes,
43
+ }),
44
+ };
45
+ }
46
+ /** Verifies the standard credential and all scanned companion proofs offline through caller-owned trust resolvers. */
47
+ export async function verifyVeterinaryHealthCardCredential(input) {
48
+ const compactJws = decodeSmartHealthCardQr(input.shcQr);
49
+ const payloadBytes = decodeSmartHealthCardPayloadBytes(compactJws);
50
+ const shc = await input.verifyEs256(compactJws);
51
+ const pqcCompanionProofs = await Promise.all(input.pqcQr.map(qrSet => (input.verifyDetachedPqc(payloadBytes, decodePostQuantumCompanionProofQr(qrSet)))));
52
+ return {
53
+ shc,
54
+ pqcCompanionProofs,
55
+ valid: shc && pqcCompanionProofs.length > 0 && pqcCompanionProofs.every(Boolean),
56
+ };
57
+ }
58
+ /**
59
+ * Verifies every scanned proof before exposing the SHC Bundle to the shared
60
+ * IPS reader. Terminology enrichment runs only on a presentation copy after
61
+ * verification, so neither signature bytes nor payload hashes can change.
62
+ */
63
+ export async function readVerifiedVeterinaryHealthCardCredential(input) {
64
+ const compactJws = decodeSmartHealthCardQr(input.shcQr);
65
+ const payloadBytes = decodeSmartHealthCardPayloadBytes(compactJws);
66
+ const shc = await input.verifyEs256(compactJws);
67
+ const pqcCompanionProofs = await Promise.all(input.pqcQr.map(qrSet => (input.verifyDetachedPqc(payloadBytes, decodePostQuantumCompanionProofQr(qrSet)))));
68
+ const verification = {
69
+ shc,
70
+ pqcCompanionProofs,
71
+ valid: shc && pqcCompanionProofs.length > 0 && pqcCompanionProofs.every(Boolean),
72
+ };
73
+ if (!verification.valid)
74
+ throw new TypeError('veterinary_health_card_proof_invalid');
75
+ const payload = JSON.parse(new TextDecoder().decode(payloadBytes));
76
+ const bundle = await projectClinicalBundleForReading(payload.vc.credentialSubject.fhirBundle, { language: input.language, resolveTerminology: input.resolveTerminology });
77
+ return { verification, payload, bundle };
78
+ }
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export * from "./animal-onboarding.js";
6
6
  export * from "./reusable-bff.js";
7
7
  export * from "./research-study.js";
8
8
  export * from "./payment.js";
9
+ export * from "./health-card-issuance.js";
9
10
  export * from "vet-data-utils-ts";
package/dist/index.js CHANGED
@@ -6,4 +6,5 @@ export * from "./animal-onboarding.js";
6
6
  export * from "./reusable-bff.js";
7
7
  export * from "./research-study.js";
8
8
  export * from "./payment.js";
9
+ export * from "./health-card-issuance.js";
9
10
  export * from "vet-data-utils-ts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vet-sdk-core-ts",
3
- "version": "0.4.20",
3
+ "version": "0.4.22",
4
4
  "description": "Browser-safe VetChain core contracts and governed animal species identifiers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Connecting Solution & Applications Ltd",
@@ -43,6 +43,10 @@
43
43
  "./payment": {
44
44
  "types": "./dist/payment.d.ts",
45
45
  "default": "./dist/payment.js"
46
+ },
47
+ "./health-card-issuance": {
48
+ "types": "./dist/health-card-issuance.d.ts",
49
+ "default": "./dist/health-card-issuance.js"
46
50
  }
47
51
  },
48
52
  "files": [
@@ -68,6 +72,6 @@
68
72
  "dependencies": {
69
73
  "@noble/hashes": "^2.2.0",
70
74
  "gdc-common-utils-ts": "2.9.10",
71
- "vet-data-utils-ts": "0.5.6"
75
+ "vet-data-utils-ts": "0.5.9"
72
76
  }
73
77
  }