Skip to content

feat: initial DIDComm V2 support#2704

Open
genaris wants to merge 43 commits intomainfrom
feat/didcomm-v2
Open

feat: initial DIDComm V2 support#2704
genaris wants to merge 43 commits intomainfrom
feat/didcomm-v2

Conversation

@genaris
Copy link
Copy Markdown
Contributor

@genaris genaris commented Mar 18, 2026

New branch created from the current work in #2698. Added here to allow releasing pr-versions and test behaviour on different platforms before the initial merge to main.

Former feat/didcomm-v2 has been renamed to feat/didcomm-v2-old for reference and in case we need to take some things from there.

tarunvaddeSoul and others added 30 commits February 17, 2026 16:41
- DIDComm v2 envelope service with ECDH-1PU+A256KW and ECDH-ES
- OOB 2.0 and DidCommOutOfBandInvitationV2
- DidCommV2Service in DID document resolution
- Peer DID num algo 2 recipient key fingerprint support for v2
- acceptDidCommV2, sendDidCommV2, autoCreateConnectionOnFirstMessage config
- Demo scripts alice:v2 and faber:v2

Signed-off-by: Tarun Vadde <tarun@soulverse.us>
- Use did:key for skid/kid so recipients can resolve via tryParseKidAsPublicJwk
- Fix Ed25519/X25519 fingerprint matching in DID exchange and OOB receiver lookup
- Support NewDidCommV2Service (DIDCommMessaging) in document resolution
- Default acceptDidCommV2 and sendDidCommV2 to true
- Guard Ed25519->X25519 conversion against invalid key bytes

Signed-off-by: Tarun Vadde <tarun@soulverse.us>
…olution

- Extend peer DID fallback to did:peer:4 long form (in addition to did:peer:2)
- Apply fallback for both requester and responder when recipient keys are empty
- Export didToNumAlgo4DidDocument from core for peer DID parsing
- Use NewDidCommV2Service type for v2 service handling

Signed-off-by: Tarun Vadde <tarun@soulverse.us>
- Add recipientKeys type assertion in DidCommMessageSender peer DID fallback
- Extract toX25519 helper in DidCommDidExchangeResponseHandler for cleaner Ed25519/X25519 validation

Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
…e*Handlers

Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <tarun@soulverse.us>
Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
… and timing

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
…ts and time while building V2 plain text

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Protocol and message version restrictions:
- Add supportedDidCommVersions to message types; restrict Message Pickup
  and Mediation to v1 connections
- Enforce version compatibility in DidCommMessageSender

Module and API configuration:
- Replace acceptDidCommV2/sendDidCommV2 with didcommVersions array
  (default ["v1"])
- Add peerDidNumAlgoForV2OOB; default to did:peer:4, support did:peer:2
  for legacy deployments
- Add optional didcommVersion to DidCommConnectionRecord (default v1);
  outbound envelope version derived from connection

