Skip to main content

Client

Struct Client 

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

Client for the Autonomi decentralized network.

Provides high-level APIs for storing and retrieving chunks and files on the network.

Implementations§

Source§

impl Client

Source

pub async fn prepare_chunk_payment( &self, content: Bytes, ) -> Result<Option<PreparedChunk>>

Prepare a single chunk for batch payment.

Collects quotes and uses node-reported prices without making any on-chain transaction. Returns Ok(None) if the chunk is already stored on the network.

§Errors

Returns an error if quote collection or payment construction fails.

Source

pub async fn batch_pay( &self, prepared: Vec<PreparedChunk>, ) -> Result<(Vec<PaidChunk>, String, u128)>

Pay for multiple chunks in a single EVM transaction.

Flattens all quote payments from the prepared chunks into one wallet.pay_for_quotes() call, then maps transaction hashes back to per-chunk PaymentProof bytes.

§Errors

Returns an error if the wallet is not configured or the on-chain payment fails. Returns (paid_chunks, storage_cost_atto, gas_cost_wei).

Source

pub async fn batch_upload_chunks( &self, chunks: Vec<Bytes>, ) -> Result<(Vec<XorName>, String, u128)>

Upload chunks in waves with pipelined EVM payments.

Processes chunks in waves of PAYMENT_WAVE_SIZE (64). Within each wave:

  1. Prepare: collect quotes for all chunks concurrently
  2. Pay: single EVM transaction for the whole wave
  3. Store: concurrent chunk replication to close group

Stores from wave N overlap with quote collection for wave N+1 via tokio::join!.

§Errors

Returns an error if any payment or store operation fails. Returns (addresses, total_storage_cost_atto, total_gas_cost_wei).

Source

pub async fn batch_upload_chunks_with_events( &self, chunks: Vec<Bytes>, progress: Option<&Sender<UploadEvent>>, stored_offset: usize, file_total: usize, resume_key: Option<&str>, ) -> Result<(Vec<XorName>, String, u128, WaveAggregateStats)>

Same as Client::batch_upload_chunks but sends UploadEvent::ChunkStored events as each chunk is stored, enabling per-chunk progress bars.

stored_offset is the number of chunks already stored in previous waves (so events report cumulative progress). file_total is the total chunk count across ALL waves (for the total field in events).

When resume_key is Some, per-wave payment proofs are persisted to <data_dir>/payments/single/<ts>_<hash(resume_key)> via crate::data::client::cached_single so that a partial-upload failure can be resumed on the next attempt without paying twice. The caller is responsible for deleting the cache entry on full success (typically upload_with_options in file.rs).

Source§

impl Client

Source

pub async fn chunk_put(&self, content: Bytes) -> Result<XorName>

Store a chunk on the Autonomi network with payment.

Checks if the chunk already exists before paying. If it does, returns the address immediately without incurring on-chain costs. Otherwise collects quotes, pays on-chain, then stores with proof to CLOSE_GROUP_MAJORITY peers.

§Errors

Returns an error if payment or the network operation fails.

Source

pub async fn chunk_put_with_proof( &self, content: Bytes, proof: Vec<u8>, target_peer: &PeerId, peer_addrs: &[MultiAddr], ) -> Result<XorName>

Store a chunk on the Autonomi network with a pre-built payment proof.

Sends to a single peer. Callers that need replication across the close group should use chunk_put_to_close_group instead.

§Errors

Returns an error if the network operation fails.

Source

pub async fn chunk_get(&self, address: &XorName) -> Result<Option<DataChunk>>

Retrieve a chunk from the Autonomi network.

Queries all peers in the close group for the chunk address, returning the first successful response. This handles the case where the storing peer differs from the first peer returned by DHT routing.

§Adaptive controller feedback

Each per-peer GET attempt is fed individually to the adaptive fetch limiter via controller().fetch.observe(...). This is deliberately finer-grained than wrapping the outer chunk_get with observe_op: when a chunk takes 6 peer tries to land, 5 of them are real capacity signals (timeouts / network errors) that should pull the cap down even if the chunk eventually succeeds. The outer Ok(_) would mask all five as a single Outcome::Success. See adaptive::Outcome for the per-attempt classification rules used below.

Callers should therefore NOT wrap chunk_get in observe_op.

§Errors

Returns an error if the network operation fails.

Source

pub async fn chunk_get_from_closest_peers( &self, address: &XorName, peer_count: usize, ) -> Result<Option<DataChunk>>

Retrieve a chunk from the requested number of closest peers.

Queries peers in XOR-distance order for the chunk address, returning the first successful response. This handles the case where the storing peer differs from the first peer returned by DHT routing.

