diff --git a/aries_cloudagent/anoncreds/anoncreds/__init__.py b/aries_cloudagent/anoncreds/anoncreds/__init__.py index e69de29bb2..9506346d5d 100644 --- a/aries_cloudagent/anoncreds/anoncreds/__init__.py +++ b/aries_cloudagent/anoncreds/anoncreds/__init__.py @@ -0,0 +1,45 @@ +import logging + +from ...config.injection_context import InjectionContext +from ...config.provider import ClassProvider + +from ..anoncreds.anoncreds_registry import AnonCredsRegistry + +LOGGER = logging.getLogger(__name__) + + +async def setup(context: InjectionContext): + """Set up default resolvers.""" + registry = context.inject_or(AnonCredsRegistry) + if not registry: + LOGGER.warning("No AnonCredsRegistry instance found in context") + return + + indy_registry = ClassProvider( + "aries_cloudagent.anoncreds.anoncreds.default.did_indy_registry.registry" + ".DIDIndyRegistry", + supported_identifiers=[], + method_name="did:indy", + ).provide(context.settings, context.injector) + await indy_registry.setup(context) + registry.register_registry(indy_registry) + + web_registry = ClassProvider( + "aries_cloudagent.anoncreds.anoncreds.default.did_web_registry.registry" + ".DIDWebRegistry", + supported_identifiers=[], + method_name="did:web", + ).provide(context.settings, context.injector) + await web_registry.setup(context) + registry.register_registry(web_registry) + + legacy_indy_registry = ClassProvider( + "aries_cloudagent.anoncreds.anoncreds.default.legacy_indy_registry.registry" + ".LegacyIndyRegistry", + supported_identifiers=[], + method_name="", + ).provide(context.settings, context.injector) + await legacy_indy_registry.setup(context) + registry.register_registry(legacy_indy_registry) + + # TODO: add context.settings diff --git a/aries_cloudagent/anoncreds/anoncreds/anoncreds_registry.py b/aries_cloudagent/anoncreds/anoncreds/anoncreds_registry.py new file mode 100644 index 0000000000..fbc82f633e --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/anoncreds_registry.py @@ -0,0 +1,69 @@ +"""AnonCreds Registry""" +import logging +from typing import List + +from .base_registry import BaseRegistry +from .models import ( + AnonCredsRegistryGetCredentialDefinition, + AnonCredsRegistryGetRevocationList, + AnonCredsRegistryGetRevocationRegistryDefinition, + AnonCredsRegistryGetSchema, +) +from ...config.injection_context import InjectionContext + + +LOGGER = logging.getLogger(__name__) + + +class AnonCredsRegistry(BaseRegistry): + """AnonCredsRegistry""" + + def __init__(self, registries: List[BaseRegistry] = None): + """Create DID Resolver.""" + super().__init__(supported_identifiers=[], method_name="") + # TODO: need both supported_identifiers and method_name? + self.registries = registries or [] + + # TODO: use supported_identifier and method_name to select which registry should + # resolve or register a given object + identifier + + def register_registry(self, registry: BaseRegistry): + """Register a new registry.""" + self.registries.append(registry) + + async def setup(self, context: InjectionContext): + """Setup method.""" + + async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema: + """Get a schema from the registry.""" + + # TODO: determine keyword arguments + async def register_schema(self): + """Register a schema on the registry.""" + + async def get_credential_definition( + self, credential_definition_id: str + ) -> AnonCredsRegistryGetCredentialDefinition: + """Get a credential definition from the registry.""" + + # TODO: determine keyword arguments + async def register_credential_definition(self): + """Register a credential definition on the registry.""" + + async def get_revocation_registry_definition( + self, revocation_registry_id: str + ) -> AnonCredsRegistryGetRevocationRegistryDefinition: + """Get a revocation registry definition from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_registry_definition(self): + """Register a revocation registry definition on the registry.""" + + async def get_revocation_list( + self, revocation_registry_id: str, timestamp: str + ) -> AnonCredsRegistryGetRevocationList: + """Get a revocation list from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_list(self): + """Register a revocation list on the registry.""" diff --git a/aries_cloudagent/anoncreds/anoncreds/base_registry.py b/aries_cloudagent/anoncreds/anoncreds/base_registry.py new file mode 100644 index 0000000000..0ebe38456e --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/base_registry.py @@ -0,0 +1,64 @@ +"""Base Registry""" +from abc import ABC, abstractmethod +from typing import List +from ...config.injection_context import InjectionContext + +from .models import ( + AnonCredsRegistryGetCredentialDefinition, + AnonCredsRegistryGetRevocationList, + AnonCredsRegistryGetRevocationRegistryDefinition, + AnonCredsRegistryGetSchema, +) + + +class BaseRegistry(ABC): + """BaseRegistry""" + + def __init__(self, supported_identifiers: List[str], method_name: str): + """Initialize Base Registry.""" + + @abstractmethod + async def setup(self, context: InjectionContext): + """Setup method.""" + + @abstractmethod + async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema: + """Get a schema from the registry.""" + + # TODO: determine keyword arguments + @abstractmethod + async def register_schema(self): + """Register a schema on the registry.""" + + @abstractmethod + async def get_credential_definition( + self, credential_definition_id: str + ) -> AnonCredsRegistryGetCredentialDefinition: + """Get a credential definition from the registry.""" + + # TODO: determine keyword arguments + @abstractmethod + async def register_credential_definition(self): + """Register a credential definition on the registry.""" + + @abstractmethod + async def get_revocation_registry_definition( + self, revocation_registry_id: str + ) -> AnonCredsRegistryGetRevocationRegistryDefinition: + """Get a revocation registry definition from the registry.""" + + # TODO: determine keyword arguments + @abstractmethod + async def register_revocation_registry_definition(self): + """Register a revocation registry definition on the registry.""" + + @abstractmethod + async def get_revocation_list( + self, revocation_registry_id: str, timestamp: str + ) -> AnonCredsRegistryGetRevocationList: + """Get a revocation list from the registry.""" + + # TODO: determine keyword arguments + @abstractmethod + async def register_revocation_list(self): + """Register a revocation list on the registry.""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/__init__.py b/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/registry.py b/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/registry.py new file mode 100644 index 0000000000..68a2f729d2 --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/registry.py @@ -0,0 +1,51 @@ +"""DID Indy Registry""" +from ...models import ( + AnonCredsRegistryGetCredentialDefinition, + AnonCredsRegistryGetRevocationList, + AnonCredsRegistryGetRevocationRegistryDefinition, + AnonCredsRegistryGetSchema, +) +from .....config.injection_context import InjectionContext +from ...anoncreds_registry import BaseRegistry + + +class DIDIndyRegistry(BaseRegistry): + """DIDIndyRegistry""" + + async def setup(self, context: InjectionContext): + """Setup.""" + print("Successfully registered DIDIndyRegistry") + + async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema: + """Get a schema from the registry.""" + + # TODO: determine keyword arguments + async def register_schema(self): + """Register a schema on the registry.""" + + async def get_credential_definition( + self, credential_definition_id: str + ) -> AnonCredsRegistryGetCredentialDefinition: + """Get a credential definition from the registry.""" + + # TODO: determine keyword arguments + async def register_credential_definition(self): + """Register a credential definition on the registry.""" + + async def get_revocation_registry_definition( + self, revocation_registry_id: str + ) -> AnonCredsRegistryGetRevocationRegistryDefinition: + """Get a revocation registry definition from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_registry_definition(self): + """Register a revocation registry definition on the registry.""" + + async def get_revocation_list( + self, revocation_registry_id: str, timestamp: str + ) -> AnonCredsRegistryGetRevocationList: + """Get a revocation list from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_list(self): + """Register a revocation list on the registry.""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/routes.py b/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/routes.py new file mode 100644 index 0000000000..f38bfd6623 --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/did_indy_registry/routes.py @@ -0,0 +1 @@ +"""Routes for DID Indy Registry""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/__init__.py b/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/registry.py b/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/registry.py new file mode 100644 index 0000000000..ad0749fe7d --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/registry.py @@ -0,0 +1,51 @@ +"""DID Web Registry""" +from ...models import ( + AnonCredsRegistryGetCredentialDefinition, + AnonCredsRegistryGetRevocationList, + AnonCredsRegistryGetRevocationRegistryDefinition, + AnonCredsRegistryGetSchema, +) +from .....config.injection_context import InjectionContext +from ...anoncreds_registry import BaseRegistry + + +class DIDWebRegistry(BaseRegistry): + """DIDWebRegistry""" + + async def setup(self, context: InjectionContext): + """Setup.""" + print("Successfully registered DIDWebRegistry") + + async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema: + """Get a schema from the registry.""" + + # TODO: determine keyword arguments + async def register_schema(self): + """Register a schema on the registry.""" + + async def get_credential_definition( + self, credential_definition_id: str + ) -> AnonCredsRegistryGetCredentialDefinition: + """Get a credential definition from the registry.""" + + # TODO: determine keyword arguments + async def register_credential_definition(self): + """Register a credential definition on the registry.""" + + async def get_revocation_registry_definition( + self, revocation_registry_id: str + ) -> AnonCredsRegistryGetRevocationRegistryDefinition: + """Get a revocation registry definition from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_registry_definition(self): + """Register a revocation registry definition on the registry.""" + + async def get_revocation_list( + self, revocation_registry_id: str, timestamp: str + ) -> AnonCredsRegistryGetRevocationList: + """Get a revocation list from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_list(self): + """Register a revocation list on the registry.""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/routes.py b/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/routes.py new file mode 100644 index 0000000000..0900c1440c --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/did_web_registry/routes.py @@ -0,0 +1 @@ +"""Routes for DID Web Registry""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/__init__.py b/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/registry.py b/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/registry.py new file mode 100644 index 0000000000..5badd4de1b --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/registry.py @@ -0,0 +1,51 @@ +"""Legacy Indy Registry""" +from ...models import ( + AnonCredsRegistryGetCredentialDefinition, + AnonCredsRegistryGetRevocationList, + AnonCredsRegistryGetRevocationRegistryDefinition, + AnonCredsRegistryGetSchema, +) +from .....config.injection_context import InjectionContext +from ...anoncreds_registry import BaseRegistry + + +class LegacyIndyRegistry(BaseRegistry): + """LegacyIndyRegistry""" + + async def setup(self, context: InjectionContext): + """Setup.""" + print("Successfully registered LegacyIndyRegistry") + + async def get_schema(self, schema_id: str) -> AnonCredsRegistryGetSchema: + """Get a schema from the registry.""" + + # TODO: determine keyword arguments + async def register_schema(self): + """Register a schema on the registry.""" + + async def get_credential_definition( + self, credential_definition_id: str + ) -> AnonCredsRegistryGetCredentialDefinition: + """Get a credential definition from the registry.""" + + # TODO: determine keyword arguments + async def register_credential_definition(self): + """Register a credential definition on the registry.""" + + async def get_revocation_registry_definition( + self, revocation_registry_id: str + ) -> AnonCredsRegistryGetRevocationRegistryDefinition: + """Get a revocation registry definition from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_registry_definition(self): + """Register a revocation registry definition on the registry.""" + + async def get_revocation_list( + self, revocation_registry_id: str, timestamp: str + ) -> AnonCredsRegistryGetRevocationList: + """Get a revocation list from the registry.""" + + # TODO: determine keyword arguments + async def register_revocation_list(self): + """Register a revocation list on the registry.""" diff --git a/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/routes.py b/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/routes.py new file mode 100644 index 0000000000..759ee608c8 --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/default/legacy_indy_registry/routes.py @@ -0,0 +1 @@ +"""Routes for Legacy Indy Registry""" diff --git a/aries_cloudagent/anoncreds/anoncreds/models.py b/aries_cloudagent/anoncreds/anoncreds/models.py new file mode 100644 index 0000000000..c034c52466 --- /dev/null +++ b/aries_cloudagent/anoncreds/anoncreds/models.py @@ -0,0 +1,99 @@ +"""AnonCreds Objects""" +from typing import Any, Dict, List, Optional +from typing_extensions import Literal +from dataclasses import dataclass + + +@dataclass +class AnonCredsSchema: + """AnonCredsSchema""" + + issuerId: str + attrNames: List[str] + name: str + version: str + + +@dataclass +class AnonCredsRegistryGetSchema: + """AnonCredsRegistryGetSchema""" + + schema: AnonCredsSchema + schema_id: str + resolution_metadata: Dict[str, Any] + schema_metadata: Dict[str, Any] + + +# TODO: determine types for `primary` and `revocation` +@dataclass +class AnonCredsCredentialDefinitionValue: + """AnonCredsCredentialDefinitionValue""" + + primary: Any + revocation: Optional[Any] + + +@dataclass +class AnonCredsCredentialDefinition: + """AnonCredsCredentialDefinition""" + + issuerId: str + schemaId: str + type: Literal["CL"] + tag: str + value: AnonCredsCredentialDefinitionValue + + +@dataclass +class AnonCredsRegistryGetCredentialDefinition: + """AnonCredsRegistryGetCredentialDefinition""" + + credential_definition: AnonCredsCredentialDefinition + credential_definition_id: str + resolution_metadata: Dict[str, Any] + credential_definition_metadata: Dict[str, Any] + + +@dataclass +class AnonCredsRevocationRegistryDefinition: + """AnonCredsRevocationRegistryDefinition""" + + issuerId: str + type: Literal["CL_ACCUM"] + credDefId: str + tag: str + # TODO: determine type for `publicKeys` + publicKeys: Any + maxCredNum: int + tailsLocation: str + tailsHash: str + + +@dataclass +class AnonCredsRegistryGetRevocationRegistryDefinition: + """AnonCredsRegistryGetRevocationRegistryDefinition""" + + revocation_registry: AnonCredsRevocationRegistryDefinition + revocation_registry_id: str + resolution_metadata: Dict[str, Any] + revocation_registry_metadata: Dict[str, Any] + + +@dataclass +class AnonCredsRevocationList: + """AnonCredsRevocationList""" + + issuerId: str + revRegId: str + revocationList: List[int] + currentAccumulator: str + timestamp: int + + +@dataclass +class AnonCredsRegistryGetRevocationList: + """AnonCredsRegistryGetRevocationList""" + + revocation_list: AnonCredsRevocationList + resolution_metadata: Dict[str, Any] + revocation_registry_metadata: Dict[str, Any] diff --git a/aries_cloudagent/config/default_context.py b/aries_cloudagent/config/default_context.py index 360f103fa1..03ba24f45c 100644 --- a/aries_cloudagent/config/default_context.py +++ b/aries_cloudagent/config/default_context.py @@ -1,5 +1,6 @@ """Classes for configuring the default injection context.""" +from ..anoncreds.anoncreds.anoncreds_registry import AnonCredsRegistry from ..cache.base import BaseCache from ..cache.in_memory import InMemoryCache from ..core.event_bus import EventBus @@ -51,6 +52,7 @@ async def build_context(self) -> InjectionContext: # Global did resolver context.injector.bind_instance(DIDResolver, DIDResolver([])) + context.injector.bind_instance(AnonCredsRegistry, AnonCredsRegistry()) context.injector.bind_instance(DIDMethods, DIDMethods()) context.injector.bind_instance(KeyTypes, KeyTypes()) @@ -127,6 +129,16 @@ async def load_plugins(self, context: InjectionContext): plugin_registry.register_plugin("aries_cloudagent.revocation") plugin_registry.register_plugin("aries_cloudagent.resolver") plugin_registry.register_plugin("aries_cloudagent.wallet") + plugin_registry.register_plugin("aries_cloudagent.anoncreds.anoncreds") + plugin_registry.register_plugin( + "aries_cloudagent.anoncreds.anoncreds.default.did_indy_registry" + ) + plugin_registry.register_plugin( + "aries_cloudagent.anoncreds.anoncreds.default.did_web_registry" + ) + plugin_registry.register_plugin( + "aries_cloudagent.anoncreds.anoncreds.default.legacy_indy_registry" + ) if context.settings.get("multitenant.admin_enabled"): plugin_registry.register_plugin("aries_cloudagent.multitenant.admin")