mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-19 21:55:03 +01:00
chore: Update rust-version (MSRV) to 1.75.0 (#623)
This commit is contained in:
29
.github/workflows/ci.yml
vendored
29
.github/workflows/ci.yml
vendored
@@ -102,7 +102,6 @@ jobs:
|
|||||||
-p cdk-cln,
|
-p cdk-cln,
|
||||||
-p cdk-lnd,
|
-p cdk-lnd,
|
||||||
-p cdk-phoenixd,
|
-p cdk-phoenixd,
|
||||||
-p cdk-strike,
|
|
||||||
-p cdk-lnbits,
|
-p cdk-lnbits,
|
||||||
-p cdk-fake-wallet,
|
-p cdk-fake-wallet,
|
||||||
--bin cdk-cli,
|
--bin cdk-cli,
|
||||||
@@ -111,6 +110,7 @@ jobs:
|
|||||||
--bin cdk-mintd --no-default-features --features redis,
|
--bin cdk-mintd --no-default-features --features redis,
|
||||||
--bin cdk-mintd --no-default-features --features "redis swagger",
|
--bin cdk-mintd --no-default-features --features "redis swagger",
|
||||||
--bin cdk-mintd --no-default-features --features management-rpc,
|
--bin cdk-mintd --no-default-features --features management-rpc,
|
||||||
|
--bin cdk-mintd --no-default-features --features redb,
|
||||||
--bin cdk-mint-cli,
|
--bin cdk-mint-cli,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
@@ -216,12 +216,14 @@ jobs:
|
|||||||
-p cdk --no-default-features --features "mint mint",
|
-p cdk --no-default-features --features "mint mint",
|
||||||
-p cdk-axum,
|
-p cdk-axum,
|
||||||
-p cdk-axum --no-default-features --features redis,
|
-p cdk-axum --no-default-features --features redis,
|
||||||
-p cdk-strike,
|
|
||||||
-p cdk-lnbits,
|
-p cdk-lnbits,
|
||||||
-p cdk-phoenixd,
|
-p cdk-phoenixd,
|
||||||
-p cdk-fake-wallet,
|
-p cdk-fake-wallet,
|
||||||
-p cdk-cln,
|
-p cdk-cln,
|
||||||
|
-p cdk-lnd,
|
||||||
-p cdk-mint-rpc,
|
-p cdk-mint-rpc,
|
||||||
|
-p cdk-sqlite,
|
||||||
|
-p cdk-mintd,
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
@@ -236,29 +238,6 @@ jobs:
|
|||||||
run: nix develop -i -L .#msrv --command cargo build ${{ matrix.build-args }}
|
run: nix develop -i -L .#msrv --command cargo build ${{ matrix.build-args }}
|
||||||
|
|
||||||
|
|
||||||
db-msrv-build:
|
|
||||||
name: "DB MSRV build"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 15
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
build-args:
|
|
||||||
[
|
|
||||||
-p cdk-sqlite,
|
|
||||||
-p cdk-redb,
|
|
||||||
]
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install Nix
|
|
||||||
uses: DeterminateSystems/nix-installer-action@v11
|
|
||||||
- name: Nix Cache
|
|
||||||
uses: DeterminateSystems/magic-nix-cache-action@v6
|
|
||||||
- name: Rust Cache
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
- name: Build
|
|
||||||
run: nix develop -i -L .#db_shell --command cargo build ${{ matrix.build-args }}
|
|
||||||
|
|
||||||
check-wasm:
|
check-wasm:
|
||||||
name: Check WASM
|
name: Check WASM
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
58
Cargo.toml
58
Cargo.toml
@@ -5,13 +5,69 @@ members = [
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.75.0"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
anyhow = "1"
|
||||||
|
async-trait = "0.1"
|
||||||
|
axum = { version = "0.8.1", features = ["ws"] }
|
||||||
|
bitcoin = { version = "0.32.2", features = ["base64", "serde", "rand", "rand-std"] }
|
||||||
|
bip39 = { version = "2.0", features = ["rand"] }
|
||||||
|
cashu = { path = "./crates/cashu", version = "=0.7.1" }
|
||||||
|
cdk = { path = "./crates/cdk", default-features = false, version = "=0.7.2" }
|
||||||
|
cdk-common = { path = "./crates/cdk-common", default-features = false, version = "=0.7.1" }
|
||||||
|
cdk-axum = { path = "./crates/cdk-axum", default-features = false, version = "=0.7.1" }
|
||||||
|
cdk-cln = { path = "./crates/cdk-cln", version = "=0.7.1" }
|
||||||
|
cdk-lnbits = { path = "./crates/cdk-lnbits", version = "=0.7.1" }
|
||||||
|
cdk-lnd = { path = "./crates/cdk-lnd", version = "=0.7.1" }
|
||||||
|
cdk-phoenixd = { path = "./crates/cdk-phoenixd", version = "=0.7.1" }
|
||||||
|
cdk-fake-wallet = { path = "./crates/cdk-fake-wallet", version = "=0.7.1" }
|
||||||
|
cdk-mint-rpc = { path = "./crates/cdk-mint-rpc", version = "=0.7.1" }
|
||||||
|
cdk-redb = { path = "./crates/cdk-redb", default-features = true, version = "=0.7.1" }
|
||||||
|
cdk-sqlite = { path = "./crates/cdk-sqlite", default-features = true, version = "=0.7.1" }
|
||||||
|
clap = { version = "4.5.31", features = ["derive"] }
|
||||||
|
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
||||||
|
cbor-diag = "0.1.12"
|
||||||
|
futures = { version = "0.3.28", default-features = false, features = ["async-await"] }
|
||||||
|
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
thiserror = { version = "1" }
|
||||||
|
tokio = { version = "1", default-features = false }
|
||||||
|
tokio-util = { version = "0.7.11", default-features = false }
|
||||||
|
tower-http = { version = "0.6.1", features = ["compression-full", "decompression-full", "cors", "trace"] }
|
||||||
|
tokio-tungstenite = { version = "0.26.0", default-features = false }
|
||||||
|
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
url = "2.3"
|
||||||
|
uuid = { version = "=1.12.1", features = ["v4", "serde"] }
|
||||||
|
utoipa = { version = "5.3.1", features = [
|
||||||
|
"preserve_order",
|
||||||
|
"preserve_path_order",
|
||||||
|
]}
|
||||||
|
serde_with = "3"
|
||||||
|
reqwest = { version = "0.12", default-features = false, features = [
|
||||||
|
"json",
|
||||||
|
"rustls-tls",
|
||||||
|
"rustls-tls-native-roots",
|
||||||
|
"socks",
|
||||||
|
"zstd",
|
||||||
|
"brotli",
|
||||||
|
"gzip",
|
||||||
|
"deflate",
|
||||||
|
]}
|
||||||
|
once_cell = "1.20.2"
|
||||||
|
instant = { version = "0.1", default-features = false }
|
||||||
|
rand = "0.8.5"
|
||||||
|
home = "0.5.5"
|
||||||
|
|
||||||
|
|
||||||
[workspace.metadata]
|
[workspace.metadata]
|
||||||
authors = ["CDK Developers"]
|
authors = ["CDK Developers"]
|
||||||
edition = "2021"
|
|
||||||
description = "Cashu Development Kit"
|
description = "Cashu Development Kit"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/cashubtc/cdk"
|
repository = "https://github.com/cashubtc/cdk"
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ The project is split up into several crates in the `crates/` directory:
|
|||||||
* [**cdk-axum**](./crates/cdk-axum/): Axum webserver for mint.
|
* [**cdk-axum**](./crates/cdk-axum/): Axum webserver for mint.
|
||||||
* [**cdk-cln**](./crates/cdk-cln/): CLN Lightning backend for mint.
|
* [**cdk-cln**](./crates/cdk-cln/): CLN Lightning backend for mint.
|
||||||
* [**cdk-lnd**](./crates/cdk-lnd/): Lnd Lightning backend for mint.
|
* [**cdk-lnd**](./crates/cdk-lnd/): Lnd Lightning backend for mint.
|
||||||
* [**cdk-strike**](./crates/cdk-strike/): Strike Lightning backend for mint.
|
|
||||||
* [**cdk-lnbits**](./crates/cdk-lnbits/): [LNbits](https://lnbits.com/) Lightning backend for mint.
|
* [**cdk-lnbits**](./crates/cdk-lnbits/): [LNbits](https://lnbits.com/) Lightning backend for mint.
|
||||||
* [**cdk-phoenixd**](./crates/cdk-phoenixd/): Phoenixd Lightning backend for mint.
|
* [**cdk-phoenixd**](./crates/cdk-phoenixd/): Phoenixd Lightning backend for mint.
|
||||||
* [**cdk-fake-wallet**](./crates/cdk-fake-wallet/): Fake Lightning backend for mint. To be used only for testing, quotes are automatically filled.
|
* [**cdk-fake-wallet**](./crates/cdk-fake-wallet/): Fake Lightning backend for mint. To be used only for testing, quotes are automatically filled.
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cashu"
|
name = "cashu"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
authors = ["CDK Developers"]
|
authors = ["CDK Developers"]
|
||||||
description = "Cashu shared types and crypto utilities, used as the foundation for the CDK and their crates"
|
description = "Cashu shared types and crypto utilities, used as the foundation for the CDK and their crates"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["mint", "wallet"]
|
default = ["mint", "wallet"]
|
||||||
@@ -17,28 +17,23 @@ wallet = []
|
|||||||
bench = []
|
bench = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uuid = { version = "=1.12.1", features = ["v4", "serde"], optional = true }
|
uuid = { workspace = true, optional = true }
|
||||||
bitcoin = { version = "0.32.2", features = [
|
bitcoin.workspace = true
|
||||||
"base64",
|
cbor-diag.workspace = true
|
||||||
"serde",
|
ciborium.workspace = true
|
||||||
"rand",
|
once_cell.workspace = true
|
||||||
"rand-std",
|
serde.workspace = true
|
||||||
] }
|
lightning-invoice.workspace = true
|
||||||
cbor-diag = "0.1.12"
|
thiserror.workspace = true
|
||||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
tracing.workspace = true
|
||||||
once_cell = "1.20.2"
|
url.workspace = true
|
||||||
serde = { version = "1", features = ["derive"] }
|
utoipa = { workspace = true, optional = true }
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
serde_json.workspace = true
|
||||||
thiserror = "2"
|
serde_with.workspace = true
|
||||||
tracing = "0.1"
|
|
||||||
url = "2.3"
|
|
||||||
utoipa = { version = "4", optional = true }
|
|
||||||
serde_json = "1"
|
|
||||||
serde_with = "3"
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bip39 = "2.0"
|
bip39.workspace = true
|
||||||
uuid = { version = "=1.12.1", features = ["v4", "serde"] }
|
uuid.workspace = true
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub struct PreSwap {
|
|||||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub struct SwapRequest {
|
pub struct SwapRequest {
|
||||||
/// Proofs that are to be spent in a `Swap`
|
/// Proofs that are to be spent in a `Swap`
|
||||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<Proof>))]
|
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
|
||||||
pub inputs: Proofs,
|
pub inputs: Proofs,
|
||||||
/// Blinded Messages for Mint to sign
|
/// Blinded Messages for Mint to sign
|
||||||
pub outputs: Vec<BlindedMessage>,
|
pub outputs: Vec<BlindedMessage>,
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ pub struct MeltBolt11Request<Q> {
|
|||||||
/// Quote ID
|
/// Quote ID
|
||||||
pub quote: Q,
|
pub quote: Q,
|
||||||
/// Proofs
|
/// Proofs
|
||||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<Proof>))]
|
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
|
||||||
pub inputs: Proofs,
|
pub inputs: Proofs,
|
||||||
/// Blinded Message that can be used to return change [NUT-08]
|
/// Blinded Message that can be used to return change [NUT-08]
|
||||||
/// Amount field of BlindedMessages `SHOULD` be set to zero
|
/// Amount field of BlindedMessages `SHOULD` be set to zero
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ pub struct Params<I> {
|
|||||||
|
|
||||||
/// Check state Settings
|
/// Check state Settings
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub struct SupportedSettings {
|
pub struct SupportedSettings {
|
||||||
/// Supported methods
|
/// Supported methods
|
||||||
pub supported: Vec<SupportedMethods>,
|
pub supported: Vec<SupportedMethods>,
|
||||||
@@ -34,6 +35,7 @@ pub struct SupportedSettings {
|
|||||||
|
|
||||||
/// Supported WS Methods
|
/// Supported WS Methods
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub struct SupportedMethods {
|
pub struct SupportedMethods {
|
||||||
/// Payment Method
|
/// Payment Method
|
||||||
pub method: PaymentMethod,
|
pub method: PaymentMethod,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ pub struct Settings {
|
|||||||
|
|
||||||
/// List of the methods and paths for which caching is enabled
|
/// List of the methods and paths for which caching is enabled
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub struct CachedEndpoint {
|
pub struct CachedEndpoint {
|
||||||
/// HTTP Method
|
/// HTTP Method
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
@@ -33,6 +34,7 @@ impl CachedEndpoint {
|
|||||||
/// HTTP method
|
/// HTTP method
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "UPPERCASE")]
|
#[serde(rename_all = "UPPERCASE")]
|
||||||
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub enum Method {
|
pub enum Method {
|
||||||
/// Get
|
/// Get
|
||||||
Get,
|
Get,
|
||||||
@@ -42,6 +44,7 @@ pub enum Method {
|
|||||||
|
|
||||||
/// Route path
|
/// Route path
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||||
pub enum Path {
|
pub enum Path {
|
||||||
/// Bolt11 Mint
|
/// Bolt11 Mint
|
||||||
#[serde(rename = "/v1/mint/bolt11")]
|
#[serde(rename = "/v1/mint/bolt11")]
|
||||||
|
|||||||
@@ -1,40 +1,35 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cdk-axum"
|
name = "cdk-axum"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
description = "Cashu CDK axum webserver"
|
description = "Cashu CDK axum webserver"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
redis = ["dep:redis"]
|
||||||
|
swagger = ["cdk/swagger", "dep:utoipa"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
async-trait = "0.1.83"
|
async-trait.workspace = true
|
||||||
axum = { version = "0.6.20", features = ["ws"] }
|
axum = { workspace = true, features = ["ws"] }
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
cdk = { workspace = true, features = [
|
||||||
"mint",
|
"mint",
|
||||||
] }
|
] }
|
||||||
tokio = { version = "1", default-features = false, features = ["io-util"] }
|
tokio.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tracing.workspace = true
|
||||||
"attributes",
|
utoipa = { workspace = true, optional = true }
|
||||||
"log",
|
futures.workspace = true
|
||||||
] }
|
|
||||||
utoipa = { version = "4", features = [
|
|
||||||
"preserve_order",
|
|
||||||
"preserve_path_order",
|
|
||||||
], optional = true }
|
|
||||||
futures = { version = "0.3.28", default-features = false }
|
|
||||||
moka = { version = "0.11.1", features = ["future"] }
|
moka = { version = "0.11.1", features = ["future"] }
|
||||||
serde_json = "1"
|
serde_json.workspace = true
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde.workspace = true
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
uuid.workspace = true
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
redis = { version = "0.23.3", features = [
|
redis = { version = "0.23.3", features = [
|
||||||
"tokio-rustls-comp",
|
"tokio-rustls-comp",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
|
|
||||||
[features]
|
|
||||||
redis = ["dep:redis"]
|
|
||||||
swagger = ["cdk/swagger", "dep:utoipa"]
|
|
||||||
|
|||||||
2
crates/cdk-axum/src/cache/mod.rs
vendored
2
crates/cdk-axum/src/cache/mod.rs
vendored
@@ -117,7 +117,7 @@ impl HttpCache {
|
|||||||
tti: Duration,
|
tti: Duration,
|
||||||
storage: Option<Box<dyn HttpCacheStorage + Send + Sync + 'static>>,
|
storage: Option<Box<dyn HttpCacheStorage + Send + Sync + 'static>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut storage = storage.unwrap_or_else(|| Box::new(InMemoryHttpCache::default()));
|
let mut storage = storage.unwrap_or_else(|| Box::<InMemoryHttpCache>::default());
|
||||||
storage.set_expiration_times(ttl, tti);
|
storage.set_expiration_times(ttl, tti);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ mod swagger_imports {
|
|||||||
|
|
||||||
#[cfg(feature = "swagger")]
|
#[cfg(feature = "swagger")]
|
||||||
use swagger_imports::*;
|
use swagger_imports::*;
|
||||||
#[cfg(feature = "swagger")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
/// CDK Mint State
|
/// CDK Mint State
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -75,16 +73,16 @@ pub struct MintState {
|
|||||||
KeysetResponse,
|
KeysetResponse,
|
||||||
KeySet,
|
KeySet,
|
||||||
KeySetInfo,
|
KeySetInfo,
|
||||||
MeltBolt11Request<Uuid>,
|
MeltBolt11Request<String>,
|
||||||
MeltQuoteBolt11Request,
|
MeltQuoteBolt11Request,
|
||||||
MeltQuoteBolt11Response<Uuid>,
|
MeltQuoteBolt11Response<String>,
|
||||||
MeltQuoteState,
|
MeltQuoteState,
|
||||||
MeltMethodSettings,
|
MeltMethodSettings,
|
||||||
MintBolt11Request<Uuid>,
|
MintBolt11Request<String>,
|
||||||
MintBolt11Response,
|
MintBolt11Response,
|
||||||
MintInfo,
|
MintInfo,
|
||||||
MintQuoteBolt11Request,
|
MintQuoteBolt11Request,
|
||||||
MintQuoteBolt11Response<Uuid>,
|
MintQuoteBolt11Response<String>,
|
||||||
MintQuoteState,
|
MintQuoteState,
|
||||||
MintMethodSettings,
|
MintMethodSettings,
|
||||||
MintVersion,
|
MintVersion,
|
||||||
@@ -148,18 +146,18 @@ pub async fn create_mint_router_with_custom_cache(
|
|||||||
let v1_router = Router::new()
|
let v1_router = Router::new()
|
||||||
.route("/keys", get(get_keys))
|
.route("/keys", get(get_keys))
|
||||||
.route("/keysets", get(get_keysets))
|
.route("/keysets", get(get_keysets))
|
||||||
.route("/keys/:keyset_id", get(get_keyset_pubkeys))
|
.route("/keys/{keyset_id}", get(get_keyset_pubkeys))
|
||||||
.route("/swap", post(cache_post_swap))
|
.route("/swap", post(cache_post_swap))
|
||||||
.route("/mint/quote/bolt11", post(post_mint_bolt11_quote))
|
.route("/mint/quote/bolt11", post(post_mint_bolt11_quote))
|
||||||
.route(
|
.route(
|
||||||
"/mint/quote/bolt11/:quote_id",
|
"/mint/quote/bolt11/{quote_id}",
|
||||||
get(get_check_mint_bolt11_quote),
|
get(get_check_mint_bolt11_quote),
|
||||||
)
|
)
|
||||||
.route("/mint/bolt11", post(cache_post_mint_bolt11))
|
.route("/mint/bolt11", post(cache_post_mint_bolt11))
|
||||||
.route("/melt/quote/bolt11", post(post_melt_bolt11_quote))
|
.route("/melt/quote/bolt11", post(post_melt_bolt11_quote))
|
||||||
.route("/ws", get(ws_handler))
|
.route("/ws", get(ws_handler))
|
||||||
.route(
|
.route(
|
||||||
"/melt/quote/bolt11/:quote_id",
|
"/melt/quote/bolt11/{quote_id}",
|
||||||
get(get_check_melt_bolt11_quote),
|
get(get_check_melt_bolt11_quote),
|
||||||
)
|
)
|
||||||
.route("/melt/bolt11", post(cache_post_melt_bolt11))
|
.route("/melt/bolt11", post(cache_post_melt_bolt11))
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ pub async fn get_keysets(State(state): State<MintState>) -> Result<Json<KeysetRe
|
|||||||
path = "/mint/quote/bolt11",
|
path = "/mint/quote/bolt11",
|
||||||
request_body(content = MintQuoteBolt11Request, description = "Request params", content_type = "application/json"),
|
request_body(content = MintQuoteBolt11Request, description = "Request params", content_type = "application/json"),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MintQuoteBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MintQuoteBolt11Response<String>, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
@@ -165,7 +165,7 @@ pub async fn post_mint_bolt11_quote(
|
|||||||
("quote_id" = String, description = "The quote ID"),
|
("quote_id" = String, description = "The quote ID"),
|
||||||
),
|
),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MintQuoteBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MintQuoteBolt11Response<String>, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
@@ -201,7 +201,7 @@ pub async fn ws_handler(State(state): State<MintState>, ws: WebSocketUpgrade) ->
|
|||||||
post,
|
post,
|
||||||
context_path = "/v1",
|
context_path = "/v1",
|
||||||
path = "/mint/bolt11",
|
path = "/mint/bolt11",
|
||||||
request_body(content = MintBolt11Request, description = "Request params", content_type = "application/json"),
|
request_body(content = MintBolt11Request<String>, description = "Request params", content_type = "application/json"),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MintBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MintBolt11Response, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
@@ -229,7 +229,7 @@ pub async fn post_mint_bolt11(
|
|||||||
path = "/melt/quote/bolt11",
|
path = "/melt/quote/bolt11",
|
||||||
request_body(content = MeltQuoteBolt11Request, description = "Quote params", content_type = "application/json"),
|
request_body(content = MeltQuoteBolt11Request, description = "Quote params", content_type = "application/json"),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response<String>, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
@@ -256,7 +256,7 @@ pub async fn post_melt_bolt11_quote(
|
|||||||
("quote_id" = String, description = "The quote ID"),
|
("quote_id" = String, description = "The quote ID"),
|
||||||
),
|
),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response<String>, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
@@ -284,9 +284,9 @@ pub async fn get_check_melt_bolt11_quote(
|
|||||||
post,
|
post,
|
||||||
context_path = "/v1",
|
context_path = "/v1",
|
||||||
path = "/melt/bolt11",
|
path = "/melt/bolt11",
|
||||||
request_body(content = MeltBolt11Request, description = "Melt params", content_type = "application/json"),
|
request_body(content = MeltBolt11Request<String>, description = "Melt params", content_type = "application/json"),
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response, content_type = "application/json"),
|
(status = 200, description = "Successful response", body = MeltQuoteBolt11Response<String>, content_type = "application/json"),
|
||||||
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
(status = 500, description = "Server error", body = ErrorResponse, content_type = "application/json")
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ pub struct WsContext {
|
|||||||
///
|
///
|
||||||
/// For simplicity sake this function will spawn tasks for each subscription and
|
/// For simplicity sake this function will spawn tasks for each subscription and
|
||||||
/// keep them in a hashmap, and will have a single subscriber for all of them.
|
/// keep them in a hashmap, and will have a single subscriber for all of them.
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
||||||
let (publisher, mut subscriber) = mpsc::channel(100);
|
let (publisher, mut subscriber) = mpsc::channel(100);
|
||||||
let mut context = WsContext {
|
let mut context = WsContext {
|
||||||
@@ -75,7 +74,7 @@ pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err)= socket.send(Message::Text(message)).await {
|
if let Err(err)= socket.send(Message::Text(message.into())).await {
|
||||||
tracing::error!("Could not send websocket message: {}", err);
|
tracing::error!("Could not send websocket message: {}", err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -92,7 +91,7 @@ pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
|||||||
match process(&mut context, request).await {
|
match process(&mut context, request).await {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
if let Err(err) = socket
|
if let Err(err) = socket
|
||||||
.send(Message::Text(result.to_string()))
|
.send(Message::Text(result.to_string().into()))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
tracing::error!("Could not send request: {}", err);
|
tracing::error!("Could not send request: {}", err);
|
||||||
|
|||||||
@@ -1,42 +1,33 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cdk-cli"
|
name = "cdk-cli"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
edition = "2021"
|
|
||||||
authors = ["CDK Developers"]
|
authors = ["CDK Developers"]
|
||||||
description = "Cashu cli wallet built on CDK"
|
description = "Cashu cli wallet built on CDK"
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage.workspace = true
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository.workspace = true
|
||||||
rust-version = "1.63.0" # MSRV
|
edition.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
bip39 = { version = "2.0", features = ["rand"] }
|
bip39.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["wallet"]}
|
cdk = { workspace = true, default-features = false, features = ["wallet"]}
|
||||||
cdk-redb = { path = "../cdk-redb", version = "0.7.1", default-features = false, features = ["wallet"] }
|
cdk-redb = { workspace = true, features = ["wallet"] }
|
||||||
cdk-sqlite = { path = "../cdk-sqlite", version = "0.7.1", default-features = false, features = ["wallet"] }
|
cdk-sqlite = { workspace = true, features = ["wallet"] }
|
||||||
clap = { version = "~4.0.32", features = ["derive"] }
|
clap.workspace = true
|
||||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
serde.workspace = true
|
||||||
serde_json = "1"
|
serde_json.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
tracing-subscriber.workspace = true
|
||||||
home = "0.5.5"
|
home.workspace = true
|
||||||
nostr-sdk = { version = "0.35.0", default-features = false, features = [
|
nostr-sdk = { version = "0.35.0", default-features = false, features = [
|
||||||
"nip04",
|
"nip04",
|
||||||
"nip44",
|
"nip44",
|
||||||
"nip59"
|
"nip59"
|
||||||
]}
|
]}
|
||||||
reqwest = { version = "0.12", default-features = false, features = [
|
reqwest.workspace = true
|
||||||
"json",
|
url.workspace = true
|
||||||
"rustls-tls",
|
serde_with.workspace = true
|
||||||
"rustls-tls-native-roots",
|
|
||||||
"socks",
|
|
||||||
]}
|
|
||||||
url = "2.3"
|
|
||||||
|
|
||||||
# Indirect dep
|
|
||||||
base64ct = "=1.6.0"
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ authors = ["CDK Developers"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
description = "CDK ln backend for cln"
|
description = "CDK ln backend for cln"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
bitcoin.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
cdk = { workspace = true, features = ["mint"] }
|
||||||
cln-rpc = "0.3.0"
|
cln-rpc = "0.3.0"
|
||||||
futures = { version = "0.3.28", default-features = false }
|
futures.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
tokio-util.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
uuid = { version = "1", features = ["v4"] }
|
uuid.workspace = true
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ impl MintLightning for Cln {
|
|||||||
self.wait_invoice_cancel_token.cancel()
|
self.wait_invoice_cancel_token.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
// Clippy thinks select is not stable but it compiles fine on MSRV (1.63.0)
|
|
||||||
async fn wait_any_invoice(
|
async fn wait_any_invoice(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cdk-common"
|
name = "cdk-common"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
edition = "2021"
|
|
||||||
authors = ["CDK Developers"]
|
authors = ["CDK Developers"]
|
||||||
description = "CDK common types and traits"
|
description = "CDK common types and traits"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
edition.workspace = true
|
||||||
license = "MIT"
|
rust-version = "1.75.0" # MSRV
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["mint", "wallet"]
|
default = ["mint", "wallet"]
|
||||||
@@ -17,31 +17,26 @@ wallet = ["cashu/wallet"]
|
|||||||
mint = ["cashu/mint", "dep:uuid"]
|
mint = ["cashu/mint", "dep:uuid"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
bitcoin = { version = "0.32.2", features = [
|
bitcoin.workspace = true
|
||||||
"base64",
|
cashu.workspace = true
|
||||||
"serde",
|
cbor-diag.workspace = true
|
||||||
"rand",
|
ciborium.workspace = true
|
||||||
"rand-std",
|
serde.workspace = true
|
||||||
] }
|
lightning-invoice.workspace = true
|
||||||
cashu = { path = "../cashu", default-features = false, version = "0.7.1" }
|
thiserror.workspace = true
|
||||||
cbor-diag = "0.1.12"
|
tracing.workspace = true
|
||||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
url.workspace = true
|
||||||
serde = { version = "1", features = ["derive"] }
|
uuid = { workspace = true, optional = true }
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
utoipa = { workspace = true, optional = true }
|
||||||
thiserror = "2"
|
futures.workspace = true
|
||||||
tracing = "0.1"
|
anyhow.workspace = true
|
||||||
url = "2.3"
|
serde_json.workspace = true
|
||||||
uuid = { version = "=1.12.1", features = ["v4", "serde"], optional = true }
|
serde_with.workspace = true
|
||||||
utoipa = { version = "4", optional = true }
|
|
||||||
futures = "0.3.31"
|
|
||||||
anyhow = "1.0"
|
|
||||||
serde_json = "1"
|
|
||||||
serde_with = "3"
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.5"
|
rand.workspace = true
|
||||||
bip39 = "2.0"
|
bip39.workspace = true
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ pub mod error;
|
|||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
pub mod lightning;
|
pub mod lightning;
|
||||||
pub mod pub_sub;
|
pub mod pub_sub;
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
pub mod subscription;
|
pub mod subscription;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
//! Subscription types and traits
|
//! Subscription types and traits
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use cashu::nut17::{self, Error, Kind, Notification};
|
use cashu::nut17::{self};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use cashu::nut17::{Error, Kind, Notification};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use cashu::{NotificationPayload, PublicKey};
|
use cashu::{NotificationPayload, PublicKey};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
|
use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
|
||||||
use crate::pub_sub::SubId;
|
use crate::pub_sub::SubId;
|
||||||
|
|
||||||
@@ -15,15 +22,18 @@ use crate::pub_sub::SubId;
|
|||||||
pub type Params = nut17::Params<SubId>;
|
pub type Params = nut17::Params<SubId>;
|
||||||
|
|
||||||
/// Wrapper around `nut17::Params` to implement `Indexable` for `Notification`.
|
/// Wrapper around `nut17::Params` to implement `Indexable` for `Notification`.
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct IndexableParams(Params);
|
pub struct IndexableParams(Params);
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
impl From<Params> for IndexableParams {
|
impl From<Params> for IndexableParams {
|
||||||
fn from(params: Params) -> Self {
|
fn from(params: Params) -> Self {
|
||||||
Self(params)
|
Self(params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
|
impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(params: IndexableParams) -> Result<Self, Self::Error> {
|
fn try_from(params: IndexableParams) -> Result<Self, Self::Error> {
|
||||||
@@ -49,12 +59,14 @@ impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
impl AsRef<SubId> for IndexableParams {
|
impl AsRef<SubId> for IndexableParams {
|
||||||
fn as_ref(&self) -> &SubId {
|
fn as_ref(&self) -> &SubId {
|
||||||
&self.0.id
|
&self.0.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
impl Indexable for NotificationPayload<Uuid> {
|
impl Indexable for NotificationPayload<Uuid> {
|
||||||
type Type = Notification;
|
type Type = Notification;
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ authors = ["CDK Developers"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
description = "CDK fake ln backend"
|
description = "CDK fake ln backend"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1.74"
|
async-trait.workspace = true
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
bitcoin.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
cdk = { workspace = true, features = ["mint"] }
|
||||||
futures = { version = "0.3.28", default-features = false }
|
futures.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
tokio-util.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
serde = "1"
|
serde.workspace = true
|
||||||
serde_json = "1"
|
serde_json.workspace = true
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
lightning-invoice.workspace = true
|
||||||
tokio-stream = "0.1.15"
|
tokio-stream = "0.1.15"
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ description = "Core Cashu Development Kit library implementing the Cashu protoco
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
http_subscription = ["cdk/http_subscription"]
|
http_subscription = ["cdk/http_subscription"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
axum = "0.6.20"
|
axum.workspace = true
|
||||||
rand = "0.8.5"
|
rand.workspace = true
|
||||||
bip39 = { version = "2.0", features = ["rand"] }
|
bip39 = { workspace = true, features = ["rand"] }
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
cashu = { path = "../cashu", features = ["mint", "wallet"] }
|
cashu = { path = "../cashu", features = ["mint", "wallet"] }
|
||||||
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
||||||
cdk-cln = { path = "../cdk-cln" }
|
cdk-cln = { path = "../cdk-cln" }
|
||||||
@@ -27,42 +27,34 @@ cdk-axum = { path = "../cdk-axum" }
|
|||||||
cdk-sqlite = { path = "../cdk-sqlite" }
|
cdk-sqlite = { path = "../cdk-sqlite" }
|
||||||
cdk-redb = { path = "../cdk-redb" }
|
cdk-redb = { path = "../cdk-redb" }
|
||||||
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
|
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
|
||||||
tower-http = { version = "0.4.4", features = ["cors"] }
|
futures = { workspace = true, default-features = false, features = [
|
||||||
futures = { version = "0.3.28", default-features = false, features = [
|
|
||||||
"executor",
|
"executor",
|
||||||
] }
|
] }
|
||||||
once_cell = "1.19.0"
|
once_cell.workspace = true
|
||||||
uuid = { version = "1", features = ["v4"] }
|
uuid.workspace = true
|
||||||
serde = "1"
|
serde.workspace = true
|
||||||
serde_json = "1"
|
serde_json.workspace = true
|
||||||
# ln-regtest-rs = { path = "../../../../ln-regtest-rs" }
|
# ln-regtest-rs = { path = "../../../../ln-regtest-rs" }
|
||||||
ln-regtest-rs = { git = "https://github.com/thesimplekid/ln-regtest-rs", rev = "bf09ad6" }
|
ln-regtest-rs = { git = "https://github.com/thesimplekid/ln-regtest-rs", rev = "ed24716" }
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tracing.workspace = true
|
||||||
"attributes",
|
tracing-subscriber.workspace = true
|
||||||
"log",
|
tokio-tungstenite.workspace = true
|
||||||
] }
|
tower-http = { workspace = true, features = ["cors"] }
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
|
||||||
tower-service = "0.3.3"
|
tower-service = "0.3.3"
|
||||||
tokio-tungstenite = "0.24.0"
|
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
tokio = { version = "1", features = [
|
tokio.workspace = true
|
||||||
"rt-multi-thread",
|
|
||||||
"time",
|
|
||||||
"macros",
|
|
||||||
"sync",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
tokio = { version = "1", features = ["rt", "macros", "sync", "time"] }
|
tokio = { workspace = true, features = ["rt", "macros", "sync", "time"] }
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bip39 = { version = "2.0", features = ["rand"] }
|
bip39 = { workspace = true, features = ["rand"] }
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
||||||
cdk-axum = { path = "../cdk-axum" }
|
cdk-axum = { path = "../cdk-axum" }
|
||||||
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
|
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
|
||||||
tower-http = { version = "0.4.4", features = ["cors"] }
|
tower-http = { workspace = true, features = ["cors"] }
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ pub async fn attempt_to_swap_pending(wallet: &Wallet) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
pub async fn wait_for_mint_to_be_paid(
|
pub async fn wait_for_mint_to_be_paid(
|
||||||
wallet: &Wallet,
|
wallet: &Wallet,
|
||||||
mint_quote_id: &str,
|
mint_quote_id: &str,
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ async fn test_regtest_mint_melt_round_trip() -> Result<()> {
|
|||||||
let melt = wallet.melt_quote(invoice, None).await?;
|
let melt = wallet.melt_quote(invoice, None).await?;
|
||||||
|
|
||||||
write
|
write
|
||||||
.send(Message::Text(serde_json::to_string(&json!({
|
.send(Message::Text(
|
||||||
|
serde_json::to_string(&json!({
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"method": "subscribe",
|
"method": "subscribe",
|
||||||
@@ -122,7 +123,9 @@ async fn test_regtest_mint_melt_round_trip() -> Result<()> {
|
|||||||
"subId": "test-sub",
|
"subId": "test-sub",
|
||||||
}
|
}
|
||||||
|
|
||||||
}))?))
|
}))?
|
||||||
|
.into(),
|
||||||
|
))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ authors = ["CDK Developers"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
description = "CDK ln backend for lnbits"
|
description = "CDK ln backend for lnbits"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
axum = "0.6.20"
|
axum.workspace = true
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
bitcoin.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
cdk = { workspace = true, features = ["mint"] }
|
||||||
futures = { version = "0.3.28", default-features = false }
|
futures.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
tokio-util.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
lnbits-rs = "0.3.0"
|
lnbits-rs = "0.4.0"
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ impl MintLightning for LNbits {
|
|||||||
self.wait_invoice_cancel_token.cancel()
|
self.wait_invoice_cancel_token.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
async fn wait_any_invoice(
|
async fn wait_any_invoice(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||||
@@ -182,7 +181,7 @@ impl MintLightning for LNbits {
|
|||||||
) -> Result<PayInvoiceResponse, Self::Err> {
|
) -> Result<PayInvoiceResponse, Self::Err> {
|
||||||
let pay_response = self
|
let pay_response = self
|
||||||
.lnbits_api
|
.lnbits_api
|
||||||
.pay_invoice(&melt_quote.request)
|
.pay_invoice(&melt_quote.request, None)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
tracing::error!("Could not pay invoice");
|
tracing::error!("Could not pay invoice");
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ repository = "https://github.com/cashubtc/cdk.git"
|
|||||||
description = "CDK ln backend for lnd"
|
description = "CDK ln backend for lnd"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
cdk = { path = "../cdk", version= "0.7.1", default-features = false, features = ["mint"] }
|
cdk = { workspace = true, features = ["mint"] }
|
||||||
fedimint-tonic-lnd = "0.2.0"
|
fedimint-tonic-lnd = "0.2.0"
|
||||||
futures = { version = "0.3.28", default-features = false }
|
futures.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
tokio-util.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
|
|||||||
@@ -1,14 +1,4 @@
|
|||||||
|
|
||||||
## Minimum Supported Rust Version (MSRV)
|
## Minimum Supported Rust Version (MSRV)
|
||||||
|
|
||||||
The `cdk` library should always compile with any combination of features on Rust **1.66.0**.
|
The `cdk-lnd` library should always compile with any combination of features on Rust **1.75.0**.
|
||||||
|
|
||||||
To build and test with the MSRV you will need to pin the below dependency versions:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cargo update -p home --precise 0.5.5
|
|
||||||
cargo update -p prost --precise 0.12.3
|
|
||||||
cargo update -p prost-types --precise 0.12.3
|
|
||||||
cargo update -p prost-build --precise 0.12.3
|
|
||||||
cargo update -p prost-derive --precise 0.12.3
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -7,35 +7,32 @@ description = "CDK mintd mint managment RPC client and server"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "cdk-mint-cli"
|
name = "cdk-mint-cli"
|
||||||
path = "src/bin/mint_rpc_cli.rs"
|
path = "src/bin/mint_rpc_cli.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
cdk = { workspace = true, features = [
|
||||||
"mint",
|
"mint",
|
||||||
] }
|
] }
|
||||||
clap = { version = "~4.0.32", features = ["derive"] }
|
clap.workspace = true
|
||||||
tonic = { version = "0.9", features = [
|
tonic = { version = "0.12.3", features = [
|
||||||
"channel",
|
"channel",
|
||||||
"tls",
|
"tls",
|
||||||
"tls-webpki-roots",
|
"tls-webpki-roots",
|
||||||
] }
|
] }
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tracing.workspace = true
|
||||||
"attributes",
|
tracing-subscriber.workspace = true
|
||||||
"log",
|
tokio.workspace = true
|
||||||
] }
|
serde_json.workspace = true
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
serde.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
thiserror.workspace = true
|
||||||
serde_json = "1"
|
prost = "0.13.1"
|
||||||
serde = { version = "1", features = ["derive"] }
|
home.workspace = true
|
||||||
thiserror = "1"
|
|
||||||
prost = "0.11.0"
|
|
||||||
home = "0.5.5"
|
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.9"
|
tonic-build = "0.12"
|
||||||
|
|||||||
@@ -7,53 +7,49 @@ license = "MIT"
|
|||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
description = "CDK mint binary"
|
description = "CDK mint binary"
|
||||||
|
rust-version = "1.75.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["management-rpc"]
|
default = ["management-rpc"]
|
||||||
swagger = ["cdk-axum/swagger", "dep:utoipa", "dep:utoipa-swagger-ui"]
|
swagger = ["cdk-axum/swagger", "dep:utoipa", "dep:utoipa-swagger-ui"]
|
||||||
redis = ["cdk-axum/redis"]
|
redis = ["cdk-axum/redis"]
|
||||||
management-rpc = ["cdk-mint-rpc"]
|
management-rpc = ["cdk-mint-rpc"]
|
||||||
|
# MSRV is not commited to with redb enabled
|
||||||
|
redb = ["dep:cdk-redb"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
axum = "0.6.20"
|
async-trait.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
axum.workspace = true
|
||||||
|
cdk = { workspace = true, features = [
|
||||||
"mint",
|
"mint",
|
||||||
] }
|
] }
|
||||||
cdk-redb = { path = "../cdk-redb", version = "0.7.1", default-features = false, features = [
|
cdk-redb = { workspace = true, features = [
|
||||||
|
"mint",
|
||||||
|
], optional = true }
|
||||||
|
cdk-sqlite = { workspace = true, features = [
|
||||||
"mint",
|
"mint",
|
||||||
] }
|
] }
|
||||||
cdk-sqlite = { path = "../cdk-sqlite", version = "0.7.1", default-features = false, features = [
|
cdk-cln.workspace = true
|
||||||
"mint",
|
cdk-lnbits.workspace = true
|
||||||
] }
|
cdk-phoenixd.workspace = true
|
||||||
cdk-cln = { path = "../cdk-cln", version = "0.7.1", default-features = false }
|
cdk-lnd.workspace = true
|
||||||
cdk-lnbits = { path = "../cdk-lnbits", version = "0.7.1", default-features = false }
|
cdk-fake-wallet.workspace = true
|
||||||
cdk-phoenixd = { path = "../cdk-phoenixd", version = "0.7.1", default-features = false }
|
cdk-axum.workspace = true
|
||||||
cdk-lnd = { path = "../cdk-lnd", version = "0.7.1", default-features = false }
|
cdk-mint-rpc = { workspace = true, optional = true }
|
||||||
cdk-fake-wallet = { path = "../cdk-fake-wallet", version = "0.7.1", default-features = false }
|
|
||||||
cdk-strike = { path = "../cdk-strike", version = "0.7.1" }
|
|
||||||
cdk-axum = { path = "../cdk-axum", version = "0.7.1", default-features = false }
|
|
||||||
cdk-mint-rpc = { path = "../cdk-mint-rpc", version = "0.7.1", default-features = false, optional = true }
|
|
||||||
config = { version = "0.13.3", features = ["toml"] }
|
config = { version = "0.13.3", features = ["toml"] }
|
||||||
clap = { version = "~4.0.32", features = ["derive"] }
|
clap.workspace = true
|
||||||
bitcoin = { version = "0.32.2", features = [
|
bitcoin.workspace = true
|
||||||
"base64",
|
tokio = { workspace = true, default-features = false, features = ["signal"] }
|
||||||
"serde",
|
tracing.workspace = true
|
||||||
"rand",
|
tracing-subscriber.workspace = true
|
||||||
"rand-std",
|
futures.workspace = true
|
||||||
] }
|
serde.workspace = true
|
||||||
tokio = { version = "1", default-features = false, features = ["signal"] }
|
bip39.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tower-http = { workspace = true, features = ["compression-full", "decompression-full"] }
|
||||||
"attributes",
|
tower = "0.5.2"
|
||||||
"log",
|
lightning-invoice.workspace = true
|
||||||
] }
|
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
|
||||||
futures = { version = "0.3.28", default-features = false }
|
|
||||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
|
||||||
bip39 = { version = "2.0", features = ["rand"] }
|
|
||||||
tower-http = { version = "0.4.4", features = ["cors", "compression-full"] }
|
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
|
||||||
home = "0.5.5"
|
home = "0.5.5"
|
||||||
url = "2.3"
|
url.workspace = true
|
||||||
utoipa = { version = "4", optional = true }
|
utoipa = { workspace = true, optional = true }
|
||||||
utoipa-swagger-ui = { version = "4", features = ["axum"], optional = true }
|
utoipa-swagger-ui = { version = "9.0.0", features = ["axum"], optional = true }
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ pub enum LnBackend {
|
|||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
Cln,
|
Cln,
|
||||||
Strike,
|
|
||||||
LNbits,
|
LNbits,
|
||||||
FakeWallet,
|
FakeWallet,
|
||||||
Phoenixd,
|
Phoenixd,
|
||||||
@@ -60,7 +59,6 @@ impl std::str::FromStr for LnBackend {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
"cln" => Ok(LnBackend::Cln),
|
"cln" => Ok(LnBackend::Cln),
|
||||||
"strike" => Ok(LnBackend::Strike),
|
|
||||||
"lnbits" => Ok(LnBackend::LNbits),
|
"lnbits" => Ok(LnBackend::LNbits),
|
||||||
"fakewallet" => Ok(LnBackend::FakeWallet),
|
"fakewallet" => Ok(LnBackend::FakeWallet),
|
||||||
"phoenixd" => Ok(LnBackend::Phoenixd),
|
"phoenixd" => Ok(LnBackend::Phoenixd),
|
||||||
@@ -93,12 +91,6 @@ impl Default for Ln {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
||||||
pub struct Strike {
|
|
||||||
pub api_key: String,
|
|
||||||
pub supported_units: Option<Vec<CurrencyUnit>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
pub struct LNbits {
|
pub struct LNbits {
|
||||||
pub admin_api_key: String,
|
pub admin_api_key: String,
|
||||||
@@ -172,6 +164,7 @@ fn default_max_delay_time() -> u64 {
|
|||||||
pub enum DatabaseEngine {
|
pub enum DatabaseEngine {
|
||||||
#[default]
|
#[default]
|
||||||
Sqlite,
|
Sqlite,
|
||||||
|
#[cfg(feature = "redb")]
|
||||||
Redb,
|
Redb,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +174,7 @@ impl std::str::FromStr for DatabaseEngine {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
"sqlite" => Ok(DatabaseEngine::Sqlite),
|
"sqlite" => Ok(DatabaseEngine::Sqlite),
|
||||||
|
#[cfg(feature = "redb")]
|
||||||
"redb" => Ok(DatabaseEngine::Redb),
|
"redb" => Ok(DatabaseEngine::Redb),
|
||||||
_ => Err(format!("Unknown database engine: {}", s)),
|
_ => Err(format!("Unknown database engine: {}", s)),
|
||||||
}
|
}
|
||||||
@@ -199,7 +193,6 @@ pub struct Settings {
|
|||||||
pub mint_info: MintInfo,
|
pub mint_info: MintInfo,
|
||||||
pub ln: Ln,
|
pub ln: Ln,
|
||||||
pub cln: Option<Cln>,
|
pub cln: Option<Cln>,
|
||||||
pub strike: Option<Strike>,
|
|
||||||
pub lnbits: Option<LNbits>,
|
pub lnbits: Option<LNbits>,
|
||||||
pub phoenixd: Option<Phoenixd>,
|
pub phoenixd: Option<Phoenixd>,
|
||||||
pub lnd: Option<Lnd>,
|
pub lnd: Option<Lnd>,
|
||||||
@@ -291,10 +284,6 @@ impl Settings {
|
|||||||
settings.cln.is_some(),
|
settings.cln.is_some(),
|
||||||
"CLN backend requires a valid config."
|
"CLN backend requires a valid config."
|
||||||
),
|
),
|
||||||
LnBackend::Strike => assert!(
|
|
||||||
settings.strike.is_some(),
|
|
||||||
"Strike backend requires a valid config."
|
|
||||||
),
|
|
||||||
LnBackend::LNbits => assert!(
|
LnBackend::LNbits => assert!(
|
||||||
settings.lnbits.is_some(),
|
settings.lnbits.is_some(),
|
||||||
"LNbits backend requires a valid config"
|
"LNbits backend requires a valid config"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use cdk::nuts::CurrencyUnit;
|
|||||||
use crate::config::MintManagementRpc;
|
use crate::config::MintManagementRpc;
|
||||||
use crate::config::{
|
use crate::config::{
|
||||||
Cln, Database, DatabaseEngine, FakeWallet, Info, LNbits, Ln, LnBackend, Lnd, MintInfo,
|
Cln, Database, DatabaseEngine, FakeWallet, Info, LNbits, Ln, LnBackend, Lnd, MintInfo,
|
||||||
Phoenixd, Settings, Strike,
|
Phoenixd, Settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ENV_WORK_DIR: &str = "CDK_MINTD_WORK_DIR";
|
pub const ENV_WORK_DIR: &str = "CDK_MINTD_WORK_DIR";
|
||||||
@@ -45,9 +45,6 @@ pub const ENV_CLN_RPC_PATH: &str = "CDK_MINTD_CLN_RPC_PATH";
|
|||||||
pub const ENV_CLN_BOLT12: &str = "CDK_MINTD_CLN_BOLT12";
|
pub const ENV_CLN_BOLT12: &str = "CDK_MINTD_CLN_BOLT12";
|
||||||
pub const ENV_CLN_FEE_PERCENT: &str = "CDK_MINTD_CLN_FEE_PERCENT";
|
pub const ENV_CLN_FEE_PERCENT: &str = "CDK_MINTD_CLN_FEE_PERCENT";
|
||||||
pub const ENV_CLN_RESERVE_FEE_MIN: &str = "CDK_MINTD_CLN_RESERVE_FEE_MIN";
|
pub const ENV_CLN_RESERVE_FEE_MIN: &str = "CDK_MINTD_CLN_RESERVE_FEE_MIN";
|
||||||
// Strike
|
|
||||||
pub const ENV_STRIKE_API_KEY: &str = "CDK_MINTD_STRIKE_API_KEY";
|
|
||||||
pub const ENV_STRIKE_SUPPORTED_UNITS: &str = "CDK_MINTD_STRIKE_SUPPORTED_UNITS";
|
|
||||||
// LND environment variables
|
// LND environment variables
|
||||||
pub const ENV_LND_ADDRESS: &str = "CDK_MINTD_LND_ADDRESS";
|
pub const ENV_LND_ADDRESS: &str = "CDK_MINTD_LND_ADDRESS";
|
||||||
pub const ENV_LND_CERT_FILE: &str = "CDK_MINTD_LND_CERT_FILE";
|
pub const ENV_LND_CERT_FILE: &str = "CDK_MINTD_LND_CERT_FILE";
|
||||||
@@ -107,9 +104,6 @@ impl Settings {
|
|||||||
LnBackend::Cln => {
|
LnBackend::Cln => {
|
||||||
self.cln = Some(self.cln.clone().unwrap_or_default().from_env());
|
self.cln = Some(self.cln.clone().unwrap_or_default().from_env());
|
||||||
}
|
}
|
||||||
LnBackend::Strike => {
|
|
||||||
self.strike = Some(self.strike.clone().unwrap_or_default().from_env());
|
|
||||||
}
|
|
||||||
LnBackend::LNbits => {
|
LnBackend::LNbits => {
|
||||||
self.lnbits = Some(self.lnbits.clone().unwrap_or_default().from_env());
|
self.lnbits = Some(self.lnbits.clone().unwrap_or_default().from_env());
|
||||||
}
|
}
|
||||||
@@ -298,27 +292,6 @@ impl Cln {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Strike {
|
|
||||||
pub fn from_env(mut self) -> Self {
|
|
||||||
// API Key
|
|
||||||
if let Ok(api_key) = env::var(ENV_STRIKE_API_KEY) {
|
|
||||||
self.api_key = api_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supported Units - expects comma-separated list
|
|
||||||
if let Ok(units_str) = env::var(ENV_STRIKE_SUPPORTED_UNITS) {
|
|
||||||
self.supported_units = Some(
|
|
||||||
units_str
|
|
||||||
.split(',')
|
|
||||||
.filter_map(|s| s.trim().parse().ok())
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Lnd {
|
impl Lnd {
|
||||||
pub fn from_env(mut self) -> Self {
|
pub fn from_env(mut self) -> Self {
|
||||||
if let Ok(address) = env::var(ENV_LND_ADDRESS) {
|
if let Ok(address) = env::var(ENV_LND_ADDRESS) {
|
||||||
|
|||||||
@@ -5,15 +5,13 @@
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use axum::http::Request;
|
use axum::Router;
|
||||||
use axum::middleware::Next;
|
|
||||||
use axum::response::Response;
|
|
||||||
use axum::{middleware, Router};
|
|
||||||
use bip39::Mnemonic;
|
use bip39::Mnemonic;
|
||||||
use cdk::cdk_database::{self, MintDatabase};
|
use cdk::cdk_database::{self, MintDatabase};
|
||||||
use cdk::cdk_lightning;
|
use cdk::cdk_lightning;
|
||||||
@@ -30,12 +28,15 @@ use cdk_mintd::cli::CLIArgs;
|
|||||||
use cdk_mintd::config::{self, DatabaseEngine, LnBackend};
|
use cdk_mintd::config::{self, DatabaseEngine, LnBackend};
|
||||||
use cdk_mintd::env_vars::ENV_WORK_DIR;
|
use cdk_mintd::env_vars::ENV_WORK_DIR;
|
||||||
use cdk_mintd::setup::LnBackendSetup;
|
use cdk_mintd::setup::LnBackendSetup;
|
||||||
|
#[cfg(feature = "redb")]
|
||||||
use cdk_redb::MintRedbDatabase;
|
use cdk_redb::MintRedbDatabase;
|
||||||
use cdk_sqlite::MintSqliteDatabase;
|
use cdk_sqlite::MintSqliteDatabase;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tokio::sync::Notify;
|
use tokio::sync::Notify;
|
||||||
|
use tower::ServiceBuilder;
|
||||||
use tower_http::compression::CompressionLayer;
|
use tower_http::compression::CompressionLayer;
|
||||||
use tower_http::cors::CorsLayer;
|
use tower_http::decompression::RequestDecompressionLayer;
|
||||||
|
use tower_http::trace::TraceLayer;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
#[cfg(feature = "swagger")]
|
#[cfg(feature = "swagger")]
|
||||||
use utoipa::OpenApi;
|
use utoipa::OpenApi;
|
||||||
@@ -49,10 +50,11 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let sqlx_filter = "sqlx=warn";
|
let sqlx_filter = "sqlx=warn";
|
||||||
let hyper_filter = "hyper=warn";
|
let hyper_filter = "hyper=warn";
|
||||||
let h2_filter = "h2=warn";
|
let h2_filter = "h2=warn";
|
||||||
|
let tower_http = "tower_http=warn";
|
||||||
|
|
||||||
let env_filter = EnvFilter::new(format!(
|
let env_filter = EnvFilter::new(format!(
|
||||||
"{},{},{},{}",
|
"{},{},{},{},{}",
|
||||||
default_filter, sqlx_filter, hyper_filter, h2_filter
|
default_filter, sqlx_filter, hyper_filter, h2_filter, tower_http
|
||||||
));
|
));
|
||||||
|
|
||||||
tracing_subscriber::fmt().with_env_filter(env_filter).init();
|
tracing_subscriber::fmt().with_env_filter(env_filter).init();
|
||||||
@@ -100,6 +102,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
Arc::new(sqlite_db)
|
Arc::new(sqlite_db)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "redb")]
|
||||||
DatabaseEngine::Redb => {
|
DatabaseEngine::Redb => {
|
||||||
let redb_path = work_dir.join("cdk-mintd.redb");
|
let redb_path = work_dir.join("cdk-mintd.redb");
|
||||||
Arc::new(MintRedbDatabase::new(&redb_path)?)
|
Arc::new(MintRedbDatabase::new(&redb_path)?)
|
||||||
@@ -180,29 +183,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
mint_builder = mint_builder.add_supported_websockets(nut17_supported);
|
mint_builder = mint_builder.add_supported_websockets(nut17_supported);
|
||||||
}
|
}
|
||||||
LnBackend::Strike => {
|
|
||||||
let strike_settings = settings.clone().strike.expect("Checked on config load");
|
|
||||||
|
|
||||||
for unit in strike_settings
|
|
||||||
.clone()
|
|
||||||
.supported_units
|
|
||||||
.unwrap_or(vec![CurrencyUnit::Sat])
|
|
||||||
{
|
|
||||||
let strike = strike_settings
|
|
||||||
.setup(&mut ln_routers, &settings, unit.clone())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
mint_builder = mint_builder.add_ln_backend(
|
|
||||||
unit.clone(),
|
|
||||||
PaymentMethod::Bolt11,
|
|
||||||
mint_melt_limits,
|
|
||||||
Arc::new(strike),
|
|
||||||
);
|
|
||||||
let nut17_supported = SupportedMethods::new(PaymentMethod::Bolt11, unit);
|
|
||||||
|
|
||||||
mint_builder = mint_builder.add_supported_websockets(nut17_supported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LnBackend::LNbits => {
|
LnBackend::LNbits => {
|
||||||
let lnbits_settings = settings.clone().lnbits.expect("Checked on config load");
|
let lnbits_settings = settings.clone().lnbits.expect("Checked on config load");
|
||||||
let lnbits = lnbits_settings
|
let lnbits = lnbits_settings
|
||||||
@@ -341,9 +321,12 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let mut mint_service = Router::new()
|
let mut mint_service = Router::new()
|
||||||
.merge(v1_service)
|
.merge(v1_service)
|
||||||
.layer(CompressionLayer::new())
|
.layer(
|
||||||
.layer(middleware::from_fn(logging_middleware))
|
ServiceBuilder::new()
|
||||||
.layer(CorsLayer::permissive());
|
.layer(RequestDecompressionLayer::new())
|
||||||
|
.layer(CompressionLayer::new()),
|
||||||
|
)
|
||||||
|
.layer(TraceLayer::new_for_http());
|
||||||
|
|
||||||
#[cfg(feature = "swagger")]
|
#[cfg(feature = "swagger")]
|
||||||
{
|
{
|
||||||
@@ -406,13 +389,13 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
mint.set_quote_ttl(QuoteTTL::new(10_000, 10_000)).await?;
|
mint.set_quote_ttl(QuoteTTL::new(10_000, 10_000)).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let axum_result = axum::Server::bind(
|
let socket_addr = SocketAddr::from_str(&format!("{}:{}", listen_addr, listen_port))?;
|
||||||
&format!("{}:{}", listen_addr, listen_port)
|
|
||||||
.as_str()
|
let listener = tokio::net::TcpListener::bind(socket_addr).await?;
|
||||||
.parse()?,
|
|
||||||
)
|
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||||
.serve(mint_service.into_make_service())
|
|
||||||
.with_graceful_shutdown(shutdown_signal());
|
let axum_result = axum::serve(listener, mint_service).with_graceful_shutdown(shutdown_signal());
|
||||||
|
|
||||||
match axum_result.await {
|
match axum_result.await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -437,29 +420,6 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logs infos about the request and the response
|
|
||||||
async fn logging_middleware<B>(req: Request<B>, next: Next<B>) -> Response {
|
|
||||||
let start = std::time::Instant::now();
|
|
||||||
let path = req.uri().path().to_owned();
|
|
||||||
let method = req.method().clone();
|
|
||||||
|
|
||||||
let response = next.run(req).await;
|
|
||||||
|
|
||||||
let duration = start.elapsed();
|
|
||||||
let status = response.status();
|
|
||||||
let compression = response
|
|
||||||
.headers()
|
|
||||||
.get("content-encoding")
|
|
||||||
.map(|h| h.to_str().unwrap_or("none"))
|
|
||||||
.unwrap_or("none");
|
|
||||||
|
|
||||||
tracing::trace!(
|
|
||||||
"Request: {method} {path} | Status: {status} | Compression: {compression} | Duration: {duration:?}",
|
|
||||||
);
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
|
||||||
|
|
||||||
fn work_dir() -> Result<PathBuf> {
|
fn work_dir() -> Result<PathBuf> {
|
||||||
let home_dir = home::home_dir().ok_or(anyhow!("Unknown home dir"))?;
|
let home_dir = home::home_dir().ok_or(anyhow!("Unknown home dir"))?;
|
||||||
let dir = home_dir.join(".cdk-mintd");
|
let dir = home_dir.join(".cdk-mintd");
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
use axum::{async_trait, Router};
|
use async_trait::async_trait;
|
||||||
|
use axum::Router;
|
||||||
use bip39::rand::{thread_rng, Rng};
|
use bip39::rand::{thread_rng, Rng};
|
||||||
use cdk::cdk_lightning::MintLightning;
|
use cdk::cdk_lightning::MintLightning;
|
||||||
use cdk::mint::FeeReserve;
|
use cdk::mint::FeeReserve;
|
||||||
@@ -50,40 +51,6 @@ impl LnBackendSetup for config::Cln {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl LnBackendSetup for config::Strike {
|
|
||||||
async fn setup(
|
|
||||||
&self,
|
|
||||||
routers: &mut Vec<Router>,
|
|
||||||
settings: &Settings,
|
|
||||||
unit: CurrencyUnit,
|
|
||||||
) -> anyhow::Result<cdk_strike::Strike> {
|
|
||||||
let api_key = &self.api_key;
|
|
||||||
|
|
||||||
// Channel used for strike web hook
|
|
||||||
let (sender, receiver) = tokio::sync::mpsc::channel(8);
|
|
||||||
let webhook_endpoint = format!("/webhook/{}/invoice", unit);
|
|
||||||
|
|
||||||
let mint_url: MintUrl = settings.info.url.parse()?;
|
|
||||||
let webhook_url = mint_url.join(&webhook_endpoint)?;
|
|
||||||
|
|
||||||
let strike = cdk_strike::Strike::new(
|
|
||||||
api_key.clone(),
|
|
||||||
unit,
|
|
||||||
Arc::new(Mutex::new(Some(receiver))),
|
|
||||||
webhook_url.to_string(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let router = strike
|
|
||||||
.create_invoice_webhook(&webhook_endpoint, sender)
|
|
||||||
.await?;
|
|
||||||
routers.push(router);
|
|
||||||
|
|
||||||
Ok(strike)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LnBackendSetup for config::LNbits {
|
impl LnBackendSetup for config::LNbits {
|
||||||
async fn setup(
|
async fn setup(
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ authors = ["CDK Developers"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
description = "CDK ln backend for phoenixd"
|
description = "CDK ln backend for phoenixd"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
anyhow = "1"
|
anyhow.workspace = true
|
||||||
axum = "0.6.20"
|
axum.workspace = true
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
bitcoin.workspace = true
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
cdk = { workspace = true, features = ["mint"] }
|
||||||
futures = { version = "0.3.28", default-features = false }
|
futures.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
tokio-util.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
tracing.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
phoenixd-rs = "0.4.0"
|
phoenixd-rs = "0.5.0"
|
||||||
uuid = { version = "1", features = ["v4"] }
|
uuid.workspace = true
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ impl MintLightning for Phoenixd {
|
|||||||
self.wait_invoice_cancel_token.cancel()
|
self.wait_invoice_cancel_token.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
async fn wait_any_invoice(
|
async fn wait_any_invoice(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||||
|
|||||||
@@ -7,24 +7,21 @@ description = "Redb storage backend for CDK"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.66.0" # MSRV
|
rust-version = "1.81.0" # MSRV
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
[features]
|
[features]
|
||||||
default = ["mint", "wallet"]
|
default = ["mint", "wallet"]
|
||||||
mint = []
|
mint = ["cdk-common/mint"]
|
||||||
wallet = []
|
wallet = ["cdk-common/wallet"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
cdk-common.workspace = true
|
||||||
redb = "2.2.0"
|
redb = "2.4.0"
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tracing.workspace = true
|
||||||
"attributes",
|
serde.workspace = true
|
||||||
"log",
|
serde_json.workspace = true
|
||||||
] }
|
lightning-invoice.workspace = true
|
||||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
uuid.workspace = true
|
||||||
serde_json = "1"
|
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ description = "Indexdb storage backend for CDK in the browser"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
[features]
|
[features]
|
||||||
@@ -16,11 +16,11 @@ wallet = ["cdk/wallet"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rexie = "0.6.0"
|
rexie = "0.6.0"
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false }
|
cdk.workspace = true
|
||||||
async-trait = "0.1.74"
|
async-trait.workspace = true
|
||||||
tokio = { version = "1", default-features = false }
|
tokio.workspace = true
|
||||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
serde.workspace = true
|
||||||
serde_json = "1"
|
serde_json.workspace = true
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
serde-wasm-bindgen = "0.6.5"
|
serde-wasm-bindgen = "0.6.5"
|
||||||
web-sys = { version = "0.3.69", default-features = false, features = ["console"] }
|
web-sys = { version = "0.3.69", default-features = false, features = ["console"] }
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ description = "SQLite storage backend for CDK"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.66.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
[features]
|
[features]
|
||||||
default = ["mint", "wallet"]
|
default = ["mint", "wallet"]
|
||||||
mint = []
|
mint = ["cdk-common/mint"]
|
||||||
wallet = []
|
wallet = ["cdk-common/wallet"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
cdk-common.workspace = true
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
bitcoin.workspace = true
|
||||||
sqlx = { version = "0.6.3", default-features = false, features = [
|
sqlx = { version = "0.6.3", default-features = false, features = [
|
||||||
"runtime-tokio-rustls",
|
"runtime-tokio-rustls",
|
||||||
"sqlite",
|
"sqlite",
|
||||||
@@ -26,12 +26,9 @@ sqlx = { version = "0.6.3", default-features = false, features = [
|
|||||||
"migrate",
|
"migrate",
|
||||||
"uuid",
|
"uuid",
|
||||||
] }
|
] }
|
||||||
thiserror = "1"
|
thiserror.workspace = true
|
||||||
tokio = { version = "1", features = ["time", "macros", "sync"] }
|
tokio.workspace = true
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
tracing.workspace = true
|
||||||
"attributes",
|
serde_json.workspace = true
|
||||||
"log",
|
lightning-invoice.workspace = true
|
||||||
] }
|
uuid.workspace = true
|
||||||
serde_json = "1"
|
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "cdk-strike"
|
|
||||||
version = "0.7.1"
|
|
||||||
edition = "2021"
|
|
||||||
authors = ["CDK Developers"]
|
|
||||||
license = "MIT"
|
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
|
||||||
rust-version = "1.63.0" # MSRV
|
|
||||||
description = "CDK ln backend for Strike api"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
async-trait = "0.1"
|
|
||||||
anyhow = "1"
|
|
||||||
axum = "0.6.20"
|
|
||||||
bitcoin = { version = "0.32.2", default-features = false }
|
|
||||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
|
||||||
futures = { version = "0.3.28", default-features = false }
|
|
||||||
tokio = { version = "1", default-features = false }
|
|
||||||
tokio-util = { version = "0.7.11", default-features = false }
|
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
|
||||||
thiserror = "1"
|
|
||||||
uuid = { version = "1", features = ["v4"] }
|
|
||||||
strike-rs = "0.4.0"
|
|
||||||
# strike-rs = { path = "../../../../strike-rs" }
|
|
||||||
# strike-rs = { git = "https://github.com/thesimplekid/strike-rs.git", rev = "577ad9591" }
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
//! Error for Strike ln backend
|
|
||||||
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
/// Strike Error
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum Error {
|
|
||||||
/// Invoice amount not defined
|
|
||||||
#[error("Unknown invoice amount")]
|
|
||||||
UnknownInvoiceAmount,
|
|
||||||
/// Unknown invoice
|
|
||||||
#[error("Unknown invoice")]
|
|
||||||
UnknownInvoice,
|
|
||||||
/// Strikers error
|
|
||||||
#[error(transparent)]
|
|
||||||
StrikeRs(#[from] strike_rs::Error),
|
|
||||||
/// Anyhow error
|
|
||||||
#[error(transparent)]
|
|
||||||
Anyhow(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Error> for cdk::cdk_lightning::Error {
|
|
||||||
fn from(e: Error) -> Self {
|
|
||||||
Self::Lightning(Box::new(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,381 +0,0 @@
|
|||||||
//! CDK lightning backend for Strike
|
|
||||||
|
|
||||||
#![warn(missing_docs)]
|
|
||||||
#![warn(rustdoc::bare_urls)]
|
|
||||||
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use axum::Router;
|
|
||||||
use cdk::amount::Amount;
|
|
||||||
use cdk::cdk_lightning::{
|
|
||||||
self, CreateInvoiceResponse, MintLightning, PayInvoiceResponse, PaymentQuoteResponse, Settings,
|
|
||||||
};
|
|
||||||
use cdk::nuts::{CurrencyUnit, MeltQuoteBolt11Request, MeltQuoteState, MintQuoteState};
|
|
||||||
use cdk::util::unix_time;
|
|
||||||
use cdk::{mint, Bolt11Invoice};
|
|
||||||
use error::Error;
|
|
||||||
use futures::stream::StreamExt;
|
|
||||||
use futures::Stream;
|
|
||||||
use strike_rs::{
|
|
||||||
Amount as StrikeAmount, Currency as StrikeCurrencyUnit, InvoiceRequest, InvoiceState,
|
|
||||||
PayInvoiceQuoteRequest, Strike as StrikeApi,
|
|
||||||
};
|
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use tokio_util::sync::CancellationToken;
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
pub mod error;
|
|
||||||
|
|
||||||
/// Strike
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Strike {
|
|
||||||
strike_api: StrikeApi,
|
|
||||||
unit: CurrencyUnit,
|
|
||||||
receiver: Arc<Mutex<Option<tokio::sync::mpsc::Receiver<String>>>>,
|
|
||||||
webhook_url: String,
|
|
||||||
wait_invoice_cancel_token: CancellationToken,
|
|
||||||
wait_invoice_is_active: Arc<AtomicBool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Strike {
|
|
||||||
/// Create new [`Strike`] wallet
|
|
||||||
pub async fn new(
|
|
||||||
api_key: String,
|
|
||||||
unit: CurrencyUnit,
|
|
||||||
receiver: Arc<Mutex<Option<tokio::sync::mpsc::Receiver<String>>>>,
|
|
||||||
webhook_url: String,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let strike = StrikeApi::new(&api_key, None)?;
|
|
||||||
Ok(Self {
|
|
||||||
strike_api: strike,
|
|
||||||
receiver,
|
|
||||||
unit,
|
|
||||||
webhook_url,
|
|
||||||
wait_invoice_cancel_token: CancellationToken::new(),
|
|
||||||
wait_invoice_is_active: Arc::new(AtomicBool::new(false)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl MintLightning for Strike {
|
|
||||||
type Err = cdk_lightning::Error;
|
|
||||||
|
|
||||||
fn get_settings(&self) -> Settings {
|
|
||||||
Settings {
|
|
||||||
mpp: false,
|
|
||||||
unit: self.unit.clone(),
|
|
||||||
invoice_description: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_wait_invoice_active(&self) -> bool {
|
|
||||||
self.wait_invoice_is_active.load(Ordering::SeqCst)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cancel_wait_invoice(&self) {
|
|
||||||
self.wait_invoice_cancel_token.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
async fn wait_any_invoice(
|
|
||||||
&self,
|
|
||||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
|
||||||
self.strike_api
|
|
||||||
.subscribe_to_invoice_webhook(self.webhook_url.clone())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let receiver = self
|
|
||||||
.receiver
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.take()
|
|
||||||
.ok_or(anyhow!("No receiver"))?;
|
|
||||||
|
|
||||||
let strike_api = self.strike_api.clone();
|
|
||||||
let cancel_token = self.wait_invoice_cancel_token.clone();
|
|
||||||
|
|
||||||
Ok(futures::stream::unfold(
|
|
||||||
(
|
|
||||||
receiver,
|
|
||||||
strike_api,
|
|
||||||
cancel_token,
|
|
||||||
Arc::clone(&self.wait_invoice_is_active),
|
|
||||||
),
|
|
||||||
|(mut receiver, strike_api, cancel_token, is_active)| async move {
|
|
||||||
tokio::select! {
|
|
||||||
|
|
||||||
_ = cancel_token.cancelled() => {
|
|
||||||
// Stream is cancelled
|
|
||||||
is_active.store(false, Ordering::SeqCst);
|
|
||||||
tracing::info!("Waiting for phonixd invoice ending");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_option = receiver.recv() => {
|
|
||||||
match msg_option {
|
|
||||||
Some(msg) => {
|
|
||||||
let check = strike_api.get_incoming_invoice(&msg).await;
|
|
||||||
|
|
||||||
match check {
|
|
||||||
Ok(state) => {
|
|
||||||
if state.state == InvoiceState::Paid {
|
|
||||||
Some((msg, (receiver, strike_api, cancel_token, is_active)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.boxed())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_payment_quote(
|
|
||||||
&self,
|
|
||||||
melt_quote_request: &MeltQuoteBolt11Request,
|
|
||||||
) -> Result<PaymentQuoteResponse, Self::Err> {
|
|
||||||
if melt_quote_request.unit != self.unit {
|
|
||||||
return Err(Self::Err::Anyhow(anyhow!("Unsupported unit")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let source_currency = match melt_quote_request.unit {
|
|
||||||
CurrencyUnit::Sat => StrikeCurrencyUnit::BTC,
|
|
||||||
CurrencyUnit::Msat => StrikeCurrencyUnit::BTC,
|
|
||||||
CurrencyUnit::Usd => StrikeCurrencyUnit::USD,
|
|
||||||
CurrencyUnit::Eur => StrikeCurrencyUnit::EUR,
|
|
||||||
_ => return Err(Self::Err::UnsupportedUnit),
|
|
||||||
};
|
|
||||||
|
|
||||||
let payment_quote_request = PayInvoiceQuoteRequest {
|
|
||||||
ln_invoice: melt_quote_request.request.to_string(),
|
|
||||||
source_currency,
|
|
||||||
};
|
|
||||||
|
|
||||||
let quote = self.strike_api.payment_quote(payment_quote_request).await?;
|
|
||||||
|
|
||||||
let fee = from_strike_amount(quote.lightning_network_fee, &melt_quote_request.unit)?;
|
|
||||||
|
|
||||||
let amount = from_strike_amount(quote.amount, &melt_quote_request.unit)?.into();
|
|
||||||
|
|
||||||
Ok(PaymentQuoteResponse {
|
|
||||||
request_lookup_id: quote.payment_quote_id,
|
|
||||||
amount,
|
|
||||||
fee: fee.into(),
|
|
||||||
state: MeltQuoteState::Unpaid,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn pay_invoice(
|
|
||||||
&self,
|
|
||||||
melt_quote: mint::MeltQuote,
|
|
||||||
_partial_msats: Option<Amount>,
|
|
||||||
_max_fee_msats: Option<Amount>,
|
|
||||||
) -> Result<PayInvoiceResponse, Self::Err> {
|
|
||||||
let pay_response = self
|
|
||||||
.strike_api
|
|
||||||
.pay_quote(&melt_quote.request_lookup_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let state = match pay_response.state {
|
|
||||||
InvoiceState::Paid => MeltQuoteState::Paid,
|
|
||||||
InvoiceState::Unpaid => MeltQuoteState::Unpaid,
|
|
||||||
InvoiceState::Completed => MeltQuoteState::Paid,
|
|
||||||
InvoiceState::Pending => MeltQuoteState::Pending,
|
|
||||||
};
|
|
||||||
|
|
||||||
let total_spent = from_strike_amount(pay_response.total_amount, &melt_quote.unit)?.into();
|
|
||||||
|
|
||||||
Ok(PayInvoiceResponse {
|
|
||||||
payment_lookup_id: pay_response.payment_id,
|
|
||||||
payment_preimage: None,
|
|
||||||
status: state,
|
|
||||||
total_spent,
|
|
||||||
unit: melt_quote.unit,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create_invoice(
|
|
||||||
&self,
|
|
||||||
amount: Amount,
|
|
||||||
_unit: &CurrencyUnit,
|
|
||||||
description: String,
|
|
||||||
unix_expiry: u64,
|
|
||||||
) -> Result<CreateInvoiceResponse, Self::Err> {
|
|
||||||
let time_now = unix_time();
|
|
||||||
assert!(unix_expiry > time_now);
|
|
||||||
let request_lookup_id = Uuid::new_v4();
|
|
||||||
|
|
||||||
let invoice_request = InvoiceRequest {
|
|
||||||
correlation_id: Some(request_lookup_id.to_string()),
|
|
||||||
amount: to_strike_unit(amount, &self.unit)?,
|
|
||||||
description: Some(description),
|
|
||||||
};
|
|
||||||
|
|
||||||
let create_invoice_response = self.strike_api.create_invoice(invoice_request).await?;
|
|
||||||
|
|
||||||
let quote = self
|
|
||||||
.strike_api
|
|
||||||
.invoice_quote(&create_invoice_response.invoice_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let request: Bolt11Invoice = quote.ln_invoice.parse()?;
|
|
||||||
let expiry = request.expires_at().map(|t| t.as_secs());
|
|
||||||
|
|
||||||
Ok(CreateInvoiceResponse {
|
|
||||||
request_lookup_id: create_invoice_response.invoice_id,
|
|
||||||
request: quote.ln_invoice.parse()?,
|
|
||||||
expiry,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn check_incoming_invoice_status(
|
|
||||||
&self,
|
|
||||||
request_lookup_id: &str,
|
|
||||||
) -> Result<MintQuoteState, Self::Err> {
|
|
||||||
let invoice = self
|
|
||||||
.strike_api
|
|
||||||
.get_incoming_invoice(request_lookup_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let state = match invoice.state {
|
|
||||||
InvoiceState::Paid => MintQuoteState::Paid,
|
|
||||||
InvoiceState::Unpaid => MintQuoteState::Unpaid,
|
|
||||||
InvoiceState::Completed => MintQuoteState::Paid,
|
|
||||||
InvoiceState::Pending => MintQuoteState::Pending,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn check_outgoing_payment(
|
|
||||||
&self,
|
|
||||||
payment_id: &str,
|
|
||||||
) -> Result<PayInvoiceResponse, Self::Err> {
|
|
||||||
let invoice = self.strike_api.get_outgoing_payment(payment_id).await;
|
|
||||||
|
|
||||||
let pay_invoice_response = match invoice {
|
|
||||||
Ok(invoice) => {
|
|
||||||
let state = match invoice.state {
|
|
||||||
InvoiceState::Paid => MeltQuoteState::Paid,
|
|
||||||
InvoiceState::Unpaid => MeltQuoteState::Unpaid,
|
|
||||||
InvoiceState::Completed => MeltQuoteState::Paid,
|
|
||||||
InvoiceState::Pending => MeltQuoteState::Pending,
|
|
||||||
};
|
|
||||||
|
|
||||||
PayInvoiceResponse {
|
|
||||||
payment_lookup_id: invoice.payment_id,
|
|
||||||
payment_preimage: None,
|
|
||||||
status: state,
|
|
||||||
total_spent: from_strike_amount(invoice.total_amount, &self.unit)?.into(),
|
|
||||||
unit: self.unit.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => match err {
|
|
||||||
strike_rs::Error::NotFound => PayInvoiceResponse {
|
|
||||||
payment_lookup_id: payment_id.to_string(),
|
|
||||||
payment_preimage: None,
|
|
||||||
status: MeltQuoteState::Unknown,
|
|
||||||
total_spent: Amount::ZERO,
|
|
||||||
unit: self.unit.clone(),
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
return Err(Error::from(err).into());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(pay_invoice_response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Strike {
|
|
||||||
/// Create invoice webhook
|
|
||||||
pub async fn create_invoice_webhook(
|
|
||||||
&self,
|
|
||||||
webhook_endpoint: &str,
|
|
||||||
sender: tokio::sync::mpsc::Sender<String>,
|
|
||||||
) -> anyhow::Result<Router> {
|
|
||||||
let subs = self.strike_api.get_current_subscriptions().await?;
|
|
||||||
|
|
||||||
tracing::debug!("Got {} current subscriptions", subs.len());
|
|
||||||
|
|
||||||
for sub in subs {
|
|
||||||
tracing::info!("Deleting webhook: {}", &sub.id);
|
|
||||||
if let Err(err) = self.strike_api.delete_subscription(&sub.id).await {
|
|
||||||
tracing::error!("Error deleting webhook subscription: {} {}", sub.id, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.strike_api
|
|
||||||
.create_invoice_webhook_router(webhook_endpoint, sender)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn from_strike_amount(
|
|
||||||
strike_amount: StrikeAmount,
|
|
||||||
target_unit: &CurrencyUnit,
|
|
||||||
) -> anyhow::Result<u64> {
|
|
||||||
match target_unit {
|
|
||||||
CurrencyUnit::Sat => strike_amount.to_sats(),
|
|
||||||
CurrencyUnit::Msat => Ok(strike_amount.to_sats()? * 1000),
|
|
||||||
CurrencyUnit::Usd => {
|
|
||||||
if strike_amount.currency == StrikeCurrencyUnit::USD {
|
|
||||||
Ok((strike_amount.amount * 100.0).round() as u64)
|
|
||||||
} else {
|
|
||||||
bail!("Could not convert strike USD");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CurrencyUnit::Eur => {
|
|
||||||
if strike_amount.currency == StrikeCurrencyUnit::EUR {
|
|
||||||
Ok((strike_amount.amount * 100.0).round() as u64)
|
|
||||||
} else {
|
|
||||||
bail!("Could not convert to EUR");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => bail!("Unsupported unit"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn to_strike_unit<T>(
|
|
||||||
amount: T,
|
|
||||||
current_unit: &CurrencyUnit,
|
|
||||||
) -> anyhow::Result<StrikeAmount>
|
|
||||||
where
|
|
||||||
T: Into<u64>,
|
|
||||||
{
|
|
||||||
let amount = amount.into();
|
|
||||||
match current_unit {
|
|
||||||
CurrencyUnit::Sat => Ok(StrikeAmount::from_sats(amount)),
|
|
||||||
CurrencyUnit::Msat => Ok(StrikeAmount::from_sats(amount / 1000)),
|
|
||||||
CurrencyUnit::Usd => {
|
|
||||||
let dollars = (amount as f64 / 100_f64) * 100.0;
|
|
||||||
|
|
||||||
Ok(StrikeAmount {
|
|
||||||
currency: StrikeCurrencyUnit::USD,
|
|
||||||
amount: dollars.round() / 100.0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
CurrencyUnit::Eur => {
|
|
||||||
let euro = (amount as f64 / 100_f64) * 100.0;
|
|
||||||
|
|
||||||
Ok(StrikeAmount {
|
|
||||||
currency: StrikeCurrencyUnit::EUR,
|
|
||||||
amount: euro.round() / 100.0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => bail!("Unsupported unit"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cdk"
|
name = "cdk"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["CDK Developers"]
|
authors = ["CDK Developers"]
|
||||||
description = "Core Cashu Development Kit library implementing the Cashu protocol"
|
description = "Core Cashu Development Kit library implementing the Cashu protocol"
|
||||||
homepage = "https://github.com/cashubtc/cdk"
|
homepage = "https://github.com/cashubtc/cdk"
|
||||||
repository = "https://github.com/cashubtc/cdk.git"
|
repository = "https://github.com/cashubtc/cdk.git"
|
||||||
rust-version = "1.63.0" # MSRV
|
rust-version = "1.75.0" # MSRV
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
|
||||||
@@ -21,63 +21,45 @@ http_subscription = []
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
cdk-common.workspace = true
|
||||||
cbor-diag = "0.1.12"
|
cbor-diag.workspace = true
|
||||||
async-trait = "0.1"
|
async-trait.workspace = true
|
||||||
anyhow = { version = "1.0.43", features = ["backtrace"] }
|
anyhow.workspace = true
|
||||||
bitcoin = { version = "0.32.2", features = [
|
bitcoin.workspace = true
|
||||||
"base64",
|
ciborium.workspace = true
|
||||||
"serde",
|
lightning-invoice.workspace = true
|
||||||
"rand",
|
|
||||||
"rand-std",
|
|
||||||
] }
|
|
||||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
|
||||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
|
||||||
regex = "1"
|
regex = "1"
|
||||||
reqwest = { version = "0.12", default-features = false, features = [
|
reqwest = { workspace = true, optional = true }
|
||||||
"json",
|
serde.workspace = true
|
||||||
"rustls-tls",
|
serde_json.workspace = true
|
||||||
"rustls-tls-native-roots",
|
serde_with.workspace = true
|
||||||
"socks",
|
tracing.workspace = true
|
||||||
"zstd",
|
thiserror.workspace = true
|
||||||
"brotli",
|
futures = { workspace = true, optional = true, features = ["alloc"] }
|
||||||
"gzip",
|
url.workspace = true
|
||||||
"deflate",
|
utoipa = { workspace = true, optional = true }
|
||||||
], optional = true }
|
uuid.workspace = true
|
||||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
|
||||||
serde_json = "1"
|
|
||||||
serde_with = "3"
|
|
||||||
tracing = { version = "0.1", default-features = false, features = [
|
|
||||||
"attributes",
|
|
||||||
"log",
|
|
||||||
] }
|
|
||||||
thiserror = "1"
|
|
||||||
futures = { version = "0.3.28", default-features = false, optional = true, features = [
|
|
||||||
"alloc",
|
|
||||||
] }
|
|
||||||
url = "2.3"
|
|
||||||
utoipa = { version = "4", optional = true }
|
|
||||||
uuid = { version = "=1.12.1", features = ["v4", "serde"] }
|
|
||||||
|
|
||||||
# -Z minimal-versions
|
# -Z minimal-versions
|
||||||
sync_wrapper = "0.1.2"
|
sync_wrapper = "0.1.2"
|
||||||
bech32 = "0.9.1"
|
bech32 = "0.9.1"
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
tokio = { version = "1.21", features = [
|
tokio = { workspace = true, features = [
|
||||||
"rt-multi-thread",
|
"rt-multi-thread",
|
||||||
"time",
|
"time",
|
||||||
"macros",
|
"macros",
|
||||||
"sync",
|
"sync",
|
||||||
] }
|
] }
|
||||||
getrandom = { version = "0.2" }
|
getrandom = { version = "0.2" }
|
||||||
tokio-tungstenite = { version = "0.19.0", features = [
|
tokio-tungstenite = { workspace = true, features = [
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-tls-native-roots",
|
"rustls-tls-native-roots",
|
||||||
|
"connect"
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
tokio = { version = "1.21", features = ["rt", "macros", "sync", "time"] }
|
tokio = { workspace = true, features = ["rt", "macros", "sync", "time"] }
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
@@ -98,9 +80,9 @@ required-features = ["wallet"]
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
bip39 = "2.0"
|
cdk-sqlite.workspace = true
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
bip39.workspace = true
|
||||||
cdk-sqlite = { path = "../cdk-sqlite" }
|
tracing-subscriber.workspace = true
|
||||||
criterion = "0.5.1"
|
criterion = "0.5.1"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
pub mod cdk_database {
|
pub mod cdk_database {
|
||||||
//! CDK Database
|
//! CDK Database
|
||||||
pub use cdk_common::database::{Error, MintDatabase, WalletDatabase};
|
pub use cdk_common::database::Error;
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
pub use cdk_common::database::MintDatabase;
|
||||||
|
#[cfg(feature = "wallet")]
|
||||||
|
pub use cdk_common::database::WalletDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
@@ -20,9 +24,11 @@ pub mod pub_sub;
|
|||||||
pub use cdk_common::{
|
pub use cdk_common::{
|
||||||
amount, common as types, dhke,
|
amount, common as types, dhke,
|
||||||
error::{self, Error},
|
error::{self, Error},
|
||||||
lightning as cdk_lightning, lightning_invoice, mint_url, nuts, secret, subscription, util, ws,
|
lightning_invoice, mint_url, nuts, secret, util, ws, Amount, Bolt11Invoice,
|
||||||
Amount, Bolt11Invoice,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use cdk_common::{lightning as cdk_lightning, subscription};
|
||||||
|
|
||||||
pub mod fees;
|
pub mod fees;
|
||||||
|
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ impl Mint {
|
|||||||
|
|
||||||
if let Ok(Some(quote)) = self.localstore.get_melt_quote(&melt_request.quote).await {
|
if let Ok(Some(quote)) = self.localstore.get_melt_quote(&melt_request.quote).await {
|
||||||
self.pubsub_manager
|
self.pubsub_manager
|
||||||
.melt_quote_status("e, None, None, MeltQuoteState::Unpaid);
|
.melt_quote_status(quote, None, None, MeltQuoteState::Unpaid);
|
||||||
}
|
}
|
||||||
|
|
||||||
for public_key in input_ys {
|
for public_key in input_ys {
|
||||||
|
|||||||
@@ -139,8 +139,6 @@ impl Mint {
|
|||||||
/// Wait for any invoice to be paid
|
/// Wait for any invoice to be paid
|
||||||
/// For each backend starts a task that waits for any invoice to be paid
|
/// For each backend starts a task that waits for any invoice to be paid
|
||||||
/// Once invoice is paid mint quote status is updated
|
/// Once invoice is paid mint quote status is updated
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
// Clippy thinks select is not stable but it compiles fine on MSRV (1.63.0)
|
|
||||||
pub async fn wait_for_paid_invoices(&self, shutdown: Arc<Notify>) -> Result<(), Error> {
|
pub async fn wait_for_paid_invoices(&self, shutdown: Arc<Notify>) -> Result<(), Error> {
|
||||||
let mint_arc = Arc::new(self.clone());
|
let mint_arc = Arc::new(self.clone());
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ async fn convert_subscription(
|
|||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn http_main<S: IntoIterator<Item = SubId>>(
|
pub async fn http_main<S: IntoIterator<Item = SubId>>(
|
||||||
initial_state: S,
|
initial_state: S,
|
||||||
|
|||||||
@@ -290,7 +290,6 @@ impl SubscriptionClient {
|
|||||||
///
|
///
|
||||||
/// This is a WebSocket based subscription, where the client will connect to
|
/// This is a WebSocket based subscription, where the client will connect to
|
||||||
/// the server and stay there idle waiting for server-side notifications
|
/// the server and stay there idle waiting for server-side notifications
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(feature = "http_subscription"),
|
not(feature = "http_subscription"),
|
||||||
feature = "mint",
|
feature = "mint",
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ async fn fallback_to_http<S: IntoIterator<Item = SubId>>(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::incompatible_msrv)]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn ws_main(
|
pub async fn ws_main(
|
||||||
http_client: Arc<dyn MintConnector + Send + Sync>,
|
http_client: Arc<dyn MintConnector + Send + Sync>,
|
||||||
@@ -131,7 +130,7 @@ pub async fn ws_main(
|
|||||||
.get(sub_id)
|
.get(sub_id)
|
||||||
.map(|(_, params)| get_sub_request(params.clone()))
|
.map(|(_, params)| get_sub_request(params.clone()))
|
||||||
{
|
{
|
||||||
let _ = write.send(Message::Text(req)).await;
|
let _ = write.send(Message::Text(req.into())).await;
|
||||||
subscription_requests.insert(req_id);
|
subscription_requests.insert(req_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +191,7 @@ pub async fn ws_main(
|
|||||||
tracing::debug!("Subscribing to {:?}", sub.1);
|
tracing::debug!("Subscribing to {:?}", sub.1);
|
||||||
active_subscriptions.insert(subid, sub.0.clone());
|
active_subscriptions.insert(subid, sub.0.clone());
|
||||||
if let Some((req_id, json)) = get_sub_request(sub.1.clone()) {
|
if let Some((req_id, json)) = get_sub_request(sub.1.clone()) {
|
||||||
let _ = write.send(Message::Text(json)).await;
|
let _ = write.send(Message::Text(json.into())).await;
|
||||||
subscription_requests.insert(req_id);
|
subscription_requests.insert(req_id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -203,7 +202,7 @@ pub async fn ws_main(
|
|||||||
}
|
}
|
||||||
tracing::debug!("Unsubscribing from {:?}", subid);
|
tracing::debug!("Unsubscribing from {:?}", subid);
|
||||||
if let Some(json) = get_unsub_request(subid) {
|
if let Some(json) = get_unsub_request(subid) {
|
||||||
let _ = write.send(Message::Text(json)).await;
|
let _ = write.send(Message::Text(json.into())).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
flake.nix
54
flake.nix
@@ -55,13 +55,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
# MSRV stable
|
# MSRV stable
|
||||||
msrv_toolchain = pkgs.rust-bin.stable."1.63.0".default.override {
|
msrv_toolchain = pkgs.rust-bin.stable."1.75.0".default.override {
|
||||||
targets = [ "wasm32-unknown-unknown" ]; # wasm
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
# DB MSRV stable
|
|
||||||
db_msrv_toolchain = pkgs.rust-bin.stable."1.66.0".default.override {
|
|
||||||
targets = [ "wasm32-unknown-unknown" ]; # wasm
|
targets = [ "wasm32-unknown-unknown" ]; # wasm
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,6 +80,7 @@
|
|||||||
clightning
|
clightning
|
||||||
bitcoind
|
bitcoind
|
||||||
sqlx-cli
|
sqlx-cli
|
||||||
|
cargo-outdated
|
||||||
|
|
||||||
# Needed for github ci
|
# Needed for github ci
|
||||||
libz
|
libz
|
||||||
@@ -232,29 +227,16 @@
|
|||||||
msrv = pkgs.mkShell ({
|
msrv = pkgs.mkShell ({
|
||||||
shellHook = "
|
shellHook = "
|
||||||
${_shellHook}
|
${_shellHook}
|
||||||
cargo update -p half --precise 2.2.1
|
cargo update
|
||||||
cargo update -p tokio --precise 1.38.1
|
|
||||||
cargo update -p tokio-util --precise 0.7.11
|
|
||||||
cargo update -p tokio-stream --precise 0.1.15
|
|
||||||
cargo update -p reqwest --precise 0.12.4
|
|
||||||
cargo update -p serde_with --precise 3.1.0
|
|
||||||
cargo update -p regex --precise 1.9.6
|
|
||||||
cargo update -p backtrace --precise 0.3.58
|
|
||||||
cargo update -p async-compression --precise 0.4.3
|
cargo update -p async-compression --precise 0.4.3
|
||||||
cargo update -p zstd-sys --precise 2.0.8+zstd.1.5.5
|
|
||||||
|
|
||||||
cargo update -p clap_lex --precise 0.3.0
|
|
||||||
cargo update -p regex --precise 1.9.6
|
|
||||||
cargo update -p petgraph --precise 0.6.2
|
|
||||||
cargo update -p hashbrown@0.15.2 --precise 0.15.0
|
|
||||||
cargo update -p async-stream --precise 0.3.5
|
|
||||||
cargo update -p home --precise 0.5.5
|
cargo update -p home --precise 0.5.5
|
||||||
|
cargo update -p zerofrom --precise 0.1.5
|
||||||
|
|
||||||
|
cargo update -p url --precise 2.5.2
|
||||||
|
|
||||||
# For wasm32-unknown-unknown target
|
# For wasm32-unknown-unknown target
|
||||||
cargo update -p bumpalo --precise 3.12.0
|
|
||||||
cargo update -p moka --precise 0.11.1
|
|
||||||
cargo update -p triomphe --precise 0.1.11
|
cargo update -p triomphe --precise 0.1.11
|
||||||
cargo update -p url --precise 2.5.2
|
|
||||||
|
|
||||||
";
|
";
|
||||||
buildInputs = buildInputs ++ WASMInputs ++ [ msrv_toolchain ];
|
buildInputs = buildInputs ++ WASMInputs ++ [ msrv_toolchain ];
|
||||||
@@ -268,28 +250,6 @@
|
|||||||
} // envVars);
|
} // envVars);
|
||||||
|
|
||||||
|
|
||||||
db_shell = pkgs.mkShell ({
|
|
||||||
shellHook = ''
|
|
||||||
${_shellHook}
|
|
||||||
cargo update -p half --precise 2.2.1
|
|
||||||
cargo update -p home --precise 0.5.5
|
|
||||||
cargo update -p tokio --precise 1.38.1
|
|
||||||
cargo update -p tokio-stream --precise 0.1.15
|
|
||||||
cargo update -p tokio-util --precise 0.7.11
|
|
||||||
cargo update -p serde_with --precise 3.1.0
|
|
||||||
cargo update -p reqwest --precise 0.12.4
|
|
||||||
cargo update -p url --precise 2.5.2
|
|
||||||
cargo update -p allocator-api2 --precise 0.2.18
|
|
||||||
cargo update -p async-compression --precise 0.4.3
|
|
||||||
cargo update -p zstd-sys --precise 2.0.8+zstd.1.5.5
|
|
||||||
cargo update -p redb --precise 2.2.0
|
|
||||||
'';
|
|
||||||
buildInputs = buildInputs ++ WASMInputs ++ [ db_msrv_toolchain ];
|
|
||||||
inherit nativeBuildInputs;
|
|
||||||
} // envVars);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nightly = pkgs.mkShell ({
|
nightly = pkgs.mkShell ({
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
${_shellHook}
|
${_shellHook}
|
||||||
@@ -305,7 +265,7 @@
|
|||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit msrv stable nightly db_shell;
|
inherit msrv stable nightly;
|
||||||
default = stable;
|
default = stable;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export CDK_MINTD_DATABASE=$MINT_DATABASE;
|
|||||||
|
|
||||||
|
|
||||||
echo "Starting fake mintd";
|
echo "Starting fake mintd";
|
||||||
cargo run --bin cdk-mintd &
|
cargo run --bin cdk-mintd --features "redb" &
|
||||||
cdk_mintd_pid=$!
|
cdk_mintd_pid=$!
|
||||||
|
|
||||||
URL="http://$cdk_itests_mint_addr:$cdk_itests_mint_port/v1/info"
|
URL="http://$cdk_itests_mint_addr:$cdk_itests_mint_port/v1/info"
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export CDK_MINTD_DATABASE=$MINT_DATABASE;
|
|||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
|
|
||||||
echo "Starting cln mintd";
|
echo "Starting cln mintd";
|
||||||
cargo run --bin cdk-mintd &
|
cargo run --bin cdk-mintd --features "redb" &
|
||||||
cdk_mintd_pid=$!
|
cdk_mintd_pid=$!
|
||||||
|
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ export CDK_MINTD_LN_BACKEND="lnd";
|
|||||||
export CDK_MINTD_MNEMONIC="eye survey guilt napkin crystal cup whisper salt luggage manage unveil loyal";
|
export CDK_MINTD_MNEMONIC="eye survey guilt napkin crystal cup whisper salt luggage manage unveil loyal";
|
||||||
|
|
||||||
echo "Starting lnd mintd";
|
echo "Starting lnd mintd";
|
||||||
cargo run --bin cdk-mintd &
|
cargo run --bin cdk-mintd --features "redb" &
|
||||||
cdk_mintd_lnd_pid=$!
|
cdk_mintd_lnd_pid=$!
|
||||||
|
|
||||||
URL="http://$cdk_itests_mint_addr:$cdk_itests_mint_port_1/v1/info"
|
URL="http://$cdk_itests_mint_addr:$cdk_itests_mint_port_1/v1/info"
|
||||||
|
|||||||
Reference in New Issue
Block a user