chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
use super ::build_response ;
2026-03-22 03:30:21 +00:00
use crate ::config ::Config ;
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
use crate ::content_server ;
2026-03-22 03:30:21 +00:00
use anyhow ::Result ;
use hyper ::{ Response , StatusCode } ;
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
use super ::{ is_valid_app_id , ApiHandler } ;
2026-03-22 03:30:21 +00:00
impl ApiHandler {
pub ( super ) async fn handle_content_catalog ( config : & Config ) -> Result < Response < hyper ::Body > > {
match content_server ::load_catalog ( & config . data_dir ) . await {
Ok ( catalog ) = > {
// Only expose public metadata for available items
let items : Vec < serde_json ::Value > = catalog
. items
. iter ( )
. filter ( | i | ! matches! ( i . availability , content_server ::Availability ::Nobody ) )
. map ( | i | {
serde_json ::json! ( {
" id " : i . id ,
" filename " : i . filename ,
" mime_type " : i . mime_type ,
" size_bytes " : i . size_bytes ,
" description " : i . description ,
" access " : i . access ,
} )
} )
. collect ( ) ;
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
let body =
serde_json ::to_vec ( & serde_json ::json! ( { " items " : items } ) ) . unwrap_or_default ( ) ;
Ok ( build_response (
StatusCode ::OK ,
" application/json " ,
hyper ::Body ::from ( body ) ,
) )
2026-03-22 03:30:21 +00:00
}
Err ( e ) = > {
let body = serde_json ::json! ( { " error " : e . to_string ( ) } ) ;
let body_bytes = serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ;
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
Ok ( build_response (
StatusCode ::INTERNAL_SERVER_ERROR ,
" application/json " ,
hyper ::Body ::from ( body_bytes ) ,
) )
2026-03-22 03:30:21 +00:00
}
}
}
pub ( super ) async fn handle_content_request (
path : & str ,
headers : & hyper ::HeaderMap ,
config : & Config ,
) -> Result < Response < hyper ::Body > > {
let content_id = path . strip_prefix ( " /content/ " ) . unwrap_or ( " " ) ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) {
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid content ID " ) ,
) ) ;
2026-03-22 03:30:21 +00:00
}
// Extract payment token from X-Payment-Token header
let payment_token = headers
. get ( " x-payment-token " )
. and_then ( | v | v . to_str ( ) . ok ( ) )
. map ( | s | s . to_string ( ) ) ;
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
// Extract a paid-entitlement gate token from X-Invoice-Hash (Lightning)
// or X-Onchain-Address (on-chain) — both authorize the download if this
// node issued+settled them, and both resolve against the same shared
// entitlement store keyed by the token string (#46).
let invoice_hash = headers
. get ( " x-invoice-hash " )
. and_then ( | v | v . to_str ( ) . ok ( ) )
. map ( | s | s . to_string ( ) )
. or_else ( | | {
headers
. get ( " x-onchain-address " )
. and_then ( | v | v . to_str ( ) . ok ( ) )
. map ( | s | s . to_string ( ) )
} ) ;
2026-03-22 03:30:21 +00:00
// Extract federation peer DID from X-Federation-DID header
let peer_did = headers
. get ( " x-federation-did " )
. and_then ( | v | v . to_str ( ) . ok ( ) )
. map ( | s | s . to_string ( ) ) ;
// Parse Range header for streaming support
let range = headers
. get ( " range " )
. and_then ( | v | v . to_str ( ) . ok ( ) )
. and_then ( content_server ::parse_range_header ) ;
match content_server ::serve_content (
& config . data_dir ,
content_id ,
payment_token . as_deref ( ) ,
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
invoice_hash . as_deref ( ) ,
2026-03-22 03:30:21 +00:00
peer_did . as_deref ( ) ,
range ,
)
. await
{
Ok ( content_server ::ServeResult ::Ok ( bytes , mime_type ) ) = > {
let len = bytes . len ( ) ;
Ok ( Response ::builder ( )
. status ( StatusCode ::OK )
. header ( " Content-Type " , mime_type )
. header ( " Content-Length " , len . to_string ( ) )
. header ( " Accept-Ranges " , " bytes " )
. body ( hyper ::Body ::from ( bytes ) )
. unwrap ( ) )
}
Ok ( content_server ::ServeResult ::Partial {
bytes ,
mime_type ,
start ,
end ,
total ,
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
} ) = > Ok ( Response ::builder ( )
. status ( StatusCode ::PARTIAL_CONTENT )
. header ( " Content-Type " , mime_type )
. header ( " Content-Length " , bytes . len ( ) . to_string ( ) )
. header (
" Content-Range " ,
format! ( " bytes {} - {} / {} " , start , end , total ) ,
)
. header ( " Accept-Ranges " , " bytes " )
. body ( hyper ::Body ::from ( bytes ) )
. unwrap ( ) ) ,
2026-03-22 03:30:21 +00:00
Ok ( content_server ::ServeResult ::PaymentRequired ( price_sats ) ) = > {
let body = serde_json ::json! ( {
" error " : " Payment required " ,
" price_sats " : price_sats ,
" payment_header " : " X-Payment-Token " ,
} ) ;
let body_bytes = serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ;
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
Ok ( build_response (
StatusCode ::PAYMENT_REQUIRED ,
" application/json " ,
hyper ::Body ::from ( body_bytes ) ,
) )
2026-03-22 03:30:21 +00:00
}
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
Ok ( content_server ::ServeResult ::Forbidden ) = > Ok ( build_response (
StatusCode ::FORBIDDEN ,
" application/json " ,
2026-06-19 05:03:18 -04:00
hyper ::Body ::from (
r # "{"error":"This file is shared with the host's federation peers only. Federate with that node (exchange invites) so it recognizes you, then try again."}"# ,
) ,
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
) ) ,
Ok ( content_server ::ServeResult ::NotFound ) | Err ( _ ) = > Ok ( build_response (
StatusCode ::NOT_FOUND ,
" text/plain " ,
hyper ::Body ::from ( " Content not found " ) ,
) ) ,
2026-03-22 03:30:21 +00:00
}
}
feat: botfights, discover, mobile gamepad, content handler, package config updates
Miscellaneous improvements: botfights manifest, discover page curated
apps, mobile gamepad enhancements, content HTTP handler, package
install config updates, health monitor tweaks, shared content UI,
container specs and image version updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:11:41 -04:00
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
/// Seller side (#46): mint a Lightning invoice for a paid catalog item so a
/// buyer can pay from any external wallet. Path: GET /content/{id}/invoice.
/// Records a pending entitlement keyed by the invoice's payment hash.
2026-06-17 19:50:46 -04:00
pub ( super ) async fn handle_content_invoice ( & self , path : & str ) -> Result < Response < hyper ::Body > > {
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
let content_id = path
. strip_prefix ( " /content/ " )
. and_then ( | s | s . strip_suffix ( " /invoice " ) )
. unwrap_or ( " " ) ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid content ID " ) ,
) ) ;
}
let catalog = content_server ::load_catalog ( & self . config . data_dir )
. await
. unwrap_or_default ( ) ;
let item = match catalog . items . iter ( ) . find ( | i | i . id = = content_id ) {
Some ( i ) = > i ,
None = > {
return Ok ( build_response (
StatusCode ::NOT_FOUND ,
" text/plain " ,
hyper ::Body ::from ( " Content not found " ) ,
) )
}
} ;
let price_sats = match & item . access {
2026-07-23 16:15:11 -04:00
content_server ::AccessControl ::Paid { price_sats , .. } = > * price_sats ,
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
_ = > {
// Not a paid item — no invoice to issue.
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"Item is not paid"}"# ) ,
) ) ;
}
} ;
2026-07-23 16:15:11 -04:00
if ! content_server ::method_accepted ( & item . access , " lightning " ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"The seller does not accept Lightning for this item"}"# ) ,
) ) ;
}
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
let memo = format! ( " Archipelago peer file {content_id} " ) ;
match self
. rpc_handler
. create_invoice ( price_sats as i64 , & memo )
. await
{
Ok ( ( bolt11 , payment_hash ) ) if ! payment_hash . is_empty ( ) = > {
crate ::content_invoice ::record_pending ( & payment_hash , content_id , price_sats ) . await ;
let body = serde_json ::json! ( {
" bolt11 " : bolt11 ,
" payment_hash " : payment_hash ,
" price_sats " : price_sats ,
} ) ;
Ok ( build_response (
StatusCode ::OK ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
Ok ( _ ) = > Ok ( build_response (
StatusCode ::INTERNAL_SERVER_ERROR ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"Invoice missing payment hash"}"# ) ,
) ) ,
Err ( e ) = > {
2026-06-18 09:23:56 -04:00
// Surface the FULL error chain ({:#}) — the generic top-level
// message hid the real cause (e.g. the LND REST connection
// failing), which made this 503 undiagnosable.
tracing ::warn! ( " content invoice creation failed: {e:#} " ) ;
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
let body = serde_json ::json! ( {
2026-06-18 09:23:56 -04:00
" error " : format ! ( " Could not create invoice: {e:#} " )
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
} ) ;
Ok ( build_response (
StatusCode ::SERVICE_UNAVAILABLE ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
}
}
/// Seller side (#46): report whether a previously-issued invoice has settled.
/// Path: GET /content/{id}/invoice-status/{payment_hash}. On settlement the
/// entitlement is marked paid so the buyer can then download the file.
pub ( super ) async fn handle_content_invoice_status (
& self ,
path : & str ,
) -> Result < Response < hyper ::Body > > {
let rest = path . strip_prefix ( " /content/ " ) . unwrap_or ( " " ) ;
let ( content_id , payment_hash ) = match rest . split_once ( " /invoice-status/ " ) {
Some ( ( id , hash ) ) = > ( id , hash ) ,
None = > {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid request " ) ,
) )
}
} ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) | | payment_hash . is_empty ( ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid request " ) ,
) ) ;
}
// The hash must be one we issued for exactly this content item.
match crate ::content_invoice ::lookup ( payment_hash ) . await {
Some ( ( cid , _ ) ) if cid = = content_id = > { }
_ = > {
return Ok ( build_response (
StatusCode ::NOT_FOUND ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"Unknown invoice"}"# ) ,
) )
}
}
// Already paid? Otherwise ask our LND and persist the result.
let mut paid = crate ::content_invoice ::is_paid_for ( payment_hash , content_id ) . await ;
if ! paid {
if let Ok ( true ) = self . rpc_handler . invoice_is_settled ( payment_hash ) . await {
crate ::content_invoice ::mark_paid ( payment_hash ) . await ;
paid = true ;
}
}
let body = serde_json ::json! ( { " paid " : paid } ) ;
Ok ( build_response (
StatusCode ::OK ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
/// Seller side (#46): issue a fresh on-chain address for a paid catalog item
/// so a buyer can pay on-chain. Path: GET /content/{id}/onchain. Records a
/// pending entitlement keyed by the address; price doubles as expected amount.
2026-06-17 19:50:46 -04:00
pub ( super ) async fn handle_content_onchain ( & self , path : & str ) -> Result < Response < hyper ::Body > > {
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
let content_id = path
. strip_prefix ( " /content/ " )
. and_then ( | s | s . strip_suffix ( " /onchain " ) )
. unwrap_or ( " " ) ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid content ID " ) ,
) ) ;
}
let catalog = content_server ::load_catalog ( & self . config . data_dir )
. await
. unwrap_or_default ( ) ;
let price_sats = match catalog . items . iter ( ) . find ( | i | i . id = = content_id ) {
Some ( i ) = > match & i . access {
2026-07-23 16:15:11 -04:00
content_server ::AccessControl ::Paid { price_sats , .. } = > {
if ! content_server ::method_accepted ( & i . access , " onchain " ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" application/json " ,
hyper ::Body ::from (
r # "{"error":"The seller does not accept on-chain payment for this item"}"# ,
) ,
) ) ;
}
* price_sats
}
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
_ = > {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"Item is not paid"}"# ) ,
) )
}
} ,
None = > {
return Ok ( build_response (
StatusCode ::NOT_FOUND ,
" text/plain " ,
hyper ::Body ::from ( " Content not found " ) ,
) )
}
} ;
match self . rpc_handler . new_onchain_address ( ) . await {
Ok ( address ) if ! address . is_empty ( ) = > {
crate ::content_invoice ::record_pending ( & address , content_id , price_sats ) . await ;
let body = serde_json ::json! ( {
" address " : address ,
" amount_sats " : price_sats ,
} ) ;
Ok ( build_response (
StatusCode ::OK ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
_ = > {
let body = serde_json ::json! ( {
" error " : " Could not generate an on-chain address (is the wallet ready?) "
} ) ;
Ok ( build_response (
StatusCode ::SERVICE_UNAVAILABLE ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
}
}
/// Seller side (#46): report whether an on-chain payment to a previously-
/// issued address has arrived (>= price, >= 1 conf). Path:
/// GET /content/{id}/onchain-status/{address}. Marks the entitlement paid.
pub ( super ) async fn handle_content_onchain_status (
& self ,
path : & str ,
) -> Result < Response < hyper ::Body > > {
let rest = path . strip_prefix ( " /content/ " ) . unwrap_or ( " " ) ;
let ( content_id , address ) = match rest . split_once ( " /onchain-status/ " ) {
Some ( ( id , addr ) ) = > ( id , addr ) ,
None = > {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid request " ) ,
) )
}
} ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) | | address . is_empty ( ) {
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid request " ) ,
) ) ;
}
// The address must be one we issued for exactly this content item.
let price = match crate ::content_invoice ::lookup ( address ) . await {
Some ( ( cid , price ) ) if cid = = content_id = > price ,
_ = > {
return Ok ( build_response (
StatusCode ::NOT_FOUND ,
" application/json " ,
hyper ::Body ::from ( r # "{"error":"Unknown address"}"# ) ,
) )
}
} ;
let mut paid = crate ::content_invoice ::is_paid_for ( address , content_id ) . await ;
if ! paid {
if let Ok ( true ) = self . rpc_handler . onchain_received ( address , price ) . await {
crate ::content_invoice ::mark_paid ( address ) . await ;
paid = true ;
}
}
let body = serde_json ::json! ( { " paid " : paid } ) ;
Ok ( build_response (
StatusCode ::OK ,
" application/json " ,
hyper ::Body ::from ( serde_json ::to_vec ( & body ) . unwrap_or_default ( ) ) ,
) )
}
feat: botfights, discover, mobile gamepad, content handler, package config updates
Miscellaneous improvements: botfights manifest, discover page curated
apps, mobile gamepad enhancements, content HTTP handler, package
install config updates, health monitor tweaks, shared content UI,
container specs and image version updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:11:41 -04:00
/// Serve a degraded preview of paid content (blurred image or first 2% of video).
pub ( super ) async fn handle_content_preview (
path : & str ,
config : & Config ,
) -> Result < Response < hyper ::Body > > {
// Path format: /content/{id}/preview
let content_id = path
. strip_prefix ( " /content/ " )
. and_then ( | s | s . strip_suffix ( " /preview " ) )
. unwrap_or ( " " ) ;
if content_id . is_empty ( ) | | ! is_valid_app_id ( content_id ) {
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
return Ok ( build_response (
StatusCode ::BAD_REQUEST ,
" text/plain " ,
hyper ::Body ::from ( " Invalid content ID " ) ,
) ) ;
feat: botfights, discover, mobile gamepad, content handler, package config updates
Miscellaneous improvements: botfights manifest, discover page curated
apps, mobile gamepad enhancements, content HTTP handler, package
install config updates, health monitor tweaks, shared content UI,
container specs and image version updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:11:41 -04:00
}
match content_server ::serve_content_preview ( & config . data_dir , content_id ) . await {
Ok ( content_server ::PreviewResult ::FullContent ( bytes , mime_type ) ) = > {
let len = bytes . len ( ) ;
Ok ( Response ::builder ( )
. status ( StatusCode ::OK )
. header ( " Content-Type " , mime_type )
. header ( " Content-Length " , len . to_string ( ) )
. body ( hyper ::Body ::from ( bytes ) )
. unwrap ( ) )
}
Ok ( content_server ::PreviewResult ::BlurPreview ( bytes , mime_type ) ) = > {
let len = bytes . len ( ) ;
Ok ( Response ::builder ( )
. status ( StatusCode ::OK )
. header ( " Content-Type " , mime_type )
. header ( " Content-Length " , len . to_string ( ) )
. header ( " X-Content-Preview " , " blur " )
. body ( hyper ::Body ::from ( bytes ) )
. unwrap ( ) )
}
Ok ( content_server ::PreviewResult ::TruncatedPreview ( bytes , mime_type , total_size ) ) = > {
let len = bytes . len ( ) ;
Ok ( Response ::builder ( )
. status ( StatusCode ::OK )
. header ( " Content-Type " , mime_type )
. header ( " Content-Length " , len . to_string ( ) )
. header ( " X-Content-Preview " , " truncated " )
. header ( " X-Content-Total-Size " , total_size . to_string ( ) )
. body ( hyper ::Body ::from ( bytes ) )
. unwrap ( ) )
}
feat(wallet,content,seed): Fedimint dual-ecash, paid content streaming, seed ceremony
- Fedimint ecash alongside Cashu: fedimint-clientd (fmcd) HTTP bridge,
fedimint_client, fedimint RPC, wallet wiring
- Paid peer content: content invoices + streaming content server + content RPCs
- Seed-phrase ceremony/reveal RPCs and CLI ceremony tool
- LND wallet, mesh status/messaging, app-stack (netbird HTTPS), and
decoupled-update wiring; Fedimint Client core app in catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:21:07 -04:00
Ok ( content_server ::PreviewResult ::PreviewUnavailable ) = > Ok ( Response ::builder ( )
. status ( StatusCode ::UNSUPPORTED_MEDIA_TYPE )
. header ( " Content-Type " , " text/plain " )
. header ( " X-Content-Preview " , " unavailable " )
. body ( hyper ::Body ::from (
" Preview unavailable for this media (needs re-encoding) " ,
) )
. unwrap ( ) ) ,
chore(ci): rustfmt + clippy clean-up to unblock the Rust CI job
The .github/workflows/ci.yml Rust job runs cargo fmt --check, clippy
with -D warnings, and tests. All three were failing. This commit:
- Applies rustfmt across the tree (the bulk of the diff — untouched
since the last toolchain bump, so a wide sweep was unavoidable).
- Fixes the correctness-level clippy errors:
container/bitcoin_simulator.rs wildcard-in-or-pattern
container/manifest.rs from_str rename to parse (reserved name)
container/podman_client.rs .get(0) -> .first()
container/runtime.rs manual += collapse
archipelago/src/constants.rs doc-comment → module-doc
api/rpc/package/install.rs stray /// comment above a non-item
container/docker_packages.rs redundant field init
streaming/advertisement.rs missing Metric import in tests
tests/orchestration_tests.rs `vec!` in non-Vec contexts
mesh/listener/dispatch.rs unused store_plain_message import
api/rpc/tor/mod.rs and mesh/steganography.rs: push-after-new → vec!
- Quiets wide legacy surfaces with crate-level allows in main.rs for
stylistic lints (too_many_arguments, type_complexity, doc indent,
enum variant prefix, wildcard-in-or, assertions-on-constants,
drop_non_drop, unused_io_amount, ptr_arg) — these fired in dozens
of places with no correctness payoff and have been churning every
toolchain bump.
- Tags intentional-dead-code helpers: wallet/ and streaming/ modules
are WIP, mesh::send_chunked_payload and DM_V1_MARKER are kept for
rollback compatibility, vpn::get_nostr_vpn_status is surface-area
for a not-yet-landed RPC.
cargo fmt --check, cargo clippy --all-targets --all-features
-- -D warnings, and cargo test --all-features now all pass locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:23:46 -04:00
Ok ( content_server ::PreviewResult ::NotFound ) | Err ( _ ) = > Ok ( build_response (
StatusCode ::NOT_FOUND ,
" text/plain " ,
hyper ::Body ::from ( " Preview not available " ) ,
) ) ,
feat: botfights, discover, mobile gamepad, content handler, package config updates
Miscellaneous improvements: botfights manifest, discover page curated
apps, mobile gamepad enhancements, content HTTP handler, package
install config updates, health monitor tweaks, shared content UI,
container specs and image version updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:11:41 -04:00
}
}
2026-03-22 03:30:21 +00:00
}