bee/postage/mod.rs
1//! Postage batch CRUD + stamp metadata. Mirrors `pkg/postage` in
2//! bee-go.
3//!
4//! The endpoint methods live on [`PostageApi`] (get one from
5//! [`crate::Client::postage`]). Pure stamp math — `get_stamp_cost`,
6//! `get_stamp_effective_bytes`, etc. — is exposed as free functions
7//! since it has no I/O.
8//!
9//! # Batch-usability delay
10//!
11//! A batch is not usable for uploads immediately after
12//! [`PostageApi::create_postage_batch`] returns. Bee waits for N
13//! confirmations of the purchase transaction (typically 8) before
14//! flipping [`PostageBatch::usable`] to `true`. On Gnosis (5-second
15//! blocks) this is ~40 s; on Sepolia (12-second blocks) it can be 2-3
16//! minutes and occasionally longer.
17//!
18//! Poll [`PostageApi::get_postage_batch`] in a loop until `usable` is
19//! true, or supply the batch via an environment variable so tests can
20//! reuse a known-good batch. Uploading against a not-yet-usable batch
21//! returns HTTP 422 "stamp not usable", surfaced as
22//! [`crate::Error::Response`] with `status = 422`.
23//!
24//! # Dilute is one-way
25//!
26//! [`PostageApi::dilute_batch`] only allows depth to grow. Once a
27//! batch's depth is increased its previously-issued stamps remain
28//! valid; there is no way to shrink depth and reclaim funds.
29
30mod endpoints;
31mod stamp_math;
32mod stamper;
33mod types;
34
35use std::sync::Arc;
36
37use crate::client::Inner;
38
39pub use stamp_math::{
40 EFFECTIVE_SIZE_BREAKPOINTS, get_depth_for_size, get_stamp_cost, get_stamp_effective_bytes,
41 get_stamp_theoretical_bytes, get_stamp_usage,
42};
43pub use stamper::{
44 Envelope, MARSHALED_STAMP_LENGTH, MIN_DEPTH, NUM_BUCKETS, Stamper,
45 convert_envelope_to_marshaled_stamp, marshal_stamp,
46};
47pub use types::{BatchBucket, GlobalPostageBatch, PostageBatch, PostageBatchBuckets};
48
49/// Handle exposing the postage endpoints. Cheap to clone.
50#[derive(Clone, Debug)]
51pub struct PostageApi {
52 pub(crate) inner: Arc<Inner>,
53}
54
55impl PostageApi {
56 pub(crate) fn new(inner: Arc<Inner>) -> Self {
57 Self { inner }
58 }
59}