[package]
name = "lastid-sdk"
version = "0.3.0"
edition = "2024"
rust-version = "1.89"
license = "MIT OR Apache-2.0"
description = "Rust SDK for LastID IDP integration - request and verify credentials with type-safe policy builders"
repository = "https://github.com/GetTrustedApp/lastid-rust-sdk"
homepage = "https://lastid.co"
documentation = "https://docs.rs/lastid-sdk"
readme = "README.md"
keywords = ["did", "sdjwt", "dpop", "oid4vci", "credentials"]
categories = ["authentication", "cryptography"]
authors = ["LastID Team <team@lastid.co>"]

[lib]
name = "lastid_sdk"
path = "src/lib.rs"
crate-type = ["cdylib", "rlib"]

[features]
default = ["base-policy"]
full = ["base-policy", "persona-policy", "verified-email-policy", "verified-phone-policy", "verified-persona-policy", "employment-policy", "trust-policy", "age-proof-policy", "tracing"]

# Policy builder features
base-policy = []
persona-policy = []
verified-email-policy = []
verified-phone-policy = []
verified-persona-policy = []
employment-policy = []
trust-policy = []
age-proof-policy = []

# Optional features
tracing = ["dep:tracing"]
json-schema = ["dep:schemars"]
test-utils = ["dep:wiremock"]
# Enable DPoP keypair serialization for serverless persistence (SEC-002)
# WARNING: Serialized keypairs contain private keys - ensure encrypted storage
keypair-serialization = []
wasm = ["dep:wasm-bindgen", "dep:wasm-bindgen-futures", "dep:web-sys", "dep:js-sys", "dep:gloo-storage", "dep:serde-wasm-bindgen", "dep:console_error_panic_hook"]
websocket = ["dep:futures-util", "dep:tokio-tungstenite"]
napi = ["dep:napi", "dep:napi-derive", "dep:napi-build", "base-policy", "persona-policy", "verified-email-policy", "verified-phone-policy", "verified-persona-policy", "employment-policy", "trust-policy", "age-proof-policy", "websocket"]

[dependencies]
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.8"

# Error handling
thiserror = "1.0"

# Async runtime (native only - wasm uses wasm-bindgen-futures)
async-trait = "0.1"

# HTTP client - note: reqwest config is per-target below since WASM can't use rustls-tls

# URL encoding for trust registry DIDs
urlencoding = "2.1"

# Crypto
p256 = { version = "0.13", features = ["ecdsa", "jwk", "pem"] }
secrecy = { version = "0.10", features = ["serde"] }
zeroize = { version = "1.8", features = ["derive"] }
sha2 = "0.10"
base64 = "0.22"
rand = "0.8"

# UUID for request IDs and DPoP jti
# Note: js feature needed for wasm32-unknown-unknown target
uuid = { version = "1", features = ["v4", "js"] }

# Cache (native)
mini-moka = { version = "0.10", optional = true }

# Time handling
chrono = { version = "0.4", features = ["serde"] }

# Filesystem paths for config discovery
dirs = "5"

# Regex for policy constraints
regex = "1.10"

# Tracing (optional)
tracing = { version = "0.1", optional = true }

# JSON Schema generation (optional)
schemars = { version = "0.8", optional = true }

# WASM dependencies (optional)
wasm-bindgen = { version = "0.2", optional = true }
wasm-bindgen-futures = { version = "0.4", optional = true }
web-sys = { version = "0.3", features = ["Window", "Storage", "WebSocket", "MessageEvent", "CloseEvent", "ErrorEvent", "BinaryType"], optional = true }
js-sys = { version = "0.3", optional = true }
gloo-storage = { version = "0.3", optional = true }
serde-wasm-bindgen = { version = "0.6", optional = true }
console_error_panic_hook = { version = "0.1", optional = true }

# Test utilities feature - exposes mock implementations for testing
wiremock = { version = "0.5", optional = true }

# Node.js native binding (optional - napi feature)
napi = { version = "2", features = ["async", "serde-json", "tokio_rt"], optional = true }
napi-derive = { version = "2", optional = true }

# WebSocket support (optional)
futures-util = { version = "0.3", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1", features = ["rt", "sync", "time", "macros"] }
mini-moka = "0.10"
# Thread-safe locks without poisoning - critical for reliability in identity/auth SDKs
parking_lot = "0.12"
# Native HTTP client with TLS
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
# Native WebSocket client (optional - enabled by websocket feature)
tokio-tungstenite = { version = "0.24", features = ["rustls-tls-webpki-roots"], optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
micro-moka = "0.1"
# WASM HTTP client - no TLS (browser provides it), uses fetch API
reqwest = { version = "0.12", default-features = false, features = ["json"] }
# WASM WebSocket support (for Feature 027 - real-time status updates)
gloo-timers = { version = "0.3", features = ["futures"] }
futures-channel = "0.3"
# WASM RNG support - required for DPoP key generation in browser
getrandom = { version = "0.2", features = ["js"] }

[build-dependencies]
napi-build = { version = "2", optional = true }

[dev-dependencies]
wasm-bindgen-test = "0.3"
ts-rs = { version = "11", features = ["serde-compat", "serde-json-impl"] }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { version = "1", features = ["full", "test-util"] }
tokio-test = "0.4"
wiremock = "0.5"
proptest = "1"
tempfile = "3"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"

# WASM-optimized release profile
# Use with: cargo build --profile wasm-release --target wasm32-unknown-unknown
[profile.wasm-release]
inherits = "release"
opt-level = "z"          # Optimize for size
lto = true               # Enable link-time optimization
codegen-units = 1        # Better optimization, slower compile
panic = "abort"          # Smaller code, no unwinding

[profile.dev]
# Faster incremental builds
incremental = true

[lints.rust]
unsafe_code = "forbid"

[lints.clippy]
# Lint groups with lower priority so specific lints can override
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
# Allow common patterns
module_name_repetitions = "allow"
must_use_candidate = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
too_many_lines = "allow"
# Dependency issues we can't control
multiple_crate_versions = "allow"

# Examples with required features
[[example]]
name = "base_credential"
required-features = ["base-policy"]

[[example]]
name = "persona_credential"
required-features = ["persona-policy"]

[[example]]
name = "verified_email_credential"
required-features = ["verified-email-policy"]

[[example]]
name = "employment_verification"
required-features = ["employment-policy"]

[[example]]
name = "trust_credential"
required-features = ["trust-policy"]

[[example]]
name = "age_verification"
required-features = ["age-proof-policy"]

[[example]]
name = "config_loading"
required-features = []

[[example]]
name = "poll_and_verify"
required-features = ["base-policy"]

[[example]]
name = "enterprise_domain_filter"
required-features = ["employment-policy"]

[[example]]
name = "subject_binding"
required-features = ["persona-policy"]

[[example]]
name = "typed_response_parsing"
required-features = ["persona-policy"]

[[example]]
name = "multi_credential_chain"
required-features = ["persona-policy"]