§Errors

Returns an error if the network operation fails.

Source

pub async fn chunk_get_from_close_group( &self, address: &XorName, ) -> Result<Vec<ChunkPeerGetResult>>

Retrieve a chunk from every peer in the close group.

Unlike Client::chunk_get, this method does not return early after the first successful response. It returns one result per close-group peer, sorted from closest XOR distance to furthest.

§Errors

Returns an error if the close-group lookup fails.

Source

pub async fn chunk_get_from_closest_peer_group( &self, address: &XorName, peer_count: usize, ) -> Result<Vec<ChunkPeerGetResult>>

Retrieve a chunk from the requested number of closest peers.

Unlike Client::chunk_get_from_closest_peers, this method does not return early after the first successful response. It returns one result per queried peer, sorted from closest XOR distance to furthest.

§Errors

Returns an error if the DHT lookup fails.

Source

pub async fn chunk_exists(&self, address: &XorName) -> Result<bool>

Check if a chunk exists on the network.

§Errors

Returns an error if the network operation fails.

Source

pub async fn finalize_chunk( &self, prepared: PreparedChunk, tx_hash_map: &HashMap<QuoteHash, TxHash>, ) -> Result<XorName>

Finalize a single-chunk publish after an external signer has paid.

Single-chunk analogue of Client::finalize_upload. Takes a PreparedChunk (from Client::prepare_chunk_payment) and a quote_hash -> tx_hash map containing receipts for every non-zero quote in the chunk’s payment. Builds the PaymentProof and stores the chunk on CLOSE_GROUP_MAJORITY peers, returning its address.

Wave-batch payment shape only. Single-chunk publishes don’t need Merkle batching: one chunk’s worth of quotes is well below the wave-batch threshold.

§Errors

Returns an error if the proof construction fails (e.g. missing tx_hash for a non-zero quote) or if fewer than CLOSE_GROUP_MAJORITY peers accept the chunk.

Source§

impl Client

Source

pub async fn data_upload(&self, content: Bytes) -> Result<DataUploadResult>

Upload in-memory data to the network using self-encryption.

The content is encrypted and split into chunks, each stored as a content-addressed chunk on the network. Returns a DataMap that can be used to retrieve and decrypt the data.

§Errors

Returns an error if encryption fails or any chunk cannot be stored.

Source

pub async fn data_upload_with_mode( &self, content: Bytes, mode: PaymentMode, ) -> Result<DataUploadResult>

Upload in-memory data with a specific payment mode.

When mode is Auto and the chunk count >= threshold, or when mode is Merkle, this buffers all chunks and pays via a single merkle batch transaction. Otherwise falls back to per-chunk payment.

§Errors

Returns an error if encryption fails or any chunk cannot be stored.

Source

pub async fn data_prepare_upload( &self, content: Bytes, ) -> Result<PreparedUpload>

Phase 1 of external-signer data upload: encrypt and collect quotes.

Equivalent to Client::data_prepare_upload_with_visibility with Visibility::Private — see that method for details.

Source

pub async fn data_prepare_upload_with_visibility( &self, content: Bytes, visibility: Visibility, ) -> Result<PreparedUpload>

Phase 1 of external-signer data upload with explicit Visibility control.

Encrypts in-memory data via self-encryption, then collects storage quotes for each chunk without making any on-chain payment. Returns a PreparedUpload containing the data map and a PaymentIntent with the payment details for external signing.

When visibility is Visibility::Public, the serialized DataMap is bundled into the payment batch as an additional chunk and its address is recorded on the returned PreparedUpload. After Client::finalize_upload succeeds, that address is surfaced via crate::data::client::file::FileUploadResult::data_map_address so the uploader can share a single address from which anyone can retrieve the data.

Wave-batch payment only — the in-memory data path does not currently support merkle batching. Use Client::file_prepare_upload_with_visibility for merkle-eligible public uploads.

After the caller signs and submits the payment transaction, call Client::finalize_upload with the tx hashes to complete storage.

§Errors

Returns an error if encryption fails, DataMap serialization fails (public only), or quote collection fails.

Source

pub async fn data_map_store(&self, data_map: &DataMap) -> Result<[u8; 32]>

Store a DataMap on the network as a public chunk.

The serialized DataMap is stored as a regular content-addressed chunk. Anyone who knows the returned address can retrieve and use the DataMap to download the original data.

§Errors

Returns an error if serialization or the chunk store fails.

Source

pub async fn data_map_fetch(&self, address: &[u8; 32]) -> Result<DataMap>

Fetch a DataMap from the network by its chunk address.

Retrieves the chunk at address and deserializes it as a DataMap.

