Skip to content

Commit

Permalink
Merge pull request #2067 from sicpa-dlab/feature/create-all-registere…
Browse files Browse the repository at this point in the history
…d-dids

feat: enable creation of DIDs for all registered methods
  • Loading branch information
ianco authored Jan 16, 2023
2 parents 748ec9c + 0c93947 commit ea31bd7
Show file tree
Hide file tree
Showing 27 changed files with 369 additions and 72 deletions.
45 changes: 45 additions & 0 deletions DIDMethods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# DID methods in ACA-Py
Decentralized Identifiers, or DIDs, are URIs that point to documents that describe cryptographic primitives and protocols used in decentralized identity management.
DIDs include methods that describe where and how documents can be retrieved.
DID methods support specific types of keys and may or may not require the holder to specify the DID itself.

ACA-Py provides a `DIDMethods` registry holding all the DID methods supported for storage in a wallet

> :warning: Askar and InMemory are the only wallets supporting this registry.
## Registering a DID method
By default, ACA-Py supports `did:key` and `did:sov`.
Plugins can register DID additional methods to make them available to holders.
Here's a snippet adding support for `did:web` to the registry from a plugin `setup` method.

```python=
WEB = DIDMethod(
name="web",
key_types=[ED25519, BLS12381G2],
rotation=True,
holder_defined_did=HolderDefinedDid.REQUIRED # did:web is not derived from key material but from a user-provided respository name
)
async def setup(context: InjectionContext):
methods = context.inject(DIDMethods)
methods.register(WEB)
```

## Creating a DID

`POST /wallet/did/create` can be provided with parameters for any registered DID method. Here's a follow-up to the
`did:web` method example:

```json=
{
"method": "web",
"options": {
"did": "did:web:doma.in",
"key_type": "ed25519"
}
}
```

## Resolving DIDs

For specifics on how DIDs are resolved in ACA-Py, see: [DID Resolution](DIDResolution.md).
3 changes: 2 additions & 1 deletion aries_cloudagent/core/tests/test_conductor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from ...utils.stats import Collector
from ...version import __version__
from ...wallet.base import BaseWallet
from ...wallet.did_method import SOV
from ...wallet.did_method import SOV, DIDMethods
from ...wallet.key_type import ED25519
from .. import conductor as test_module

Expand Down Expand Up @@ -87,6 +87,7 @@ async def build_context(self) -> InjectionContext:
context.injector.bind_instance(ProfileManager, InMemoryProfileManager())
context.injector.bind_instance(ProtocolRegistry, ProtocolRegistry())
context.injector.bind_instance(BaseWireFormat, self.wire_format)
context.injector.bind_instance(DIDMethods, DIDMethods())
context.injector.bind_instance(DIDResolver, DIDResolver([]))
context.injector.bind_instance(EventBus, MockEventBus())
return context
Expand Down
2 changes: 1 addition & 1 deletion aries_cloudagent/ledger/tests/test_indy_vdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

@pytest.fixture()
def ledger():
profile = InMemoryProfile.test_profile()
profile = InMemoryProfile.test_profile(bind={DIDMethods: DIDMethods()})
ledger = IndyVdrLedger(IndyVdrLedgerPool("test-ledger"), profile)

async def open():
Expand Down
3 changes: 2 additions & 1 deletion aries_cloudagent/messaging/jsonld/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from ....resolver.did_resolver import DIDResolver
from ....vc.ld_proofs.document_loader import DocumentLoader
from ....wallet.base import BaseWallet
from ....wallet.did_method import SOV
from ....wallet.did_method import SOV, DIDMethods
from ....wallet.error import WalletError
from ....wallet.key_type import ED25519
from ..error import (
Expand Down Expand Up @@ -274,6 +274,7 @@ async def setUp(self):
self.context.profile.context.injector.bind_instance(
DocumentLoader, custom_document_loader
)
self.context.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.did_info = await (await self.context.session()).wallet.create_local_did(
SOV, ED25519
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .....storage.error import StorageNotFoundError
from .....transport.inbound.receipt import MessageReceipt
from .....wallet.base import DIDInfo
from .....wallet.did_method import SOV
from .....wallet.did_method import SOV, DIDMethods
from .....wallet.error import WalletNotFoundError
from .....wallet.in_memory import InMemoryWallet
from .....wallet.key_type import ED25519
Expand Down Expand Up @@ -94,6 +94,7 @@ async def setUp(self):
BaseCache: InMemoryCache(),
OobMessageProcessor: self.oob_mock,
RouteManager: self.route_manager,
DIDMethods: DIDMethods(),
},
)
self.context = self.profile.context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ...models.mediation_record import MediationRecord

