Final pass
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@ import { NYM_SDK_VERSION } from "./versions";
|
||||
|
||||
const INSTALL_PATH = "/developers/rust/importing";
|
||||
|
||||
export const CratesPaused = () => (
|
||||
export const VersionBanner = () => (
|
||||
<Callout type="info">
|
||||
Code examples target <strong>v{NYM_SDK_VERSION}</strong> of the Nym crates
|
||||
on{" "}
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Centralised version constants for documentation.
|
||||
*
|
||||
* Components (CratesPaused, CodeVerified, etc.) import from here so there is a
|
||||
* Components (VersionBanner, CodeVerified, etc.) import from here so there is a
|
||||
* single place to update on each release.
|
||||
*
|
||||
* Fenced code blocks still hardcode versions for copy-paste friendliness.
|
||||
|
||||
@@ -18,8 +18,8 @@ Two integration options are available, both delivered as packages bundled into y
|
||||
|
||||
| Module | What it does | Links |
|
||||
|---|---|---|
|
||||
| **mixFetch** | Drop-in `fetch` replacement — HTTP(S) requests via Exit Gateways with an embedded CA store for browser-to-destination TLS over the Mixnet | [docs](./typescript#mixfetch) · [example](./typescript/playground/mixfetch) |
|
||||
| **WASM Client** | Sphinx packets and cover traffic in WASM, sent over WebSocket to the Entry Gateway — messaging mode only (text/binary payloads), runs in a web worker | [docs](./typescript#mixnet-client) · [example](./typescript/playground/traffic) |
|
||||
| **mixFetch** | Drop-in `fetch` replacement — HTTP(S) requests via Exit Gateways with an embedded CA store for browser-to-destination TLS over the Mixnet | [docs](/developers/typescript#mixfetch) · [example](/developers/typescript/playground/mixfetch) |
|
||||
| **WASM Client** | Sphinx packets and cover traffic in WASM, sent over WebSocket to the Entry Gateway — messaging mode only (text/binary payloads), runs in a web worker | [docs](/developers/typescript#mixnet-client) · [example](/developers/typescript/playground/traffic) |
|
||||
|
||||
<Callout type="info">
|
||||
`mixFetch` currently supports a maximum of 10 concurrent in-flight requests. `mixFetchv2`, which will function as a general-purpose userspace IP stack, is in development.
|
||||
|
||||
@@ -19,13 +19,13 @@ Both sides of your app run Nym clients. All traffic stays Sphinx-encrypted the e
|
||||
|
||||
| SDK Module | What it does | Status | Links |
|
||||
|---|---|---|---|
|
||||
| **Stream** | `AsyncRead + AsyncWrite` byte streams multiplexed over the mixnet — the closest analogue to TCP sockets | Recommended | [docs](./rust/stream) · [tutorial](./rust/stream/tutorial) |
|
||||
| **Mixnet** | Raw message API and `MixnetClient` — full control over the communication model | Stable | [docs](./rust/mixnet) · [tutorial](./rust/mixnet/tutorial) |
|
||||
| **Client Pool** | Pre-connected client pool for bursty workloads | Stable | [docs](./rust/client-pool) |
|
||||
| **TcpProxy** | Localhost TCP sockets that proxy traffic through the mixnet | Unmaintained | [docs](./rust/tcpproxy) |
|
||||
| **Stream** | `AsyncRead + AsyncWrite` byte streams multiplexed over the mixnet — the closest analogue to TCP sockets | Recommended | [docs](/developers/rust/stream) · [tutorial](/developers/rust/stream/tutorial) |
|
||||
| **Mixnet** | Raw message API and `MixnetClient` — full control over the communication model | Stable | [docs](/developers/rust/mixnet) · [tutorial](/developers/rust/mixnet/tutorial) |
|
||||
| **Client Pool** | Pre-connected client pool for bursty workloads | Stable | [docs](/developers/rust/client-pool) |
|
||||
| **TcpProxy** | Localhost TCP sockets that proxy traffic through the mixnet | Unmaintained | [docs](/developers/rust/tcpproxy) |
|
||||
|
||||
<Callout type="error">
|
||||
**TcpProxy is unmaintained.** Use the [Stream module](./rust/stream) for new projects.
|
||||
**TcpProxy is unmaintained.** Use the [Stream module](/developers/rust/stream) for new projects.
|
||||
</Callout>
|
||||
|
||||
## Mixnet-As-Proxy
|
||||
@@ -39,8 +39,8 @@ Traffic is Sphinx-encrypted until the Exit Gateway, where it's unwrapped into HT
|
||||
|
||||
| Standalone Crate | What it does | Links |
|
||||
|---|---|---|
|
||||
| **`smolmix`** | Userspace IP tunnel — `TcpStream` and `UdpSocket` over the mixnet, compatible with the entire async Rust ecosystem. Also serves as the core for companion crates that plug into specific frameworks (e.g. hyper connectors, DNS resolvers) | [docs](./smolmix) |
|
||||
| **`smolmix`** | Userspace IP tunnel — `TcpStream` and `UdpSocket` over the mixnet, compatible with the entire async Rust ecosystem. Also serves as the core for companion crates that plug into specific frameworks (e.g. hyper connectors, DNS resolvers) | [docs](/developers/smolmix) |
|
||||
|
||||
| SDK Module | What it does | Links |
|
||||
|---|---|---|
|
||||
| **SOCKS Client** | SOCKS4/4a/5 proxy via the Exit Gateway's Network Requester — works with any SOCKS-capable application without code changes, just point it at the local proxy | [docs](./rust/mixnet) |
|
||||
| **SOCKS Client** | SOCKS4/4a/5 proxy via the Exit Gateway's Network Requester — works with any SOCKS-capable application without code changes, just point it at the local proxy | [docs](/developers/rust/mixnet) |
|
||||
|
||||
@@ -9,7 +9,7 @@ lastUpdated: "2026-03-13"
|
||||
# Rust SDK
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
import { CratesPaused } from '../../components/crates-paused'
|
||||
import { VersionBanner } from '../../components/version-banner'
|
||||
|
||||
All modules share a common `MixnetClient` that manages gateway connections, Sphinx packet encryption, routing, and cover traffic.
|
||||
|
||||
@@ -17,7 +17,7 @@ All modules share a common `MixnetClient` that manages gateway connections, Sphi
|
||||
Full API reference: [**docs.rs/nym-sdk**](https://docs.rs/nym-sdk/latest/nym_sdk/)
|
||||
</Callout>
|
||||
|
||||
<CratesPaused />
|
||||
<VersionBanner />
|
||||
|
||||
For an overview of what the SDK can do, see the **[Tour](./rust/tour)**. For setup instructions, see [Installation](./rust/importing).
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ lastUpdated: "2026-04-17"
|
||||
# Installation
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
import { CratesPaused } from '../../../components/crates-paused'
|
||||
import { VersionBanner } from '../../../components/version-banner'
|
||||
import { RUST_MSRV } from '../../../components/versions'
|
||||
|
||||
<CratesPaused />
|
||||
<VersionBanner />
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
|
||||
@@ -141,19 +141,36 @@ async fn main() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("Address: {}", client.nym_address());
|
||||
let our_address = client.nym_address();
|
||||
println!("Address: {our_address}");
|
||||
|
||||
// Same API as before — send, receive, reply.
|
||||
// Same API as before — send, receive, SURB reply.
|
||||
client
|
||||
.send_plain_message(*client.nym_address(), "persistent identity!")
|
||||
.send_plain_message(*our_address, "hello from persistent client!")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Sent — waiting for arrival...");
|
||||
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
for m in msgs.into_iter().filter(|m| !m.message.is_empty()) {
|
||||
println!("Received: {}", String::from_utf8_lossy(&m.message));
|
||||
let message = loop {
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
if let Some(msg) = msgs.into_iter().find(|m| !m.message.is_empty()) {
|
||||
break msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
println!("Received: {}", String::from_utf8_lossy(&message.message));
|
||||
|
||||
let sender_tag = message.sender_tag.expect("should have sender tag");
|
||||
client.send_reply(sender_tag, "anonymous reply!").await.unwrap();
|
||||
|
||||
let reply = loop {
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
if let Some(msg) = msgs.into_iter().find(|m| !m.message.is_empty()) {
|
||||
break msg;
|
||||
}
|
||||
}
|
||||
};
|
||||
println!("Reply: {}", String::from_utf8_lossy(&reply.message));
|
||||
|
||||
// Always disconnect for clean shutdown — background tasks need to be
|
||||
// stopped and state files flushed.
|
||||
@@ -281,18 +298,35 @@ async fn main() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("Address: {}", client.nym_address());
|
||||
let our_address = client.nym_address();
|
||||
println!("Address: {our_address}");
|
||||
|
||||
client
|
||||
.send_plain_message(*client.nym_address(), "persistent identity!")
|
||||
.send_plain_message(*our_address, "hello from persistent client!")
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Sent — waiting for arrival...");
|
||||
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
for m in msgs.into_iter().filter(|m| !m.message.is_empty()) {
|
||||
println!("Received: {}", String::from_utf8_lossy(&m.message));
|
||||
let message = loop {
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
if let Some(msg) = msgs.into_iter().find(|m| !m.message.is_empty()) {
|
||||
break msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
println!("Received: {}", String::from_utf8_lossy(&message.message));
|
||||
|
||||
let sender_tag = message.sender_tag.expect("should have sender tag");
|
||||
client.send_reply(sender_tag, "anonymous reply!").await.unwrap();
|
||||
|
||||
let reply = loop {
|
||||
if let Some(msgs) = client.wait_for_messages().await {
|
||||
if let Some(msg) = msgs.into_iter().find(|m| !m.message.is_empty()) {
|
||||
break msg;
|
||||
}
|
||||
}
|
||||
};
|
||||
println!("Reply: {}", String::from_utf8_lossy(&reply.message));
|
||||
|
||||
client.disconnect().await;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ lastUpdated: "2026-03-15"
|
||||
# Stream Module
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
import { CratesPaused } from '../../../components/crates-paused'
|
||||
import { VersionBanner } from '../../../components/version-banner'
|
||||
|
||||
<CratesPaused />
|
||||
<VersionBanner />
|
||||
|
||||
The Mixnet is fundamentally message-based: no persistent connections, no guaranteed ordering, no TCP. The default [message API](./mixnet) works at this level, sending individual payloads independently through Mix Nodes. This is effective for privacy but unlike how most networking code is structured.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user