Skip to main content

WatchHandle

Struct WatchHandle 

Source
pub struct WatchHandle { /* private fields */ }
Expand description

A handle to send control messages on a bidirectional Watch stream.

Typed helpers build and send the right SubscribeControl for each watch kind; send_control remains for raw access. Empty inputs are no-ops (nothing is sent). Dropping the handle closes the control channel, which the server uses to tear the stream down.

Implementations§

Source§

impl WatchHandle

Source

pub async fn send_control( &self, ctrl: SubscribeControl, ) -> Result<(), StreamError>

Send a raw SubscribeControl message.

Source

pub async fn add_scripts( &self, items: impl IntoIterator<Item = ([u8; 32], Option<u64>)>, ) -> Result<(), StreamError>

Add scripthashes (each sha256(scriptPubKey)), with an optional per-script min_value floor in satoshis. Matches below a script’s floor are suppressed (a None floor delivers everything). Re-asserting a held scripthash updates its floor. Charges one watch-quota unit per scripthash.

Source

pub async fn remove_scripts( &self, scripthashes: impl IntoIterator<Item = [u8; 32]>, ) -> Result<(), StreamError>

Remove scripthashes from the watch-set, releasing their quota.

Source

pub async fn add_outpoints( &self, outpoints: impl IntoIterator<Item = ([u8; 32], u32)>, ) -> Result<(), StreamError>

Add outpoints (txid:vout) to the watch-set. Charges one unit each.

Source

pub async fn remove_outpoints( &self, outpoints: impl IntoIterator<Item = ([u8; 32], u32)>, ) -> Result<(), StreamError>

Remove outpoints from the watch-set, releasing their quota.

Source

pub async fn add_tx_lifecycle( &self, txids: impl IntoIterator<Item = [u8; 32]>, auto_close: AutoClose, ) -> Result<(), StreamError>

Add persistent lifecycle watches on txids (seen → confirmed → replaced / evicted / unconfirmed). auto_close optionally self-evicts the watch once the tx is buried. Charges one unit per txid.

Source

pub async fn remove_tx_lifecycle( &self, txids: impl IntoIterator<Item = [u8; 32]>, ) -> Result<(), StreamError>

Remove lifecycle watches on txids.

Source

pub async fn add_depth_alarms( &self, txids: impl IntoIterator<Item = [u8; 32]>, depths: impl IntoIterator<Item = u32>, ) -> Result<(), StreamError>

Arm single-shot depth alarms over the cross product of txids and depths: each txid fires TxidDepthReached once it is depth confirmations deep, then self-evicts. Charges one unit per (txid, depth).

Depths must be >= 1; depths < 1 are dropped client-side. If that leaves no valid depths (or no txids), this is a no-op — importantly, it does not send an empty min_depths, which the server would otherwise reinterpret as a lifecycle add rather than a depth alarm.

Source

pub async fn remove_depth_alarms( &self, txids: impl IntoIterator<Item = [u8; 32]>, depths: impl IntoIterator<Item = u32>, ) -> Result<(), StreamError>

Remove depth alarms over the cross product of txids and depths. Depths < 1 are dropped client-side; an all-invalid (or empty) call is a no-op and never sends an empty min_depths (which would target lifecycle watches instead).

Source

pub async fn add_descriptor( &self, descriptor: impl Into<String>, gap_limit: u32, start: u32, ) -> Result<(), StreamError>

Expand a public output descriptor into a watch-set over the window [start, start + gap_limit). The server retains the descriptor → scripthashes membership, so the client owns gap-limit advancement by re-sending with an advanced start (the server reconciles the slid window) and can drop the whole window with remove_descriptor.

Source

pub async fn remove_descriptor( &self, descriptor: impl Into<String>, ) -> Result<(), StreamError>

Remove a descriptor previously added with add_descriptor, releasing every scripthash its window contributed whose last owner this drops. A scripthash the descriptor shares with a direct add_scripts or another descriptor stays watched. descriptor must byte-match the string it was added with; removing an unknown descriptor is a no-op.

Source

pub async fn add_script_prefixes( &self, prefixes: impl IntoIterator<Item = (Vec<u8>, u32)>, ) -> Result<(), StreamError>

