pub struct NostrRootResolver { /* private fields */ }Expand description
NostrRootResolver - Maps npub/treename keys to merkle root hashes
Implementations§
Source§impl NostrRootResolver
impl NostrRootResolver
Sourcepub async fn resolve_open(
&self,
key: &str,
window: Duration,
) -> Result<Cid, ResolverError>
pub async fn resolve_open( &self, key: &str, window: Duration, ) -> Result<Cid, ResolverError>
Observe a mutable root for a bounded window, keeping the subscription open after EOSE. Returns the newest usable signed root observed in that window; a quiet window is a timeout, not proof that the root does not exist. Unlike quick resolution, this does not use cached observations or a quorum shortcut. It closes only its own subscription before returning.
Source§impl NostrRootResolver
impl NostrRootResolver
Sourcepub async fn new(
config: NostrResolverConfig,
) -> Result<NostrRootResolver, ResolverError>
pub async fn new( config: NostrResolverConfig, ) -> Result<NostrRootResolver, ResolverError>
Create a new NostrRootResolver
Sourcepub fn pubkey(&self) -> Option<PublicKey>
pub fn pubkey(&self) -> Option<PublicKey>
Get current user’s public key (if we have a secret key)
Sourcepub fn filter_for_key(key: &str) -> Result<Filter, ResolverError>
pub fn filter_for_key(key: &str) -> Result<Filter, ResolverError>
Build the exact Nostr filter for a resolver key without opening a relay connection. Pubsub transports can use this to subscribe on behalf of the resolver.
Sourcepub fn root_event_builder(
tree_name: &str,
cid: &Cid,
latest_created_at: Option<Timestamp>,
) -> EventBuilder
pub fn root_event_builder( tree_name: &str, cid: &Cid, latest_created_at: Option<Timestamp>, ) -> EventBuilder
Build an unsigned public-root announcement for any event transport. The caller signs with the owner of the resolver key.
Sourcepub fn event_matches_key(
key: &str,
event: &Event,
) -> Result<bool, ResolverError>
pub fn event_matches_key( key: &str, event: &Event, ) -> Result<bool, ResolverError>
Validate that a signed event is a usable root for exactly this key.
Pubsub consumers can use this before caching an event obtained from an untrusted transport. Private roots require resolver keys and therefore are not considered usable by this transport-neutral check.
Sourcepub fn root_from_event(
key: &str,
event: &Event,
) -> Result<Option<Cid>, ResolverError>
pub fn root_from_event( key: &str, event: &Event, ) -> Result<Option<Cid>, ResolverError>
Authenticate and decode a public root without creating a relay client.
Sourcepub async fn ingest_event(&self, event: Event) -> Result<bool, ResolverError>
pub async fn ingest_event(&self, event: Event) -> Result<bool, ResolverError>
Ingest a signed root event obtained from any transport. Returns true only when it advances the replaceable root for its author and tree.
Sourcepub async fn resolve_wait(&self, key: &str) -> Result<Cid, ResolverError>
pub async fn resolve_wait(&self, key: &str) -> Result<Cid, ResolverError>
Resolve a key, waiting indefinitely until found.
Unlike resolve() which returns None after timeout, this method
subscribes and waits until a Cid is found. Caller should apply their
own timeout if needed (e.g., via tokio::time::timeout).
This matches the behavior of hashtree-ts NostrRootResolver.
Sourcepub async fn publish_private(
&self,
key: &str,
cid: &Cid,
) -> Result<bool, ResolverError>
pub async fn publish_private( &self, key: &str, cid: &Cid, ) -> Result<bool, ResolverError>
Publish a private root (selfEncryptedKey tag, NIP-44 to self)
Trait Implementations§
Source§impl RootResolver for NostrRootResolver
impl RootResolver for NostrRootResolver
Source§fn resolve<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Cid>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
fn resolve<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Cid>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
Source§fn subscribe<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Receiver<Option<Cid>>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
fn subscribe<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Receiver<Option<Cid>>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
Source§fn publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
cid: &'life2 Cid,
) -> Pin<Box<dyn Future<Output = Result<bool, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
NostrRootResolver: 'async_trait,
fn publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
cid: &'life2 Cid,
) -> Pin<Box<dyn Future<Output = Result<bool, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
NostrRootResolver: 'async_trait,
Source§fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<ResolverEntry>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<ResolverEntry>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
NostrRootResolver: 'async_trait,
Source§fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
NostrRootResolver: 'async_trait,
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
NostrRootResolver: 'async_trait,
Source§fn subscribe_list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Receiver<Vec<ResolverEntry>>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn subscribe_list<'life0, 'life1, 'async_trait>(
&'life0 self,
prefix: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Receiver<Vec<ResolverEntry>>, ResolverError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Auto Trait Implementations§
impl !RefUnwindSafe for NostrRootResolver
impl !UnwindSafe for NostrRootResolver
impl Freeze for NostrRootResolver
impl Send for NostrRootResolver
impl Sync for NostrRootResolver
impl Unpin for NostrRootResolver
impl UnsafeUnpin for NostrRootResolver
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more