diff --git a/Taskfile.yml b/Taskfile.yml index a60ee48..56a52d2 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -5,11 +5,11 @@ version: "3" vars: # renovate: datasource=github-releases depName=agntcy/dir versioning=semver - DIR_CHART_VERSION: '{{ .DIR_CHART_VERSION | default "v1.7.1" }}' + DIR_CHART_VERSION: '{{ .DIR_CHART_VERSION | default "v1.8.0" }}' # renovate: datasource=github-releases depName=agntcy/dir versioning=semver - DIR_IMAGE_TAG: '{{ .DIR_IMAGE_TAG | default "v1.7.1" }}' + DIR_IMAGE_TAG: '{{ .DIR_IMAGE_TAG | default "v1.8.0" }}' # renovate: datasource=github-releases depName=agntcy/dir versioning=semver - DIRCTL_IMAGE_TAG: '{{ .DIRCTL_IMAGE_TAG | default "v1.7.1" }}' + DIRCTL_IMAGE_TAG: '{{ .DIRCTL_IMAGE_TAG | default "v1.8.0" }}' # renovate: datasource=github-releases depName=renovatebot/renovate versioning=semver RENOVATE_VERSION: "44.141.0" @@ -243,7 +243,6 @@ tasks: --set apiserver.service.nodePort="{{.API_NODEPORT}}" \ --set apiserver.service.metricsNodePort="{{.METRICS_NODEPORT}}" \ {{ if .DIRECTORY_SERVER_PUBLICATION_SCHEDULER_INTERVAL }}--set apiserver.config.publication.scheduler_interval="{{ .DIRECTORY_SERVER_PUBLICATION_SCHEDULER_INTERVAL }}"{{ end }} \ - {{ if .DIRECTORY_SERVER_NAMING_TTL }}--set apiserver.config.naming.ttl="{{ .DIRECTORY_SERVER_NAMING_TTL }}"{{ end }} \ --set apiserver.config.routing.refresh_interval="1s" \ --set-json 'apiserver.config.routing.bootstrap_peers=[]' \ --set apiserver.secrets.ociAuth.username="${HTPASSWD_USERNAME}" \ diff --git a/dir-sdk-python/agntcy/dir_sdk/client/client.py b/dir-sdk-python/agntcy/dir_sdk/client/client.py index 598c5fc..2f642da 100644 --- a/dir-sdk-python/agntcy/dir_sdk/client/client.py +++ b/dir-sdk-python/agntcy/dir_sdk/client/client.py @@ -19,7 +19,7 @@ from agntcy.dir_sdk.client.auth.token_cache import CachedToken, TokenCache from agntcy.dir_sdk.client.config import Config from agntcy.dir_sdk.client.services.events import EventService -from agntcy.dir_sdk.client.services.naming import NamingService +from agntcy.dir_sdk.client.services.identity import IdentityService from agntcy.dir_sdk.client.services.publication import PublicationService from agntcy.dir_sdk.client.services.routing import RoutingService from agntcy.dir_sdk.client.services.search import SearchService @@ -34,7 +34,7 @@ from agntcy.dir_sdk.models import ( core_v1, events_v1, - naming_v1, + identity_v1, routing_v1, search_v1, sign_v1, @@ -75,7 +75,7 @@ def __init__(self, config: Config | None = None) -> None: self.sign_client = sign_v1.SignServiceStub(channel) self.sync_client = store_v1.SyncServiceStub(channel) self.event_client = events_v1.EventServiceStub(channel) - self.naming_client = naming_v1.NamingServiceStub(channel) + self.identity_client = identity_v1.IdentityServiceStub(channel) # Service-layer adapters grouped by technical area. self.store_service = StoreService(self.store_client, logger) @@ -85,7 +85,7 @@ def __init__(self, config: Config | None = None) -> None: self.sign_service = SignService(self.config, self.sign_client, logger) self.sync_service = SyncService(self.sync_client, logger) self.event_service = EventService(self.event_client, logger) - self.naming_service = NamingService(self.naming_client, logger) + self.identity_service = IdentityService(self.identity_client, logger) def has_cached_oauth_token(self) -> bool: return self.oauth_session.has_access_token() @@ -254,8 +254,8 @@ def resolve( name: str, version: str | None = None, metadata: Sequence[tuple[str, str]] | None = None, - ) -> naming_v1.ResolveResponse: - return self.naming_service.resolve(name, version=version, metadata=metadata) + ) -> identity_v1.ResolveResponse: + return self.identity_service.resolve(name, version=version, metadata=metadata) def get_verification_info( self, @@ -263,8 +263,8 @@ def get_verification_info( name: str | None = None, version: str | None = None, metadata: Sequence[tuple[str, str]] | None = None, - ) -> naming_v1.GetVerificationInfoResponse: - return self.naming_service.get_verification_info( + ) -> identity_v1.GetVerificationInfoResponse: + return self.identity_service.get_verification_info( cid=cid, name=name, version=version, diff --git a/dir-sdk-python/agntcy/dir_sdk/client/services/__init__.py b/dir-sdk-python/agntcy/dir_sdk/client/services/__init__.py index 9687f55..c1b5668 100644 --- a/dir-sdk-python/agntcy/dir_sdk/client/services/__init__.py +++ b/dir-sdk-python/agntcy/dir_sdk/client/services/__init__.py @@ -4,7 +4,7 @@ """Service-layer wrappers around generated gRPC stubs.""" from agntcy.dir_sdk.client.services.events import EventService -from agntcy.dir_sdk.client.services.naming import NamingService +from agntcy.dir_sdk.client.services.identity import IdentityService from agntcy.dir_sdk.client.services.publication import PublicationService from agntcy.dir_sdk.client.services.routing import RoutingService from agntcy.dir_sdk.client.services.search import SearchService @@ -14,7 +14,7 @@ __all__ = [ "EventService", - "NamingService", + "IdentityService", "PublicationService", "RoutingService", "SearchService", diff --git a/dir-sdk-python/agntcy/dir_sdk/client/services/identity.py b/dir-sdk-python/agntcy/dir_sdk/client/services/identity.py new file mode 100644 index 0000000..246faf3 --- /dev/null +++ b/dir-sdk-python/agntcy/dir_sdk/client/services/identity.py @@ -0,0 +1,88 @@ +# Copyright AGNTCY Contributors (https://github.com/agntcy) +# SPDX-License-Identifier: Apache-2.0 + +"""Identity service wrappers.""" + +from __future__ import annotations + +import logging +from collections.abc import Sequence + +from agntcy.dir_sdk.client.services.base import RpcServiceBase +from agntcy.dir_sdk.models import identity_v1 + +# The reported method for a record resolved through a verified owner claim. +_OWNER_CLAIM_METHOD = "owner-claim" + + +class IdentityService(RpcServiceBase): + def __init__( + self, identity_client: identity_v1.IdentityServiceStub, logger: logging.Logger + ) -> None: + super().__init__(logger) + self._identity_client = identity_client + + def resolve( + self, + name: str, + version: str | None = None, + metadata: Sequence[tuple[str, str]] | None = None, + ) -> identity_v1.ResolveResponse: + def call() -> identity_v1.ResolveResponse: + req = identity_v1.ResolveRequest(name=name) + if version: + req.version = version + return self._identity_client.Resolve(req, metadata=metadata) + + return self._invoke("resolve", "Failed to resolve name", call) + + def get_verification_info( + self, + cid: str | None = None, + name: str | None = None, + version: str | None = None, + metadata: Sequence[tuple[str, str]] | None = None, + ) -> identity_v1.GetVerificationInfoResponse: + def call() -> identity_v1.GetVerificationInfoResponse: + req = identity_v1.GetIdentityStatusRequest() + if cid: + req.cid = cid + if name: + req.name = name + if version: + req.version = version + status = self._identity_client.GetIdentityStatus(req, metadata=metadata) + return _verification_info(status) + + return self._invoke( + "get_verification_info", + "Failed to get verification info", + call, + ) + + +def _verification_info( + status: identity_v1.GetIdentityStatusResponse, +) -> identity_v1.GetVerificationInfoResponse: + """Projects the ownership claim result onto the legacy result shape.""" + owner = status.owner + if not status.HasField("owner"): + return identity_v1.GetVerificationInfoResponse( + error_message="no verification found" + ) + + if owner.status != identity_v1.CLAIM_VERIFICATION_STATUS_VERIFIED: + return identity_v1.GetVerificationInfoResponse( + error_message=owner.error or "verification failed" + ) + + return identity_v1.GetVerificationInfoResponse( + verified=True, + verification=identity_v1.Verification( + domain=identity_v1.DomainVerification( + domain=owner.subject, + method=_OWNER_CLAIM_METHOD, + verified_at=owner.verified_at, + ) + ), + ) diff --git a/dir-sdk-python/agntcy/dir_sdk/client/services/naming.py b/dir-sdk-python/agntcy/dir_sdk/client/services/naming.py deleted file mode 100644 index 3361941..0000000 --- a/dir-sdk-python/agntcy/dir_sdk/client/services/naming.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright AGNTCY Contributors (https://github.com/agntcy) -# SPDX-License-Identifier: Apache-2.0 - -"""Naming service wrappers.""" - -from __future__ import annotations - -import logging -from collections.abc import Sequence - -from agntcy.dir_sdk.client.services.base import RpcServiceBase -from agntcy.dir_sdk.models import naming_v1 - - -class NamingService(RpcServiceBase): - def __init__( - self, naming_client: naming_v1.NamingServiceStub, logger: logging.Logger - ) -> None: - super().__init__(logger) - self._naming_client = naming_client - - def resolve( - self, - name: str, - version: str | None = None, - metadata: Sequence[tuple[str, str]] | None = None, - ) -> naming_v1.ResolveResponse: - def call() -> naming_v1.ResolveResponse: - req = naming_v1.ResolveRequest(name=name) - if version: - req.version = version - return self._naming_client.Resolve(req, metadata=metadata) - - return self._invoke("resolve", "Failed to resolve name", call) - - def get_verification_info( - self, - cid: str | None = None, - name: str | None = None, - version: str | None = None, - metadata: Sequence[tuple[str, str]] | None = None, - ) -> naming_v1.GetVerificationInfoResponse: - def call() -> naming_v1.GetVerificationInfoResponse: - req = naming_v1.GetVerificationInfoRequest() - if cid: - req.cid = cid - if name: - req.name = name - if version: - req.version = version - return self._naming_client.GetVerificationInfo(req, metadata=metadata) - - return self._invoke( - "get_verification_info", - "Failed to get verification info", - call, - ) diff --git a/dir-sdk-python/agntcy/dir_sdk/models/__init__.py b/dir-sdk-python/agntcy/dir_sdk/models/__init__.py index ca78424..158ecb4 100644 --- a/dir-sdk-python/agntcy/dir_sdk/models/__init__.py +++ b/dir-sdk-python/agntcy/dir_sdk/models/__init__.py @@ -6,7 +6,7 @@ from . import core_v1 as core_v1 from . import events_v1 as events_v1 -from . import naming_v1 as naming_v1 +from . import identity_v1 as identity_v1 from . import routing_v1 as routing_v1 from . import search_v1 as search_v1 from . import sign_v1 as sign_v1 diff --git a/dir-sdk-python/agntcy/dir_sdk/models/identity_v1.py b/dir-sdk-python/agntcy/dir_sdk/models/identity_v1.py new file mode 100644 index 0000000..379a16a --- /dev/null +++ b/dir-sdk-python/agntcy/dir_sdk/models/identity_v1.py @@ -0,0 +1,38 @@ +# Copyright AGNTCY Contributors (https://github.com/agntcy) +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from dataclasses import dataclass + +from agntcy.dir.identity.v1.claim_pb2 import * +from agntcy.dir.identity.v1.identity_service_pb2 import * +from agntcy.dir.identity.v1.identity_service_pb2_grpc import * +from google.protobuf.timestamp_pb2 import Timestamp + + +@dataclass +class DomainVerification: + """Describes the verified owner of a record's name.""" + + domain: str + method: str + verified_at: Timestamp | None = None + + +@dataclass +class Verification: + """Holds the details of a verified name.""" + + domain: DomainVerification | None = None + + +@dataclass +class GetVerificationInfoResponse: + """The result of a name ownership lookup, projected from the record's + ownership claim (identity.v1). + """ + + verified: bool = False + verification: Verification | None = None + error_message: str = "" diff --git a/dir-sdk-python/agntcy/dir_sdk/models/naming_v1.py b/dir-sdk-python/agntcy/dir_sdk/models/naming_v1.py deleted file mode 100644 index 7b21e98..0000000 --- a/dir-sdk-python/agntcy/dir_sdk/models/naming_v1.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright AGNTCY Contributors (https://github.com/agntcy) -# SPDX-License-Identifier: Apache-2.0 - -from agntcy.dir.naming.v1.name_verification_pb2 import * -from agntcy.dir.naming.v1.naming_service_pb2 import * -from agntcy.dir.naming.v1.naming_service_pb2_grpc import * diff --git a/examples/uv.lock b/examples/uv.lock index bd73e58..884c3fb 100644 --- a/examples/uv.lock +++ b/examples/uv.lock @@ -8,7 +8,6 @@ version = "1.7.0" source = { editable = "../" } dependencies = [ { name = "agntcy-dir-grpc-python" }, - { name = "agntcy-dir-protocolbuffers-pyi" }, { name = "agntcy-dir-protocolbuffers-python" }, { name = "authlib" }, { name = "grpcio" }, @@ -21,9 +20,8 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "agntcy-dir-grpc-python", specifier = "==1.83.1.3.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, - { name = "agntcy-dir-protocolbuffers-pyi", specifier = "==36.2.0.1.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, - { name = "agntcy-dir-protocolbuffers-python", specifier = "==36.1.0.1.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, + { name = "agntcy-dir-grpc-python", specifier = "==1.83.1.3.20261015113725+c24aeb0a65d8", index = "https://buf.build/gen/python" }, + { name = "agntcy-dir-protocolbuffers-python", specifier = "==36.1.0.1.20261015113725+c24aeb0a65d8", index = "https://buf.build/gen/python" }, { name = "authlib", specifier = ">=1.6.9" }, { name = "grpcio", specifier = ">=1.78.0" }, { name = "httpx", specifier = ">=0.28.1" }, @@ -45,7 +43,7 @@ dev = [ [[package]] name = "agntcy-dir-grpc-python" -version = "1.83.1.3.20260922140046+fd75d73eab52" +version = "1.83.1.3.20261015113725+c24aeb0a65d8" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "agntcy-dir-protocolbuffers-python" }, @@ -54,12 +52,12 @@ dependencies = [ { name = "grpcio" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-grpc-python/agntcy_dir_grpc_python-1.83.1.3.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-grpc-python/agntcy_dir_grpc_python-1.83.1.3.20261015113725+c24aeb0a65d8-py3-none-any.whl", upload-time = "2026-10-15T11:37:25Z" }, ] [[package]] name = "agntcy-dir-protocolbuffers-pyi" -version = "36.2.0.1.20260922140046+fd75d73eab52" +version = "36.2.0.1.20261006085230+1106da22f446" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "bufbuild-protovalidate-protocolbuffers-pyi" }, @@ -68,12 +66,12 @@ dependencies = [ { name = "types-protobuf" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-pyi/agntcy_dir_protocolbuffers_pyi-36.2.0.1.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-pyi/agntcy_dir_protocolbuffers_pyi-36.2.0.1.20261006085230+1106da22f446-py3-none-any.whl", upload-time = "2026-10-06T08:52:30Z" }, ] [[package]] name = "agntcy-dir-protocolbuffers-python" -version = "36.1.0.1.20260922140046+fd75d73eab52" +version = "36.1.0.1.20261015113725+c24aeb0a65d8" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "agntcy-dir-protocolbuffers-pyi" }, @@ -82,7 +80,7 @@ dependencies = [ { name = "protobuf" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-python/agntcy_dir_protocolbuffers_python-36.1.0.1.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-python/agntcy_dir_protocolbuffers_python-36.1.0.1.20261015113725+c24aeb0a65d8-py3-none-any.whl", upload-time = "2026-10-15T11:37:25Z" }, ] [[package]] @@ -319,7 +317,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ diff --git a/pyproject.toml b/pyproject.toml index 243a374..4c81a46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,9 +5,8 @@ description = "Directory SDK" readme = "README.md" requires-python = ">=3.10" dependencies = [ - "agntcy-dir-grpc-python==1.83.1.3.20260922140046+fd75d73eab52", # v1.7.1 - "agntcy-dir-protocolbuffers-python==36.1.0.1.20260922140046+fd75d73eab52", # v1.7.1 - "agntcy-dir-protocolbuffers-pyi==36.2.0.1.20260922140046+fd75d73eab52", # v1.7.1 + "agntcy-dir-grpc-python==1.83.1.3.20261015113725+c24aeb0a65d8", # v1.8.0 + "agntcy-dir-protocolbuffers-python==36.1.0.1.20261015113725+c24aeb0a65d8", # v1.8.0 "authlib>=1.6.9", "httpx>=0.28.1", "grpcio>=1.78.0", diff --git a/uv.lock b/uv.lock index 4103fe0..90ba3fb 100644 --- a/uv.lock +++ b/uv.lock @@ -12,7 +12,6 @@ version = "1.7.0" source = { editable = "." } dependencies = [ { name = "agntcy-dir-grpc-python" }, - { name = "agntcy-dir-protocolbuffers-pyi" }, { name = "agntcy-dir-protocolbuffers-python" }, { name = "authlib" }, { name = "grpcio" }, @@ -35,9 +34,8 @@ dev = [ [package.metadata] requires-dist = [ - { name = "agntcy-dir-grpc-python", specifier = "==1.83.1.3.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, - { name = "agntcy-dir-protocolbuffers-pyi", specifier = "==36.2.0.1.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, - { name = "agntcy-dir-protocolbuffers-python", specifier = "==36.1.0.1.20260922140046+fd75d73eab52", index = "https://buf.build/gen/python" }, + { name = "agntcy-dir-grpc-python", specifier = "==1.83.1.3.20261015113725+c24aeb0a65d8", index = "https://buf.build/gen/python" }, + { name = "agntcy-dir-protocolbuffers-python", specifier = "==36.1.0.1.20261015113725+c24aeb0a65d8", index = "https://buf.build/gen/python" }, { name = "authlib", specifier = ">=1.6.9" }, { name = "grpcio", specifier = ">=1.78.0" }, { name = "httpx", specifier = ">=0.28.1" }, @@ -59,7 +57,7 @@ dev = [ [[package]] name = "agntcy-dir-grpc-python" -version = "1.83.1.3.20260922140046+fd75d73eab52" +version = "1.83.1.3.20261015113725+c24aeb0a65d8" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "agntcy-dir-protocolbuffers-python" }, @@ -68,12 +66,12 @@ dependencies = [ { name = "grpcio" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-grpc-python/agntcy_dir_grpc_python-1.83.1.3.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-grpc-python/agntcy_dir_grpc_python-1.83.1.3.20261015113725+c24aeb0a65d8-py3-none-any.whl", upload-time = "2026-10-15T11:37:25Z" }, ] [[package]] name = "agntcy-dir-protocolbuffers-pyi" -version = "36.2.0.1.20260922140046+fd75d73eab52" +version = "36.2.0.1.20261006085230+1106da22f446" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "bufbuild-protovalidate-protocolbuffers-pyi" }, @@ -82,12 +80,12 @@ dependencies = [ { name = "types-protobuf" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-pyi/agntcy_dir_protocolbuffers_pyi-36.2.0.1.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-pyi/agntcy_dir_protocolbuffers_pyi-36.2.0.1.20261006085230+1106da22f446-py3-none-any.whl", upload-time = "2026-10-06T08:52:30Z" }, ] [[package]] name = "agntcy-dir-protocolbuffers-python" -version = "36.1.0.1.20260922140046+fd75d73eab52" +version = "36.1.0.1.20261015113725+c24aeb0a65d8" source = { registry = "https://buf.build/gen/python" } dependencies = [ { name = "agntcy-dir-protocolbuffers-pyi" }, @@ -96,7 +94,7 @@ dependencies = [ { name = "protobuf" }, ] wheels = [ - { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-python/agntcy_dir_protocolbuffers_python-36.1.0.1.20260922140046+fd75d73eab52-py3-none-any.whl", upload-time = "2026-09-22T14:00:46Z" }, + { url = "https://buf.build/gen/python/agntcy-dir-protocolbuffers-python/agntcy_dir_protocolbuffers_python-36.1.0.1.20261015113725+c24aeb0a65d8-py3-none-any.whl", upload-time = "2026-10-15T11:37:25Z" }, ] [[package]] @@ -500,7 +498,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [