vet-sdk-core-ts
v0.4.37
Published
Browser-safe VetChain core contracts and governed animal species identifiers
Readme
VetChain Core SDK
vet-sdk-core-ts/place-service-directory is the VetChain-only bundle boundary
for claims-first Schema.org Place and Service resources. It builds GW VET
batch/search envelopes and joins authorized directory search responses for the
PetChain marketplace; it does not extend gdc-*.
Development and releases follow the mandatory
local-first TDD and release contract.
Browser-safe VetChain domain contracts. This repository is independent from UHC SDK packages and must not import them.
The SDK consumes governed browser-safe values from vet-data-utils-ts and
owns gateway request construction. GW VET remains the policy authority.
vet-sdk-core-ts/health-dcat provides the neutral manager for tenant-owned
HealthDCAT metadata. It publishes and searches claims-first resources, asks an
ICA adapter for host catalogue capabilities, and sends explicit controller
federation requests. GW authentication, OpenID Federation trust resolution,
OpenID4VP verification and Dataspace Protocol exchange stay in injected
transports; the SDK neither exposes tenant inventories through ICA nor treats
the host as the tenant publisher.
Study publication writes the derived Dataset and its CatalogRecord together.
Withdrawal updates only that record to archived; it does not delete or alter
the ResearchStudy, eligibility/team Groups, ResearchSubjects or data-access
classification.
Veterinary scheduling bundles
The vet-sdk-core-ts/scheduling entrypoint extends the generic GW bundle
boundary without changing gdc-*. It builds claims-first JSON:API batches,
reads canonical body.data[].resource search matches and reconciles removed
occupied Slots as pending Appointments plus durable rescheduling
Communications. The same product extension can later be promoted for SOSChain
or UHC/UNID after their resource policy is defined.
Veterinary health-card issuance
issueVeterinaryHealthCardCredential(...) accepts only an authoritative
readback Bundle, creates the standard ES256 SHC signing input, and asks each
attester for an independent RFC 7797 ML-DSA proof over the exact uncompressed
payload. pqcQr.qrCount configures the number of numeric companion labels; it
defaults to two and never copies the payload into those labels.
The result contains printable vaccination data plus both
payloadReferences.multihashUrn for an exact blockchain-index lookup and
payloadReferences.cidV1 for content-addressed retrieval. The issuer supplies
the validity interval explicitly; FHIR Immunization.expirationDate remains
the vaccine-batch expiry.
pqcProofLookupReference is separate: it hashes the exact compact SHC JWS so
publishVeterinaryHealthCardPqcProofs(...) and
resolveVeterinaryHealthCardPqcProofs(...) can use a product ledger/resolver
to retrieve the unchanged detached pqc:/ proofs from a single printed SHC
QR when online. It does not replace the offline companion QR labels.
Private clinic documents and index projection
sealVeterinarySecureClinicMessage(...) signs the complete FHIR Bundle
document with ML-DSA-44 and encrypts it to the clinic/controller endpoint with
ML-KEM-768 plus AES-256-GCM. Its separate index projection contains only each
source fullUrl and the server-policy allowlisted resource.meta.tag[]
codings. Every coding system must be the concrete
<ResourceType>.<search-parameter-or-custom> key; repeated values become one
CSV flat claim. The GW never receives the encrypted message or private Bundle.
USDC payment quotes
vet-sdk-core-ts/payment separates the payment provider, asset and EVM network
instead of treating every token named USDC as equivalent. It pins Circle USDC
on Base Sepolia and Base mainnet, validates the server-authored recipient,
integer six-decimal amount and expiry, and keeps mainnet disabled unless the
caller supplies a separately approved release policy. Local Anvil deployments
provide their deployed mock-token contract through the same network contract;
they never reuse a production address.
The quote authorizes no payment by itself. A server payment adapter must still verify the receipt, Transfer log, payer, recipient, amount, confirmation depth, invoice state and transaction-hash idempotency before reconciling the payment.
Research studies
buildVeterinaryResearchStudyCreateWorkflowIds accepts a client-generated
operation UUID and the exact PractitionerRole/... references. It reuses the
operation UUID as researchStudyId and deterministically derives distinct
UUIDv5 values for the Group and every Communication/draft Consent pair. A
retry therefore addresses the same resources and a partially completed saga
can resume safely. Stable identifiers do not make separate service calls
atomic and confer no membership, Consent or SMART authority.
buildVeterinaryResearchStudyCreateEntry accepts ResearchStudy business data
and projects it into the canonical JSON:API resource object: resourceType,
id and flat resource.meta.claims. It does not send native status, title,
associatedParty or recruitment objects to GW. Associated parties use one
independent flat-claim PATCH entry per party, so references, roles, periods and
classifiers cannot be mixed across employees. Native FHIR JSON is produced
only by an explicit later export/projection boundary.
Study participation does not itself authorize access. The separate
buildVeterinaryResearchStudySmartAuthorization request is limited to create,
read, update and search for ResearchSubjects filtered by the exact study. It
never requests deletion of the twin; deletion of selected clinical facts must
target those concrete resources under an active controller-approved Consent.
The builder fails closed unless the professional has completed DCR and the
later controller-approved Consent is active. It emits the canonical purpose
HRESCH and the unescaped scope
organization/ResearchSubject.crus?study=ResearchStudy/<id> so it can be
passed to the protected professional runtime; the DCR-bound runtime supplies
the professional actor as sub.
buildVeterinaryResearchStudyActiveConsentBatch builds the controller's
separate JSON:API Consent/_batch. Every POST is fixed to active, permit,
HRESCH, one PractitionerRole, its ISCO-08 role, and that same exact
ResearchStudy scope. The API does not accept caller-authored actions, so it
cannot be broadened to delete.
buildVeterinaryResearchStudyPartyInvitations creates exactly one claims-only
Communication per associated PractitionerRole. Its canonical attachment
claims carry an application/vnd.api+json primary document containing one
JSON:API resource object with type, id and flat Consent claims in
attributes; resource, request and FHIR Bundle shapes are rejected.
Consent.source-reference pins the ResearchStudy
and Consent.resource-type pins ResearchSubject. The draft requests only
create, read, update and search; it contains no delete permission and never
authorizes SMART access. Native FHIR Communication, Consent or Bundle objects
are accepted only by explicit import/projection/export adapters.
buildVeterinaryResearchStudyGroupCreateEntry and
buildVeterinaryResearchStudyGroupMemberPatchEntries build flat-claim Group
POST/PATCH entries for an enumerated professional review team. Every member is
a registered PractitionerRole; the exact twelve Group search claims are
derived from vet-data-utils-ts/group, and each member has its own PATCH entry.
The Group stays independent: individual professionals are related to the study
through separate ResearchStudy.associatedParty PATCH entries. It must not use
ResearchStudy.recruitment.eligibility, which represents research-subject
cohorts or eligibility criteria. Group grants no authorization, permission or
SMART scope; DCR and active Consent remain separate.
The Group create builder requires the ResearchStudy UUID and derives a
governed Group.identifier. Its exported search helper re-derives
the same deterministic UUIDv5 review-team identifier after refresh without
using eligibility or granting authority.
The complete controller-to-professional contract and a browser-safe snippet
are in
docs/101-RESEARCH-STUDY-INVITATIONS.md.
FHIR references:
- https://hl7.org/fhir/R5/researchstudy.html
- https://hl7.org/fhir/R5/researchsubject-search.html
- https://hl7.org/fhir/R5/communication.html
- https://hl7.org/fhir/R5/consent-definitions.html
- https://hl7.org/fhir/R5/group.html
- https://hl7.org/fhir/R5/group-search.html
Reusable professional BFF
ReusableProfessionalBffClient exposes the complete business-level portal
journey for UHC UNID, VetChain and SOSChain adapters: post-login profile gate,
organization admission and review, activation, licences, employees, individual
creation, clinical data, secondary-use consent, Digital Twin search and
break-glass. Product adapters inject sectors, translations, routes and policy.
The client rejects GW, wallet, DCR, SMART and VP plumbing from browser payloads.
Start with docs/101-REUSABLE_PROFESSIONAL_BFF.md
and its commented snippet.
Professional break-glass authorization
Node BFFs call buildVeterinaryBreakGlassSmartAuthorization with only the
animal DID, governed sections, incident id and clinical justification. The
result can be passed directly to
ServerProfileSessionManager.openProfessional().requestSmartToken(...).
It contains the veterinary purpose, scope, 15-minute cap and audited emergency
claims, but never a client_id, SMART audience, private-key assertion or VP.
Those OpenID proofs are reconstructed and signed by the registered server
wallet in gdc-sdk-node-ts.
const authorization = buildVeterinaryBreakGlassSmartAuthorization({
subjectDid,
requestedSections,
incidentId,
justification,
})
await openedProfessional.requestSmartToken(authorization)buildVeterinaryBreakGlassSmartRequest remains only as a low-level
compatibility envelope for integrations that already own the OpenID fields.
The numeric animal identity and external evidence contract is documented in
docs/ANIMAL_IDENTITY.md.
The personal controller identity flow uses only the high-level reusable BFF
methods documented in
docs/101-PERSONAL-IDENTITY-EVIDENCE.md.
Animal species
VetChainDomesticAnimalSpecies provides stable application keys, official
NCBI Taxonomy identifiers, scientific names and broad animal groups for common
domesticated, farmed and companion animals. User-facing common names remain in
each portal's i18n catalogue.
The catalogue is a governed starter set, not a closed biological universe. Callers may retain another verified positive non-human NCBI Taxonomy identifier. This matters because animal keeping varies by jurisdiction and taxonomy evolves.
Current cards are issued with issueVetChainAnimalCard: five jurisdiction
digits plus animalNumericId15 + checkDigit1, and the matching
did:web:{host}:card:vetchain:{jurisdiction5}:{animal16}. Species is separate
card context and participates in the Damm calculation as speciesId7 without
being repeated in the 21 printed digits.
import {
VetChainDomesticAnimalSpecies,
findVetChainSpeciesByTaxonomyId,
} from "vet-sdk-core-ts/species";
VetChainDomesticAnimalSpecies.DomesticFerret.ncbiTaxonomyId; // "9669"
findVetChainSpeciesByTaxonomyId("9685")?.key; // "Cat"Digital-twin search
buildVeterinaryDigitalTwinSearchRequest accepts only one governed section,
free text and dates. It returns both the basic FHIR
Parameters body and the filters map for DigitalTwinSdk.search; callers do
not author Composition.section, resource families or flat claim names. The returned public
resource is ResearchSubject, so the Node SDK sends
POST digitaltwin/.../ResearchSubject/_search; the Composition.* fields
inside GW index the canonical Composition embedded in that ResearchSubject.
const request = buildVeterinaryDigitalTwinSearchRequest({
thid: crypto.randomUUID(),
search: { section, text, dateFrom, ...(dateTo ? { dateTo } : {}) },
})
await digitalTwins.search(routeContext, {
thid: request.payload.thid,
format: request.format,
resourceType: request.resourceType,
filters: request.filters,
})