§Errors

Returns Error::NotFound if no chunk exists at address; other errors if retrieval or deserialization fails.

Source

pub async fn data_map_fetch_from_closest_peers( &self, address: &[u8; 32], peer_count: NonZeroUsize, ) -> Result<DataMap>

Fetch a DataMap from the network by trying the requested number of closest peers for the DataMap chunk.

§Errors

Returns Error::NotFound if no chunk exists at address; other errors if retrieval or deserialization fails.

Source

pub async fn data_download(&self, data_map: &DataMap) -> Result<Bytes>

Download and decrypt data from the network using its DataMap.

Retrieves all chunks referenced by the data map, then decrypts and reassembles the original content. Fetches chunks concurrently; the fan-out is sized by the adaptive controller’s fetch channel and ramps up under healthy conditions.

Large uploads produce a shrunk (child) DataMap whose infos() reference wrapper chunks rather than the root content chunks. Such a map is resolved back to its root form before download, keeping this primitive symmetric with data_upload.

Resolving a shrunk map bridges self-encryption’s synchronous fetcher onto the async network via block_in_place, so it requires a multi-threaded Tokio runtime; on a current-thread runtime it returns Error::Config instead of panicking. Flat maps (the common case) take neither path, so this requirement never applies to them.

§Errors

Returns an error if any chunk cannot be retrieved (a chunk absent from every queried peer surfaces as Error::NotFound), if decryption fails, or if a shrunk map must be resolved on a current-thread runtime.

Source§

impl Client

Source

pub async fn file_upload(&self, path: &Path) -> Result<FileUploadResult>

Upload a file to the network using streaming self-encryption.

Automatically selects merkle batch payment for files that produce 64+ chunks (saves gas). Encrypted chunks are spilled to a temp directory so peak memory stays at ~256 MB regardless of file size.

§Errors

Returns an error if the file cannot be read, encryption fails, or any chunk cannot be stored.

Source

pub async fn estimate_upload_cost( &self, path: &Path, mode: PaymentMode, progress: Option<Sender<UploadEvent>>, ) -> Result<UploadCostEstimate>

Estimate the cost of uploading a file without actually uploading.

Encrypts the file to determine chunk count and sizes, then requests a single quote from the network for a representative chunk. The per-chunk price is extrapolated to the total chunk count.

The estimate is fast (~2-5s) and does not require a wallet. Spilled chunks are cleaned up automatically when the function returns.

Gas cost is an advisory heuristic, not a live gas-oracle query. It is derived from realistic per-transaction budgets (GAS_PER_WAVE_TX, GAS_PER_MERKLE_TX) priced at ARBITRUM_GAS_PRICE_WEI. Real gas varies with network conditions.

Sampled chunk addresses are spread across the whole file (not the first N) so a shared leading prefix doesn’t bias the sample. When a sample returns a live quote the per-chunk price is extrapolated and the result is tagged CostEstimateConfidence::PricedSample.

When every sampled chunk is already stored the result is still Ok with storage_cost_atto: "0", tagged either CostEstimateConfidence::VerifiedAllAlreadyStored when the whole file was sampled (exactly free) or CostEstimateConfidence::AllSamplesAlreadyStoredIncomplete when the tail was unsampled (a best-effort guess that payment reconciles).

§Errors

Returns an error if the file cannot be read, encryption fails, or the network cannot provide a quote.

Source

pub async fn file_prepare_upload(&self, path: &Path) -> Result<PreparedUpload>

Phase 1 of external-signer upload: encrypt file and prepare chunks.

Equivalent to Client::file_prepare_upload_with_visibility with Visibility::Private — see that method for details.

Source

pub async fn file_prepare_upload_with_visibility( &self, path: &Path, visibility: Visibility, ) -> Result<PreparedUpload>

Phase 1 of external-signer upload with explicit Visibility control.

Equivalent to Client::file_prepare_upload_with_progress with progress: None — see that method for details.

Source

pub async fn file_prepare_upload_with_progress( &self, path: &Path, visibility: Visibility, progress: Option<Sender<UploadEvent>>, ) -> Result<PreparedUpload>

Phase 1 of external-signer upload with progress events.

Equivalent to Client::file_prepare_upload_with_mode with PaymentMode::Auto — see that method for details.

Source

pub async fn file_prepare_upload_with_mode( &self, path: &Path, visibility: Visibility, mode: PaymentMode, progress: Option<Sender<UploadEvent>>, ) -> Result<PreparedUpload>

Phase 1 of external-signer upload with an explicit PaymentMode.

