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:
- A registered - did:cheqdDecentralized 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/cheqdfor DID operations and resource publishing.
- @credo-ts/anoncredsfor AnonCreds credential handling.
- @credo-ts/didcommfor 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.
const createNewInvitation = async (agent: Agent) => {
  const outOfBandRecord = await agent.modules.oob.createInvitation()
  return {
    invitationUrl: outOfBandRecord.outOfBandInvitation.toUrl({ domain: 'http://localhost:3001' }),
    outOfBandRecord,
  }
}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:
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
}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.
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,
        },
      },
    })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.
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)
  }
})Summary
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
Last updated
Was this helpful?
