diff --git a/overlay_social/client.py b/overlay_social/client.py index ccabe65..c397e2f 100644 --- a/overlay_social/client.py +++ b/overlay_social/client.py @@ -94,6 +94,13 @@ def _interp_resolve(ok: bool, data: Any) -> dict[str, ResolvedIdentity]: return {k: ResolvedIdentity.from_dict(v) for k, v in ids.items() if isinstance(v, dict)} +def _interp_list_identities(data: Any) -> list[ResolvedIdentity]: + if not isinstance(data, dict): + return [] + ids = data.get("identities") or [] + return [ResolvedIdentity.from_dict(v) for v in ids if isinstance(v, dict)] + + def _interp_identity(data: Any) -> IdentityBundle | None: if not isinstance(data, dict) or data.get("error") or not data.get("pubkey"): return None @@ -201,6 +208,20 @@ def resolve_identities( except Exception: return {} + def list_identities(self, *, limit: int = 50, offset: int = 0) -> list[ResolvedIdentity]: + """GET /v1/identities — people-discovery: canonical profiles, newest + first ("who's on the overlay"). Returns [] on any error.""" + try: + r = self._client.get( + f"{self.base_url}/v1/identities", + params={"limit": limit, "offset": offset}, + ) + if r.status_code // 100 != 2: + return [] + return _interp_list_identities(r.json() if r.content else None) + except Exception: + return [] + def get_identity(self, pubkey: str) -> IdentityBundle | None: if not pubkey: return None diff --git a/overlay_social/models.py b/overlay_social/models.py index 2b75282..4bf98df 100644 --- a/overlay_social/models.py +++ b/overlay_social/models.py @@ -28,6 +28,7 @@ class ResolvedIdentity: display_name: str | None = None avatar_ref: str | None = None profile_outpoint: str | None = None + minted_at: str | None = None # set by GET /v1/identities (discovery); None from resolve @classmethod def from_dict(cls, d: dict[str, Any]) -> "ResolvedIdentity": @@ -38,6 +39,7 @@ def from_dict(cls, d: dict[str, Any]) -> "ResolvedIdentity": display_name=d.get("displayName"), avatar_ref=d.get("avatarRef"), profile_outpoint=d.get("profileOutpoint"), + minted_at=d.get("mintedAt"), )