V2 envelope and conversion:
- Add v2 OOB invitations with optional ourDid for stable connection lookup
- Support decorators (e.g. threading) in v1/v2 conversion (normalize,
  plaintextBuilder)

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Tarun Vadde <142969534+tarunvaddeSoul@users.noreply.github.com>
Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Add support for BasicMessage 2.0 (https://didcomm.org/basicmessage/2.0/)
over both DIDComm v1 and v2 envelopes, per spec.

- Add DidCommBasicMessageV2 message class with toV2Plaintext() for v2 packing
- Add BasicMessageV2Handler and DidCommBasicMessageService.createMessageV2/saveV2
- Extend DidCommBasicMessagesModuleConfig with protocols: ['1.0' | '2.0']
- When protocols includes 2.0, DidCommBasicMessagesApi uses BM 2.0
- BM 2.0 fields: content, created_time (Unix epoch), optional lang
- BM 2.0 works over v1 envelope (v1-style plaintext) and v2 envelope (body, type, id)
- Add DidCommBasicMessageV2StateChanged event for received BM 2.0 messages
- plaintxtBuilder uses toV2Plaintext() for messages that implement it

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
tarunvaddeSoul and others added 3 commits March 18, 2026 00:50
Implement Message Pickup protocol 3.0 per https://didcomm.org/messagepickup/3.0/
for DIDComm v2 connections (mediation 2.0, pickup v3).

Protocol:
- Add DidCommMessagePickupV3Protocol with PIURI https://didcomm.org/messagepickup/3.0
- Message types: status-request, status, delivery-request, delivery,
  messages-received, live-delivery-change (all with return_route: all)
- Handlers: StatusRequestV3, StatusV3, DeliveryRequestV3, MessageDeliveryV3,
  MessagesReceivedV3, LiveDeliveryChangeV3
- Optional recipient_did in status-request/delivery-request; required limit
  in delivery-request; base64 attachments in delivery; message_id_list in
  messages-received

API and module:
- DidCommMessagePickupApi: pickupMessages, setLiveDeliveryMode, deliverMessages,
  deliverMessagesFromQueue with protocolVersion 'v3' and recipientDid for v3
- DidCommMessagePickupModule registers DidCommMessagePickupV3Protocol
- Pickup v3 restricted to DIDComm v2 (assertDidCommV2Connection)

Live mode:
- processLiveDeliveryChange saves/removes live session by sessionId; responds
  with status including live_delivery and message_count
- When live_delivery is true on non-persistent transport (no sessionId), send
  problem report with code e.m.live-mode-not-supported per spec

Tests:
- protocol/v3/__tests__/pickup-v3-protocol.test.ts for v3 protocol and
  live-delivery-change (including problem report when sessionId missing)
- Existing pickup/MessagePickupApi/MessagePickupModule tests unchanged

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Add full Coordinate Mediation 2.0 support in Credo-ts, including mediator/recipient coordination,
key registration, and routing behavior aligned with DIF messaging expectations.

- Introduce Coordinate Mediation 2.0 message types and models:
  mediate-request, mediate-grant, mediate-deny, keylist-update, keylist-update-response,
  keylist-query, and keylist
- Implement mediator-side services and handlers for:
  processing Forward (routing 2.0/forward) and coordinating delivery strategies,
  handling keylist updates/queries, and emitting state/keylist events
- Implement recipient-side services and handlers for:
  provisioning mediation v2, awaiting grants, and issuing keylist updates (v2)
- Update routing/mediation integration paths used by DIDComm v2 sender/receiver flow
  (including v2 routing DID and Forward message handling)
- Add/extend tests covering mediation v2 messaging + message pickup v3 interoperability
- Update Drizzle storage adapters and mediation record typing to support mediation v2 fields

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
@genaris genaris requested a review from a team as a code owner March 18, 2026 22:35
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 18, 2026

⚠️ No Changeset found

Latest commit: 5076e4a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

tarunvaddeSoul and others added 10 commits March 20, 2026 10:28
…2706)

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
…d did:key (#2718)

* fix(didcomm): align v2 decryption and mediation lookup with peer:4 and did:key

Mediators and mobile agents often use different encodings for the same
recipient (short vs long did:peer:4, did:key vs peer DID in CM2 keylists,
and varied DIDComm v2 JWE recipient kid formats). Exact tag and naive
kid resolution then failed at runtime.

DidCommV2KeyResolver (resolveV2Keys):
- Resolve recipient keys via KMS kid, DID URL / VM dereference, and
  relative # fragment kids against created peer DIDs, preferring OOB
  sender recipientDid ordering when multiple DIDs exist.
- Fall back to mediator routing keys, OOB inline / V2 service shapes,
  and receiver recipientRouting metadata; retry X25519 interpretation
  for ambiguous raw base58 kids before giving up.

DidCommMediationRepository:
- getSingleByRecipientDid tries did:peer:4 query variants (short/long).
- When tags still miss, scan granted mediator records using
  areEquivalentDidPeer4Forms.
- For long-form did:peer:4, match keylist entries stored as did:key
  (or legacy recipient keys) using Ed25519 material derived from the doc.

DidCommMessageReceiver:
- Improve v2 connection lookup using from/to (ourDid/theirDid), handle
  duplicate theirDid, findByKeys fallback, and return-route skid from
  the local DID document when possible.

Fixes CredoError No matching recipient key found for DIDComm v2 message
and RecordNotFoundError on MediationRecord queries keyed by recipientDids
when forward next and keylist tags use equivalent but unequal strings.

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* chore: update comment in DidRecord

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* refactor(didcomm): resolve mediation records with single  recipientDid query

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* refactor: move getRecipientDidQueryVariants to @credo-ts/core

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* refactor(didcomm): use non-throwing mediation lookup in processForwardMessage

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* Update packages/didcomm/src/modules/routing/services/DidCommMediationRecipientService.ts

Co-authored-by: Timo Glastra <timo@animo.id>
Signed-off-by: Tarun Vadde <142969534+tarunvaddeSoul@users.noreply.github.com>

* fix(didcomm): enforce strict v2 key resolution and normalize DID recipient tags to X25519

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* chore: remove log

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

* fix(didcomm): address v2 mediation and key handling review feedback

Revert DidRecord.getTags() and PeerDidRegistrar to match upstream main; no DIDComm-v2-specific logic in generic DID classes

Fix senderKeySkid to use keyAgreement VM (X25519 #key-2) per DIDComm v2 section 5.1.4

Restrict resolveSenderKey to keyAgreement only

Simplify MediationRepository to single canonical-form query

Remove diagnostic logging and unused did:peer:4 utility exports

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

---------

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Tarun Vadde <142969534+tarunvaddeSoul@users.noreply.github.com>
Co-authored-by: Timo Glastra <timo@animo.id>
…sues (#2733)

fix(didcomm): resolve v2 mediation runtime issues with key handling and message pickup

- Fix KMS key resolution for X25519 keyAgreement VMs by falling back to Ed25519 authentication key derivation (did:webvh, did:peer compatibility)

- Ensure skid/kid in JWE headers are always full DID URLs, not relative fragments

- Prefer X25519 services for v2 connections in message sender service ordering

- Filter to keyAgreement VMs only (not authentication) for v2 key resolution

- Auto-create connection for implicit v2 OOB invitations on responder side

- Auto-upgrade message pickup strategy (v1/v2 → v3) for Coordinate Mediation 2.0

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Signed-off-by: Ariel Gentile <gentilester@gmail.com>
…didcomm-v2

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
* feat(core): improved x509 certificate validation with RSA (#2740)

* fix(core): correctly set the RSA jwk alg when from spki (#2741)

* fix(core): revert previous two RSA commits (#2742)

* fix(askar,didcomm): align API names with core v0.7.0 renames

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>

---------

Signed-off-by: Tarun Vadde <vaddeofficial@gmail.com>
Co-authored-by: Henrique Dias <mail@hacdias.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants