routing

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2026 License: BSD-2-Clause Imports: 6 Imported by: 0

Documentation

Overview

Package routing implements DIDComm v2.1 message routing.

The routing package provides support for DIDComm mediators and message forwarding as defined in the DIDComm Messaging v2.1 specification (Section 9: Routing Protocol 2.0).

Forward Messages

When a sender cannot deliver directly to a recipient, they can wrap the message in a forward envelope addressed to a mediator:

forward := routing.NewForward(
    "did:example:mediator",     // mediator DID
    "did:example:recipient",    // final recipient
    encryptedMessage,           // the wrapped message
)

Route Building

The RouteBuilder constructs multi-hop routes by analyzing service endpoints:

builder := routing.NewRouteBuilder(resolver)
route, err := builder.BuildRoute(ctx, recipientDID)
// route contains the sequence of hops needed

Message Wrapping

For multi-hop routing, messages are wrapped in nested forward envelopes:

wrapped, err := routing.WrapForRoute(ctx, message, route, encrypter)
// wrapped is ready to send to the first hop

Mediator Support

The package supports both sender-side wrapping and mediator-side unwrapping:

// At mediator: unwrap and forward
inner, nextHop, err := routing.UnwrapForward(ctx, received, decrypter)

See the DIDComm v2.1 specification for complete routing protocol details: https://identity.foundation/didcomm-messaging/spec/v2.1/#routing-protocol-20

Index

Constants

View Source
const DefaultMaxHops = 10

DefaultMaxHops is the default maximum number of routing hops allowed.

View Source
const ForwardMessageType = "https://didcomm.org/routing/2.0/forward"

ForwardMessageType is the DIDComm message type for forward messages. Per DIDComm v2.1 spec Section 9.3.

Variables

View Source
var (
	// ErrNoRoute indicates no route could be found to the recipient.
	ErrNoRoute = errors.New("didcomm/routing: no route to recipient")

	// ErrInvalidForward indicates a malformed forward message.
	ErrInvalidForward = errors.New("didcomm/routing: invalid forward message")

	// ErrMissingNext indicates a forward message is missing the 'next' field.
	ErrMissingNext = errors.New("didcomm/routing: forward message missing 'next' field")

	// ErrNoRoutingKeys indicates no routing keys found in service endpoint.
	ErrNoRoutingKeys = errors.New("didcomm/routing: no routing keys in service endpoint")

	// ErrMaxHopsExceeded indicates the route exceeds the maximum allowed hops.
	ErrMaxHopsExceeded = errors.New("didcomm/routing: maximum hops exceeded")

	// ErrUnwrapFailed indicates failure to unwrap a forward message.
	ErrUnwrapFailed = errors.New("didcomm/routing: failed to unwrap forward message")
)

Functions

func UnwrapForward

func UnwrapForward(ctx context.Context, encrypted []byte, decrypter Decrypter) (innerMessage []byte, nextHop string, err error)

UnwrapForward decrypts and unwraps a forward message. Returns the inner message, the next hop DID, and any error.

func WrapForRoute

func WrapForRoute(ctx context.Context, encryptedForRecipient []byte, route *Route, encrypter Encrypter) ([]byte, error)

WrapForRoute wraps a message with forward envelopes for the given route. The message should already be encrypted for the final recipient. This function adds forward wrappers for each mediator hop.

Types

type DIDCommService

type DIDCommService struct {
	// ServiceEndpoint is the URI for the service.
	ServiceEndpoint string

	// RoutingKeys are the keys to use for routing to this endpoint.
	// May be empty for direct delivery.
	RoutingKeys []string

	// Accept lists accepted message content types.
	Accept []string
}

DIDCommService represents a DIDCommMessaging service endpoint.

type Decrypter

type Decrypter interface {
	// Decrypt decrypts an encrypted message.
	Decrypt(ctx context.Context, encrypted []byte) ([]byte, error)
}

Decrypter is an interface for decrypting messages during routing.

type Encrypter

type Encrypter interface {
	// Encrypt encrypts a plaintext message for the given recipient keys.
	Encrypt(ctx context.Context, plaintext []byte, recipientDIDs []string) ([]byte, error)
}

Encrypter is an interface for encrypting messages for routing.

type Forward

