All pages
Powered by GitBook
1 of 3

Loading...

Loading...

Loading...

Present a Verifiable Credential

Present a Verifiable Credential, signed by a did:cheqd Decentralized Identifier (DID), using Credo.

Verifiable Credentials signed by a did:cheqd can be securely presented using the AnonCreds proof format and the Present Proof Protocol v2 within the Credo framework. This enables trust-minimised, selective disclosure of credential data between a Holder and a Verifier.

Prerequisites

Before presenting a credential:

  • A Verifiable Credential must have been issued and accepted by the Holder

  • A Credo Agent is running for both the Verifier and the Holder

  • A DIDComm connection exists between Holder and Verifier (via OOB or another method)

  • Both agents are configured with:

    • @credo-ts/anoncreds

    • @credo-ts/didcomm

Step 1: Create a Connection with Holder

Use any supported method to create a connection with the Holder. Automated is recommended. You can follow the same steps as described in .

Step 2: Send Proof Request

After connection is established, the Verifier can send a proof request to the Holder.

Step 3: Holder sends Presentation Proof

Holder can get the stored credentials from own wallet and format a proof to send to the Verifier.

When we want to send a proof, we have to listen to incoming proof requests and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the request.

What’s Happening Behind the Scenes?

  • The Verifier sends a proof request with specific attributes and credential requirements

  • The Holder uses locally stored credentials to generate a selective disclosure proof

  • The proof is signed using AnonCreds and returned to the Verifier over DIDComm

  • The Verifier cryptographically validates the proof and the issuing DID (did:cheqd

Next Steps

For more tutorials and examples, visit .

Issue a Verifiable Credential

Issue a Verifiable Credential (AnonCreds), signed with a did:cheqd Decentralized Identifier (DID).

Using AnonCreds and the Issue Credential v2 Protocol, you can issue Verifiable Credentials signed by a did:cheqd identifier with just a few lines of code. This guide walks through the full flow using the Credo Agent.

Prerequisites

Before you begin, make sure you have:

)
out-of-band protocol
Issue a Verifiable Credential
Credo Docs

