Build a verifier
You run the buyer or retailer side: ask the product's wallet to present its authenticity credential, then verify the proof — over the same VCALM exchange loop the wallet speaks.
Under the hood: the raw VCALM exchange
Want to build your own coordinator, or just see exactly what the server does on the wire? It's a short HTTP loop — three things:
- Expose an interaction URL that advertises
vcapi. - When the wallet POSTs to start, respond with a
verifiablePresentationRequestdescribing the credential you need. - Receive the
verifiablePresentationand verify its proof, challenge, and domain.
1. Request the credential
When the wallet POSTs an empty body to your exchange URL, respond with a
QueryByExample asking for the credential type you need:
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": [{
"reason": "Please present this product's authenticity credential.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/traceability/v1"
],
"type": "ProductPassportCredential"
},
"trustedIssuer": [{
"required": true,
"issuer": "did:web:brand.example"
}]
}]
}],
"challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f",
"domain": "retailer.example"
}
}
The challenge and domain are what you'll verify in
the returned proof — they stop a captured presentation from being replayed.
Use trustedIssuer to require the credential come from the real
brand.
2. Receive the presentation
The wallet POSTs the signed presentation back to the same exchange URL:
{
"verifiablePresentation": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiablePresentation"],
"holder": "did:example:bag-456",
"verifiableCredential": [{ "...": "the authenticity VC" }],
"proof": {
"challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f",
"domain": "retailer.example",
"...": "holder signature"
}
}
}
3. Verify the proof
Before you trust the product is genuine, check all of the following:
- The presentation proof is valid and the
challenge/domainmatch what you sent. - The credential's proof is valid and the issuer is the brand you trust.
- The credential is not revoked (e.g. reported stolen or recalled) — check its status.
- The credential is unexpired and the type matches your request.
That's it
A conformant provenance verifier is this exchange: request, receive, verify. The cryptographic verification is your verifier instance's job — the coordinator just runs the exchange.
On the wallet end, a standalone client-side VCALM library is still planned; until it ships, the raw HTTP flow is the supported path there. For the verifier/coordinator side shown here, use @bedrock/vc-delivery.