type Forward struct {
	// ID is the unique message identifier.
	ID string `json:"id"`

	// Type is always ForwardMessageType.
	Type string `json:"type"`

	// To contains the DID of the mediator receiving this forward.
	To []string `json:"to,omitempty"`

	// Body contains the forward-specific fields.
	Body ForwardBody `json:"body"`

	// Attachments contains the wrapped message as an attachment.
	Attachments []message.Attachment `json:"attachments,omitempty"`
}

Forward represents a DIDComm forward message used for routing. The forward message wraps an encrypted message and specifies the next hop.

func NewForward

func NewForward(mediatorDID, nextDID string, wrappedMessage []byte) *Forward

NewForward creates a new forward message.

Parameters:

  • mediatorDID: The DID of the mediator that will process this forward
  • nextDID: The DID of the next recipient (may be final recipient or another mediator)
  • wrappedMessage: The encrypted message to forward (as bytes)

func NewForwardWithID

func NewForwardWithID(id, mediatorDID, nextDID string, wrappedMessage []byte) *Forward

NewForwardWithID creates a new forward message with a specific ID.

func ParseForward

func ParseForward(msg *message.Message) (*Forward, error)

ParseForward parses a DIDComm message as a forward message.

func ParseForwardFromJSON

func ParseForwardFromJSON(data []byte) (*Forward, error)

ParseForwardFromJSON parses JSON bytes as a forward message.

func WrapInForward

func WrapInForward(mediatorDID, nextDID string, encryptedMessage []byte) *Forward

WrapInForward wraps an encrypted message in a forward envelope. The resulting forward message should be encrypted for the mediator.

func (*Forward) GetWrappedMessage

func (f *Forward) GetWrappedMessage() ([]byte, error)

GetWrappedMessage extracts the wrapped message from the forward's attachments.

func (*Forward) ToMessage

func (f *Forward) ToMessage() *message.Message

ToMessage converts the Forward to a generic DIDComm message.

type ForwardBody

type ForwardBody struct {
	// Next is the DID or DID URL of the next recipient.
	// This is the entity that should receive the wrapped message.
	Next string `json:"next"`
}

ForwardBody contains the body of a forward message.

type Hop

type Hop struct {
	// RecipientDID is the DID that should receive the message at this hop.
	// This is used for encryption (Encrypter interface requires DIDs).
	RecipientDID string

	// RoutingKey is the original key ID from the service endpoint.
	// May be a DID URL (e.g., did:example:mediator#key-1) or a DID.
	// The Encrypter uses RecipientDID (extracted from RoutingKey if needed)
	// since the encryption interface operates on DIDs, not key IDs.
	RoutingKey string

	// ServiceEndpoint is the endpoint URL for this hop (if known).
	ServiceEndpoint string
}

Hop represents a single hop in a routing path.

type Route

type Route struct {
	// Hops is the sequence of hops from first mediator to final recipient.
	// The last hop is always the final recipient.
	Hops []Hop

	// FinalRecipient is the DID of the ultimate message recipient.
	FinalRecipient string
}

Route represents a complete routing path from sender to final recipient.

func (*Route) FirstHop

func (r *Route) FirstHop() *Hop

FirstHop returns the first hop (first mediator or direct recipient).

func (*Route) IsDirectRoute

func (r *Route) IsDirectRoute() bool

IsDirectRoute returns true if no mediators are involved.

func (*Route) MediatorCount

func (r *Route) MediatorCount() int

MediatorCount returns the number of mediators in the route.

type RouteBuilder

type RouteBuilder struct {
	// contains filtered or unexported fields
}

RouteBuilder constructs routes to recipients.

func NewRouteBuilder

func NewRouteBuilder(resolver ServiceResolver) *RouteBuilder

NewRouteBuilder creates a new route builder with the given resolver.

func (*RouteBuilder) BuildRoute

func (rb *RouteBuilder) BuildRoute(ctx context.Context, recipientDID string) (*Route, error)

BuildRoute constructs a route to the given recipient. It resolves the recipient's DIDComm service and any routing keys.

func (*RouteBuilder) WithMaxHops

func (rb *RouteBuilder) WithMaxHops(max int) *RouteBuilder

WithMaxHops sets the maximum number of hops allowed.

type ServiceResolver

type ServiceResolver interface {
	// ResolveDIDCommService resolves DIDComm service endpoint information.
	ResolveDIDCommService(ctx context.Context, did string) (*DIDCommService, error)
}

ServiceResolver resolves DIDComm service endpoints from DIDs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL