Skip to content

Commit e1d77bf

Browse files
thesimplekidcrodas
authored andcommitted
feat: add OHTTP (NUT-26) support
Add Oblivious HTTP support for enhanced privacy between wallets and mints. - Add ohttp-gateway crate: OHTTP gateway server that can be embedded in cdk-mintd or run standalone, handling BHTTP encapsulation/decapsulation and key management - Add ohttp-client crate: client library for OHTTP key discovery and request encapsulation - Add OHTTP transport layer in cdk wallet for routing requests through an OHTTP relay - Add OhttpSettings (NUT-26) to MintInfo for advertising OHTTP support - Add MintBuilder::with_ohttp() for configuring OHTTP on the mint side - Add ohttp_gateway config section to cdk-mintd - Add --ohttp-relay CLI flag to cdk-cli - Wire OHTTP gateway router into cdk-mintd when enabled
1 parent 014d68c commit e1d77bf

35 files changed

Lines changed: 2719 additions & 124 deletions

File tree

Cargo.lock

Lines changed: 329 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.lock.msrv

Lines changed: 479 additions & 94 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cashu/src/nuts/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub use nut05::{
6060
MeltMethodSettings, MeltQuoteCustomRequest, MeltQuoteCustomResponse, MeltRequest,
6161
QuoteState as MeltQuoteState, Settings as NUT05Settings,
6262
};
63-
pub use nut06::{ContactInfo, MintInfo, MintVersion, Nuts};
63+
pub use nut06::{ContactInfo, MintInfo, MintVersion, Nuts, OhttpSettings};
6464
pub use nut07::{CheckStateRequest, CheckStateResponse, ProofState, State};
6565
pub use nut09::{RestoreRequest, RestoreResponse};
6666
pub use nut10::{

crates/cashu/src/nuts/nut06.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ pub struct Nuts {
332332
#[serde(rename = "22")]
333333
#[serde(skip_serializing_if = "Option::is_none")]
334334
pub nut22: Option<BlindAuthSettings>,
335+
/// NUT26 Settings
336+
#[serde(rename = "26")]
337+
#[serde(skip_serializing_if = "Option::is_none")]
338+
pub nut26: Option<OhttpSettings>,
335339
/// NUT29 Settings
336340
#[serde(default)]
337341
#[serde(rename = "29")]
@@ -454,6 +458,14 @@ impl Nuts {
454458
}
455459
}
456460

461+
/// Nut26 OHTTP settings
462+
pub fn nut26(self, ohttp_settings: OhttpSettings) -> Self {
463+
Self {
464+
nut26: Some(ohttp_settings),
465+
..self
466+
}
467+
}
468+
457469
/// Nut29 settings
458470
pub fn nut29(self, settings: nut29::Settings) -> Self {
459471
Self {
@@ -485,6 +497,42 @@ impl Nuts {
485497
}
486498
}
487499

500+
/// NUT-26 OHTTP Settings
501+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
502+
pub struct OhttpSettings {
503+
/// Ohttp is supported
504+
pub supported: bool,
505+
/// OHTTP gateway URL
506+
#[serde(skip_serializing_if = "Option::is_none")]
507+
pub gateway_url: Option<String>,
508+
}
509+
510+
impl OhttpSettings {
511+
/// Create new [`OhttpSettings`]
512+
pub fn new(supported: bool, gateway_url: Option<String>) -> Self {
513+
Self {
514+
supported,
515+
gateway_url,
516+
}
517+
}
518+
}
519+
520+
impl MintInfo {
521+
/// Check if mint supports OHTTP
522+
pub fn supports_ohttp(&self) -> bool {
523+
self.nuts
524+
.nut26
525+
.as_ref()
526+
.map(|s| s.supported)
527+
.unwrap_or_default()
528+
}
529+
530+
/// Get OHTTP configuration if supported
531+
pub fn ohttp_config(&self) -> Option<&OhttpSettings> {
532+
self.nuts.nut26.as_ref()
533+
}
534+
}
535+
488536
/// Check state Settings
489537
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash, Serialize, Deserialize)]
490538
pub struct SupportedSettings {

crates/cdk-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ sqlcipher = ["cdk-sqlite/sqlcipher"]
1717
redb = ["dep:cdk-redb"]
1818
tor = ["cdk/tor"]
1919
npubcash = ["cdk/npubcash"]
20+
ohttp = ["cdk/ohttp"]
2021

2122
[dependencies]
2223
anyhow.workspace = true

crates/cdk-cli/README.md

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,105 @@ cdk-cli burn
571571
cdk-cli restore <MINT_URL>
572572
```
573573

574+
574575
## License
575576

576577
Code is under the [MIT License](../../LICENSE)
577578

578-
## Contribution
579+
## Contributing
579580

580581
All contributions are welcome.
581582

582-
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions.
583+
### Basic Commands
584+
585+
Check wallet balance:
586+
```bash
587+
cdk-cli balance
588+
```
589+
590+
Send tokens:
591+
```bash
592+
cdk-cli send --amount 100
593+
```
594+
595+
Receive tokens:
596+
```bash
597+
cdk-cli receive <TOKEN>
598+
```
599+
600+
### OHTTP Support
601+
602+
The CLI supports OHTTP (Oblivious HTTP) for enhanced privacy when communicating with mints. OHTTP is enabled by default and automatically used when:
603+
604+
1. The mint supports OHTTP (advertised in mint info)
605+
2. You provide an OHTTP relay URL using `--ohttp-relay`
606+
607+
#### OHTTP Usage
608+
609+
To use OHTTP, simply provide a relay URL. The CLI will automatically detect if the mint supports OHTTP and configure the connection appropriately:
610+
611+
```bash
612+
# Use OHTTP relay - CLI auto-detects OHTTP support and gateway URL from mint
613+
cdk-cli --ohttp-relay https://relay.example.com balance
614+
cdk-cli --ohttp-relay https://relay.example.com send --amount 100
615+
cdk-cli --ohttp-relay https://relay.example.com receive <TOKEN>
616+
```
617+
618+
#### How OHTTP Works in CDK-CLI
619+
620+
1. **Automatic Detection**: When `--ohttp-relay` is provided, the CLI checks if the mint supports OHTTP
621+
2. **Gateway Discovery**: The gateway URL is automatically discovered from the mint's OHTTP configuration, or falls back to using the mint URL directly
622+
3. **Transport Setup**: An OHTTP transport layer is created with the mint URL, relay, and gateway
623+
4. **Privacy Protection**: Requests are routed through the relay, providing privacy from both the relay and the gateway
624+
625+
#### OHTTP Arguments
626+
627+
- `--ohttp-relay <URL>`: OHTTP relay URL for routing requests through a privacy relay
628+
629+
#### Example OHTTP Usage
630+
631+
```bash
632+
# Standard OHTTP usage with relay
633+
cdk-cli --ohttp-relay https://ohttp-relay.example.com balance
634+
635+
# All commands work with OHTTP
636+
cdk-cli --ohttp-relay https://relay.example.com send --amount 100
637+
cdk-cli --ohttp-relay https://relay.example.com receive <TOKEN>
638+
cdk-cli --ohttp-relay https://relay.example.com mint --amount 1000
639+
```
640+
641+
#### OHTTP vs Regular Proxy
642+
643+
OHTTP provides significantly better privacy compared to regular HTTP proxies:
644+
645+
- **Regular proxy:** `cdk-cli --proxy https://proxy.example.com balance`
646+
- Proxy can see all request content and your IP
647+
- **OHTTP relay:** `cdk-cli --ohttp-relay https://relay.example.com balance`
648+
- Relay cannot see request content (cryptographically protected)
649+
- Gateway cannot see your real IP address
650+
- Provides true metadata protection
651+
652+
#### Important Notes
653+
654+
- OHTTP requires the mint to explicitly support it
655+
- If you specify `--ohttp-relay` but the mint doesn't support OHTTP, you'll see a warning and fall back to regular HTTP
656+
- Gateway URL is automatically determined from the mint's OHTTP configuration
657+
- When OHTTP is used, WebSocket subscriptions are automatically disabled in favor of HTTP polling
658+
659+
## Building
660+
661+
### Features
662+
663+
- `ohttp`: Enables OHTTP support for enhanced privacy
664+
- `sqlcipher`: Enables SQLCipher support for encrypted databases
665+
- `redb`: Enables redb as an alternative database backend
666+
667+
### Examples
668+
669+
```bash
670+
# Build with all features
671+
cargo build --features "ohttp,sqlcipher,redb"
672+
673+
# Build with just OHTTP
674+
cargo build --features ohttp
675+
```

crates/cdk-cli/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ struct Cli {
7070
#[cfg(all(feature = "tor", not(target_arch = "wasm32")))]
7171
#[arg(long = "tor", value_enum, default_value_t = TorToggle::On)]
7272
transport: TorToggle,
73+
/// OHTTP Relay URL for proxying requests (advanced usage)
74+
#[cfg(feature = "ohttp")]
75+
#[arg(long)]
76+
ohttp_relay: Option<Url>,
7377
/// Subcommand to run
7478
#[command(subcommand)]
7579
command: Commands,

crates/cdk-ffi/src/types/mint.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ impl TryFrom<Nuts> for cdk::nuts::Nuts {
572572
},
573573
nut21: n.nut21.map(|s| s.try_into()).transpose()?,
574574
nut22: n.nut22.map(|s| s.try_into()).transpose()?,
575+
nut26: None,
575576
nut29: n.nut29.into(),
576577
})
577578
}
@@ -747,6 +748,7 @@ mod tests {
747748
),
748749
)],
749750
}),
751+
nut26: None,
750752
nut29: Default::default(),
751753
}
752754
}
@@ -887,6 +889,7 @@ mod tests {
887889
nut20: cdk::nuts::nut06::SupportedSettings { supported: false },
888890
nut21: None,
889891
nut22: None,
892+
nut26: None,
890893
nut29: Default::default(),
891894
};
892895