from ..mediation_request_handler import MediationRequestHandler
from ......wallet.did_method import DIDMethods

TEST_CONN_ID = "conn-id"
TEST_VERKEY = "3Dn1SJNPaCXcvvJvSbsFWP2xaCjMom3can8CQNhWrTRx"
Expand All @@ -24,6 +25,7 @@ class TestMediationRequestHandler(AsyncTestCase):
async def setUp(self):
"""setup dependencies of messaging"""
self.context = RequestContext.test_context()
self.context.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.session = await self.context.session()
self.context.message = MediationRequest()
self.context.connection_ready = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from ..messages.mediate_grant import MediationGrant
from ..messages.mediate_request import MediationRequest
from ..models.mediation_record import MediationRecord
from .....wallet.did_method import DIDMethods

TEST_CONN_ID = "conn-id"
TEST_THREAD_ID = "thread-id"
Expand All @@ -42,7 +43,9 @@
def profile() -> Iterable[Profile]:
"""Fixture for profile used in tests."""
# pylint: disable=W0621
yield InMemoryProfile.test_profile(bind={EventBus: MockEventBus()})
yield InMemoryProfile.test_profile(
bind={EventBus: MockEventBus(), DIDMethods: DIDMethods()}
)


@pytest.fixture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
from .....storage.error import StorageError, StorageNotFoundError
from ..models.mediation_record import MediationRecord
from ..route_manager import RouteManager
from .....wallet.did_method import DIDMethods


class TestCoordinateMediationRoutes(AsyncTestCase):
def setUp(self):
self.profile = InMemoryProfile.test_profile()
self.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.context = AdminRequestContext.test_context(profile=self.profile)
self.outbound_message_router = async_mock.CoroutineMock()
self.request_dict = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
from ...messages.problem_report_reason import ProblemReportReason

from .. import complete_handler as test_module
from ......wallet.did_method import DIDMethods


@pytest.fixture()
def request_context() -> RequestContext:
ctx = RequestContext.test_context()
ctx.injector.bind_instance(DIDMethods, DIDMethods())
ctx.message_receipt = MessageReceipt()
yield ctx

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

from ...handlers.invitation_handler import InvitationHandler
from ...messages.problem_report_reason import ProblemReportReason
from ......wallet.did_method import DIDMethods


@pytest.fixture()
def request_context() -> RequestContext:
ctx = RequestContext.test_context()
ctx.injector.bind_instance(DIDMethods, DIDMethods())
ctx.message_receipt = MessageReceipt()
yield ctx

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Service,
)
from ......core.in_memory import InMemoryProfile
from ......wallet.did_method import SOV
from ......wallet.did_method import SOV, DIDMethods
from ......wallet.key_type import ED25519
from ......messaging.decorators.attach_decorator import AttachDecorator
from ......messaging.request_context import RequestContext
Expand Down Expand Up @@ -76,6 +76,7 @@ async def setUp(self):
"debug.auto_accept_requests_public": True,
}
)
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())