Requires an EVM network (for contract price queries) but NOT a wallet. Returns a PreparedUpload containing the data map and either a PaymentIntent (wave-batch) or prepared merkle sub-batches that the external signer uses to construct and submit the on-chain payment transaction(s) — one per sub-batch (ADR-0003).

mode mirrors the wallet path’s Client::file_upload_with_mode: PaymentMode::Auto picks merkle at the chunk threshold, PaymentMode::Merkle forces merkle for ≥ 2 upload chunks (this is how tests exercise the external merkle flow with small files), and PaymentMode::Single forces wave-batch.

When visibility is Visibility::Public, the serialized DataMap is bundled into the payment batch as an additional chunk and its address is recorded on the returned PreparedUpload. After Client::finalize_upload (or _merkle) succeeds, that address is surfaced via FileUploadResult::data_map_address so the uploader can share a single address from which anyone can retrieve the file.

When progress is Some, UploadEvents are emitted on the channel during encryption (UploadEvent::Encrypting / UploadEvent::Encrypted) and per-chunk quoting (UploadEvent::ChunkQuoted). Storage events are emitted later by Client::finalize_upload_with_progress / Client::finalize_upload_merkle_with_progress.

Memory note: on the merkle path, chunk bodies stay in the on-disk encryption spill inside the returned PreparedUpload and are read back ≤ store-cap at a time during finalize, so peak RAM stays bounded (~256 MB) regardless of file size (ADR-0003). The spill directory lives as long as the PreparedUpload does. The wave-batch path — below the merkle threshold, so < ~64 × 4 MiB of chunks (unless PaymentMode::Single forces it for a larger file) — still holds its chunk bodies resident.

§Errors

Returns an error if there is insufficient disk space, the file cannot be read, encryption fails, or quote collection fails.

Source

pub async fn finalize_upload( &self, prepared: PreparedUpload, tx_hash_map: &HashMap<QuoteHash, TxHash>, ) -> Result<FileUploadResult>

Phase 2 of external-signer upload (wave-batch): finalize with externally-signed tx hashes.

Takes a PreparedUpload that used wave-batch payment and a map of quote_hash -> tx_hash provided by the external signer after on-chain payment. Builds payment proofs and stores chunks on the network.

§Errors

Returns an error if the prepared upload used merkle payment (use Client::finalize_upload_merkle instead), proof construction fails, or any chunk cannot be stored.

Source

pub async fn finalize_upload_with_progress( &self, prepared: PreparedUpload, tx_hash_map: &HashMap<QuoteHash, TxHash>, progress: Option<Sender<UploadEvent>>, ) -> Result<FileUploadResult>

Phase 2 of external-signer upload (wave-batch) with progress events.

Same as Client::finalize_upload but emits UploadEvent::ChunkStored on the provided channel as each chunk is successfully stored.

§Errors

Same as Client::finalize_upload.

Source

pub async fn finalize_upload_merkle( &self, prepared: PreparedUpload, winner_pool_hash: [u8; 32], ) -> Result<FileUploadResult>

Phase 2 of external-signer upload (merkle): finalize with winner pool hash.

The single-batch special case of Client::finalize_upload_merkle_multi: valid only for uploads that prepared as exactly one merkle sub-batch (any fresh upload below MAX_LEAVES chunks). Generates proofs and stores chunks on the network.

§Errors

Returns an error if the prepared upload used wave-batch payment (use Client::finalize_upload instead), was prepared as more than one sub-batch (use Client::finalize_upload_merkle_multi), or proof generation fails. Chunks still short of quorum after all retries surface as Error::PartialUpload carrying the stored and failed addresses — the same contract as Client::finalize_upload. Re-preparing the same file skips chunks that are already stored.

Source

pub async fn finalize_upload_merkle_with_progress( &self, prepared: PreparedUpload, winner_pool_hash: [u8; 32], progress: Option<Sender<UploadEvent>>, ) -> Result<FileUploadResult>

Phase 2 of external-signer upload (merkle) with progress events.

Same as Client::finalize_upload_merkle but emits UploadEvent::ChunkStored on the provided channel as each chunk is successfully stored.

§Errors

Same as Client::finalize_upload_merkle.

Source

pub async fn finalize_upload_merkle_multi( &self, prepared: PreparedUpload, winner_pool_hashes: Vec<Option<[u8; 32]>>, ) -> Result<FileUploadResult>

Phase 2 of external-signer upload (merkle): finalize with one winner pool hash per prepared sub-batch.

winner_pool_hashes aligns with ExternalPaymentInfo::Merkle::prepared_batches: entry i is the MerklePaymentMade winner hash of batch i’s on-chain payment, or None if the signer never paid that batch (e.g. the user abandoned the flow midway). Paid batches make forward progress: their proofs are folded — mirroring the wallet path’s multi-batch fold — and their chunks stored from the on-disk spill in a bounded fan-out; chunks of unpaid batches are reported through Error::PartialUpload (ADR-0003).

