osmaczko c09459c0a0
fix: signer-scoped DirectV1 routing (#162)
Core is no longer account-aware: the client resolves an account address
to signer ids via the account directory, and the signer's verifying-key
hex serves as registry key, inbox subscription, and Welcome routing
target end to end. The MLS credential stays the full id().

- GroupV2 reads the de-mls member id from the fetched key package and
  maps it to the signer id the welcome is delivered to.
- All account machinery (directory trait, bundle codec, resolution)
  moves out of core into logos-account; the RegistrationService
  supertrait and Core::account_directory() are gone, and the client
  holds its own directory handle.
- The account exposes functionality, never a signer: add_delegate_signer
  does the lamport upsert and signs internally.
- Every client acts for an account (ChatClientBuilder::new(account)).
  DelegateSigner is a pure keypair; the client composes the wire
  credential from the signer and the account, so the association is
  client state. addr() is the account address.
- resolve_device_ids fails fast (NotAnAccountKey / NoDeviceBundle /
  Directory) instead of falling back to treating an unresolved address
  as a signer id. LogosChatClient::open and chat-cli mint and publish a
  dev account each launch.
- EphemeralRegistry keys key packages by hex pubkey like HttpRegistry.

Supersedes #155 (routing_id).
2026-07-03 23:18:10 +02:00

53 lines
1.6 KiB
Rust

use components::EphemeralRegistry;
use logos_account::TestLogosAccount;
use logos_chat::{ChatClientBuilder, Event, InProcessDelivery, MessageBus};
use std::time::Duration;
fn main() {
let bus = MessageBus::default();
let reg = EphemeralRegistry::new();
let (mut saro, saro_events) = ChatClientBuilder::new(TestLogosAccount::new().address())
.transport(InProcessDelivery::new(bus.clone()))
.registration(reg.clone())
.build()
.unwrap();
let (mut raya, raya_events) = ChatClientBuilder::new(TestLogosAccount::new().address())
.transport(InProcessDelivery::new(bus))
.registration(reg)
.build()
.unwrap();
let raya_bundle = raya.create_intro_bundle().unwrap();
#[allow(deprecated)]
saro.create_conversation(&raya_bundle, b"hello raya")
.unwrap();
let raya_convo_id = match raya_events.recv_timeout(Duration::from_secs(5)).unwrap() {
Event::ConversationStarted { convo_id, .. } => convo_id,
other => panic!("expected ConversationStarted, got {other:?}"),
};
if let Event::MessageReceived { content, .. } =
raya_events.recv_timeout(Duration::from_secs(5)).unwrap()
{
println!(
"Raya received: {:?}",
std::str::from_utf8(&content).unwrap()
);
}
raya.send_message(&raya_convo_id, b"hi saro").unwrap();
if let Event::MessageReceived { content, .. } =
saro_events.recv_timeout(Duration::from_secs(5)).unwrap()
{
println!(
"Saro received: {:?}",
std::str::from_utf8(&content).unwrap()
);
}
println!("Message exchange complete.");
}