self.conn_rec = conn_record.ConnRecord(
my_did="55GkHamhTU1ZbTbV2ab9DE",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ......messaging.request_context import RequestContext
from ......messaging.responder import MockResponder
from ......transport.inbound.receipt import MessageReceipt
from ......wallet.did_method import SOV
from ......wallet.did_method import SOV, DIDMethods
from ......wallet.key_type import ED25519

from .....problem_report.v1_0.message import ProblemReport
Expand Down Expand Up @@ -63,6 +63,7 @@ async def setUp(self):
self.ctx = RequestContext.test_context()
self.ctx.message_receipt = MessageReceipt()

self.ctx.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
wallet = (await self.ctx.session()).wallet
self.did_info = await wallet.create_local_did(
method=SOV,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ......connections.models.diddoc import DIDDoc, PublicKey, PublicKeyType, Service
from ......core.in_memory import InMemoryProfile
from ......messaging.decorators.attach_decorator import AttachDecorator
from ......wallet.did_method import SOV
from ......wallet.did_method import SOV, DIDMethods
from ......wallet.key_type import ED25519
from .....didcomm_prefix import DIDCommPrefix
from ...message_types import DIDX_REQUEST
Expand Down Expand Up @@ -49,7 +49,9 @@ def make_did_doc(self):

class TestDIDXRequest(AsyncTestCase, TestConfig):
async def setUp(self):
self.wallet = InMemoryProfile.test_session().wallet
self.session = InMemoryProfile.test_session()
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.wallet = self.session.wallet
self.did_info = await self.wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down Expand Up @@ -106,7 +108,9 @@ class TestDIDXRequestSchema(AsyncTestCase, TestConfig):
"""Test request schema."""

async def setUp(self):
self.wallet = InMemoryProfile.test_session().wallet
self.session = InMemoryProfile.test_session()
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.wallet = self.session.wallet
self.did_info = await self.wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ......connections.models.diddoc import DIDDoc, PublicKey, PublicKeyType, Service
from ......core.in_memory import InMemoryProfile
from ......messaging.decorators.attach_decorator import AttachDecorator
from ......wallet.did_method import SOV
from ......wallet.did_method import SOV, DIDMethods
from ......wallet.key_type import ED25519
from .....didcomm_prefix import DIDCommPrefix
from ...message_types import DIDX_RESPONSE
Expand Down Expand Up @@ -48,7 +48,10 @@ def make_did_doc(self):

class TestDIDXResponse(AsyncTestCase, TestConfig):
async def setUp(self):
self.wallet = InMemoryProfile.test_session().wallet
self.session = InMemoryProfile.test_session()
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.wallet = self.session.wallet

self.did_info = await self.wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down Expand Up @@ -102,7 +105,10 @@ class TestDIDXResponseSchema(AsyncTestCase, TestConfig):
"""Test response schema."""

async def setUp(self):
self.wallet = InMemoryProfile.test_session().wallet
self.session = InMemoryProfile.test_session()
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.wallet = self.session.wallet

self.did_info = await self.wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .....storage.error import StorageNotFoundError
from .....transport.inbound.receipt import MessageReceipt
from .....wallet.did_info import DIDInfo
from .....wallet.did_method import SOV
from .....wallet.did_method import SOV, DIDMethods
from .....wallet.error import WalletError
from .....wallet.in_memory import InMemoryWallet
from .....wallet.key_type import ED25519
Expand Down Expand Up @@ -102,6 +102,7 @@ async def setUp(self):
BaseCache: InMemoryCache(),
OobMessageProcessor: self.oob_mock,
RouteManager: self.route_manager,
DIDMethods: DIDMethods(),
},
)
self.context = self.profile.context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from .....ledger.base import BaseLedger
from .....storage.error import StorageNotFoundError
from .....wallet.base import BaseWallet
from .....wallet.did_method import SOV
from .....wallet.did_method import SOV, DIDMethods
from .....wallet.key_type import ED25519
from ..manager import TransactionManager, TransactionManagerError
from ..models.transaction_record import TransactionRecord
Expand Down Expand Up @@ -112,6 +112,7 @@ async def setUp(self):
self.profile = self.context.profile
injector = self.profile.context.injector
injector.bind_instance(BaseLedger, self.ledger)
injector.bind_instance(DIDMethods, DIDMethods())

async with self.profile.session() as session:
self.wallet: BaseWallet = session.inject_or(BaseWallet)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .....storage.vc_holder.vc_record import VCRecord
from .....wallet.base import BaseWallet, DIDInfo
from .....wallet.crypto import KeyType
from .....wallet.did_method import SOV, KEY
from .....wallet.did_method import SOV, KEY, DIDMethods
from .....wallet.error import WalletNotFoundError
from .....vc.ld_proofs import (
BbsBlsSignature2020,
Expand Down Expand Up @@ -69,7 +69,7 @@ def event_loop(request):

@pytest.fixture(scope="class")
def profile():
profile = InMemoryProfile.test_profile()
profile = InMemoryProfile.test_profile(bind={DIDMethods: DIDMethods()})
context = profile.context
context.injector.bind_instance(DIDResolver, DIDResolver([]))
context.injector.bind_instance(DocumentLoader, custom_document_loader)
Expand Down
3 changes: 2 additions & 1 deletion aries_cloudagent/transport/tests/test_pack_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ...protocols.didcomm_prefix import DIDCommPrefix
from ...protocols.routing.v1_0.message_types import FORWARD
from ...wallet.base import BaseWallet
from ...wallet.did_method import SOV
from ...wallet.did_method import SOV, DIDMethods
from ...wallet.error import WalletError
from ...wallet.key_type import ED25519
from .. import pack_format as test_module
Expand All @@ -33,6 +33,7 @@ class TestPackWireFormat(AsyncTestCase):

def setUp(self):
self.session = InMemoryProfile.test_session()
self.session.profile.context.injector.bind_instance(DIDMethods, DIDMethods())
self.wallet = self.session.inject(BaseWallet)

async def test_errors(self):
Expand Down
Loading

0 comments on commit ea31bd7

Please sign in to comment.