feat: http server based key package registry (#124)

* feat: http server based key package registry

* chore: instructions on running the registration service

* chore: remove duplicate post param

* chore: revert out sourced account id for multi devices support

* feat: signature on account id and key packages

* chore: include http registry in contact registry module

* refactor: use device id for retrieve key package

* chore: use string for device id

* feat: server verification on the register

* chore: doc the smoke test

* chore: fix data folder non exist

* chore: use payload for register and retrieve

* chore: fix clippy
This commit is contained in:
kaichao
2026-06-04 10:09:29 +08:00
committed by GitHub
parent 6f5838af51
commit cd7dd6a330
23 changed files with 1825 additions and 53 deletions
+35 -4
View File
@@ -2,7 +2,8 @@ use std::sync::Arc;
use libchat::{
AddressedEnvelope, ChatError, ChatStorage, Context, ConversationId, ConvoOutcome,
DeliveryService, InboxOutcome, Introduction, PayloadOutcome, StorageConfig,
DeliveryService, InboxOutcome, Introduction, PayloadOutcome, RegistrationService,
StorageConfig,
};
use components::EphemeralRegistry;
@@ -10,11 +11,13 @@ use components::EphemeralRegistry;
use crate::errors::ClientError;
use crate::event::Event;
pub struct ChatClient<D: DeliveryService> {
ctx: Context<D, EphemeralRegistry, ChatStorage>,
pub struct ChatClient<D: DeliveryService, R: RegistrationService = EphemeralRegistry> {
ctx: Context<D, R, ChatStorage>,
}
impl<D: DeliveryService + 'static> ChatClient<D> {
// ── Default-registry constructors ────────────────────────────────────────────
impl<D: DeliveryService + 'static> ChatClient<D, EphemeralRegistry> {
/// Create an in-memory, ephemeral client. Identity is lost on drop.
pub fn new(name: impl Into<String>, delivery: D) -> Self {
let registry = EphemeralRegistry::new();
@@ -38,6 +41,34 @@ impl<D: DeliveryService + 'static> ChatClient<D> {
let ctx = Context::new_from_store(name, delivery, registry, store)?;
Ok(Self { ctx })
}
}
// ── Caller-supplied registry + shared methods ────────────────────────────────
impl<D, R> ChatClient<D, R>
where
D: DeliveryService + 'static,
R: RegistrationService + 'static,
{
/// Open or create a persistent client with a caller-supplied registration
/// service. Use this to swap in a network-backed registry (e.g. the
/// testnet KeyPackage Registry) in place of the default in-memory store.
///
/// Submits this account's KeyPackage to the registry as the last step of
/// construction. The default in-memory `open` path skips this call, but
/// when a real registry is wired in we want each session to publish so
/// other clients can fetch it.
pub fn open_with_registry(
name: impl Into<String>,
config: StorageConfig,
delivery: D,
registry: R,
) -> Result<Self, ClientError<D::Error>> {
let store = ChatStorage::new(config).map_err(ChatError::from)?;
let mut ctx = Context::new_from_store(name, delivery, registry, store)?;
ctx.register_keypackage()?;
Ok(Self { ctx })
}
/// Returns the installation name (identity label) of this client.
pub fn installation_name(&self) -> &str {
+6 -1
View File
@@ -10,5 +10,10 @@ pub use event::Event;
// Re-export types callers need to interact with ChatClient.
pub use libchat::{
AddressedEnvelope, ConversationClass, ConversationId, DeliveryService, StorageConfig,
AddressedEnvelope, ConversationClass, ConversationId, DeliveryService, RegistrationService,
StorageConfig,
};
// Re-export bundled registry implementations so callers can pick one without
// pulling in `components` directly.
pub use components::{EphemeralRegistry, HttpRegistry, HttpRegistryError};