# API Reference
Public API reference for `bsv-payment-actix-middleware`. All types listed below
are re-exported from the crate root.
## Table of Contents
- [Middleware Types](#middleware-types)
- [Configuration](#configuration)
- [Payment Types](#payment-types)
- [Error Types](#error-types)
- [Extractors](#extractors)
- [Bridge Types](#bridge-types) (feature: `bridge`)
- [Constants](#constants)
---
## Middleware Types
### `PaymentMiddlewareFactory<W>`
**Module:** `middleware`
Factory that produces `PaymentMiddlewareService` instances for each Actix
worker. Implements `actix_web::dev::Transform` so it can be passed to
`App::wrap()` or `Scope::wrap()`.
```rust
pub struct PaymentMiddlewareFactory<W: WalletInterface> {
// config: Arc<PaymentMiddlewareConfig<W>> (private)
}
impl<W: WalletInterface> PaymentMiddlewareFactory<W> {
pub fn new(config: PaymentMiddlewareConfig<W>) -> Self;
}
```
**Type parameter:**
- `W` -- any type implementing `bsv::wallet::interfaces::WalletInterface`.
**Usage:**
```rust,ignore
let factory = PaymentMiddlewareFactory::new(config);
App::new().wrap(factory);
```
---
### `PaymentMiddlewareService<S, W>`
**Module:** `middleware`
Per-worker middleware service that enforces BSV payment on each request.
Implements `actix_web::dev::Service`. Created automatically by the factory;
not constructed directly.
```rust
pub struct PaymentMiddlewareService<S, W: WalletInterface> {
// service: Rc<S>, (private)
// config: Arc<PaymentMiddlewareConfig<W>>, (private)
}
```
**Type parameters:**
- `S` -- the inner Actix service being wrapped.
- `W` -- wallet implementation.
**Response type:** `ServiceResponse<EitherBody<B>>` -- the middleware can
return either a passthrough response from the inner service (left body) or an
error/402 response constructed by the middleware itself (right body).
---
## Configuration
### `PaymentMiddlewareConfig<W>`
**Module:** `config`
Configuration struct holding the wallet and optional pricing callback. Created
via `PaymentMiddlewareConfigBuilder`.
```rust
pub struct PaymentMiddlewareConfig<W: WalletInterface> {
pub wallet: W,
pub calculate_request_price: Option<Arc<CalculateRequestPrice>>,
}
```
**Fields:**
- `wallet` -- the wallet instance used for nonce HMAC operations and
transaction internalization.
- `calculate_request_price` -- optional async callback that determines the
price in satoshis for a given request. When `None`, the middleware uses
`DEFAULT_SATOSHIS` (100).
---
### `PaymentMiddlewareConfigBuilder<W>`
**Module:** `config`
Builder pattern for constructing `PaymentMiddlewareConfig`. The `wallet` field
is required; calling `build()` without it returns
`Err(PaymentError::ServerMisconfigured)`.
```rust
pub struct PaymentMiddlewareConfigBuilder<W: WalletInterface> {
// wallet: Option<W>, (private)
// calculate_request_price: Option<Arc<CalculateRequestPrice>>, (private)
}
impl<W: WalletInterface> PaymentMiddlewareConfigBuilder<W> {
pub fn new() -> Self;
pub fn wallet(self, wallet: W) -> Self;
pub fn calculate_request_price(self, cb: CalculateRequestPrice) -> Self;
pub fn build(self) -> Result<PaymentMiddlewareConfig<W>, PaymentError>;
}
```
**Example:**
```rust,ignore
let config = PaymentMiddlewareConfigBuilder::new()
.wallet(my_wallet)
.calculate_request_price(Box::new(|_req| Box::pin(async { Ok(500u64) })))
.build()
.expect("wallet is set");
```
---
## Payment Types
### `BSVPayment`
**Module:** `types`
Deserialized content of the `X-BSV-Payment` request header. Uses camelCase
serde renaming to match the TypeScript wire format.
```rust
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BSVPayment {
pub derivation_prefix: String,
pub derivation_suffix: String,
pub transaction: serde_json::Value,
}
```
**Fields:**
- `derivation_prefix` -- the nonce originally returned by the server in the
402 response's `x-bsv-payment-derivation-prefix` header.
- `derivation_suffix` -- client-chosen suffix for key derivation.
- `transaction` -- the raw BSV transaction as an opaque JSON value (typically
a base64-encoded string).
---
### `PaymentInfo`
**Module:** `types`
Result of payment processing, inserted into request extensions by the
middleware. Extractable in handlers via `FromRequest`.
```rust
#[derive(Clone, Debug)]
pub struct PaymentInfo {
pub satoshis_paid: u64,
pub accepted: Option<bool>,
pub tx: Option<serde_json::Value>,
}
```
**Fields:**
- `satoshis_paid` -- amount paid in satoshis (0 for zero-price passthrough).
- `accepted` -- whether the wallet accepted the transaction (`None` for
zero-price passthrough).
- `tx` -- the raw transaction data after internalization (`None` for
zero-price passthrough).
---
### `CalculateRequestPrice`
**Module:** `types`
Type alias for the async pricing callback.
```rust
pub type CalculateRequestPrice = Box<
dyn Fn(
&actix_web::dev::ServiceRequest,
) -> futures_util::future::BoxFuture<
'static,
Result<u64, Box<dyn std::error::Error + Send + Sync>>,
> + Send
+ Sync,
>;
```
The callback receives a reference to the incoming `ServiceRequest` and returns
the price in satoshis. Return `Ok(0)` to allow a request through without
payment.
---
## Error Types
### `PaymentError`
**Module:** `error`
Error enum with five variants. Each variant produces a JSON error response
matching the TypeScript implementation's wire format:
`{"status":"error","code":"ERR_*","description":"..."}`.
```rust
#[derive(Debug, thiserror::Error)]
pub enum PaymentError {
#[error("The payment middleware must be executed after the Auth middleware.")]
ServerMisconfigured,
#[error("The X-BSV-Payment header is not valid JSON.")]
MalformedPayment,
#[error("The X-BSV-Payment-Derivation-Prefix header is not valid.")]
InvalidDerivationPrefix,
#[error("{0}")]
PaymentFailed(String),
#[error("An internal error occurred while determining the payment required for this request.")]
PaymentInternal,
}
```
**Variant details:**
| `ServerMisconfigured` | 500 | `ERR_SERVER_MISCONFIGURED` |
| `MalformedPayment` | 400 | `ERR_MALFORMED_PAYMENT` |
| `InvalidDerivationPrefix`| 400 | `ERR_INVALID_DERIVATION_PREFIX` |
| `PaymentFailed(msg)` | 400 | `ERR_PAYMENT_FAILED` |
| `PaymentInternal` | 500 | `ERR_PAYMENT_INTERNAL` |
Note: The 402 `ERR_PAYMENT_REQUIRED` response is not a `PaymentError` variant.
It is built directly in the middleware because it includes extra fields
(`satoshisRequired`) and custom headers.
---
## Extractors
### `AuthIdentity`
**Module:** `extractor`
Identity of the authenticated caller, extracted from request extensions.
Implements `FromRequest`.
```rust
#[derive(Clone, Debug)]
pub struct AuthIdentity {
pub identity_key: String,
}
```
The auth middleware (or the bridge) inserts this into request extensions. The
payment middleware reads it to obtain the sender's public identity key for
transaction internalization.
### `PaymentInfo` (as extractor)
`PaymentInfo` also implements `FromRequest`, allowing handlers to extract
payment results directly:
```rust,ignore
async fn handler(payment: PaymentInfo) -> HttpResponse {
// payment.satoshis_paid, payment.accepted, payment.tx
}
```
Returns `PaymentError::ServerMisconfigured` if the payment middleware did not
run.
---
## Bridge Types
*Available with the `bridge` feature flag.*
### `AuthToPaymentBridge`
**Module:** `bridge`
Middleware that bridges `bsv_auth_actix_middleware::Authenticated` to
`AuthIdentity`. Resolves the `TypeId` mismatch between the auth crate's
identity struct and the payment crate's identity struct.
```rust
pub struct AuthToPaymentBridge;
```
**Usage:**
```rust,ignore
use bsv_payment_actix_middleware::AuthToPaymentBridge;
App::new()
.wrap(PaymentMiddlewareFactory::new(config))
.wrap(AuthToPaymentBridge)
.wrap(AuthMiddleware::new(auth_config))
```
Register between the auth middleware and the payment middleware. When
`Authenticated` is absent from request extensions, the bridge passes through
silently and lets the payment middleware handle the missing identity.
---
### `AuthToPaymentBridgeService<S>`
**Module:** `bridge`
The inner service half of `AuthToPaymentBridge`. Created automatically by the
transform; not constructed directly.
```rust
pub struct AuthToPaymentBridgeService<S> {
// service: Rc<S> (private)
}
```
---
## Constants
### `DEFAULT_SATOSHIS`
**Module:** `types`
```rust
pub const DEFAULT_SATOSHIS: u64 = 100;
```
Default price in satoshis when no `calculate_request_price` callback is
configured.
### `PAYMENT_VERSION`
**Module:** `types`
```rust
pub const PAYMENT_VERSION: &str = "1.0";
```
Payment protocol version string, sent in the `x-bsv-payment-version` response
header on 402 responses.
---
*Generated from `bsv-payment-actix-middleware` v0.1.0 source.*