.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m40s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m50s

This commit is contained in:
2026-02-06 13:25:34 +07:00
parent fce4c1bbcd
commit 253d04f988
17 changed files with 1081 additions and 872 deletions

View File

@@ -40,7 +40,7 @@ pub struct DeviceRegistry {
tasks: Vec<Task<Result<(), Error>>>,
/// Subscriptions
_subscriptions: SmallVec<[Subscription; 1]>,
_subscriptions: SmallVec<[Subscription; 2]>,
}
impl DeviceRegistry {
@@ -58,7 +58,8 @@ impl DeviceRegistry {
fn new(cx: &mut Context<Self>) -> Self {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let identity = nostr.read(cx).identity();
let nip65_state = nostr.read(cx).nip65_state();
let nip17_state = nostr.read(cx).nip17_state();
let device_signer = cx.new(|_| None);
let requests = cx.new(|_| HashSet::default());
@@ -70,21 +71,26 @@ impl DeviceRegistry {
let mut tasks = vec![];
subscriptions.push(
// Observe the identity entity
cx.observe(&identity, |this, state, cx| {
match state.read(cx).relay_list_state() {
RelayState::Initial => {
// Observe the NIP-65 state
cx.observe(&nip65_state, |this, state, cx| {
match state.read(cx) {
RelayState::Idle => {
this.reset(cx);
}
RelayState::Set => {
RelayState::Configured => {
this.get_announcement(cx);
if state.read(cx).messaging_relays_state() == RelayState::Set {
this.get_messages(cx);
}
}
_ => {}
}
};
}),
);
subscriptions.push(
// Observe the NIP-17 state
cx.observe(&nip17_state, |this, state, cx| {
if state.read(cx) == &RelayState::Configured {
this.get_messages(cx);
};
}),
);
@@ -265,29 +271,26 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let device_signer = self.device_signer.read(cx).clone();
let messaging_relays = nostr.read(cx).messaging_relays(cx);
let public_key = nostr.read(cx).identity().read(cx).public_key();
let messaging_relays = nostr.read(cx).messaging_relays(&public_key, cx);
cx.background_spawn(async move {
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let urls = messaging_relays.await;
let user_signer = client.signer().context("Signer not found")?;
let public_key = user_signer.get_public_key().await?;
// Get messages with dekey
if let Some(signer) = device_signer.as_ref() {
if let Ok(pkey) = signer.get_public_key().await {
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(pkey);
let id = SubscriptionId::new(DEVICE_GIFTWRAP);
let device_pkey = signer.get_public_key().await?;
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(device_pkey);
let id = SubscriptionId::new(DEVICE_GIFTWRAP);
// Construct target for subscription
let target = urls
.iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
// Construct target for subscription
let target = urls
.iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
if let Err(e) = client.subscribe(target).with_id(id).await {
log::error!("Failed to subscribe to gift wrap events: {e}");
}
}
client.subscribe(target).with_id(id).await?;
}
// Get messages with user key
@@ -300,11 +303,12 @@ impl DeviceRegistry {
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
if let Err(e) = client.subscribe(target).with_id(id).await {
log::error!("Failed to subscribe to gift wrap events: {e}");
}
})
.detach();
client.subscribe(target).with_id(id).await?;
Ok(())
});
task.detach();
}
/// Get device announcement for current user
@@ -312,11 +316,9 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let task: Task<Result<Event, Error>> = cx.background_spawn(async move {
let urls = write_relays.await;
let signer = client.signer().context("Signer not found")?;
let public_key = signer.get_public_key().await?;
// Construct the filter for the device announcement event
let filter = Filter::new()
@@ -324,14 +326,8 @@ impl DeviceRegistry {
.author(public_key)
.limit(1);
// Construct target for subscription
let target = urls
.iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
let mut stream = client
.stream_events(target)
.stream_events(filter)
.timeout(Duration::from_secs(TIMEOUT))
.await?;
@@ -373,16 +369,12 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
// Generate a new device keys
let keys = Keys::generate();
let secret = keys.secret_key().to_secret_hex();
let n = keys.public_key();
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let urls = write_relays.await;
// Construct an announcement event
let builder = EventBuilder::new(Kind::Custom(10044), "").tags(vec![
Tag::custom(TagKind::custom("n"), vec![n]),
@@ -391,7 +383,7 @@ impl DeviceRegistry {
let event = client.sign_event_builder(builder).await?;
// Publish announcement
client.send_event(&event).to(urls).await?;
client.send_event(&event).to_nip65().await?;
// Save device keys to the database
Self::set_keys(&client, &secret).await?;
@@ -459,11 +451,9 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let urls = write_relays.await;
let signer = client.signer().context("Signer not found")?;
let public_key = signer.get_public_key().await?;
// Construct a filter for device key requests
let filter = Filter::new()
@@ -471,14 +461,8 @@ impl DeviceRegistry {
.author(public_key)
.since(Timestamp::now());
// Construct target for subscription
let target = urls
.iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
// Subscribe to the device key requests on user's write relays
client.subscribe(target).await?;
client.subscribe(filter).await?;
Ok(())
});
@@ -491,11 +475,9 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let urls = write_relays.await;
let signer = client.signer().context("Signer not found")?;
let public_key = signer.get_public_key().await?;
// Construct a filter for device key requests
let filter = Filter::new()
@@ -503,14 +485,8 @@ impl DeviceRegistry {
.author(public_key)
.since(Timestamp::now());
// Construct target for subscription
let target = urls
.iter()
.map(|relay| (relay, vec![filter.clone()]))
.collect::<HashMap<_, _>>();
// Subscribe to the device key requests on user's write relays
client.subscribe(target).await?;
client.subscribe(filter).await?;
Ok(())
});
@@ -523,9 +499,6 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let app_keys = nostr.read(cx).app_keys().clone();
let app_pubkey = app_keys.public_key();
@@ -557,8 +530,6 @@ impl DeviceRegistry {
Ok(Some(keys))
}
None => {
let urls = write_relays.await;
// Construct an event for device key request
let builder = EventBuilder::new(Kind::Custom(4454), "").tags(vec![
Tag::client(app_name()),
@@ -567,7 +538,7 @@ impl DeviceRegistry {
let event = client.sign_event_builder(builder).await?;
// Send the event to write relays
client.send_event(&event).to(urls).await?;
client.send_event(&event).to_nip65().await?;
Ok(None)
}
@@ -640,11 +611,7 @@ impl DeviceRegistry {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let public_key = nostr.read(cx).identity().read(cx).public_key();
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let urls = write_relays.await;
let signer = client.signer().context("Signer not found")?;
// Get device keys
@@ -673,7 +640,7 @@ impl DeviceRegistry {
let event = client.sign_event_builder(builder).await?;
// Send the response event to the user's relay list
client.send_event(&event).to(urls).await?;
client.send_event(&event).to_nip65().await?;
Ok(())
});