notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit c7b7fb9ec1f5697bbf65bd53ef9a11381c44b1e3
parent 4e494e218e1d128f3582e5c8580b6b56361f40cb
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 19 Feb 2026 13:30:46 -0500

feat(scoped-subs): add account-aware oneshot and publish APIs

Introduce OneshotApi and PublishApi as app-facing wrappers over Outbox that resolve selected-account relay targets for account-scoped operations while still supporting explicit relay targets for publish.

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck/src/lib.rs | 4++++
Acrates/notedeck/src/oneshot_api.rs | 27+++++++++++++++++++++++++++
Acrates/notedeck/src/publish.rs | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs @@ -24,10 +24,12 @@ pub mod nip05; mod nip51_set; pub mod note; mod notecache; +mod oneshot_api; mod options; mod persist; pub mod platform; pub mod profile; +mod publish; pub mod relay_debug; pub mod relayspec; mod result; @@ -87,9 +89,11 @@ pub use note::{ RootNoteIdBuf, ScrollInfo, ZapAction, }; pub use notecache::{CachedNote, NoteCache}; +pub use oneshot_api::OneshotApi; pub use options::NotedeckOptions; pub use persist::*; pub use profile::*; +pub use publish::{AccountsPublishApi, ExplicitPublishApi, PublishApi, RelayType}; pub use relay_debug::RelayDebugView; pub use relayspec::RelaySpec; pub use result::Result; diff --git a/crates/notedeck/src/oneshot_api.rs b/crates/notedeck/src/oneshot_api.rs @@ -0,0 +1,27 @@ +use enostr::RelayUrlPkgs; +use nostrdb::Filter; + +use crate::{Accounts, Outbox}; + +/// App-facing one-shot relay API. +/// +/// This keeps transient read requests (REQ/EOSE) separate from durable +/// scoped subscriptions. +pub struct OneshotApi<'o, 'a> { + pool: &'o mut Outbox<'a>, + accounts: &'o Accounts, +} + +impl<'o, 'a> OneshotApi<'o, 'a> { + pub fn new(pool: &'o mut Outbox<'a>, accounts: &'o Accounts) -> Self { + Self { pool, accounts } + } + + /// Send a one-shot request to the selected account's read relay set. + pub fn oneshot(&mut self, filters: Vec<Filter>) { + self.pool.oneshot( + filters, + RelayUrlPkgs::new(self.accounts.selected_account_read_relays()), + ); + } +} diff --git a/crates/notedeck/src/publish.rs b/crates/notedeck/src/publish.rs @@ -0,0 +1,74 @@ +use enostr::RelayId; +use nostrdb::Note; + +use crate::{Accounts, Outbox}; + +/// Relay target policy for publishing. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum RelayType { + /// Publish to the selected account's write relay set. + AccountsWrite, + /// Publish to an explicit relay target set. + Explicit(Vec<RelayId>), +} + +/// Explicit-relay publishing API that does not depend on account state. +pub struct ExplicitPublishApi<'o, 'a> { + pool: &'o mut Outbox<'a>, +} + +impl<'o, 'a> ExplicitPublishApi<'o, 'a> { + pub fn new(pool: &'o mut Outbox<'a>) -> Self { + Self { pool } + } + + /// Publish a note to an explicit relay target set. + pub fn publish_note(&mut self, note: &Note, relays: Vec<RelayId>) { + self.pool.broadcast_note(note, relays); + } +} + +/// Selected-account write-relay publishing API. +pub struct AccountsPublishApi<'o, 'a> { + pool: &'o mut Outbox<'a>, + accounts: &'o Accounts, +} + +impl<'o, 'a> AccountsPublishApi<'o, 'a> { + pub fn new(pool: &'o mut Outbox<'a>, accounts: &'o Accounts) -> Self { + Self { pool, accounts } + } + + /// Publish a note to the selected account's write relay set. + pub fn publish_note(&mut self, note: &Note) { + self.pool + .broadcast_note(note, self.accounts.selected_account_write_relays()); + } +} + +/// Compatibility wrapper over typed publishing APIs. +pub struct PublishApi<'o, 'a> { + pool: &'o mut Outbox<'a>, + accounts: &'o Accounts, +} + +impl<'o, 'a> PublishApi<'o, 'a> { + pub fn new(pool: &'o mut Outbox<'a>, accounts: &'o Accounts) -> Self { + Self { pool, accounts } + } + + pub fn explicit(&mut self) -> ExplicitPublishApi<'_, 'a> { + ExplicitPublishApi::new(self.pool) + } + + pub fn accounts_write(&mut self) -> AccountsPublishApi<'_, 'a> { + AccountsPublishApi::new(self.pool, self.accounts) + } + + pub fn publish_note(&mut self, note: &Note, relays: RelayType) { + match relays { + RelayType::AccountsWrite => self.accounts_write().publish_note(note), + RelayType::Explicit(relays) => self.explicit().publish_note(note, relays), + } + } +}