tachyon-i2p 0.0.2

Safe async wrapper around i2pd-sys (native I2P `.b32.i2p` eepsite support).
Documentation
# tachyon-i2p

Safe async wrapper around [`i2pd-sys`](https://crates.io/crates/i2pd-sys), giving Tokio code a
`Destination` (an I2P eepsite identity, reachable at a `.b32.i2p` address) with an `I2pStream`
connection type that implements `AsyncRead`/`AsyncWrite` — no external `i2pd`/Java-I2P process,
no SAM bridge, no separate service to run alongside your binary.

> **Status:** pre-0.1 (`0.0.2`). Usable standalone, and also developed alongside and consumed by
> the [`tachyon-web`]https://crates.io/crates/tachyon-web workspace (via its `i2p`
> feature). The API may still change without notice.

## Why this crate exists, and why it's `unsafe` internally

`libi2pd` (the underlying router, from [PurpleI2P/i2pd](https://github.com/PurpleI2P/i2pd)) is a
C++ library with no stable C ABI. `i2pd-sys` bridges it through a small hand-written `extern "C"`
shim; this crate is where every `unsafe` call site into that shim lives, so that consumers (like
`tachyon-web`) never have to relax their own `forbid(unsafe_code)`. **The public API is 100% safe
Rust** — no `pub unsafe fn`, no raw pointers exposed — but that safety rests entirely on this
crate's own review of libi2pd's threading/ownership contracts (documented inline at each `unsafe`
block, and in `i2pd-sys/shim/shim.h`), not on any external memory-safety guarantee the way a pure-Rust
dependency would give you.

## Usage

```toml
[dependencies]
tachyon-i2p = "0.0.2"
```

```rust,no_run
use tachyon_i2p::{CryptoType, I2pRouter, SigType};

#[tokio::main]
async fn main() -> Result<(), tachyon_i2p::I2pError> {
    let router = I2pRouter::start("my-eepsite").await?;
    let mut dest = router
        .destination_from_keys_file("my-eepsite.keys", true, SigType::default(), CryptoType::default())
        .await?;
    println!("reachable at http://{}", dest.b32_address());

    loop {
        let _stream = dest.accept().await?; // implements AsyncRead + AsyncWrite
        // ... spawn a task to serve it ...
    }
}
```

Only one `I2pRouter` may run per process — libi2pd keeps its router context as a process-wide
global, not a per-instance object.

## Crypto backend: `aws-lc` (default) vs `fips`

Mirrors `i2pd-sys`'s own two mutually exclusive features, passed straight through:

- **`aws-lc`** (default): regular AWS-LC.
- **`fips`**: the FIPS 140-3-validated AWS-LC-FIPS module instead — mutually exclusive with
  `aws-lc`, so needs `default-features = false, features = ["fips"]`. See
  [`i2pd-sys`'s README]https://crates.io/crates/i2pd-sys ("FIPS" section) for what this does
  and does not get you before reaching for it to satisfy a compliance requirement.

## License

Licensed under either of

- [Apache License, Version 2.0]LICENSE-APACHE
- [MIT license]LICENSE-MIT

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
this crate, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.