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:
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),
+ }
+ }
+}