mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-19 13:44:55 +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-lnd,
|
||||
-p cdk-phoenixd,
|
||||
-p cdk-strike,
|
||||
-p cdk-lnbits,
|
||||
-p cdk-fake-wallet,
|
||||
--bin cdk-cli,
|
||||
@@ -111,6 +110,7 @@ jobs:
|
||||
--bin cdk-mintd --no-default-features --features redis,
|
||||
--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 redb,
|
||||
--bin cdk-mint-cli,
|
||||
]
|
||||
steps:
|
||||
@@ -216,12 +216,14 @@ jobs:
|
||||
-p cdk --no-default-features --features "mint mint",
|
||||
-p cdk-axum,
|
||||
-p cdk-axum --no-default-features --features redis,
|
||||
-p cdk-strike,
|
||||
-p cdk-lnbits,
|
||||
-p cdk-phoenixd,
|
||||
-p cdk-fake-wallet,
|
||||
-p cdk-cln,
|
||||
-p cdk-lnd,
|
||||
-p cdk-mint-rpc,
|
||||
-p cdk-sqlite,
|
||||
-p cdk-mintd,
|
||||
]
|
||||
steps:
|
||||
- name: checkout
|
||||
@@ -236,29 +238,6 @@ jobs:
|
||||
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:
|
||||
name: Check WASM
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
58
Cargo.toml
58
Cargo.toml
@@ -5,13 +5,69 @@ members = [
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.75.0"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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]
|
||||
authors = ["CDK Developers"]
|
||||
edition = "2021"
|
||||
description = "Cashu Development Kit"
|
||||
readme = "README.md"
|
||||
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-cln**](./crates/cdk-cln/): CLN 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-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.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "cashu"
|
||||
version = "0.7.1"
|
||||
edition = "2021"
|
||||
edition.workspace = true
|
||||
authors = ["CDK Developers"]
|
||||
description = "Cashu shared types and crypto utilities, used as the foundation for the CDK and their crates"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
license = "MIT"
|
||||
rust-version = "1.75.0" # MSRV
|
||||
license.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["mint", "wallet"]
|
||||
@@ -17,28 +17,23 @@ wallet = []
|
||||
bench = []
|
||||
|
||||
[dependencies]
|
||||
uuid = { version = "=1.12.1", features = ["v4", "serde"], optional = true }
|
||||
bitcoin = { version = "0.32.2", features = [
|
||||
"base64",
|
||||
"serde",
|
||||
"rand",
|
||||
"rand-std",
|
||||
] }
|
||||
cbor-diag = "0.1.12"
|
||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
||||
once_cell = "1.20.2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
thiserror = "2"
|
||||
tracing = "0.1"
|
||||
url = "2.3"
|
||||
utoipa = { version = "4", optional = true }
|
||||
serde_json = "1"
|
||||
serde_with = "3"
|
||||
uuid = { workspace = true, optional = true }
|
||||
bitcoin.workspace = true
|
||||
cbor-diag.workspace = true
|
||||
ciborium.workspace = true
|
||||
once_cell.workspace = true
|
||||
serde.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
url.workspace = true
|
||||
utoipa = { workspace = true, optional = true }
|
||||
serde_json.workspace = true
|
||||
serde_with.workspace = true
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
||||
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||
|
||||
[dev-dependencies]
|
||||
bip39 = "2.0"
|
||||
uuid = { version = "=1.12.1", features = ["v4", "serde"] }
|
||||
bip39.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -40,7 +40,7 @@ pub struct PreSwap {
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub struct SwapRequest {
|
||||
/// 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,
|
||||
/// Blinded Messages for Mint to sign
|
||||
pub outputs: Vec<BlindedMessage>,
|
||||
|
||||
@@ -335,7 +335,7 @@ pub struct MeltBolt11Request<Q> {
|
||||
/// Quote ID
|
||||
pub quote: Q,
|
||||
/// Proofs
|
||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<Proof>))]
|
||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
|
||||
pub inputs: Proofs,
|
||||
/// Blinded Message that can be used to return change [NUT-08]
|
||||
/// Amount field of BlindedMessages `SHOULD` be set to zero
|
||||
|
||||
@@ -27,6 +27,7 @@ pub struct Params<I> {
|
||||
|
||||
/// Check state Settings
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub struct SupportedSettings {
|
||||
/// Supported methods
|
||||
pub supported: Vec<SupportedMethods>,
|
||||
@@ -34,6 +35,7 @@ pub struct SupportedSettings {
|
||||
|
||||
/// Supported WS Methods
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub struct SupportedMethods {
|
||||
/// Payment Method
|
||||
pub method: PaymentMethod,
|
||||
|
||||
@@ -16,6 +16,7 @@ pub struct Settings {
|
||||
|
||||
/// List of the methods and paths for which caching is enabled
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub struct CachedEndpoint {
|
||||
/// HTTP Method
|
||||
pub method: Method,
|
||||
@@ -33,6 +34,7 @@ impl CachedEndpoint {
|
||||
/// HTTP method
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub enum Method {
|
||||
/// Get
|
||||
Get,
|
||||
@@ -42,6 +44,7 @@ pub enum Method {
|
||||
|
||||
/// Route path
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
|
||||
pub enum Path {
|
||||
/// Bolt11 Mint
|
||||
#[serde(rename = "/v1/mint/bolt11")]
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
[package]
|
||||
name = "cdk-axum"
|
||||
version = "0.7.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
rust-version = "1.75.0" # MSRV
|
||||
description = "Cashu CDK axum webserver"
|
||||
|
||||
[features]
|
||||
redis = ["dep:redis"]
|
||||
swagger = ["cdk/swagger", "dep:utoipa"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
async-trait = "0.1.83"
|
||||
axum = { version = "0.6.20", features = ["ws"] }
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
axum = { workspace = true, features = ["ws"] }
|
||||
cdk = { workspace = true, features = [
|
||||
"mint",
|
||||
] }
|
||||
tokio = { version = "1", default-features = false, features = ["io-util"] }
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
utoipa = { version = "4", features = [
|
||||
"preserve_order",
|
||||
"preserve_path_order",
|
||||
], optional = true }
|
||||
futures = { version = "0.3.28", default-features = false }
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
utoipa = { workspace = true, optional = true }
|
||||
futures.workspace = true
|
||||
moka = { version = "0.11.1", features = ["future"] }
|
||||
serde_json = "1"
|
||||
serde_json.workspace = true
|
||||
paste = "1.0.15"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
serde.workspace = true
|
||||
uuid.workspace = true
|
||||
sha2 = "0.10.8"
|
||||
redis = { version = "0.23.3", features = [
|
||||
"tokio-rustls-comp",
|
||||
], 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,
|
||||
storage: Option<Box<dyn HttpCacheStorage + Send + Sync + 'static>>,
|
||||
) -> 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);
|
||||
|
||||
Self {
|
||||
|
||||
@@ -45,8 +45,6 @@ mod swagger_imports {
|
||||
|
||||
#[cfg(feature = "swagger")]
|
||||
use swagger_imports::*;
|
||||
#[cfg(feature = "swagger")]
|
||||
use uuid::Uuid;
|
||||
|
||||
/// CDK Mint State
|
||||
#[derive(Clone)]
|
||||
@@ -75,16 +73,16 @@ pub struct MintState {
|
||||
KeysetResponse,
|
||||
KeySet,
|
||||
KeySetInfo,
|
||||
MeltBolt11Request<Uuid>,
|
||||
MeltBolt11Request<String>,
|
||||
MeltQuoteBolt11Request,
|
||||
MeltQuoteBolt11Response<Uuid>,
|
||||
MeltQuoteBolt11Response<String>,
|
||||
MeltQuoteState,
|
||||
MeltMethodSettings,
|
||||
MintBolt11Request<Uuid>,
|
||||
MintBolt11Request<String>,
|
||||
MintBolt11Response,
|
||||
MintInfo,
|
||||
MintQuoteBolt11Request,
|
||||
MintQuoteBolt11Response<Uuid>,
|
||||
MintQuoteBolt11Response<String>,
|
||||
MintQuoteState,
|
||||
MintMethodSettings,
|
||||
MintVersion,
|
||||
@@ -148,18 +146,18 @@ pub async fn create_mint_router_with_custom_cache(
|
||||
let v1_router = Router::new()
|
||||
.route("/keys", get(get_keys))
|
||||
.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("/mint/quote/bolt11", post(post_mint_bolt11_quote))
|
||||
.route(
|
||||
"/mint/quote/bolt11/:quote_id",
|
||||
"/mint/quote/bolt11/{quote_id}",
|
||||
get(get_check_mint_bolt11_quote),
|
||||
)
|
||||
.route("/mint/bolt11", post(cache_post_mint_bolt11))
|
||||
.route("/melt/quote/bolt11", post(post_melt_bolt11_quote))
|
||||
.route("/ws", get(ws_handler))
|
||||
.route(
|
||||
"/melt/quote/bolt11/:quote_id",
|
||||
"/melt/quote/bolt11/{quote_id}",
|
||||
get(get_check_melt_bolt11_quote),
|
||||
)
|
||||
.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",
|
||||
request_body(content = MintQuoteBolt11Request, description = "Request params", content_type = "application/json"),
|
||||
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")
|
||||
)
|
||||
))]
|
||||
@@ -165,7 +165,7 @@ pub async fn post_mint_bolt11_quote(
|
||||
("quote_id" = String, description = "The quote ID"),
|
||||
),
|
||||
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")
|
||||
)
|
||||
))]
|
||||
@@ -201,7 +201,7 @@ pub async fn ws_handler(State(state): State<MintState>, ws: WebSocketUpgrade) ->
|
||||
post,
|
||||
context_path = "/v1",
|
||||
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(
|
||||
(status = 200, description = "Successful response", body = MintBolt11Response, 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",
|
||||
request_body(content = MeltQuoteBolt11Request, description = "Quote params", content_type = "application/json"),
|
||||
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")
|
||||
)
|
||||
))]
|
||||
@@ -256,7 +256,7 @@ pub async fn post_melt_bolt11_quote(
|
||||
("quote_id" = String, description = "The quote ID"),
|
||||
),
|
||||
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")
|
||||
)
|
||||
))]
|
||||
@@ -284,9 +284,9 @@ pub async fn get_check_melt_bolt11_quote(
|
||||
post,
|
||||
context_path = "/v1",
|
||||
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(
|
||||
(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")
|
||||
)
|
||||
))]
|
||||
|
||||
@@ -46,7 +46,6 @@ pub struct WsContext {
|
||||
///
|
||||
/// 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.
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
||||
let (publisher, mut subscriber) = mpsc::channel(100);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@@ -92,7 +91,7 @@ pub async fn main_websocket(mut socket: WebSocket, state: MintState) {
|
||||
match process(&mut context, request).await {
|
||||
Ok(result) => {
|
||||
if let Err(err) = socket
|
||||
.send(Message::Text(result.to_string()))
|
||||
.send(Message::Text(result.to_string().into()))
|
||||
.await
|
||||
{
|
||||
tracing::error!("Could not send request: {}", err);
|
||||
|
||||
@@ -1,42 +1,33 @@
|
||||
[package]
|
||||
name = "cdk-cli"
|
||||
version = "0.7.1"
|
||||
edition = "2021"
|
||||
authors = ["CDK Developers"]
|
||||
description = "Cashu cli wallet built on CDK"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
bip39 = { version = "2.0", features = ["rand"] }
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["wallet"]}
|
||||
cdk-redb = { path = "../cdk-redb", version = "0.7.1", default-features = false, features = ["wallet"] }
|
||||
cdk-sqlite = { path = "../cdk-sqlite", version = "0.7.1", default-features = false, features = ["wallet"] }
|
||||
clap = { version = "~4.0.32", features = ["derive"] }
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tokio = { version = "1", default-features = false }
|
||||
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
home = "0.5.5"
|
||||
anyhow.workspace = true
|
||||
bip39.workspace = true
|
||||
cdk = { workspace = true, default-features = false, features = ["wallet"]}
|
||||
cdk-redb = { workspace = true, features = ["wallet"] }
|
||||
cdk-sqlite = { workspace = true, features = ["wallet"] }
|
||||
clap.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
home.workspace = true
|
||||
nostr-sdk = { version = "0.35.0", default-features = false, features = [
|
||||
"nip04",
|
||||
"nip44",
|
||||
"nip59"
|
||||
]}
|
||||
reqwest = { version = "0.12", default-features = false, features = [
|
||||
"json",
|
||||
"rustls-tls",
|
||||
"rustls-tls-native-roots",
|
||||
"socks",
|
||||
]}
|
||||
url = "2.3"
|
||||
|
||||
# Indirect dep
|
||||
base64ct = "=1.6.0"
|
||||
reqwest.workspace = true
|
||||
url.workspace = true
|
||||
serde_with.workspace = true
|
||||
|
||||
|
||||
@@ -6,17 +6,17 @@ authors = ["CDK Developers"]
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
bitcoin = { version = "0.32.2", default-features = false }
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = ["mint"] }
|
||||
async-trait.workspace = true
|
||||
bitcoin.workspace = true
|
||||
cdk = { workspace = true, features = ["mint"] }
|
||||
cln-rpc = "0.3.0"
|
||||
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"] }
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -81,8 +81,6 @@ impl MintLightning for Cln {
|
||||
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(
|
||||
&self,
|
||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "cdk-common"
|
||||
version = "0.7.1"
|
||||
edition = "2021"
|
||||
authors = ["CDK Developers"]
|
||||
description = "CDK common types and traits"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
rust-version = "1.75.0" # MSRV
|
||||
license.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["mint", "wallet"]
|
||||
@@ -17,31 +17,26 @@ wallet = ["cashu/wallet"]
|
||||
mint = ["cashu/mint", "dep:uuid"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
bitcoin = { version = "0.32.2", features = [
|
||||
"base64",
|
||||
"serde",
|
||||
"rand",
|
||||
"rand-std",
|
||||
] }
|
||||
cashu = { path = "../cashu", default-features = false, version = "0.7.1" }
|
||||
cbor-diag = "0.1.12"
|
||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
thiserror = "2"
|
||||
tracing = "0.1"
|
||||
url = "2.3"
|
||||
uuid = { version = "=1.12.1", features = ["v4", "serde"], optional = true }
|
||||
utoipa = { version = "4", optional = true }
|
||||
futures = "0.3.31"
|
||||
anyhow = "1.0"
|
||||
serde_json = "1"
|
||||
serde_with = "3"
|
||||
async-trait.workspace = true
|
||||
bitcoin.workspace = true
|
||||
cashu.workspace = true
|
||||
cbor-diag.workspace = true
|
||||
ciborium.workspace = true
|
||||
serde.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
url.workspace = true
|
||||
uuid = { workspace = true, optional = true }
|
||||
utoipa = { workspace = true, optional = true }
|
||||
futures.workspace = true
|
||||
anyhow.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_with.workspace = true
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
||||
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.5"
|
||||
bip39 = "2.0"
|
||||
rand.workspace = true
|
||||
bip39.workspace = true
|
||||
|
||||
@@ -12,7 +12,6 @@ pub mod error;
|
||||
#[cfg(feature = "mint")]
|
||||
pub mod lightning;
|
||||
pub mod pub_sub;
|
||||
#[cfg(feature = "mint")]
|
||||
pub mod subscription;
|
||||
pub mod ws;
|
||||
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
//! Subscription types and traits
|
||||
#[cfg(feature = "mint")]
|
||||
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};
|
||||
#[cfg(feature = "mint")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "mint")]
|
||||
use uuid::Uuid;
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
|
||||
use crate::pub_sub::SubId;
|
||||
|
||||
@@ -15,15 +22,18 @@ use crate::pub_sub::SubId;
|
||||
pub type Params = nut17::Params<SubId>;
|
||||
|
||||
/// Wrapper around `nut17::Params` to implement `Indexable` for `Notification`.
|
||||
#[cfg(feature = "mint")]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct IndexableParams(Params);
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
impl From<Params> for IndexableParams {
|
||||
fn from(params: Params) -> Self {
|
||||
Self(params)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
|
||||
type Error = 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 {
|
||||
fn as_ref(&self) -> &SubId {
|
||||
&self.0.id
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
impl Indexable for NotificationPayload<Uuid> {
|
||||
type Type = Notification;
|
||||
|
||||
|
||||
@@ -6,19 +6,19 @@ authors = ["CDK Developers"]
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
rust-version = "1.75.0" # MSRV
|
||||
description = "CDK fake ln backend"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.74"
|
||||
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"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
async-trait.workspace = true
|
||||
bitcoin.workspace = true
|
||||
cdk = { workspace = true, features = ["mint"] }
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
tokio-stream = "0.1.15"
|
||||
|
||||
@@ -7,18 +7,18 @@ description = "Core Cashu Development Kit library implementing the Cashu protoco
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
rust-version = "1.75.0" # MSRV
|
||||
|
||||
|
||||
[features]
|
||||
http_subscription = ["cdk/http_subscription"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
axum = "0.6.20"
|
||||
rand = "0.8.5"
|
||||
bip39 = { version = "2.0", features = ["rand"] }
|
||||
anyhow = "1"
|
||||
async-trait.workspace = true
|
||||
axum.workspace = true
|
||||
rand.workspace = true
|
||||
bip39 = { workspace = true, features = ["rand"] }
|
||||
anyhow.workspace = true
|
||||
cashu = { path = "../cashu", features = ["mint", "wallet"] }
|
||||
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
||||
cdk-cln = { path = "../cdk-cln" }
|
||||
@@ -27,42 +27,34 @@ cdk-axum = { path = "../cdk-axum" }
|
||||
cdk-sqlite = { path = "../cdk-sqlite" }
|
||||
cdk-redb = { path = "../cdk-redb" }
|
||||
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
|
||||
tower-http = { version = "0.4.4", features = ["cors"] }
|
||||
futures = { version = "0.3.28", default-features = false, features = [
|
||||
futures = { workspace = true, default-features = false, features = [
|
||||
"executor",
|
||||
] }
|
||||
once_cell = "1.19.0"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
once_cell.workspace = true
|
||||
uuid.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
# 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"] }
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
tokio-tungstenite.workspace = true
|
||||
tower-http = { workspace = true, features = ["cors"] }
|
||||
tower-service = "0.3.3"
|
||||
tokio-tungstenite = "0.24.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
tokio = { version = "1", features = [
|
||||
"rt-multi-thread",
|
||||
"time",
|
||||
"macros",
|
||||
"sync",
|
||||
] }
|
||||
tokio.workspace = true
|
||||
|
||||
[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"] }
|
||||
instant = { version = "0.1", features = ["wasm-bindgen", "inaccurate"] }
|
||||
instant = { workspace = true, features = ["wasm-bindgen", "inaccurate"] }
|
||||
|
||||
[dev-dependencies]
|
||||
bip39 = { version = "2.0", features = ["rand"] }
|
||||
anyhow = "1"
|
||||
bip39 = { workspace = true, features = ["rand"] }
|
||||
anyhow.workspace = true
|
||||
cdk = { path = "../cdk", features = ["mint", "wallet"] }
|
||||
cdk-axum = { path = "../cdk-axum" }
|
||||
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(())
|
||||
}
|
||||
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
pub async fn wait_for_mint_to_be_paid(
|
||||
wallet: &Wallet,
|
||||
mint_quote_id: &str,
|
||||
|
||||
@@ -110,19 +110,22 @@ async fn test_regtest_mint_melt_round_trip() -> Result<()> {
|
||||
let melt = wallet.melt_quote(invoice, None).await?;
|
||||
|
||||
write
|
||||
.send(Message::Text(serde_json::to_string(&json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2,
|
||||
"method": "subscribe",
|
||||
"params": {
|
||||
"kind": "bolt11_melt_quote",
|
||||
"filters": [
|
||||
melt.id.clone(),
|
||||
],
|
||||
"subId": "test-sub",
|
||||
}
|
||||
.send(Message::Text(
|
||||
serde_json::to_string(&json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2,
|
||||
"method": "subscribe",
|
||||
"params": {
|
||||
"kind": "bolt11_melt_quote",
|
||||
"filters": [
|
||||
melt.id.clone(),
|
||||
],
|
||||
"subId": "test-sub",
|
||||
}
|
||||
|
||||
}))?))
|
||||
}))?
|
||||
.into(),
|
||||
))
|
||||
.await?;
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@@ -6,18 +6,18 @@ authors = ["CDK Developers"]
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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"
|
||||
|
||||
[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"
|
||||
lnbits-rs = "0.3.0"
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
axum.workspace = true
|
||||
bitcoin.workspace = true
|
||||
cdk = { workspace = true, features = ["mint"] }
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
lnbits-rs = "0.4.0"
|
||||
|
||||
@@ -83,7 +83,6 @@ impl MintLightning for LNbits {
|
||||
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> {
|
||||
@@ -182,7 +181,7 @@ impl MintLightning for LNbits {
|
||||
) -> Result<PayInvoiceResponse, Self::Err> {
|
||||
let pay_response = self
|
||||
.lnbits_api
|
||||
.pay_invoice(&melt_quote.request)
|
||||
.pay_invoice(&melt_quote.request, None)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
tracing::error!("Could not pay invoice");
|
||||
|
||||
@@ -9,12 +9,12 @@ repository = "https://github.com/cashubtc/cdk.git"
|
||||
description = "CDK ln backend for lnd"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
anyhow = "1"
|
||||
cdk = { path = "../cdk", version= "0.7.1", default-features = false, features = ["mint"] }
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
cdk = { workspace = true, features = ["mint"] }
|
||||
fedimint-tonic-lnd = "0.2.0"
|
||||
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"
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
|
||||
## Minimum Supported Rust Version (MSRV)
|
||||
|
||||
The `cdk` library should always compile with any combination of features on Rust **1.66.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
|
||||
```
|
||||
The `cdk-lnd` library should always compile with any combination of features on Rust **1.75.0**.
|
||||
|
||||
@@ -7,35 +7,32 @@ description = "CDK mintd mint managment RPC client and server"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
rust-version = "1.75.0" # MSRV
|
||||
|
||||
[[bin]]
|
||||
name = "cdk-mint-cli"
|
||||
path = "src/bin/mint_rpc_cli.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
||||
anyhow.workspace = true
|
||||
cdk = { workspace = true, features = [
|
||||
"mint",
|
||||
] }
|
||||
clap = { version = "~4.0.32", features = ["derive"] }
|
||||
tonic = { version = "0.9", features = [
|
||||
clap.workspace = true
|
||||
tonic = { version = "0.12.3", features = [
|
||||
"channel",
|
||||
"tls",
|
||||
"tls-webpki-roots",
|
||||
] }
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
tokio = { version = "1", default-features = false }
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
thiserror = "1"
|
||||
prost = "0.11.0"
|
||||
home = "0.5.5"
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
tokio.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
prost = "0.13.1"
|
||||
home.workspace = true
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.9"
|
||||
tonic-build = "0.12"
|
||||
|
||||
@@ -7,53 +7,49 @@ license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
description = "CDK mint binary"
|
||||
rust-version = "1.75.0"
|
||||
|
||||
[features]
|
||||
default = ["management-rpc"]
|
||||
swagger = ["cdk-axum/swagger", "dep:utoipa", "dep:utoipa-swagger-ui"]
|
||||
redis = ["cdk-axum/redis"]
|
||||
management-rpc = ["cdk-mint-rpc"]
|
||||
# MSRV is not commited to with redb enabled
|
||||
redb = ["dep:cdk-redb"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
axum = "0.6.20"
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false, features = [
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
axum.workspace = true
|
||||
cdk = { workspace = true, features = [
|
||||
"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",
|
||||
] }
|
||||
cdk-sqlite = { path = "../cdk-sqlite", version = "0.7.1", default-features = false, features = [
|
||||
"mint",
|
||||
] }
|
||||
cdk-cln = { path = "../cdk-cln", version = "0.7.1", default-features = false }
|
||||
cdk-lnbits = { path = "../cdk-lnbits", version = "0.7.1", default-features = false }
|
||||
cdk-phoenixd = { path = "../cdk-phoenixd", version = "0.7.1", default-features = false }
|
||||
cdk-lnd = { path = "../cdk-lnd", version = "0.7.1", default-features = false }
|
||||
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 }
|
||||
cdk-cln.workspace = true
|
||||
cdk-lnbits.workspace = true
|
||||
cdk-phoenixd.workspace = true
|
||||
cdk-lnd.workspace = true
|
||||
cdk-fake-wallet.workspace = true
|
||||
cdk-axum.workspace = true
|
||||
cdk-mint-rpc = { workspace = true, optional = true }
|
||||
config = { version = "0.13.3", features = ["toml"] }
|
||||
clap = { version = "~4.0.32", features = ["derive"] }
|
||||
bitcoin = { version = "0.32.2", features = [
|
||||
"base64",
|
||||
"serde",
|
||||
"rand",
|
||||
"rand-std",
|
||||
] }
|
||||
tokio = { version = "1", default-features = false, features = ["signal"] }
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
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"] }
|
||||
clap.workspace = true
|
||||
bitcoin.workspace = true
|
||||
tokio = { workspace = true, default-features = false, features = ["signal"] }
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
futures.workspace = true
|
||||
serde.workspace = true
|
||||
bip39.workspace = true
|
||||
tower-http = { workspace = true, features = ["compression-full", "decompression-full"] }
|
||||
tower = "0.5.2"
|
||||
lightning-invoice.workspace = true
|
||||
home = "0.5.5"
|
||||
url = "2.3"
|
||||
utoipa = { version = "4", optional = true }
|
||||
utoipa-swagger-ui = { version = "4", features = ["axum"], optional = true }
|
||||
url.workspace = true
|
||||
utoipa = { workspace = true, optional = true }
|
||||
utoipa-swagger-ui = { version = "9.0.0", features = ["axum"], optional = true }
|
||||
|
||||
@@ -47,7 +47,6 @@ pub enum LnBackend {
|
||||
#[default]
|
||||
None,
|
||||
Cln,
|
||||
Strike,
|
||||
LNbits,
|
||||
FakeWallet,
|
||||
Phoenixd,
|
||||
@@ -60,7 +59,6 @@ impl std::str::FromStr for LnBackend {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"cln" => Ok(LnBackend::Cln),
|
||||
"strike" => Ok(LnBackend::Strike),
|
||||
"lnbits" => Ok(LnBackend::LNbits),
|
||||
"fakewallet" => Ok(LnBackend::FakeWallet),
|
||||
"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)]
|
||||
pub struct LNbits {
|
||||
pub admin_api_key: String,
|
||||
@@ -172,6 +164,7 @@ fn default_max_delay_time() -> u64 {
|
||||
pub enum DatabaseEngine {
|
||||
#[default]
|
||||
Sqlite,
|
||||
#[cfg(feature = "redb")]
|
||||
Redb,
|
||||
}
|
||||
|
||||
@@ -181,6 +174,7 @@ impl std::str::FromStr for DatabaseEngine {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"sqlite" => Ok(DatabaseEngine::Sqlite),
|
||||
#[cfg(feature = "redb")]
|
||||
"redb" => Ok(DatabaseEngine::Redb),
|
||||
_ => Err(format!("Unknown database engine: {}", s)),
|
||||
}
|
||||
@@ -199,7 +193,6 @@ pub struct Settings {
|
||||
pub mint_info: MintInfo,
|
||||
pub ln: Ln,
|
||||
pub cln: Option<Cln>,
|
||||
pub strike: Option<Strike>,
|
||||
pub lnbits: Option<LNbits>,
|
||||
pub phoenixd: Option<Phoenixd>,
|
||||
pub lnd: Option<Lnd>,
|
||||
@@ -291,10 +284,6 @@ impl Settings {
|
||||
settings.cln.is_some(),
|
||||
"CLN backend requires a valid config."
|
||||
),
|
||||
LnBackend::Strike => assert!(
|
||||
settings.strike.is_some(),
|
||||
"Strike backend requires a valid config."
|
||||
),
|
||||
LnBackend::LNbits => assert!(
|
||||
settings.lnbits.is_some(),
|
||||
"LNbits backend requires a valid config"
|
||||
|
||||
@@ -9,7 +9,7 @@ use cdk::nuts::CurrencyUnit;
|
||||
use crate::config::MintManagementRpc;
|
||||
use crate::config::{
|
||||
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";
|
||||
@@ -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_FEE_PERCENT: &str = "CDK_MINTD_CLN_FEE_PERCENT";
|
||||
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
|
||||
pub const ENV_LND_ADDRESS: &str = "CDK_MINTD_LND_ADDRESS";
|
||||
pub const ENV_LND_CERT_FILE: &str = "CDK_MINTD_LND_CERT_FILE";
|
||||
@@ -107,9 +104,6 @@ impl Settings {
|
||||
LnBackend::Cln => {
|
||||
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 => {
|
||||
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 {
|
||||
pub fn from_env(mut self) -> Self {
|
||||
if let Ok(address) = env::var(ENV_LND_ADDRESS) {
|
||||
|
||||
@@ -5,15 +5,13 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use axum::http::Request;
|
||||
use axum::middleware::Next;
|
||||
use axum::response::Response;
|
||||
use axum::{middleware, Router};
|
||||
use axum::Router;
|
||||
use bip39::Mnemonic;
|
||||
use cdk::cdk_database::{self, MintDatabase};
|
||||
use cdk::cdk_lightning;
|
||||
@@ -30,12 +28,15 @@ use cdk_mintd::cli::CLIArgs;
|
||||
use cdk_mintd::config::{self, DatabaseEngine, LnBackend};
|
||||
use cdk_mintd::env_vars::ENV_WORK_DIR;
|
||||
use cdk_mintd::setup::LnBackendSetup;
|
||||
#[cfg(feature = "redb")]
|
||||
use cdk_redb::MintRedbDatabase;
|
||||
use cdk_sqlite::MintSqliteDatabase;
|
||||
use clap::Parser;
|
||||
use tokio::sync::Notify;
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::compression::CompressionLayer;
|
||||
use tower_http::cors::CorsLayer;
|
||||
use tower_http::decompression::RequestDecompressionLayer;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
#[cfg(feature = "swagger")]
|
||||
use utoipa::OpenApi;
|
||||
@@ -49,10 +50,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
let sqlx_filter = "sqlx=warn";
|
||||
let hyper_filter = "hyper=warn";
|
||||
let h2_filter = "h2=warn";
|
||||
let tower_http = "tower_http=warn";
|
||||
|
||||
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();
|
||||
@@ -100,6 +102,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
Arc::new(sqlite_db)
|
||||
}
|
||||
#[cfg(feature = "redb")]
|
||||
DatabaseEngine::Redb => {
|
||||
let redb_path = work_dir.join("cdk-mintd.redb");
|
||||
Arc::new(MintRedbDatabase::new(&redb_path)?)
|
||||
@@ -180,29 +183,6 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
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 => {
|
||||
let lnbits_settings = settings.clone().lnbits.expect("Checked on config load");
|
||||
let lnbits = lnbits_settings
|
||||
@@ -341,9 +321,12 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
let mut mint_service = Router::new()
|
||||
.merge(v1_service)
|
||||
.layer(CompressionLayer::new())
|
||||
.layer(middleware::from_fn(logging_middleware))
|
||||
.layer(CorsLayer::permissive());
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(RequestDecompressionLayer::new())
|
||||
.layer(CompressionLayer::new()),
|
||||
)
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
#[cfg(feature = "swagger")]
|
||||
{
|
||||
@@ -406,13 +389,13 @@ async fn main() -> anyhow::Result<()> {
|
||||
mint.set_quote_ttl(QuoteTTL::new(10_000, 10_000)).await?;
|
||||
}
|
||||
|
||||
let axum_result = axum::Server::bind(
|
||||
&format!("{}:{}", listen_addr, listen_port)
|
||||
.as_str()
|
||||
.parse()?,
|
||||
)
|
||||
.serve(mint_service.into_make_service())
|
||||
.with_graceful_shutdown(shutdown_signal());
|
||||
let socket_addr = SocketAddr::from_str(&format!("{}:{}", listen_addr, listen_port))?;
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(socket_addr).await?;
|
||||
|
||||
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||
|
||||
let axum_result = axum::serve(listener, mint_service).with_graceful_shutdown(shutdown_signal());
|
||||
|
||||
match axum_result.await {
|
||||
Ok(_) => {
|
||||
@@ -437,29 +420,6 @@ async fn main() -> anyhow::Result<()> {
|
||||
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> {
|
||||
let home_dir = home::home_dir().ok_or(anyhow!("Unknown home dir"))?;
|
||||
let dir = home_dir.join(".cdk-mintd");
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, bail};
|
||||
use axum::{async_trait, Router};
|
||||
use async_trait::async_trait;
|
||||
use axum::Router;
|
||||
use bip39::rand::{thread_rng, Rng};
|
||||
use cdk::cdk_lightning::MintLightning;
|
||||
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]
|
||||
impl LnBackendSetup for config::LNbits {
|
||||
async fn setup(
|
||||
|
||||
@@ -6,19 +6,19 @@ authors = ["CDK Developers"]
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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"
|
||||
|
||||
[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"
|
||||
phoenixd-rs = "0.4.0"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
axum.workspace = true
|
||||
bitcoin.workspace = true
|
||||
cdk = { workspace = true, features = ["mint"] }
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
phoenixd-rs = "0.5.0"
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -89,7 +89,6 @@ impl MintLightning for Phoenixd {
|
||||
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> {
|
||||
|
||||
@@ -7,24 +7,21 @@ description = "Redb storage backend for CDK"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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
|
||||
[features]
|
||||
default = ["mint", "wallet"]
|
||||
mint = []
|
||||
wallet = []
|
||||
mint = ["cdk-common/mint"]
|
||||
wallet = ["cdk-common/wallet"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
||||
redb = "2.2.0"
|
||||
thiserror = "1"
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_json = "1"
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
async-trait.workspace = true
|
||||
cdk-common.workspace = true
|
||||
redb = "2.4.0"
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -7,7 +7,7 @@ description = "Indexdb storage backend for CDK in the browser"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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
|
||||
[features]
|
||||
@@ -16,11 +16,11 @@ wallet = ["cdk/wallet"]
|
||||
|
||||
[dependencies]
|
||||
rexie = "0.6.0"
|
||||
cdk = { path = "../cdk", version = "0.7.1", default-features = false }
|
||||
async-trait = "0.1.74"
|
||||
tokio = { version = "1", default-features = false }
|
||||
serde = { version = "1", default-features = false, features = ["derive"] }
|
||||
serde_json = "1"
|
||||
thiserror = "1"
|
||||
cdk.workspace = true
|
||||
async-trait.workspace = true
|
||||
tokio.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
serde-wasm-bindgen = "0.6.5"
|
||||
web-sys = { version = "0.3.69", default-features = false, features = ["console"] }
|
||||
|
||||
@@ -7,18 +7,18 @@ description = "SQLite storage backend for CDK"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
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
|
||||
[features]
|
||||
default = ["mint", "wallet"]
|
||||
mint = []
|
||||
wallet = []
|
||||
mint = ["cdk-common/mint"]
|
||||
wallet = ["cdk-common/wallet"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
||||
bitcoin = { version = "0.32.2", default-features = false }
|
||||
async-trait.workspace = true
|
||||
cdk-common.workspace = true
|
||||
bitcoin.workspace = true
|
||||
sqlx = { version = "0.6.3", default-features = false, features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
@@ -26,12 +26,9 @@ sqlx = { version = "0.6.3", default-features = false, features = [
|
||||
"migrate",
|
||||
"uuid",
|
||||
] }
|
||||
thiserror = "1"
|
||||
tokio = { version = "1", features = ["time", "macros", "sync"] }
|
||||
tracing = { version = "0.1", default-features = false, features = [
|
||||
"attributes",
|
||||
"log",
|
||||
] }
|
||||
serde_json = "1"
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
serde_json.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -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]
|
||||
name = "cdk"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
edition = "2021"
|
||||
authors = ["CDK Developers"]
|
||||
description = "Core Cashu Development Kit library implementing the Cashu protocol"
|
||||
homepage = "https://github.com/cashubtc/cdk"
|
||||
repository = "https://github.com/cashubtc/cdk.git"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
rust-version = "1.75.0" # MSRV
|
||||
license = "MIT"
|
||||
|
||||
|
||||
@@ -21,63 +21,45 @@ http_subscription = []
|
||||
|
||||
|
||||
[dependencies]
|
||||
cdk-common = { path = "../cdk-common", version = "0.7.1" }
|
||||
cbor-diag = "0.1.12"
|
||||
async-trait = "0.1"
|
||||
anyhow = { version = "1.0.43", features = ["backtrace"] }
|
||||
bitcoin = { version = "0.32.2", features = [
|
||||
"base64",
|
||||
"serde",
|
||||
"rand",
|
||||
"rand-std",
|
||||
] }
|
||||
ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
|
||||
lightning-invoice = { version = "0.32.0", features = ["serde", "std"] }
|
||||
cdk-common.workspace = true
|
||||
cbor-diag.workspace = true
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
bitcoin.workspace = true
|
||||
ciborium.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
regex = "1"
|
||||
reqwest = { version = "0.12", default-features = false, features = [
|
||||
"json",
|
||||
"rustls-tls",
|
||||
"rustls-tls-native-roots",
|
||||
"socks",
|
||||
"zstd",
|
||||
"brotli",
|
||||
"gzip",
|
||||
"deflate",
|
||||
], optional = 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"] }
|
||||
reqwest = { workspace = true, optional = true }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_with.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
futures = { workspace = true, optional = true, features = ["alloc"] }
|
||||
url.workspace = true
|
||||
utoipa = { workspace = true, optional = true }
|
||||
uuid.workspace = true
|
||||
|
||||
# -Z minimal-versions
|
||||
sync_wrapper = "0.1.2"
|
||||
bech32 = "0.9.1"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
tokio = { version = "1.21", features = [
|
||||
tokio = { workspace = true, features = [
|
||||
"rt-multi-thread",
|
||||
"time",
|
||||
"macros",
|
||||
"sync",
|
||||
] }
|
||||
getrandom = { version = "0.2" }
|
||||
tokio-tungstenite = { version = "0.19.0", features = [
|
||||
tokio-tungstenite = { workspace = true, features = [
|
||||
"rustls",
|
||||
"rustls-tls-native-roots",
|
||||
"connect"
|
||||
] }
|
||||
|
||||
[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"] }
|
||||
|
||||
[[example]]
|
||||
@@ -98,9 +80,9 @@ required-features = ["wallet"]
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.5"
|
||||
bip39 = "2.0"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
cdk-sqlite = { path = "../cdk-sqlite" }
|
||||
cdk-sqlite.workspace = true
|
||||
bip39.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
criterion = "0.5.1"
|
||||
|
||||
[[bench]]
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
|
||||
pub mod 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")]
|
||||
@@ -20,9 +24,11 @@ pub mod pub_sub;
|
||||
pub use cdk_common::{
|
||||
amount, common as types, dhke,
|
||||
error::{self, Error},
|
||||
lightning as cdk_lightning, lightning_invoice, mint_url, nuts, secret, subscription, util, ws,
|
||||
Amount, Bolt11Invoice,
|
||||
lightning_invoice, mint_url, nuts, secret, util, ws, Amount, Bolt11Invoice,
|
||||
};
|
||||
#[cfg(feature = "mint")]
|
||||
#[doc(hidden)]
|
||||
pub use cdk_common::{lightning as cdk_lightning, subscription};
|
||||
|
||||
pub mod fees;
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ impl Mint {
|
||||
|
||||
if let Ok(Some(quote)) = self.localstore.get_melt_quote(&melt_request.quote).await {
|
||||
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 {
|
||||
|
||||
@@ -139,8 +139,6 @@ impl Mint {
|
||||
/// Wait 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
|
||||
#[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> {
|
||||
let mint_arc = Arc::new(self.clone());
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ async fn convert_subscription(
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
#[inline]
|
||||
pub async fn http_main<S: IntoIterator<Item = SubId>>(
|
||||
initial_state: S,
|
||||
|
||||
@@ -290,7 +290,6 @@ impl SubscriptionClient {
|
||||
///
|
||||
/// This is a WebSocket based subscription, where the client will connect to
|
||||
/// the server and stay there idle waiting for server-side notifications
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
#[cfg(all(
|
||||
not(feature = "http_subscription"),
|
||||
feature = "mint",
|
||||
|
||||
@@ -34,7 +34,6 @@ async fn fallback_to_http<S: IntoIterator<Item = SubId>>(
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
#[inline]
|
||||
pub async fn ws_main(
|
||||
http_client: Arc<dyn MintConnector + Send + Sync>,
|
||||
@@ -131,7 +130,7 @@ pub async fn ws_main(
|
||||
.get(sub_id)
|
||||
.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);
|
||||
}
|
||||
}
|
||||
@@ -192,7 +191,7 @@ pub async fn ws_main(
|
||||
tracing::debug!("Subscribing to {:?}", sub.1);
|
||||
active_subscriptions.insert(subid, sub.0.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);
|
||||
}
|
||||
},
|
||||
@@ -203,7 +202,7 @@ pub async fn ws_main(
|
||||
}
|
||||
tracing::debug!("Unsubscribing from {:?}", 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_toolchain = pkgs.rust-bin.stable."1.63.0".default.override {
|
||||
targets = [ "wasm32-unknown-unknown" ]; # wasm
|
||||
};
|
||||
|
||||
|
||||
# DB MSRV stable
|
||||
db_msrv_toolchain = pkgs.rust-bin.stable."1.66.0".default.override {
|
||||
msrv_toolchain = pkgs.rust-bin.stable."1.75.0".default.override {
|
||||
targets = [ "wasm32-unknown-unknown" ]; # wasm
|
||||
};
|
||||
|
||||
@@ -86,6 +80,7 @@
|
||||
clightning
|
||||
bitcoind
|
||||
sqlx-cli
|
||||
cargo-outdated
|
||||
|
||||
# Needed for github ci
|
||||
libz
|
||||
@@ -232,29 +227,16 @@
|
||||
msrv = pkgs.mkShell ({
|
||||
shellHook = "
|
||||
${_shellHook}
|
||||
cargo update -p half --precise 2.2.1
|
||||
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
|
||||
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 zerofrom --precise 0.1.5
|
||||
|
||||
cargo update -p url --precise 2.5.2
|
||||
|
||||
# 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 url --precise 2.5.2
|
||||
|
||||
";
|
||||
buildInputs = buildInputs ++ WASMInputs ++ [ msrv_toolchain ];
|
||||
@@ -268,28 +250,6 @@
|
||||
} // 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 ({
|
||||
shellHook = ''
|
||||
${_shellHook}
|
||||
@@ -305,7 +265,7 @@
|
||||
|
||||
in
|
||||
{
|
||||
inherit msrv stable nightly db_shell;
|
||||
inherit msrv stable nightly;
|
||||
default = stable;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export CDK_MINTD_DATABASE=$MINT_DATABASE;
|
||||
|
||||
|
||||
echo "Starting fake mintd";
|
||||
cargo run --bin cdk-mintd &
|
||||
cargo run --bin cdk-mintd --features "redb" &
|
||||
cdk_mintd_pid=$!
|
||||
|
||||
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
|
||||
|
||||
echo "Starting cln mintd";
|
||||
cargo run --bin cdk-mintd &
|
||||
cargo run --bin cdk-mintd --features "redb" &
|
||||
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";
|
||||
|
||||
echo "Starting lnd mintd";
|
||||
cargo run --bin cdk-mintd &
|
||||
cargo run --bin cdk-mintd --features "redb" &
|
||||
cdk_mintd_lnd_pid=$!
|
||||
|
||||
URL="http://$cdk_itests_mint_addr:$cdk_itests_mint_port_1/v1/info"
|
||||
|
||||
Reference in New Issue
Block a user