Add privacy-preserving script-prefix buckets: each is a bits-bit prefix of sha256(scriptPubKey), carried as the top ceil(bits/8) bytes. The server delivers every tx in the 2^-bits bucket and the client filters locally, so the server learns only the bucket. Charged by coarseness (smaller bits costs more). bits must be in 1..=32 (the server buckets on the top 32 bits of the scripthash; wider is meaningless and silently dropped) and prefix exactly ceil(bits/8) bytes; the server additionally enforces its configured [streamprefixminbits, streamprefixmaxbits] range.

Source

pub async fn remove_script_prefixes( &self, prefixes: impl IntoIterator<Item = (Vec<u8>, u32)>, ) -> Result<(), StreamError>

Remove script-prefix buckets, releasing their quota.

Source

pub async fn add_silent_payments( &self, targets: impl IntoIterator<Item = SilentPaymentTarget>, ) -> Result<(), StreamError>

Register BIP 352 scan-key watch targets (Tier 2). The node runs the ECDH match server-side and pushes an Event::SilentPaymentMatched for every output paying one of them. Up to 16 targets per connection; each charges one watch-quota unit. Re-registering an existing target (same b_scan·G) refreshes its labels.

The scan_secret is a watch credential disclosed to the node — see SilentPaymentTarget. With the bitcoin feature (the default) each target’s scan_secret and spend_pubkey are validated as curve values up front (see SilentPaymentTarget::validate), so a malformed target is a deterministic InvalidArgument here rather than a silent server-side skip that returns Ok(()) while installing no watch. Without the feature this helper moves bytes only — validate the field widths yourself or let the server reject a malformed target.

Source

pub async fn remove_silent_payments( &self, scan_pubkeys: impl IntoIterator<Item = [u8; 33]>, ) -> Result<(), StreamError>

Remove scan-key watch targets by their identity b_scan·G (33-byte compressed, from SilentPaymentTarget::scan_pubkey), releasing quota.

Source

pub async fn set_categories(&self, categories: u32) -> Result<(), StreamError>

Adjust the live firehose category bitfield (see Categories). Applies immediately; does not affect the watch-set.

Source

pub async fn set_watch_options( &self, include_raw_tx: bool, ) -> Result<(), StreamError>

Set per-stream delivery options. With include_raw_tx = true, subsequent Event::ScriptMatched on this stream carry the full serialized matching transaction in raw_tx; false restores the default (empty). Applies immediately; does not affect the watch-set. Bandwidth- heavy — the value fields (amount) already cover the common case, so enable this only when you need the whole transaction.

When driving a ResilientWatch, prefer its set_watch_options so the opt-in is re-applied across reconnects.

Source

pub async fn set_cursor(&self, cursor: Cursor) -> Result<(), StreamError>

Mid-stream re-anchor: replay confirmed history forward from cursor, then resume live, without tearing down the watch-set. Rate-limited per principal; only one re-anchor drains at a time.

Ok(()) means the request was written to the control stream — not that the re-anchor ran. The outcome arrives in-band on the event stream as exactly one of (#439):

  • Event::CursorAccepted — admitted; confirmed-history replay follows it (watch for clamped to learn the server truncated the lower end and you must full-resync below earliest_replayed).
  • Event::CursorRejected — declined (rate-limited, concurrent re-anchor, empty cursor, or no block source); the live stream is unchanged. Retry, back off, or escalate to a full resnapshot per the reason.

A consumer that needs at-least-once delivery should drive its catch-up state machine off these events rather than treating Ok(()) as success.

Source

pub async fn rescan( &self, from_height: u32, to_height: u32, ) -> Result<(), StreamError>

Request a bounded historical rescan of the current watch-set over the inclusive height range [from_height, to_height]. The outcome arrives in-band on the event stream as Event::RescanAccepted / RescanRejected; on accept, confirmed watch-matches for the range follow in height order, terminated by RescanComplete.

A side query: it does not move the durable cursor and runs independently of the live tail or any in-flight re-anchor. The server span-caps the range and admits at most one rescan at a time (a second is rejected ConcurrentRescan). Ok(()) means the request was sent, not that it was admitted — drive off the in-band result.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more