@@ -919,6 +922,7 @@ mod tests {
919922
nut20_supported: false,
920923
nut21: None,
921924
nut22: None,
925+
nut26: None,
922926
nut29: Default::default(),
923927
mint_units: vec![],
924928
melt_units: vec![],

crates/cdk-integration-tests/src/bin/start_regtest_mints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ fn create_ldk_settings(
333333
ldk_node: Some(ldk_config),
334334
fake_wallet: None,
335335
onchain: None,
336+
ohttp_gateway: None,
336337
..Default::default()
337338
}
338339
}

crates/cdk-integration-tests/src/shared.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ pub fn create_fake_wallet_settings(
227227
mint_management_rpc: None,
228228
auth: None,
229229
prometheus: Some(Default::default()),
230+
ohttp_gateway: None,
230231
..Default::default()
231232
}
232233
}
@@ -285,6 +286,7 @@ pub fn create_cln_settings(
285286
mint_management_rpc: None,
286287
auth: None,
287288
prometheus: Some(Default::default()),
289+
ohttp_gateway: None,
288290
..Default::default()
289291
}
290292
}
@@ -338,6 +340,7 @@ pub fn create_lnd_settings(
338340
mint_management_rpc: None,
339341
auth: None,
340342
prometheus: Some(Default::default()),
343+
ohttp_gateway: None,
341344
..Default::default()
342345
}
343346
}

0 commit comments

Comments
 (0)