Credential Handler API (CHAPI) implementation for TrustWeave.
Overview
CHAPI is a browser-based API that enables credential wallet interactions through the browser’s credential management system. It provides a standardized way for web applications to interact with credential wallets.
valoffer=registry.offerCredential(protocolName="chapi",request=CredentialOfferRequest(issuerDid="did:key:issuer",holderDid="did:key:holder",credentialPreview=CredentialPreview(attributes=listOf(CredentialAttribute("name","Alice"),CredentialAttribute("email","alice@example.com")))))// The offer contains a CHAPI message that can be used in the browservalchapiMessage=offer.offerDataasJsonObject
Browser Integration
In a browser environment, use the CHAPI messages with the Credential Handler API:
1
2
3
4
5
6
7
8
9
10
11
12
// Store credential offerconstoffer={"@context":["https://www.w3.org/2018/credentials/v1","https://w3id.org/credential-handler/v1"],"type":["VerifiableCredential","CredentialOffer"],// ... offer data from offer.offerData};navigator.credentials.store(newCredential({id:"credential-offer",type:"web",data:offer}));
valcredential=VerifiableCredential(type=listOf("VerifiableCredential","PersonCredential"),issuer="did:key:issuer",credentialSubject=buildJsonObject{put("id","did:key:holder")put("name","Alice")put("email","alice@example.com")},issuanceDate=Instant.now().toString())valissue=registry.issueCredential(protocolName="chapi",request=CredentialIssueRequest(issuerDid="did:key:issuer",holderDid="did:key:holder",credential=credential,requestId="request-id"))// The issue result contains a CHAPI message for browser storagevalchapiMessage=issue.issueDataasJsonObject
Proof Request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
valproofRequest=registry.requestProof(protocolName="chapi",request=ProofRequestRequest(verifierDid="did:key:verifier",proverDid="did:key:prover",name="Proof of Identity",requestedAttributes=mapOf("name"toRequestedAttribute(name="name",restrictions=listOf(AttributeRestriction(issuerDid="did:key:issuer"))))))// The proof request contains a CHAPI message for browser usevalchapiMessage=proofRequest.requestDataasJsonObject
// Request proofconstproofRequest={"@context":["https://www.w3.org/2018/credentials/v1","https://w3id.org/credential-handler/v1"],"type":["VerifiablePresentationRequest"],// ... proof request data from proofRequest.requestData};navigator.credentials.get({publicKey:{challenge:newUint8Array(32),rpId:window.location.hostname,userVerification:"preferred"},web:{data:proofRequest}}).then(credential=>{// Handle the presentation responseconstpresentation=credential.data;});
Proof Presentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
valpresentation=VerifiablePresentation(type=listOf("VerifiablePresentation"),verifier="did:key:verifier",verifiableCredential=listOf(credential))valpresentationResult=registry.presentProof(protocolName="chapi",request=ProofPresentationRequest(proverDid="did:key:prover",verifierDid="did:key:verifier",presentation=presentation,requestId=proofRequest.requestId))// The presentation result contains a CHAPI messagevalchapiMessage=presentationResult.presentationDataasJsonObject
CHAPI Flow
Credential Offer: Issuer creates a CHAPI-compatible offer message
Browser Storage: Offer is stored using navigator.credentials.store()
Wallet Interaction: Wallet processes the offer and stores the credential
Proof Request: Verifier creates a CHAPI-compatible proof request
Browser Retrieval: Request is retrieved using navigator.credentials.get()
Proof Presentation: Wallet presents proof using CHAPI message format
Message Format
CHAPI messages follow the W3C Credential Handler API specification: