Skip to main content
DIDComm (Decentralized Identity Communication) is a secure messaging protocol for communication between decentralized identity agents.

Installation

npm install @credo-ts/didcomm

Basic Setup

The DidCommModule provides messaging, connections, credentials, proofs, and more:
import { Agent } from '@credo-ts/core'
import { DidCommModule } from '@credo-ts/didcomm'
import { agentDependencies } from '@credo-ts/node'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      endpoints: ['http://localhost:3000'],
      connections: {
        autoAcceptConnections: true,
      },
    }),
  },
})

await agent.initialize()

Configuration Options

Endpoints

Specify where your agent can receive messages:
new DidCommModule({
  endpoints: [
    'http://localhost:3000',
    'https://my-agent.example.com',
  ],
})
If no endpoints are provided, the agent uses a queue-based transport.

Transports

Configure inbound and outbound transports:
import {
  DidCommModule,
  DidCommHttpOutboundTransport,
  DidCommWsOutboundTransport,
} from '@credo-ts/didcomm'
import {
  DidCommHttpInboundTransport,
  DidCommWsInboundTransport,
} from '@credo-ts/node'

new DidCommModule({
  transports: {
    inbound: [
      new DidCommHttpInboundTransport({ port: 3000 }),
      new DidCommWsInboundTransport({ port: 3001 }),
    ],
    outbound: [
      new DidCommHttpOutboundTransport(),
      new DidCommWsOutboundTransport(),
    ],
  },
})

Auto-Accept Settings

Control automatic acceptance of connections, credentials, and proofs:
import {
  DidCommModule,
  DidCommAutoAcceptCredential,
  DidCommAutoAcceptProof,
} from '@credo-ts/didcomm'

new DidCommModule({
  connections: {
    autoAcceptConnections: true,
  },
  credentials: {
    autoAcceptCredentials: DidCommAutoAcceptCredential.ContentApproved,
  },
  proofs: {
    autoAcceptProofs: DidCommAutoAcceptProof.ContentApproved,
  },
})
Auto-accept options:
  • DidCommAutoAcceptCredential.Always - Accept all
  • DidCommAutoAcceptCredential.ContentApproved - Accept if content matches
  • DidCommAutoAcceptCredential.Never - Manual acceptance only

Creating Connections

Create an Invitation (Inviter)

const outOfBand = await agent.didcomm.oob.createInvitation()

const invitationUrl = outOfBand.outOfBandInvitation.toUrl({
  domain: 'https://example.com',
})

console.log('Share this invitation:', invitationUrl)

Accept an Invitation (Invitee)

const { connectionRecord } = await agent.didcomm.oob.receiveInvitationFromUrl(
  invitationUrl,
  {
    label: 'My Agent',
  }
)

if (connectionRecord) {
  await agent.didcomm.connections.returnWhenIsConnected(connectionRecord.id)
  console.log('Connection established!')
}

Wait for Connection

Listen for connection state changes:
import {
  DidCommConnectionEventTypes,
  type DidCommConnectionStateChangedEvent,
} from '@credo-ts/didcomm'

agent.events.on<DidCommConnectionStateChangedEvent>(
  DidCommConnectionEventTypes.DidCommConnectionStateChanged,
  (event) => {
    const { connectionRecord, previousState } = event.payload
    console.log(
      `Connection ${connectionRecord.id} changed from ${previousState} to ${connectionRecord.state}`
    )
  }
)

Credential Protocols

Credo supports multiple credential exchange protocols:
import {
  DidCommCredentialV2Protocol,
  AnonCredsDidCommCredentialFormatService,
} from '@credo-ts/didcomm'
import { AnonCredsDidCommCredentialFormatService } from '@credo-ts/anoncreds'

new DidCommModule({
  credentials: {
    credentialProtocols: [
      new DidCommCredentialV2Protocol({
        credentialFormats: [
          new AnonCredsDidCommCredentialFormatService(),
        ],
      }),
    ],
  },
})

Issuing Credentials

Offer a Credential

await agent.didcomm.credentials.offerCredential({
  connectionId: connectionRecord.id,
  protocolVersion: 'v2',
  credentialFormats: {
    anoncreds: {
      credentialDefinitionId: 'did:example:123/resources/credential-def',
      attributes: [
        { name: 'name', value: 'Alice Smith' },
        { name: 'degree', value: 'Computer Science' },
        { name: 'date', value: '2024-01-01' },
      ],
    },
  },
})

Accept a Credential Offer

// Listen for credential offers
agent.events.on(
  DidCommCredentialEventTypes.DidCommCredentialStateChanged,
  async (event) => {
    const { credentialExchangeRecord } = event.payload

    if (credentialExchangeRecord.state === 'offer-received') {
      await agent.didcomm.credentials.acceptOffer({
        credentialExchangeRecordId: credentialExchangeRecord.id,
      })
    }
  }
)

Proof Protocols

Configure proof exchange protocols:
import {
  DidCommProofV2Protocol,
  AnonCredsDidCommProofFormatService,
} from '@credo-ts/didcomm'

new DidCommModule({
  proofs: {
    proofProtocols: [
      new DidCommProofV2Protocol({
        proofFormats: [
          new AnonCredsDidCommProofFormatService(),
        ],
      }),
    ],
  },
})

Requesting Proofs

Request a Proof

await agent.didcomm.proofs.requestProof({
  connectionId: connectionRecord.id,
  protocolVersion: 'v2',
  proofFormats: {
    anoncreds: {
      name: 'proof-request',
      version: '1.0',
      requested_attributes: {
        name: {
          name: 'name',
          restrictions: [
            { cred_def_id: credDefId },
          ],
        },
      },
    },
  },
})

Accept a Proof Request

// Select credentials for the request
const requestedCredentials = await agent.didcomm.proofs.selectCredentialsForRequest({
  proofExchangeRecordId: proofRecord.id,
})

// Accept the request
await agent.didcomm.proofs.acceptRequest({
  proofExchangeRecordId: proofRecord.id,
  proofFormats: requestedCredentials.proofFormats,
})

Basic Messaging

Send simple text messages over established connections:
await agent.didcomm.basicMessages.sendMessage(
  connectionRecord.id,
  'Hello from my agent!'
)

// Listen for messages
agent.events.on(
  DidCommBasicMessageEventTypes.DidCommBasicMessageReceived,
  (event) => {
    console.log('Received:', event.payload.message.content)
  }
)

Advanced Configuration

DID Key in Protocols

Use did:key format instead of naked keys (RFC 0360):
new DidCommModule({
  useDidKeyInProtocols: true, // Default: true
})

DID:SOV Prefix

Use legacy did:sov prefix where allowed:
new DidCommModule({
  useDidSovPrefixWhereAllowed: true, // Default: false
})

Message Processing

Process messages concurrently instead of sequentially:
new DidCommModule({
  processDidCommMessagesConcurrently: true, // Default: false
})
Enabling concurrent message processing may cause race conditions in some scenarios. Test thoroughly.

MIME Type

Customize the DIDComm MIME type:
import { DidCommMimeType } from '@credo-ts/didcomm'

new DidCommModule({
  didCommMimeType: DidCommMimeType.V1, // Default
})

Module Sub-APIs

The DidCommModule exposes several sub-modules:
// Connections
await agent.didcomm.connections.getAll()

// Out-of-Band invitations
await agent.didcomm.oob.createInvitation()

// Credentials
await agent.didcomm.credentials.getAll()

// Proofs
await agent.didcomm.proofs.getAll()

// Basic messages
await agent.didcomm.basicMessages.sendMessage(...)

// Message pickup
await agent.didcomm.messagePickup.pickupMessages(...)

// Mediation
await agent.didcomm.mediationRecipient.provision(...)

Disabling Modules

You can disable specific sub-modules:
new DidCommModule({
  credentials: false, // Disable credentials
  proofs: false,      // Disable proofs
  basicMessages: false, // Disable basic messages
  messagePickup: false, // Disable message pickup
  mediator: false,      // Disable mediator
  mediationRecipient: false, // Disable mediation recipient
})

Complete Example

Here’s a complete example from the Credo demo:
import { Agent } from '@credo-ts/core'
import {
  DidCommModule,
  DidCommAutoAcceptCredential,
  DidCommAutoAcceptProof,
  DidCommCredentialV2Protocol,
  DidCommProofV2Protocol,
  DidCommHttpOutboundTransport,
} from '@credo-ts/didcomm'
import {
  AnonCredsDidCommCredentialFormatService,
  AnonCredsDidCommProofFormatService,
} from '@credo-ts/anoncreds'
import {
  agentDependencies,
  DidCommHttpInboundTransport,
} from '@credo-ts/node'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      endpoints: ['http://localhost:3000'],
      transports: {
        inbound: [new DidCommHttpInboundTransport({ port: 3000 })],
        outbound: [new DidCommHttpOutboundTransport()],
      },
      connections: {
        autoAcceptConnections: true,
      },
      credentials: {
        autoAcceptCredentials: DidCommAutoAcceptCredential.ContentApproved,
        credentialProtocols: [
          new DidCommCredentialV2Protocol({
            credentialFormats: [
              new AnonCredsDidCommCredentialFormatService(),
            ],
          }),
        ],
      },
      proofs: {
        autoAcceptProofs: DidCommAutoAcceptProof.ContentApproved,
        proofProtocols: [
          new DidCommProofV2Protocol({
            proofFormats: [
              new AnonCredsDidCommProofFormatService(),
            ],
          }),
        ],
      },
    }),
  },
})

await agent.initialize()

Next Steps

AnonCreds

Enable privacy-preserving credentials with AnonCreds

OpenID4VC

Use OpenID for Verifiable Credentials

Multi-Tenancy

Set up multi-tenant DIDComm agents

Platform Setup

Configure transports for your platform

Build docs developers (and LLMs) love