§Errors

Returns an error if the prepared upload used wave-batch payment, the hash count does not match the batch count, every entry is None, or proof generation fails. Chunks short of quorum after all retries — and all chunks of unpaid batches — surface as Error::PartialUpload carrying the stored and failed addresses. Re-preparing the same file skips chunks that are already stored.

Source

pub async fn finalize_upload_merkle_multi_with_progress( &self, prepared: PreparedUpload, winner_pool_hashes: Vec<Option<[u8; 32]>>, progress: Option<Sender<UploadEvent>>, ) -> Result<FileUploadResult>

Same as Client::finalize_upload_merkle_multi but emits UploadEvent::ChunkStored on the provided channel as each chunk is successfully stored.

§Errors

Same as Client::finalize_upload_merkle_multi.

Source

pub async fn finalize_upload_merkle_multi_resumable( &self, prepared: PreparedUpload, winner_pool_hashes: Vec<Option<[u8; 32]>>, ) -> Result<FinalizeOutcome>

Finalize an external-signer merkle upload, returning a resume handle if some chunks remain unstored after retries.

Behaves like Client::finalize_upload_merkle_multi, but instead of surfacing a quorum shortfall as Error::PartialUpload it returns FinalizeOutcome::Partial, carrying a MerkleFinalizeResume (inside FinalizeResume::Merkle) that owns the on-disk chunk spill and the already-signed payment proofs. The caller can hand that handle to Client::finalize_resume to store only the still-unstored chunks against the same on-chain payment — no re-quoting, no second signature, no double payment (#140).

Unlike the non-resumable method, every sub-batch must be paid (winner_pool_hashes all Some). A resume handle cannot acquire proofs for unpaid chunks, so a partially-paid finalize could never drain to FinalizeOutcome::Complete; partial payment is rejected up front. To finalize a partial payment, use Client::finalize_upload_merkle_multi, which reports the unpaid chunks through Error::PartialUpload.

§Errors

Returns an error if any sub-batch is unpaid, the winner-hash count does not match the prepared batches, the payment info is wave-batch rather than merkle, or payment finalization fails. Store failures are not errors here: a quorum shortfall — and a fatal store abort, which keeps its progress the same way — comes back as FinalizeOutcome::Partial.

Source

pub async fn finalize_upload_merkle_multi_resumable_with_progress( &self, prepared: PreparedUpload, winner_pool_hashes: Vec<Option<[u8; 32]>>, progress: Option<Sender<UploadEvent>>, ) -> Result<FinalizeOutcome>

Same as Client::finalize_upload_merkle_multi_resumable but emits UploadEvent::ChunkStored on the provided channel as each chunk is stored.

§Errors

Same as Client::finalize_upload_merkle_multi_resumable.

Source

pub async fn finalize_upload_resumable( &self, prepared: PreparedUpload, tx_hash_map: &HashMap<QuoteHash, TxHash>, ) -> Result<FinalizeOutcome>

Finalize an external-signer wave-batch upload, returning a resume handle if some chunks remain unstored after retries.

Behaves like Client::finalize_upload, but instead of surfacing a storage failure as Error::PartialUpload it returns FinalizeOutcome::Partial, carrying a WaveFinalizeResume (inside FinalizeResume::Wave) that owns the already-paid chunks still needing storage. The caller can hand that handle to Client::finalize_resume to re-store only those chunks against the same on-chain payment — no re-quoting, no second signature, no double payment (#140).

§Errors

Returns an error if a tx_hash is missing for a quote, the payment info is merkle rather than wave-batch, or payment finalization fails. A plain storage shortfall is not an error — it comes back as FinalizeOutcome::Partial.

Source

pub async fn finalize_upload_resumable_with_progress( &self, prepared: PreparedUpload, tx_hash_map: &HashMap<QuoteHash, TxHash>, progress: Option<Sender<UploadEvent>>, ) -> Result<FinalizeOutcome>

Same as Client::finalize_upload_resumable but emits UploadEvent::ChunkStored on the provided channel as each chunk is stored.

§Errors

Same as Client::finalize_upload_resumable.

Source

pub async fn finalize_resume( &self, resume: FinalizeResume, ) -> Result<FinalizeOutcome>

Resume an external-signer finalize that returned FinalizeOutcome::Partial, storing only the still-unstored chunks against the already-signed payment carried by the FinalizeResume handle.

No re-quoting and no new signature: the handle owns the retained chunk bodies (wave path) or the spill + merkle proofs (merkle path). Every chunk in the handle has its payment material, so the upload always can complete once the network cooperates. Safe to call repeatedly — each call stores what it can and either completes the upload (FinalizeOutcome::Complete) or hands back the remainder, so a caller can loop until it drains or gives up (#140).

Bound that loop. Store failures — including persistent ones, such as a chunk whose close group stays unreachable — surface as FinalizeOutcome::Partial on every call, never as Err, so an unbounded while let Partial loop will spin for as long as the failure persists. Cap the attempts (or apply backoff between them) and treat a handle that stops shrinking as stuck.

§Errors

Store failures are not errors — every store-side outcome, fatal aborts included, comes back as FinalizeOutcome::Partial with the payment material retained for retry. Err is reserved for failures outside the chunk store itself.

Source

pub async fn finalize_resume_with_progress( &self, resume: FinalizeResume, progress: Option<Sender<UploadEvent>>, ) -> Result<FinalizeOutcome>

Same as Client::finalize_resume but emits UploadEvent::ChunkStored as each remaining chunk is stored.

§Errors

Same as Client::finalize_resume.

Source

pub async fn file_upload_with_mode( &self, path: &Path, mode: PaymentMode, ) -> Result<FileUploadResult>

Upload a file with a specific payment mode.

Before encryption, checks that the temp directory has enough free disk space for the spilled chunks (~1.1× source file size).

Encrypted chunks are spilled to a temp directory during encryption so that only their 32-byte addresses stay in memory. At upload time, chunks are read back one wave at a time (~64 × 4 MB ≈ 256 MB peak).

§Errors

Returns an error if there is insufficient disk space, the file cannot be read, encryption fails, or any chunk cannot be stored.

Source

pub async fn file_upload_public_with_mode( &self, path: &Path, mode: PaymentMode, ) -> Result<FileUploadResult>

Upload a file publicly, storing the serialized DataMap as part of the same upload payment batch.

The returned FileUploadResult::data_map_address can be shared for public downloads via Client::data_map_fetch.

Source

pub async fn file_upload_with_progress( &self, path: &Path, mode: PaymentMode, progress: Option<Sender<UploadEvent>>, ) -> Result<FileUploadResult>

Upload a file with progress events sent to the given channel.

Same as Client::file_upload_with_mode but sends UploadEvents to the provided channel for UI progress feedback.

Source

pub async fn file_upload_public_with_progress( &self, path: &Path, mode: PaymentMode, progress: Option<Sender<UploadEvent>>, ) -> Result<FileUploadResult>

Public file upload with progress events.

Same as Client::file_upload_public_with_mode but sends UploadEvents to the provided channel for UI progress feedback.

Source

pub async fn file_download( &self, data_map: &DataMap, output: &Path, ) -> Result<u64>

Download and decrypt a file from the network, writing it to disk.

Uses streaming_decrypt so that only one batch of chunks lives in memory at a time, avoiding OOM on large files. Chunks are fetched concurrently within each batch, then decrypted data is written to disk incrementally.

Returns the number of bytes written.

§Panics

Requires a multi-threaded Tokio runtime (flavor = "multi_thread"). Will panic if called from a current_thread runtime because streaming_decrypt takes a synchronous callback that must bridge back to async via block_in_place.

§Errors

Returns an error if any chunk cannot be retrieved, decryption fails, or the file cannot be written.

Source

pub async fn file_download_from_closest_peers( &self, data_map: &DataMap, output: &Path, peer_count: NonZeroUsize, ) -> Result<u64>

Download and decrypt a file, trying the requested number of closest peers for every chunk fetch.

Returns the number of bytes written.

§Errors

Returns an error if any chunk cannot be retrieved, decryption fails, or the file cannot be written.

Source

pub async fn file_download_with_progress_from_closest_peers( &self, data_map: &DataMap, output: &Path, progress: Option<Sender<DownloadEvent>>, peer_count: NonZeroUsize, ) -> Result<u64>

Download and decrypt a file with progress events, trying the requested number of closest peers for every chunk fetch.

Same as Client::file_download_from_closest_peers but sends DownloadEvents for UI feedback.

§Errors

Returns an error if any chunk cannot be retrieved, decryption fails, or the file cannot be written.

Source

pub async fn file_download_with_progress_and_diagnostics_from_closest_peers( &self, data_map: &DataMap, output: &Path, progress: Option<Sender<DownloadEvent>>, peer_count: NonZeroUsize, diagnostics: Option<DownloadDiagnosticsSender>, ) -> Result<u64>

Download a file with progress and optional per-attempt JSONL diagnostics.

Passing None preserves the standard path without diagnostic records.

Source

pub async fn file_download_with_peer_report_from_closest_peers( &self, data_map: &DataMap, output: &Path, progress: Option<Sender<DownloadEvent>>, peer_count: NonZeroUsize, ) -> Result<FileDownloadWithPeerReport>

Download and decrypt a file with peer-health diagnostics.

Each file chunk is fetched by querying every selected closest peer, not by returning after the first successful peer. The returned report records which peers had each chunk and which did not. DataMap resolution still uses the normal early-return fetch path; diagnostics are for file chunks only.

§Errors

Returns an error if any chunk cannot be retrieved, decryption fails, or the file cannot be written.

Source

pub async fn file_download_with_progress( &self, data_map: &DataMap, output: &Path, progress: Option<Sender<DownloadEvent>>, ) -> Result<u64>

Download and decrypt a file to disk, with optional progress events.

Same as Client::file_download but sends DownloadEvents for UI feedback. Streams to a temp file (one decrypt batch resident at a time) and renames atomically on success. A TempDownload guard removes the staging file on any error path, including a panic.

Source

pub async fn file_download_to_sender( &self, data_map: &DataMap, sink: Sender<Result<Bytes, Error>>, progress: Option<Sender<DownloadEvent>>, ) -> Result<u64>

Download and decrypt a file, streaming the plaintext to sink instead of writing to disk.

Constant memory (one decrypt batch resident at a time); the caller receives bytes progressively as each batch decrypts, suitable for forwarding to an HTTP chunked body or a gRPC response stream. The bounded sink applies backpressure. If the receiver is dropped (e.g. the client disconnected) the download stops early and returns Error::Cancelled.

The channel item type is Result<Bytes, Error>, so the caller sets up:

let (tx, rx) = tokio::sync::mpsc::channel::<Result<Bytes, Error>>(8);

Typically the caller tokio::spawns this and converts the matching Receiver into its response stream. Requires a multi-threaded Tokio runtime (the decrypt iterator uses block_in_place).

Source§

impl Client

Source

pub fn should_use_merkle(&self, chunk_count: usize, mode: PaymentMode) -> bool

Determine whether to use merkle payments for a given batch size.

Source

pub async fn pay_for_merkle_batch( &self, addresses: &[[u8; 32]], data_type: u32, data_size: u64, ) -> Result<MerkleBatchPaymentResult>

Pay for a batch of chunks using merkle batch payment.

Builds a merkle tree, collects candidate pools, pays on-chain in one tx, and returns per-chunk proofs. Anything longer than MAX_LEAVES is split by merkle_batch_sizes and paid one transaction per sub-batch.

This low-level helper assumes the caller has already selected the addresses that need payment. User-facing upload paths first run the merkle upload planner to skip chunks already stored on the network.

§Errors

Returns an error if the batch is too small, candidate collection fails, on-chain payment fails, or proof generation fails.

Source

pub async fn prepare_merkle_batches_external( &self, addresses: &[[u8; 32]], data_type: u32, data_size: u64, cap: usize, ) -> Result<Vec<PreparedMerkleBatch>>

Phase 1 of external-signer merkle payment for an address set of any size: partition into MerkleTree-sized sub-batches and prepare each.

The partition follows merkle_batch_partitions_with_cap (≤ cap leaves per batch, singleton-remainder rebalanced), so the external signer pays one transaction per returned batch — the same shape the wallet path’s pay_for_merkle_multi_batch signs internally (ADR-0003). Batch order matches address order; the caller’s finalize supplies one winner hash per batch in the same order.

cap is clamped to 3..=MAX_LEAVES (see merkle_batch_sizes_with_cap for why 3 is the floor); production callers pass MAX_LEAVES, tests pass small caps to get real multi-batch flows from kilobyte files.

§Errors

Returns an error if any sub-batch’s candidate collection fails. Nothing is spent in either case — payment happens externally after this returns.

Source

pub async fn prepare_merkle_batch_external( &self, addresses: &[[u8; 32]], data_type: u32, data_size: u64, ) -> Result<PreparedMerkleBatch>

Phase 1 of external-signer merkle payment: prepare batch without paying.

Builds the merkle tree, collects candidate pools from the network, and returns the data needed for the on-chain payment call. Requires EvmNetwork but NOT a wallet.

§Errors

Returns Error::MerkleBatchTooLarge if addresses holds more than MAX_LEAVES entries. One prepared batch is one signature and one payment, so an oversized set has no valid external-signing form; the wallet path splits it across transactions instead (Client::prepare_merkle_batches_external is the partitioned equivalent for external signing). The check runs before any candidate collection, so nothing is spent.

Source§

impl Client

Source

pub async fn pay_for_storage( &self, address: &[u8; 32], data_size: u64, data_type: u32, ) -> Result<(Vec<u8>, Vec<(PeerId, Vec<MultiAddr>)>)>

Pay for storage and return the serialized payment proof bytes.

This orchestrates the full payment flow:

  1. Collect at least one witnessed quote plus ordered PUT targets
  2. Build single-node payment using node-reported prices (median 3x, others 0)
  3. Pay on-chain via the wallet
  4. Serialize PaymentProof with transaction hashes
§Errors

Returns an error if the wallet is not set, quotes cannot be collected, on-chain payment fails, or serialization fails. Returns (proof_bytes, put_targets). The peer list is the ordered PUT target set from quote planning: it starts with peers expected to accept the paid proof and can include non-quoted fallback peers beyond the quoted close group.

Source

pub async fn approve_token_spend(&self) -> Result<()>

Approve the wallet to spend tokens on the payment vault contract.

This must be called once before any payments can be made. Approves U256::MAX (unlimited) spending.

§Errors

Returns an error if the wallet is not set or the approval transaction fails.

Source§

impl Client

Source

pub async fn get_store_quotes( &self, address: &[u8; 32], data_size: u64, data_type: u32, ) -> Result<Vec<(PeerId, Vec<MultiAddr>, PaymentQuote, Amount, Option<Vec<u8>>)>>

Get storage quotes from the closest peers for a given address.

Builds a quorum-witnessed candidate set, still attempts to collect the close-group quote count, and returns the largest supported successful quote set. The single-node path now only requires one valid quote to proceed, but still pays the median quote from the selected set when more quotes were successfully fetched.

Returns Error::AlreadyStored early if CLOSE_GROUP_MAJORITY peers report the chunk is already stored.

§Errors

Returns an error if insufficient quotes can be collected.

Source§

impl Client

Source

pub fn from_node(node: Arc<P2PNode>, config: ClientConfig) -> Self

Create a client connected to the given P2P node.

Source

pub fn from_node_with_peer_cache( node: Arc<P2PNode>, config: ClientConfig, peer_cache_path: Option<PathBuf>, ) -> Self

Create a client connected to the given P2P node and attach an optional persistent peer cache path.

Source

pub async fn connect( bootstrap_peers: &[SocketAddr], config: ClientConfig, ) -> Result<Self>

Create a client connected to bootstrap peers.

Threads config.allow_loopback and config.ipv6 through to Network::new, which controls the saorsa-transport local and ipv6 flags on the underlying CoreNodeConfig. See ClientConfig::allow_loopback and ClientConfig::ipv6 for details.

§Errors

Returns an error if the P2P node cannot be created or bootstrapping fails.

Source

pub fn with_wallet(self, wallet: Wallet) -> Self

Set the wallet for payment operations.

Also populates the EVM network from the wallet so that token approvals work without a separate with_evm_network call.

Source

pub fn with_evm_network(self, network: Network) -> Self

Set the EVM network without requiring a wallet.

This enables token approval and contract interactions for external-signer flows where the private key lives outside Rust.

Source

pub fn config(&self) -> &ClientConfig

Get the client configuration.

Source

pub fn config_mut(&mut self) -> &mut ClientConfig

Get a mutable reference to the client configuration.

Source

pub fn network(&self) -> &Network

Get a reference to the network layer.

Source

pub async fn network_health(&self) -> NetworkHealth

Compute the live network-participation snapshot.

Convenience pass-through to Network::health — the single write-readiness implementation shared by all embedded-client consumers (antd, ant-gui, ant-ffi, ant-tui).

Source

pub fn wallet(&self) -> Option<&Arc<Wallet>>

Get the wallet, if configured.

Source

pub fn chunk_cache(&self) -> &ChunkCache

Get a reference to the chunk cache.

Source

pub fn controller(&self) -> &AdaptiveController

Adaptive concurrency controller. Hot loops read controller().<channel>.current() to size their fan-out and call .observe(...) on each completion.

Source

pub fn save_adaptive_snapshot(&self)

Persist the current adaptive snapshot to disk so the next Client::connect warm-starts at the learned values instead of cold defaults. Best effort — failures log and are discarded. Idempotent. Safe to call from a Drop impl or an explicit shutdown hook.

Source

pub async fn save_peer_cache(&self)

Persist currently connected peers that have Direct-tagged addresses in the DHT. Best effort; failures are logged and do not affect the client operation that just completed.

Trait Implementations§

Source§

impl Drop for Client

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl !Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl !UnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl UnsafeUnpin for Client

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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