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
impl WatchHandle
Sourcepub async fn send_control(
&self,
ctrl: SubscribeControl,
) -> Result<(), StreamError>
pub async fn send_control( &self, ctrl: SubscribeControl, ) -> Result<(), StreamError>
Send a raw SubscribeControl message.
Sourcepub async fn add_scripts(
&self,
items: impl IntoIterator<Item = ([u8; 32], Option<u64>)>,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_scripts(
&self,
scripthashes: impl IntoIterator<Item = [u8; 32]>,
) -> Result<(), StreamError>
pub async fn remove_scripts( &self, scripthashes: impl IntoIterator<Item = [u8; 32]>, ) -> Result<(), StreamError>
Remove scripthashes from the watch-set, releasing their quota.
Sourcepub async fn add_outpoints(
&self,
outpoints: impl IntoIterator<Item = ([u8; 32], u32)>,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_outpoints(
&self,
outpoints: impl IntoIterator<Item = ([u8; 32], u32)>,
) -> Result<(), StreamError>
pub async fn remove_outpoints( &self, outpoints: impl IntoIterator<Item = ([u8; 32], u32)>, ) -> Result<(), StreamError>
Remove outpoints from the watch-set, releasing their quota.
Sourcepub async fn add_tx_lifecycle(
&self,
txids: impl IntoIterator<Item = [u8; 32]>,
auto_close: AutoClose,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_tx_lifecycle(
&self,
txids: impl IntoIterator<Item = [u8; 32]>,
) -> Result<(), StreamError>
pub async fn remove_tx_lifecycle( &self, txids: impl IntoIterator<Item = [u8; 32]>, ) -> Result<(), StreamError>
Remove lifecycle watches on txids.
Sourcepub async fn add_depth_alarms(
&self,
txids: impl IntoIterator<Item = [u8; 32]>,
depths: impl IntoIterator<Item = u32>,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_depth_alarms(
&self,
txids: impl IntoIterator<Item = [u8; 32]>,
depths: impl IntoIterator<Item = u32>,
) -> Result<(), StreamError>
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).
Sourcepub async fn add_descriptor(
&self,
descriptor: impl Into<String>,
gap_limit: u32,
start: u32,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_descriptor(
&self,
descriptor: impl Into<String>,
) -> Result<(), StreamError>
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.
Sourcepub async fn add_script_prefixes(
&self,
prefixes: impl IntoIterator<Item = (Vec<u8>, u32)>,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_script_prefixes(
&self,
prefixes: impl IntoIterator<Item = (Vec<u8>, u32)>,
) -> Result<(), StreamError>
pub async fn remove_script_prefixes( &self, prefixes: impl IntoIterator<Item = (Vec<u8>, u32)>, ) -> Result<(), StreamError>
Remove script-prefix buckets, releasing their quota.
Sourcepub async fn add_silent_payments(
&self,
targets: impl IntoIterator<Item = SilentPaymentTarget>,
) -> Result<(), StreamError>
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.
Sourcepub async fn remove_silent_payments(
&self,
scan_pubkeys: impl IntoIterator<Item = [u8; 33]>,
) -> Result<(), StreamError>
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.
Sourcepub async fn set_categories(&self, categories: u32) -> Result<(), StreamError>
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.
Sourcepub async fn set_watch_options(
&self,
include_raw_tx: bool,
) -> Result<(), StreamError>
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.
Sourcepub async fn set_cursor(&self, cursor: Cursor) -> Result<(), StreamError>
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 forclampedto learn the server truncated the lower end and you must full-resync belowearliest_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 thereason.
A consumer that needs at-least-once delivery should drive its catch-up
state machine off these events rather than treating Ok(()) as success.
Sourcepub async fn rescan(
&self,
from_height: u32,
to_height: u32,
) -> Result<(), StreamError>
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§
impl Freeze for WatchHandle
impl RefUnwindSafe for WatchHandle
impl Send for WatchHandle
impl Sync for WatchHandle
impl Unpin for WatchHandle
impl UnsafeUnpin for WatchHandle
impl UnwindSafe for WatchHandle
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
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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request