Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@
tag sets when it is built, so build it after those tags are set.
Both `send_targeted_response` and the `TargetedResponseSender` alias are
re-exported from `contextvm_sdk::transport`.
- Transparent-lifecycle payment gating on the server transport: a priced invocation now
triggers `notifications/payment_required` and reaches the MCP handler only after the
configured payment processor verifies settlement, with `notifications/payment_accepted`
sent on the way. A dynamic pricing callback can reject the invocation (emitting
`notifications/payment_rejected`) or waive payment (forwarding it untouched). Duplicate
deliveries of the same request event share one payment rather than charging twice, and
once an invoice has been issued a later failure never re-charges a client who already
paid: a verified payment is delivered even if the acceptance notification cannot be
published. Because a payment can outlast the 60 s stale-route sweep, the transport now
captures the request's routing fields when it emits `payment_required` and delivers the
eventual result from that capture when the route is gone.
`payment_notification_sender` returns the payment-notification publish as an injectable
closure for a detached middleware, alongside the existing `targeted_response_sender`.
The middleware is not registered by default; registration arrives with the payments
configuration entry point.

### Fixed

Expand Down Expand Up @@ -82,6 +97,11 @@
construct `ClientSession` via `ClientSession::new` and destructure either struct with
`..` rather than exhaustively. This matches `InboundContext`, which is already
`#[non_exhaustive]`, and makes future field additions non-breaking.
- The server transport's inbound middleware context now carries a per-event cancellation
token derived from the transport's shutdown token, so a middleware doing long-running
work stops when the transport closes. `send_notification`'s body moved into a shared
publish that both it and the new injectable sender use, so the two cannot drift. A
gated (dropped) request now releases the open-stream slot it reserved.

## [0.2.2] - 2026-07-29

Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ required-features = ["rmcp", "test-utils"]
name = "payments_negotiation_e2e"
required-features = ["test-utils"]

[[test]]
name = "payments_transparent_e2e"
required-features = ["test-utils"]

[[test]]
name = "rmcp_handshake_survival"
required-features = ["rmcp", "test-utils"]
Expand Down
3 changes: 3 additions & 0 deletions src/payments/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub const PMI_BITCOIN_LIGHTNING_BOLT11: &str = "bitcoin-lightning-bolt11";

/// Default payment TTL when `payment_required` carries no `ttl` (ms). Mirrors the server default.
pub const DEFAULT_PAYMENT_TTL_MS: u64 = 300_000;
/// Default cap on concurrently tracked pending-payment request ids (a DoS/memory guardrail).
pub const DEFAULT_MAX_PENDING_PAYMENTS: usize = 1000;
/// Default synthetic-progress heartbeat interval (ms). Half the 60 s MCP request timeout.
pub const DEFAULT_SYNTHETIC_PROGRESS_INTERVAL_MS: u64 = 30_000;
/// Per-map cap for the `AuthorizationStore` LRUs. Equals [`core::constants::DEFAULT_LRU_SIZE`](crate::core::constants::DEFAULT_LRU_SIZE).
Expand Down Expand Up @@ -46,6 +48,7 @@ mod tests {
fn pmi_and_ttls_match_ts_sdk() {
assert_eq!(PMI_BITCOIN_LIGHTNING_BOLT11, "bitcoin-lightning-bolt11");
assert_eq!(DEFAULT_PAYMENT_TTL_MS, 300_000);
assert_eq!(DEFAULT_MAX_PENDING_PAYMENTS, 1000);
assert_eq!(DEFAULT_SYNTHETIC_PROGRESS_INTERVAL_MS, 30_000);
assert_eq!(AUTH_STORE_MAX_ENTRIES, 5000);
// Mirrors the core LRU default; keep the two in lockstep.
Expand Down
5 changes: 5 additions & 0 deletions src/payments/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub mod authorization_store;
pub mod canonical;
pub mod constants;
pub mod errors;
pub mod server_payments;
pub(crate) mod server_payments_utils;
pub mod tags;
pub mod traits;
pub mod types;
Expand All @@ -32,6 +34,9 @@ pub use canonical::{
CanonicalInvocationIdentity,
};
pub use errors::PaymentError;
pub use server_payments::{
create_server_payments_middleware, ServerPaymentsMiddlewareParams, ServerPaymentsOptions,
};
pub use traits::{PaymentHandler, PaymentProcessor, ResolvePrice};
pub use types::{
Meta, PaymentAcceptedParams, PaymentHandlerRequest, PaymentInteractionPolicy, PaymentOption,
Expand Down
Loading
Loading