acdp 0.2.0

Rust client library for the Agent Context Distribution Protocol (ACDP v0.1.0)
Documentation
[package]
name    = "acdp"
version = "0.2.0"
edition = "2021"
description   = "Rust client library for the Agent Context Distribution Protocol (ACDP v0.1.0)"
license       = "MIT OR Apache-2.0"
readme        = "README.md"
repository    = "https://github.com/agentcontextdistributionprotocol/acdp-rs"
homepage      = "https://github.com/agentcontextdistributionprotocol/acdp-rs"
documentation = "https://docs.rs/acdp"
keywords      = ["acdp", "agent", "context", "did", "verifiable"]
categories    = ["web-programming", "cryptography", "data-structures"]
rust-version  = "1.86"
exclude       = [
    "/.github",
    "/target",
    "/examples",
    "/tests",
    "/plans",
    "/.gitignore",
    "/deny.toml",
    "/rustfmt.toml",
    "/CONTRIBUTING.md",
    "/SECURITY.md",
]

[features]
default = ["client"]
client  = ["dep:reqwest", "dep:lru", "dep:tokio"]
server  = []
tracing = ["dep:tracing"]
cli     = ["client", "tokio/macros", "tokio/rt-multi-thread"]

[[bin]]
name              = "acdp"
path              = "src/bin/acdp.rs"
required-features = ["cli"]

# TLS-backed fixture conformance tests need both the `client` (resolver,
# RegistryClient, CrossRegistryResolver) and `server` (RegistryServer,
# InMemoryStore — used by the pub-003 supersession lineage test) features.
# `--no-default-features` test runs skip them entirely.
[[test]]
name              = "tls_conformance"
path              = "tests/tls_conformance.rs"
required-features = ["client", "server"]

# The end-to-end example drives `RegistryClient` against a wiremock mock
# registry, so it needs the `client` feature. Declared here (rather than
# left to auto-discovery) so `--no-default-features` builds skip it
# instead of failing to compile. `producer`, `consumer`, and
# `supersession` use only the always-on core and need no gate.
[[example]]
name              = "end_to_end"
path              = "examples/end_to_end.rs"
required-features = ["client"]

# CLI subprocess tests need the `cli` feature so the `acdp` binary is
# actually built.
[[test]]
name              = "cli"
path              = "tests/cli.rs"
required-features = ["cli"]

# Receipt end-to-end tests (RFC-ACDP-0010) drive the in-process TLS
# registry harness: `client` for the resolver/RegistryClient, `server`
# for RegistryServer + InMemoryStore.
[[test]]
name              = "receipts"
path              = "tests/receipts.rs"
required-features = ["client", "server"]

[dependencies]
# Serialisation
serde      = { version = "1", features = ["derive"] }
# `float_roundtrip` makes float PARSING correctly-rounded (bit-accurate)
# rather than serde_json's default ~17-significant-digit approximation.
# JCS / RFC 8785 number canonicalization (see `crypto::jcs`) requires the
# exact IEEE-754 value so the ECMAScript `Number::toString` shortest form
# matches the spec vectors (e.g. `1.23e+25`, not `1.2299999999999998e+25`).
serde_json = { version = "1", features = ["preserve_order", "float_roundtrip"] }

# Cryptography
sha2          = "0.10"
ed25519-dalek = { version = "2", features = ["rand_core"] }
p256          = { version = "0.13", default-features = false, features = ["ecdsa", "std"] }
base64        = "0.22"
hex           = "0.4"
zeroize       = { version = "1", features = ["derive"] }
# RNG trait used by both ed25519-dalek and p256 for key generation.
# Already a transitive dep — promoted to direct so `SigningKey::generate()`
# and `P256SigningKey::generate()` can plumb `OsRng` through both libraries.
rand_core     = { version = "0.6", features = ["std"] }

# Identity / time
chrono      = { version = "0.4", features = ["serde"] }
uuid        = { version = "1", features = ["v4"] }
url         = "2"
urlencoding = "2"
bs58        = "0.5"      # base58btc for publicKeyMultibase

# Error handling
thiserror = "1"

# HTTP client (feature-gated)
reqwest = { version = "0.12", features = ["json", "rustls-tls"], optional = true, default-features = false }

# Cache (used by the DID resolver under the client feature)
lru = { version = "0.16", optional = true }

# Async runtime hooks (sleep for retry backoff). Reqwest already pulls
# in tokio transitively, but being explicit keeps the dep graph honest.
tokio = { version = "1", features = ["time"], optional = true, default-features = false }

# Optional structured logging
tracing = { version = "0.1", optional = true, default-features = false, features = ["attributes"] }

[dev-dependencies]
tokio    = { version = "1", features = ["full"] }
anyhow   = "1"
wiremock = "0.6"
proptest = "1"
# TLS test harness — used to mock a `did:web` HTTPS endpoint and a
# foreign registry so conformance fixtures pub-001 / pub-003 / pub-006
# and fed-001..006 can be bound to behavioral assertions without going
# over the network. Kept in dev-dependencies so they don't propagate to
# downstream consumers.
rcgen        = { version = "0.13", default-features = false, features = ["pem", "ring"] }
axum         = { version = "0.7", default-features = false, features = ["json"] }
axum-server  = { version = "0.7", default-features = false, features = ["tls-rustls"] }
# rustls 0.23 requires the process to install a crypto provider before
# the first TLS handshake — there's no auto-detect when more than one
# backend is in scope. We install `aws-lc-rs` (matches what `axum-server`'s
# `tls-rustls` feature pulls in transitively).
rustls       = { version = "0.23", default-features = false, features = ["aws-lc-rs"] }

[package.metadata.docs.rs]
all-features        = true
rustdoc-args        = ["--cfg", "docsrs"]
targets             = ["x86_64-unknown-linux-gnu"]

[lints.rust]
unsafe_code = "forbid"

[lints.clippy]
all = { level = "warn", priority = -1 }