A registered did:cheqd Decentralized Identifier (DID) for the Issuer.

  • A Credential Schema and Credential Definition already created and published as DID-Linked Resources.

  • A Credo Agent configured with:

    • @credo-ts/cheqd for DID operations and resource publishing.

    • @credo-ts/anoncreds for AnonCreds credential handling.

    • @credo-ts/didcomm for DIDComm messaging

  • Two agents: an Issuer and a Holder (can be separate apps or run locally)

  • Secure connectivity between agents using Out-of-Band (OOB) or a supported connection method.

  • Step 1: Create a Connection with Holder

    Use any supported method to create a connection with the Holder of the credential. Automated out-of-band protocol is recommended.

    1a: Issuer Creates Connection Invite

    The Issuer agent will create a new connection invite for the Holder. This is needed to securely communicate between the Issuer and the Holder agents.

    1b: Holder receives invitation

    The above request will have an invitation in the response. Holder will have to copy that invitation and pass URL as invitationUrl in the following code:

    Step 2: Prepare and Send Credential Offer

    Generate a credential offer and send to the holder, informing them about the available credential and its attributes.

    Step 3: Holder accepts credential offer

    When we want to accept a credential, we have to listen to incoming credentials and handle accordingly. In this example we do not have any user interaction, but is likely that your application would have a user-interface which would display the credential. When receiving a credential offer you can get the values from credentialExchangeRecord.credentialAttributes.

    Summary

    Step
    Action

    1

    Create and accept a secure connection between Issuer and Holder

    2

    Issuer prepares and sends a credential offer (via AnonCreds v2)

    3

    Holder accepts and stores the credential automatically or via UI

    Verifier/Issuer
    await this.agent.modules.proofs.requestProof({
      protocolVersion: 'v2',
      connectionId: connectionRecord.id,
      proofFormats: {
        anoncreds: {
          name: 'proof-request',
          version: '1.0',
          requested_attributes: {
            name: {
              name: 'name',
              restrictions: [
                {
                  cred_def_id: this.credentialDefinition?.credentialDefinitionId,
                },
              ],
            },
          },
        },
      },
    })
    Holder
    this.agent.events.on(ProofEventTypes.ProofStateChanged
      async ({ payload }: ProofStateChangedEvent) => {
        if (payload.proofRecord.state === ProofState.RequestReceived) {
          const requestedCredentials = await this.agent.modules.proofs.selectCredentialsForRequest({
            proofRecordId: payload.proofRecord.id,
          })
          await this.agent.modules.proofs.acceptRequest({
            proofRecordId: proofRecord.id,
            proofFormats: requestedCredentials.proofFormats,
          })
        }
    })
    Issuer
    const createNewInvitation = async (agent: Agent) => {
      const outOfBandRecord = await agent.modules.oob.createInvitation()
    
      return {
        invitationUrl: outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'http://localhost:3001' }),
        outOfBandRecord,
      }
    }
    Holder
    const receiveInvitation = async (agent: Agent, invitationUrl: string) => {
      const { outOfBandRecord } = await agent.modules.oob.receiveInvitationFromUrl(invitationUrl)
      if (!outOfBandRecord) {
          throw new Error(redText(Output.NoConnectionRecordFromOutOfBand))
      }
      return outOfBandRecord
    }
    Issuer
    await this.agent.modules.credentials.offerCredential({
          connectionId: connectionRecord.id,
          protocolVersion: 'v2',
          credentialFormats: {
            anoncreds: {
              attributes: [
                {
                  name: 'name',
                  value: 'Alice Smith',
                },
                {
                  name: 'degree',
                  value: 'Computer Science',
                },
                {
                  name: 'date',
                  value: '01/01/2022',
                },
              ],
              credentialDefinitionId: credentialDefinition.credentialDefinitionId,
            },
          },
        })
    Holder
    this.agent.events.on(CredentialEventTypes.CredentialStateChanged,
      async ({ payload }: CredentialStateChangedEvent) => {
      switch (payload.credentialRecord.state) {
        case CredentialState.OfferReceived:
          console.log('received a credential')
          // custom logic here
          await this.agent.modules.credentials.acceptOffer({ credentialRecordId: payload.credentialRecord.id })
          break
        case CredentialState.Done:
          console.log(`Credential for credential id ${payload.credentialRecord.id} is accepted`)
          // For demo purposes we exit the program here.
          process.exit(0)
      }
    })

    AnonCreds

    Issue, present and revoke AnonCreds signed by cheqd Decentralized Identifiers (DIDs), using Credo.

    AnonCreds is a privacy-preserving Verifiable Credential format designed for selective disclosure, non-correlatable presentations, and revocation support. In Credo, AnonCreds is fully supported using the Issue Credential v1/v2 and Present Proof v1/v2 protocols.

    Credo allows users to issue, hold, and verify AnonCreds credentials using a range of supported ledgers—including full integration with the cheqd network, a modern, scalable alternative to legacy Indy-based networks.

    Get started

    Issue, present and revoke AnonCreds signed by cheqd Decentralized Identifiers (DIDs), using the tutorials below:


    Why Use AnonCreds?

    AnonCreds credentials are purpose-built for high-assurance, privacy-respecting use cases that require:

    • Selective disclosure of individual claims

    • Zero-knowledge proofs

    • Revocation support via AnonCreds Status Lists

    • Credential definitions and revocation registries anchored on-ledger


    AnonCreds + cheqd Support

    Credo now supports did:cheqd for issuing AnonCreds credentials using the cheqd AnonCreds Object Method. This removes dependency on Indy-based networks while retaining the proven AnonCreds credential exchange flow.

    With Credo + cheqd, you can:

    • ✅ Register did:cheqd identifiers for use in credential issuance

    • ✅ Publish Schemas and Credential Definitions as DID-Linked Resources

    • ✅ Issue and verify AnonCreds credentials signed with did:cheqd

    ✅ This allows developers to migrate off the deprecated Sovrin network or other Indy networks without changing their existing flows or protocols.


    Features Supported in Credo

    Feature
    Supported in ACA-Py

    AnonCreds Object Method

    Take a deep dive into the cheqd AnonCreds Object Method below:

    ✅ Enable revocation using AnonCreds Status List Definitions and Entries, also stored on-ledger as DID-Linked Resources

    Issue AnonCreds credentials

    ✅ Yes

    Present and verify credentials

    ✅ Yes

    Revocation support via cheqd AnonCreds Status Lists

    ✅ Yes

    DID-Linked Resource anchoring (schemas, defs, status)

    ✅ Yes

    Use did:cheqd for AnonCreds

    ✅ Yes

    Use other Indy-compatible ledgers

    ✅ Yes

    Issue AnonCreds Credentials

    Issue AnonCreds Credentials signed by cheqd DIDs using Credo.

    Present AnonCreds Credentials

    Present AnonCreds Credentials using Credo.

    cheqd AnonCreds Object Method

    Understand how cheqd supports AnonCreds Objects using DID-Linked Resources.