# W3C AnonCreds in Aries Framework JavaScript This document outlines the design of integrating W3C VC data model compliant AnonCreds credentials into Aries Framework JavaScript and Bifold. Opportunity: https://marketplace.digital.gov.bc.ca/opportunities/code-with-us/6f08d6d5-7e3d-489a-a98f-d7c607309dc9 ## Aries Framework JavaScript The following lists all the planned changes and areas of complexities we see in Aries Framework JavaScript. **Overview:** The first step will be to update AFJ to store all credentials in the new W3C format and not break current flows. Next, we will focus on issuing credentials in the W3C format using the W3C Verifiable Credential Data Integrity Attachment format. The third step is to allow requesting and presenting presentations of verifiable credentials (`anoncredsvc-2023`) in W3C format. After creating a release in AFJ containing the previously mentioned changes, during the last part, we will update Bifold's AFJ version and integrate the newly created functionality. The implementation parts are driven by test vectors defined in [this](https://github.com/TimoGlastra/anoncreds-w3c-test-vectors) Github repo. ### Storage - Update Afj to use the latest version of anoncreds-rs. - Store AnonCreds credentials in W3C format, transforming them to the (legacy) AnonCreds format when needed during an exchange. This allows them to be used interchangeably for exchanges in W3C format and AnonCreds format. - When converting credentials from the W3C format to the legacy format, it will be taken into account whether the credential or metadata requires qualified or unqualified identifiers. - W3C Records are updated to store additional metadata required for anoncreds flows. - The W3C CredentialSubject implementation is updated to allow defining arbitrary claims, which is required to create W3C credentials containing the claims of arbitrary credential schemas. - Write a migration that re-stores all credentials stored in the legacy anoncreds format in the new w3c format. - Because credentials are stored in W3C format, the PEX presentation definition querying logic can be used to find matching AnonCreds credentials (in addition to also querying matching non-AnonCreds W3C credentials) ### W3C Credential Issuance Issuance of W3C credentials with an AnonCreds signature are handled using the new [W3C Verifiable Credential Data Integrity Attachment format](https://github.com/hyperledger/aries-rfcs/blob/2dfe5a1046aead12f66d3c68e2a7366cabb0621b/features/0809-w3c-data-integrity-credential-attachment/README.md). The DataIntegrity attachment implementation will be part of AFJ's core. For simplicity reasons, we may keep the implementation in the anoncreds package for now. Otherwise, we need to create a way to dynamically register the link-secret binding method, which requires dependencies that are not a part of the core, or move the required dependencies to the core. A credential using the new attachment format can be issued in AFJ like this: ```typescript await issuer.credentials.offerCredential({ connectionId: '<connectionId>', credentialFormats: { dataIntegrity: { // specify if the holder can request the credential without binding method bindingRequired: true, credential: { ... }, // the W3cCredential which is offered to the holder linkSecretBinding: { credentialDefinitionId: string }, didCommSignedAttachmentBinding: { // no properties required } } } }) ``` ```typescript await holder.credentials.acceptOffer({ credentialRecordId: holderRecord.id, credentialFormats: { // The holder can accept the offer with the binding // methods offered to him. Or no binding method // at all, if this is permitted. dataIntegrity: { linkSecretBinding: { linkSecretId: 'linkSecretId', }, didCommSignedAttachment: { kid: 'did:example:1234', } }, }, }) ``` ```typescript await issuer.credentials.acceptRequest({ // The issuer can accept the offer with // no additional information needed, // as the binding method(s) is implicitly specified // through the request. credentialRecordId: issuerRecord.id, credentialFormats: { dataIntegrity: { }, }, }) ``` ```typescript await holder.credentials.acceptCredential({ // the holder accepts storing the received credential in his wallet credentialRecordId: holderRecord.id, }) ``` ### W3C Credential Presentation Presentation of W3C credentials with an AnonCreds signature is handled using [Aries RFC 0510: Presentation-Exchange Attachment format for requesting and presenting proofs](https://github.com/hyperledger/aries-rfcs/blob/main/features/0510-dif-pres-exch-attach/README.md) The base integration of PEX has already been completed an is [merged into AFJ main on January 10th 2024](https://github.com/openwallet-foundation/credo-ts/pull/1676). Updates are now being made to the implementation in AFJ, as well as the [Sphereon PEX library](https://github.com/sphereon-Opensource/pex) to support the new `DataIntegrityProof` and `di_vc` proof formats as described [here](https://github.com/decentralized-identity/claim-format-registry/issues/8) and in the test vectors. Selective disclosure and predicates will are handled by the AnonCreds RS implementation. A proof request is handled like this in AFJ: ```typescript await holder.proofs.proposeProof({ protocolVersion: 'v2', connectionId: holderConnectionId, proofFormats: { presentationExchange: { presentationDefinition: { ... }, }, }, }) ``` ```typescript await verifier.proofs.acceptProposal({ proofRecordId: issuerProofExchangeRecord.id, }) ``` ```typescript const credentialsForRequest = await holder.proofs.getCredentialsForRequest({ proofExchangeId: '<proofExchangeId>' }) // object containing the credentials that satisfy the different input descriptors from the request credentialsForRequest.presentationExchange // You can then either let the framework auto-select const credentialsForRequest = await holder.proofs.selectCredentialsForRequest({ proofExchangeId: '<proofExchangeId>' }) // Or you can let the user (e.g. in a mobile wallet) select credentials based // on the credentialsForRequest structure. This is already implemented in the Paradym Wallet UI // Then finally you accept it: await holder.proofs.acceptRequest({ proofExchangeId: '<proofExchangeId>' proofFormats: { presentationExchange: { credentials: // credentials selected by user (or keep empty to auto-select) } } }) ``` ```typescript // Accept a presentation (by sending a presentation acknowledgement message) // to the connection associated with the proof record if validation succeeded. await issuer.proofs.acceptPresentation({ proofRecordId: proofExchangeRecord.id }) ``` ## Bifold The bifold work consists of integrating the added features from AFJ and adding support for rendering W3C and DIF PE models. - A new release in AFJ containing the abovementioned changes is created. - Support for rendering W3C credentials in the Bifold wallet is added. We will re-use the existing rendering logic but also allow the credential offer and credential detail screens to support W3C-encoded AnonCreds credentials - Support for rendering and selecting DIF PE presentation requests and AnonCreds proof requests. The implementation will be based on an existing implementation in our Paradym Wallet. ## Test Vectors The implementation in AFJ is based on the defined test vectors in https://github.com/TimoGlastra/anoncreds-w3c-test-vectors