{
  "name": "forge-agent402",
  "language": "rust",
  "version": "0.2.0",
  "description": "Agent-native identity + payment middleware \u2014 wraps OpenAgent challenge-response, x402 micropayments, and Arsenal capability grants into agent402::serve() and agent402::connect()",
  "manifest": "forge-rs/crates/forge-agent402/Cargo.toml",
  "manifestSha256": "7a2fba02511afaadd75b288ec9daaa339c4747d51b8e8d827983801641bf9379",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/rust/forge-agent402",
  "features": {},
  "files": [
    {
      "path": "forge-rs/crates/forge-agent402/src/client.rs",
      "sha256": "a58f88f7890f51c2e30c69f96930625a431aadab5344e92614b7dfbd2b33a51d",
      "artifactSha256": "f2c41bd50e512f060bcd25d383d8a8c01f74c0fb7a21c8c610f58a35de383e7d",
      "url": "/reference/source/forge-rs/crates/forge-agent402/src/client.rs.txt",
      "declarations": [
        {
          "name": "::AgentConfig",
          "line": 41,
          "signature": "#[derive(Zeroize, ZeroizeOnDrop)]\npub struct AgentConfig {\n/// Ed25519 secret key (32 bytes). The agent's identity key.\n\npub secret_key: [u8; 32]\n}",
          "documentation": "Configuration for an agent402 client.\n\nThe `secret_key` field is zeroed from memory on drop."
        },
        {
          "name": "::Agent",
          "line": 61,
          "signature": "pub struct Agent {\n\n}",
          "documentation": "An agent that can fetch from OpenAgent-protected + x402-priced endpoints.\n\nHandles the full protocol flow transparently:\n1. Sends request \u2192 if 401, signs challenge, retries\n2. If 402, constructs payment proof, signs, retries\n3. Caches session tokens for subsequent requests"
        },
        {
          "name": "::FetchResponse",
          "line": 100,
          "signature": "#[derive(Debug)]\npub struct FetchResponse {\n/// HTTP status code.\n\npub status: u16,\n/// Agent's DID as assigned by the server.\n\npub did: Option<String>,\n/// Trust tier assigned by the server.\n\npub trust_tier: Option<u8>,\n/// Response body bytes.\n\npub body: Vec<u8>\n}",
          "documentation": "Response from an agent402 fetch."
        },
        {
          "name": "::Agent::new",
          "line": 129,
          "signature": "pub fn new(config: AgentConfig) -> Self;",
          "documentation": "Creates a new agent from config.\n\nThe secret key is used for both OpenAgent identity challenges and\nx402 payment signing. Self-custody: the key stays in this process."
        },
        {
          "name": "::Agent::public_key_bytes",
          "line": 142,
          "signature": "pub fn public_key_bytes(&self) -> [u8; 32];",
          "documentation": "Returns the agent's Ed25519 public key bytes."
        },
        {
          "name": "::Agent::public_key_hex",
          "line": 147,
          "signature": "pub fn public_key_hex(&self) -> String;",
          "documentation": "Returns the agent's public key as hex string."
        },
        {
          "name": "::Agent::fetch",
          "line": 157,
          "signature": "pub async fn fetch(\n        &self,\n        url: &str,\n        body: Option<&[u8]>,\n    ) -> Result<FetchResponse, Agent402Error>;",
          "documentation": "Fetches a URL with automatic identity + payment handling.\n\nFlow:\n1. Delegate to `OpenAgentClient::fetch()` for challenge-response\n2. If response is 402, parse `PaymentRequirement`, sign proof, retry\n3. Return final response"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent402/src/error.rs",
      "sha256": "05559050bcf2cfc6e9912adc1062412243aa0e752fbb64c652538de76db7e554",
      "artifactSha256": "2159f7377ceb8324828f8a4dd56eaf3559b40b875224e7bcb1edce93d890d455",
      "url": "/reference/source/forge-rs/crates/forge-agent402/src/error.rs.txt",
      "declarations": [
        {
          "name": "::Agent402Error",
          "line": 7,
          "signature": "#[derive(Debug, Error)]\npub enum Agent402Error {\n    /// OpenAgent challenge-response authentication failed.\n    #[error(\"authentication failed: {reason}\")]\n    AuthFailed { reason: String },\n\n    /// x402 payment required but not provided or invalid.\n    #[error(\"payment failed: {reason}\")]\n    PaymentFailed { reason: String },\n\n    /// Session token expired or invalid.\n    #[error(\"session expired\")]\n    SessionExpired,\n\n    /// Network or transport error.\n    #[error(\"network error: {0}\")]\n    Network(String),\n\n    /// Configuration error.\n    #[error(\"configuration error: {0}\")]\n    Config(String),\n\n    /// Internal error.\n    #[error(\"internal error: {0}\")]\n    Internal(String),\n}",
          "documentation": "Errors from the agent402 layer."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent402/src/lib.rs",
      "sha256": "6accec35e3e6fc19062ebdb95a0ce58890e293914ac365ee4993f2b156548b8b",
      "artifactSha256": "609f03637d525ba6750c21625f337695efeebcd6d6e96cba42982545ea0c162f",
      "url": "/reference/source/forge-rs/crates/forge-agent402/src/lib.rs.txt",
      "declarations": [
        {
          "name": "client",
          "line": 46,
          "signature": "pub mod client;",
          "documentation": ""
        },
        {
          "name": "error",
          "line": 47,
          "signature": "pub mod error;",
          "documentation": ""
        },
        {
          "name": "server",
          "line": 48,
          "signature": "pub mod server;",
          "documentation": ""
        },
        {
          "name": "pub use client::{Agent, AgentConfig};",
          "line": 50,
          "signature": "pub use client::{Agent, AgentConfig};",
          "documentation": ""
        },
        {
          "name": "pub use server::{CapabilityConfig, GrantCondition, ServeConfig, ServeLayer};",
          "line": 51,
          "signature": "pub use server::{CapabilityConfig, GrantCondition, ServeConfig, ServeLayer};",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent402/src/server.rs",
      "sha256": "667d0ff36cf1134a0f6c01de83530e4e7697745232b6e19260d1eafe56e07fca",
      "artifactSha256": "502462601a7df76c57e775868b5305c38b59492f4e7bd1e3ffdd3d6e6a90c112",
      "url": "/reference/source/forge-rs/crates/forge-agent402/src/server.rs.txt",
      "declarations": [
        {
          "name": "::ServeConfig",
          "line": 31,
          "signature": "#[derive(Debug, Clone)]\npub struct ServeConfig {\n/// Server origin (e.g., \"https://api.example.com\").\n\npub origin: String,\n/// Optional realm for the OpenAgent challenge.\n\npub realm: Option<String>,\n/// HMAC secret for session JWTs. Must be at least 32 bytes.\n\npub session_secret: Vec<u8>,\n/// Session TTL in seconds (default: 900 = 15 minutes).\n\npub session_ttl_secs: i64,\n/// Minimum trust tier (default: 0 = Anonymous).\n\npub min_trust_tier: u8,\n/// Priced routes (empty = identity-only, no payment required).\n\npub priced_routes: Vec<RouteConfig>,\n/// Wallet address for receiving payments.\n\npub recipient_address: Option<String>,\n/// Facilitator URL for x402 settlement.\n\npub facilitator_url: Option<String>,\n/// Capability requirements per route (Arsenal scopes).\n\npub capabilities: Vec<CapabilityConfig>\n}",
          "documentation": "Configuration for the agent402 server middleware.\n\nCombines OpenAgent identity config with optional x402 route pricing."
        },
        {
          "name": "::RouteConfig",
          "line": 62,
          "signature": "#[derive(Debug, Clone)]\npub struct RouteConfig {\n/// Route path pattern (prefix match).\n\npub path: String,\n/// HTTP method (None = all methods).\n\npub method: Option<String>,\n/// Price per request as decimal string (e.g., \"0.002\").\n\npub price: String,\n/// Currency (default: \"USDC\").\n\npub currency: String\n}",
          "documentation": "Configuration for a priced route."
        },
        {
          "name": "::ServeConfig::new",
          "line": 77,
          "signature": "pub fn new(origin: impl Into<String>, session_secret: impl AsRef<[u8]>) -> Self;",
          "documentation": "Creates a new server config with the given origin and session secret.\n\nDefaults to identity-only (no payment) with Anonymous minimum trust tier."
        },
        {
          "name": "::ServeConfig::with_priced_route",
          "line": 92,
          "signature": "pub fn with_priced_route(\n        mut self,\n        path: impl Into<String>,\n        method: impl Into<String>,\n        price: impl Into<String>,\n    ) -> Self;",
          "documentation": "Adds a priced route. Requires `recipient_address` and `facilitator_url`."
        },
        {
          "name": "::ServeConfig::with_recipient",
          "line": 108,
          "signature": "pub fn with_recipient(mut self, address: impl Into<String>) -> Self;",
          "documentation": "Sets the recipient wallet address for x402 payments."
        },
        {
          "name": "::ServeConfig::with_facilitator",
          "line": 114,
          "signature": "pub fn with_facilitator(mut self, url: impl Into<String>) -> Self;",
          "documentation": "Sets the facilitator URL for x402 settlement."
        },
        {
          "name": "::ServeConfig::with_min_trust_tier",
          "line": 120,
          "signature": "pub fn with_min_trust_tier(mut self, tier: u8) -> Self;",
          "documentation": "Sets the minimum trust tier."
        },
        {
          "name": "::ServeConfig::with_realm",
          "line": 126,
          "signature": "pub fn with_realm(mut self, realm: impl Into<String>) -> Self;",
          "documentation": "Sets the optional realm."
        },
        {
          "name": "::ServeConfig::with_capability",
          "line": 136,
          "signature": "pub fn with_capability(\n        mut self,\n        path: impl Into<String>,\n        method: impl Into<String>,\n        scopes: &[&str],\n        condition: GrantCondition,\n    ) -> Self;",
          "documentation": "Adds a capability requirement for a route.\n\nWhen the agent authenticates (and optionally pays), the listed scopes\nare implicitly granted for the request. Scopes use the Arsenal format:\n`service:resource:action`."
        },
        {
          "name": "::CapabilityConfig",
          "line": 175,
          "signature": "#[derive(Debug, Clone)]\npub struct CapabilityConfig {\n/// Route path pattern (prefix match).\n\npub path: String,\n/// HTTP method (None = all methods).\n\npub method: Option<String>,\n/// Required Arsenal scopes (format: `service:resource:action`).\n\npub scopes: Vec<String>,\n/// Grant condition: \"verified\" or \"verified_and_paid\".\n\npub condition: GrantCondition\n}",
          "documentation": "Capability configuration for a route.\n\nDefines what Arsenal scopes are required for a route. When the agent\nauthenticates and (optionally) pays, these scopes are implicitly granted.\n\nFor cross-server ACT portability (Phase 2), the server would issue a\nCBOR-signed ACT via Arsenal broker. Day-one, the grant is implicit:\nauth + payment = capability granted for the request's route."
        },
        {
          "name": "::GrantCondition",
          "line": 188,
          "signature": "#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum GrantCondition {\n    /// Grant after identity verification succeeds (any trust tier).\n    Verified,\n    /// Grant after identity verification AND x402 payment succeeds.\n    VerifiedAndPaid,\n    /// Grant only if trust tier meets minimum.\n    TrustMinimum(u8),\n}",
          "documentation": "When Arsenal capabilities are granted."
        },
        {
          "name": "::ServeLayer",
          "line": 228,
          "signature": "#[derive(Clone)]\npub struct ServeLayer {\n\n}",
          "documentation": "The agent402 Axum middleware layer.\n\nComposes the OpenAgent challenge-response layer for identity verification.\n\n# Capability Model (Day-One)\n\nDay-one capabilities are **implicit**: once the agent authenticates (and\npays if the route is priced), the route's configured capabilities are\ngranted for the duration of the request. Handlers can read the agent's\nDID from the `X-OpenAgent-DID` response header.\n\nFor cross-server ACT portability (Phase 2), the server would call Arsenal\nbroker to issue a CBOR-signed ACT token.\n\n# x402 Composition\n\nWhen `ServeConfig` has priced routes, the service operator composes the\nMints `x402_payment_gate` middleware in the router stack *after* the\n`ServeLayer`. The x402 gate reads the authenticated session and returns\n402 with `PaymentRequirement` for priced routes.\n\n```rust,ignore\nlet app = Router::new()\n    .route(\"/api/analyze\", post(handler))\n    .layer(axum::middleware::from_fn_with_state(x402_gate, x402_payment_gate))\n    .layer(ServeLayer::new(config));\n```\n\nLayer order: requests flow through `ServeLayer` (identity) first,\nthen `x402_payment_gate` (payment)."
        },
        {
          "name": "::ServeLayer::new",
          "line": 235,
          "signature": "pub fn new(config: ServeConfig) -> Self;",
          "documentation": "Creates a new agent402 server layer from the given config."
        },
        {
          "name": "::ServeLayer::config",
          "line": 246,
          "signature": "pub fn config(&self) -> &ServeConfig;",
          "documentation": "Returns the serve config (for x402 gate setup)."
        },
        {
          "name": "::serve",
          "line": 275,
          "signature": "pub fn serve(config: ServeConfig) -> ServeLayer;",
          "documentation": "Convenience function to create the agent402 server layer.\n\n# Example\n\n```rust,ignore\nuse forge_agent402::server::serve;\n\nlet layer = serve(ServeConfig::new(\n    \"https://api.example.com\",\n    b\"secret-key-at-least-32-bytes!!!!\"\n));\n\nlet app = Router::new()\n    .route(\"/api/data\", get(handler))\n    .layer(layer);\n```"
        }
      ]
    }
  ]
}
