Skip to content

Commit 8f0d317

Browse files
committed
feat: add legacy dmp interface
Signed-off-by: Daniel Bluhm <[email protected]>
1 parent 7e12688 commit 8f0d317

File tree

7 files changed

+499
-163
lines changed

7 files changed

+499
-163
lines changed

didcomm_messaging/__init__.py

Lines changed: 13 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,170 +1,20 @@
11
"""DIDComm Messaging."""
22

3-
from dataclasses import dataclass
4-
import json
5-
from typing import Generic, Optional, List
6-
7-
from pydid.service import DIDCommV2Service
8-
9-
from didcomm_messaging.crypto import CryptoService, SecretsManager, P, S
3+
from didcomm_messaging.crypto import CryptoService, P, S, SecretsManager
4+
from didcomm_messaging.messaging import DIDCommMessaging, DIDCommMessagingService
105
from didcomm_messaging.packaging import PackagingService
116
from didcomm_messaging.resolver import DIDResolver
127
from didcomm_messaging.routing import RoutingService
138

149

15-
@dataclass
16-
class PackResult:
17-
"""Result of packing a message."""
18-
19-
message: bytes
20-
target_services: List[DIDCommV2Service]
21-
22-
def get_endpoint(self, protocol: str) -> str:
23-
"""Get the first matching endpoint to send the message to."""
24-
return self.get_service(protocol).service_endpoint.uri
25-
26-
def get_service(self, protocol: str) -> DIDCommV2Service:
27-
"""Get the first matching service to send the message to."""
28-
return self.filter_services_by_protocol(protocol)[0]
29-
30-
def filter_services_by_protocol(self, protocol: str) -> List[DIDCommV2Service]:
31-
"""Get all services that start with a specific uri protocol."""
32-
return [
33-
service
34-
for service in self.target_services
35-
if service.service_endpoint.uri.startswith(protocol)
36-
]
37-
38-
39-
@dataclass
40-
class UnpackResult:
41-
"""Result of unpacking a message."""
42-
43-
message: dict
44-
encrytped: bool
45-
authenticated: bool
46-
recipient_kid: str
47-
sender_kid: Optional[str] = None
48-
49-
50-
class DIDCommMessagingService(Generic[P, S]):
51-
"""Main entrypoint for DIDComm Messaging."""
52-
53-
def service_to_target(self, service: DIDCommV2Service) -> str:
54-
"""Convert a service to a target uri.
55-
56-
This is a very simple implementation that just returns the first one.
57-
"""
58-
if isinstance(service.service_endpoint, list):
59-
service_endpoint = service.service_endpoint[0]
60-
else:
61-
service_endpoint = service.service_endpoint
62-
63-
return service_endpoint.uri
64-
65-
async def pack(
66-
self,
67-
crypto: CryptoService[P, S],
68-
resolver: DIDResolver,
69-
secrets: SecretsManager[S],
70-
packaging: PackagingService[P, S],
71-
routing: RoutingService,
72-
message: dict,
73-
to: str,
74-
frm: Optional[str] = None,
75-
**options,
76-
):
77-
"""Pack a message."""
78-
# TODO crypto layer permits packing to multiple recipients; should we as well?
79-
80-
encoded_message = await packaging.pack(
81-
crypto,
82-
resolver,
83-
secrets,
84-
json.dumps(message).encode(),
85-
[to],
86-
frm,
87-
**options,
88-
)
89-
90-
forward, services = await routing.prepare_forward(
91-
crypto, packaging, resolver, secrets, to, encoded_message
92-
)
93-
return PackResult(forward, services)
94-
95-
async def unpack(
96-
self,
97-
crypto: CryptoService[P, S],
98-
resolver: DIDResolver,
99-
secrets: SecretsManager[S],
100-
packaging: PackagingService[P, S],
101-
encoded_message: bytes,
102-
**options,
103-
) -> UnpackResult:
104-
"""Unpack a message."""
105-
unpacked, metadata = await packaging.unpack(
106-
crypto, resolver, secrets, encoded_message, **options
107-
)
108-
message = json.loads(unpacked.decode())
109-
return UnpackResult(
110-
message,
111-
encrytped=bool(metadata.method),
112-
authenticated=bool(metadata.sender_kid),
113-
recipient_kid=metadata.recip_key.kid,
114-
sender_kid=metadata.sender_kid,
115-
)
116-
117-
118-
class DIDCommMessaging(Generic[P, S]):
119-
"""Main entrypoint for DIDComm Messaging."""
120-
121-
def __init__(
122-
self,
123-
crypto: CryptoService[P, S],
124-
secrets: SecretsManager[S],
125-
resolver: DIDResolver,
126-
packaging: PackagingService[P, S],
127-
routing: RoutingService,
128-
):
129-
"""Initialize the DIDComm Messaging service."""
130-
self.crypto = crypto
131-
self.secrets = secrets
132-
self.resolver = resolver
133-
self.packaging = packaging
134-
self.routing = routing
135-
self.dmp = DIDCommMessagingService()
136-
137-
async def pack(
138-
self,
139-
message: dict,
140-
to: str,
141-
frm: Optional[str] = None,
142-
**options,
143-
) -> PackResult:
144-
"""Pack a message."""
145-
return await self.dmp.pack(
146-
self.crypto,
147-
self.resolver,
148-
self.secrets,
149-
self.packaging,
150-
self.routing,
151-
message,
152-
to,
153-
frm,
154-
**options,
155-
)
156-
157-
async def unpack(
158-
self,
159-
encoded_message: bytes,
160-
**options,
161-
) -> UnpackResult:
162-
"""Unpack a message."""
163-
return await self.dmp.unpack(
164-
self.crypto,
165-
self.resolver,
166-
self.secrets,
167-
self.packaging,
168-
encoded_message,
169-
**options,
170-
)
10+
__all__ = [
11+
"CryptoService",
12+
"DIDCommMessaging",
13+
"DIDCommMessagingService",
14+
"DIDResolver",
15+
"P",
16+
"PackagingService",
17+
"RoutingService",
18+
"S",
19+
"SecretsManager",
20+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""Legacy DIDComm v1 Interfaces.
2+
3+
These components are intended to provide a similar structure to the DIDComm v2
4+
interfaces provided by this library. While the community is transitioning from
5+
DIDComm v1 to v2, having a consistent interface to interact with will help
6+
implementers to support both versions until the transition is complete.
7+
8+
It is expected that a future version of this library will eventually remove
9+
these interfaces.
10+
"""

didcomm_messaging/legacy/askar.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Optional, Sequence, Tuple, cast
55

66
from base58 import b58decode
7+
from pydid import VerificationMethod
78

89
from didcomm_messaging.crypto.jwe import JweBuilder, JweEnvelope, JweRecipient
910
from didcomm_messaging.legacy.base import (
@@ -30,6 +31,11 @@ def kid_to_public_key(self, kid: str) -> AskarKey:
3031
"""
3132
return AskarKey(Key.from_public_bytes(KeyAlg.ED25519, b58decode(kid)), kid)
3233

34+
@classmethod
35+
def verification_method_to_public_key(cls, vm: VerificationMethod) -> AskarKey:
36+
"""Convert a verification method to a public key."""
37+
return AskarKey.from_verification_method(vm)
38+
3339
async def pack_message(
3440
self,
3541
to_verkeys: Sequence[AskarKey],

didcomm_messaging/legacy/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from abc import ABC, abstractmethod
44
from typing import Generic, NamedTuple, Optional, Sequence
5+
6+
from pydid import VerificationMethod
57
from didcomm_messaging.crypto.base import P, S
68
from didcomm_messaging.crypto.jwe import JweEnvelope
79
from didcomm_messaging.multiformats.multibase import Base64UrlEncoder
@@ -36,6 +38,11 @@ def kid_to_public_key(self, kid: str) -> P:
3638
In DIDComm v1, kids are the base58 encoded keys.
3739
"""
3840

41+
@classmethod
42+
@abstractmethod
43+
def verification_method_to_public_key(cls, vm: VerificationMethod) -> P:
44+
"""Convert a verification method to a public key."""
45+
3946
@abstractmethod
4047
async def pack_message(
4148
self, to_verkeys: Sequence[P], from_key: Optional[S], message: bytes

0 commit comments

Comments
 (0)