Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/hrn-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ jobs:
- name: Run HRN Integration Tests
run: |
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn --features uniffi
RUSTFLAGS="--cfg no_download --cfg hrn_tests $RUSTFLAGS" cargo test --test integration_tests_hrn --no-default-features --features uniffi-default
6 changes: 4 additions & 2 deletions .github/workflows/postgres-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ jobs:
- name: Install Rust stable toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain stable
- name: Check all features
run: cargo check --all-features --tests --verbose --color always
- name: Enable caching for bitcoind
id: cache-bitcoind
uses: actions/cache@v4
Expand All @@ -58,9 +60,9 @@ jobs:
- name: Run PostgreSQL store tests
env:
TEST_POSTGRES_URL: "host=localhost user=postgres password=postgres"
run: cargo test --features postgres io::postgres_store
run: cargo test --features storage-postgres io::postgres_store
- name: Run PostgreSQL integration tests
env:
TEST_POSTGRES_URL: "host=localhost user=postgres password=postgres"
run: |
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features postgres --test integration_tests_postgres
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features storage-postgres --test integration_tests_postgres
8 changes: 4 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ jobs:
run: cargo build --verbose --color always
- name: Build with UniFFI support on Rust ${{ matrix.toolchain }}
if: matrix.build-uniffi
run: cargo build --features uniffi --verbose --color always
run: cargo build --no-default-features --features uniffi-default --verbose --color always
- name: Check release build on Rust ${{ matrix.toolchain }}
run: cargo check --release --verbose --color always
- name: Check release build with UniFFI support on Rust ${{ matrix.toolchain }}
if: matrix.build-uniffi
run: cargo check --release --features uniffi --verbose --color always
run: cargo check --release --no-default-features --features uniffi-default --verbose --color always
- name: Test on Rust ${{ matrix.toolchain }}
if: "matrix.platform != 'windows-latest'"
run: |
RUSTFLAGS="--cfg no_download --cfg cycle_tests --cfg tokio_unstable" cargo test
- name: Test with UniFFI support on Rust ${{ matrix.toolchain }}
if: "matrix.platform != 'windows-latest' && matrix.build-uniffi"
run: |
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features uniffi
RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --no-default-features --features uniffi-default

linting:
name: Linting
Expand All @@ -106,7 +106,7 @@ jobs:
- name: Ban `unwrap` in library code
run: |
cargo clippy --lib --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments
cargo clippy --lib --features uniffi --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments
cargo clippy --lib --no-default-features --features uniffi-default --verbose --color always -- -A warnings -D clippy::unwrap_used -A clippy::tabs_in_doc_comments

doc:
name: Documentation
Expand Down
72 changes: 56 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,48 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = 'abort' # Abort on panic

[features]
default = []
postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"]
default = [
"chain-esplora",
"chain-electrum",
"chain-bitcoind",
"storage-sqlite",
"storage-filesystem",
"storage-vss",
"unified-payments",
]
chain-esplora = [
"dep:bdk_esplora",
"dep:esplora-client",
"dep:ldk-esplora-client",
"dep:lightning-transaction-sync",
"lightning-transaction-sync/esplora-async-https",
"lightning-transaction-sync/time",
]
chain-electrum = [
"dep:bdk_electrum",
"dep:electrum-client",
"dep:lightning-transaction-sync",
"lightning-transaction-sync/electrum-rustls-ring",
]
chain-bitcoind = ["dep:lightning-block-sync"]
storage-sqlite = ["dep:rusqlite"]
storage-filesystem = ["dep:lightning-persister"]
storage-vss = ["dep:vss-client", "dep:prost"]
storage-postgres = ["dep:tokio-postgres", "dep:native-tls", "dep:postgres-native-tls"]
unified-payments = [
"dep:bip21",
"dep:bitcoin-payment-instructions",
"dep:lightning-dns-resolver",
]
uniffi = ["dep:uniffi"]
uniffi-default = [
"uniffi",
"chain-esplora",
"chain-electrum",
"storage-sqlite",
"storage-vss",
"unified-payments",
]

[dependencies]
#lightning = { version = "0.2.0", features = ["std"] }
Expand All @@ -45,35 +85,35 @@ lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["tokio"] }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["tokio"], optional = true }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["rest-client", "rpc-client", "tokio"], optional = true }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", optional = true }
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", features = ["std"] }
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb" }
lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "9174965af9437196c527a9aa0df36bbcf050c8bb", optional = true }

bdk_chain = { version = "0.23.3", default-features = false, features = ["std"] }
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"]}
bdk_electrum = { version = "0.24.0", default-features = false, features = ["use-rustls-ring"]}
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"], optional = true }
bdk_electrum = { version = "0.24.0", default-features = false, features = ["use-rustls-ring"], optional = true }
bdk_wallet = { version = "3.1.0", default-features = false, features = ["std", "keys-bip39"]}

bitreq = { version = "0.3", default-features = false, features = ["async-https", "json-using-serde"] }
rustls = { version = "0.23", default-features = false }
rusqlite = { version = "0.31.0", features = ["bundled"] }
rusqlite = { version = "0.31.0", features = ["bundled"], optional = true }
bitcoin = "0.32.7"
bip39 = { version = "2.0.0", features = ["rand"] }
bip21 = { version = "0.5", features = ["std"], default-features = false }
bip21 = { version = "0.5", features = ["std"], default-features = false, optional = true }

base64 = { version = "0.22.1", default-features = false, features = ["std"] }
getrandom = { version = "0.3", default-features = false }
chrono = { version = "0.4", default-features = false, features = ["clock"] }
tokio = { version = "1.39", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros", "net" ] }
tokio-util = { version = "0.7.10", default-features = false, features = ["rt"] }
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"] }
ldk-esplora-client = { package = "esplora-client", version = "0.13", default-features = false, features = ["tokio", "async-https-rustls"] }
electrum-client = { version = "0.25", default-features = false, features = ["proxy", "use-rustls-ring"] }
esplora-client = { version = "0.12", default-features = false, features = ["tokio", "async-https-rustls"], optional = true }
ldk-esplora-client = { package = "esplora-client", version = "0.13", default-features = false, features = ["tokio", "async-https-rustls"], optional = true }
electrum-client = { version = "0.25", default-features = false, features = ["proxy", "use-rustls-ring"], optional = true }
libc = "0.2"
uniffi = { version = "0.29.5", features = ["build"], optional = true }
serde = { version = "1.0.210", default-features = false, features = ["std", "derive"] }
Expand All @@ -84,10 +124,10 @@ async-trait = { version = "0.1", default-features = false }
tokio-postgres = { version = "0.7", default-features = false, features = ["runtime"], optional = true }
native-tls = { version = "0.2", default-features = false, optional = true }
postgres-native-tls = { version = "0.5", default-features = false, features = ["runtime"], optional = true }
vss-client = { package = "vss-client-ng", version = "0.6" }
prost = { version = "0.11.6", default-features = false}
vss-client = { package = "vss-client-ng", version = "0.6", optional = true }
prost = { version = "0.11.6", default-features = false, optional = true}
#bitcoin-payment-instructions = { version = "0.6" }
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "1d6ffaa8962391ddc84aeef98bd7439e55ccae9d" }
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "1d6ffaa8962391ddc84aeef98bd7439e55ccae9d", optional = true }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }
Expand Down
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,60 @@ LDK Node currently comes with a decidedly opinionated set of design choices:

- On-chain data is handled by the integrated [BDK][bdk] wallet.
- Chain data may currently be sourced from the Bitcoin Core RPC interface, or from an [Electrum][electrum] or [Esplora][esplora] server.
- Wallet and channel state may be persisted to an [SQLite][sqlite] or [PostgreSQL][postgresql] database, to file system, or to a custom back-end to be implemented by the user.
- Wallet and channel state may be persisted to an [SQLite][sqlite] or [PostgreSQL][postgresql] database, to the filesystem, to a VSS server, or to a custom back-end to be implemented by the user.
- Gossip data may be sourced via Lightning's peer-to-peer network or the [Rapid Gossip Sync](https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/) protocol.
- Entropy for the Lightning and on-chain wallets may be sourced from raw bytes or a [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic. In addition, LDK Node offers the means to generate and persist the entropy bytes to disk.

### Cargo Features

LDK Node's optional dependencies are grouped by the functionality they provide:

| Feature | Functionality |
| --- | --- |
| `chain-esplora` | Esplora chain source |
| `chain-electrum` | Electrum chain source |
| `chain-bitcoind` | Bitcoin Core RPC and REST chain source |
| `storage-sqlite` | SQLite storage |
| `storage-filesystem` | Filesystem storage |
| `storage-vss` | Versioned Storage Service storage |
| `storage-postgres` | PostgreSQL storage |
| `unified-payments` | BIP 21 and human-readable-name payment support |
| `uniffi` | UniFFI language bindings |
| `uniffi-default` | The standard language-binding feature set |

The `default` feature set preserves the native Rust API's previous behavior. It enables all three
chain sources, SQLite, filesystem and VSS storage, and unified payments. PostgreSQL and UniFFI
remain opt-in. Every build must enable at least one chain source feature.

Disable the default features to select only the functionality and dependencies an application
needs. For example:

```shell
cargo build --no-default-features --features chain-esplora,storage-sqlite
```

`uniffi-default` enables UniFFI, Esplora, Electrum, SQLite, VSS, and unified payments. It excludes
Bitcoin Core, filesystem storage, and PostgreSQL. Binding users can add any of those features:

```shell
cargo build --no-default-features --features uniffi-default,chain-bitcoind
```

Use `uniffi` directly instead of `uniffi-default` to assemble a fully custom binding build. For
example, a Bitcoin Core and PostgreSQL-only binding build uses:

```shell
cargo build --no-default-features --features uniffi,chain-bitcoind,storage-postgres
```

The binding generation scripts use `uniffi-default`. Set `LDK_NODE_EXTRA_FEATURES` to add features
to their builds:

```shell
LDK_NODE_EXTRA_FEATURES=chain-bitcoind,storage-postgres \
./scripts/uniffi_bindgen_generate_python.sh
```

## Compatibility

LDK Node does not provide a stable public API until v1.0. Persisted node state is backwards compatible: newer releases are guaranteed to load state written by older releases. Downgrades are not supported, so state written by a newer release may not load with an older release.
Expand Down
41 changes: 0 additions & 41 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -47,47 +47,6 @@ interface ProbingConfigBuilder {
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bindings/ldk_node.udl:73unified_payment() is declared unconditionally in the UDL while the Rust side is gated on unified-payments, so the same combo also fails with E0425. Effectively uniffi requires storage-vss + unified-payments, but nothing enforces or documents that.

interface Builder {
constructor();
[Name=from_config]
constructor(Config config);
void set_chain_source_esplora(string server_url, EsploraSyncConfig? config);
void set_chain_source_electrum(string server_url, ElectrumSyncConfig? config);
void set_chain_source_bitcoind_rpc(string rpc_host, u16 rpc_port, string rpc_user, string rpc_password, u32? wallet_rescan_from_height);
void set_chain_source_bitcoind_rest(string rest_host, u16 rest_port, string rpc_host, u16 rpc_port, string rpc_user, string rpc_password, u32? wallet_rescan_from_height);
void set_gossip_source_p2p();
void set_gossip_source_rgs(string rgs_server_url);
void set_pathfinding_scores_source(string url);
void add_liquidity_source(PublicKey node_id, SocketAddress address, string? token, boolean trust_peer_0conf);
void set_storage_dir_path(string storage_dir_path);
void set_filesystem_logger(string? log_file_path, LogLevel? max_log_level);
void set_log_facade_logger();
void set_custom_logger(LogWriter log_writer);
void set_network(Network network);
[Throws=BuildError]
void set_listening_addresses(sequence<SocketAddress> listening_addresses);
[Throws=BuildError]
void set_announcement_addresses(sequence<SocketAddress> announcement_addresses);
[Throws=BuildError]
void set_tor_config(TorConfig tor_config);
[Throws=BuildError]
void set_node_alias(string node_alias);
[Throws=BuildError]
void set_async_payments_role(AsyncPaymentsRole? role);
void set_probing_config(ProbingConfig config);
[Throws=BuildError]
Node build(NodeEntropy node_entropy);
[Throws=BuildError]
Node build_with_postgres_store(NodeEntropy node_entropy, string connection_string, string? db_name, string? kv_table_name, string? certificate_pem);
[Throws=BuildError]
Node build_with_fs_store(NodeEntropy node_entropy);
[Throws=BuildError]
Node build_with_vss_store(NodeEntropy node_entropy, string vss_url, string store_id, record<string, string> fixed_headers);
[Throws=BuildError]
Node build_with_vss_store_and_lnurl_auth(NodeEntropy node_entropy, string vss_url, string store_id, string lnurl_auth_server_url, record<string, string> fixed_headers);
[Throws=BuildError]
Node build_with_vss_store_and_fixed_headers(NodeEntropy node_entropy, string vss_url, string store_id, record<string, string> fixed_headers);
[Throws=BuildError]
Node build_with_vss_store_and_header_provider(NodeEntropy node_entropy, string vss_url, string store_id, VssHeaderProvider header_provider);
};

interface Node {
Expand Down
11 changes: 8 additions & 3 deletions scripts/uniffi_bindgen_generate_kotlin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ TARGET_DIR="target/bindings/kotlin"
PROJECT_DIR="ldk-node-jvm"
PACKAGE_DIR="org/lightningdevkit/ldknode"
UNIFFI_BINDGEN_BIN="cargo run --manifest-path bindings/uniffi-bindgen/Cargo.toml"
UNIFFI_FEATURES="uniffi-default"

if [[ -n "${LDK_NODE_EXTRA_FEATURES:-}" ]]; then
UNIFFI_FEATURES+=",$LDK_NODE_EXTRA_FEATURES"
fi

case " ${RUSTFLAGS:-} " in
*" --cfg tokio_unstable "*|*" --cfg=tokio_unstable "*) ;;
Expand All @@ -12,21 +17,21 @@ esac

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
rustup target add x86_64-unknown-linux-gnu || exit 1
cargo build --release --target x86_64-unknown-linux-gnu --features uniffi || exit 1
cargo build --release --target x86_64-unknown-linux-gnu --no-default-features --features "$UNIFFI_FEATURES" || exit 1
DYNAMIC_LIB_PATH="target/x86_64-unknown-linux-gnu/release/libldk_node.so"
RES_DIR="$BINDINGS_DIR/$PROJECT_DIR/lib/src/main/resources/linux-x86-64/"
mkdir -p $RES_DIR || exit 1
cp $DYNAMIC_LIB_PATH $RES_DIR || exit 1
else
rustup target add x86_64-apple-darwin || exit 1
cargo build --release --target x86_64-apple-darwin --features uniffi || exit 1
cargo build --release --target x86_64-apple-darwin --no-default-features --features "$UNIFFI_FEATURES" || exit 1
DYNAMIC_LIB_PATH="target/x86_64-apple-darwin/release/libldk_node.dylib"
RES_DIR="$BINDINGS_DIR/$PROJECT_DIR/lib/src/main/resources/darwin-x86-64/"
mkdir -p $RES_DIR || exit 1
cp $DYNAMIC_LIB_PATH $RES_DIR || exit 1

rustup target add aarch64-apple-darwin || exit 1
cargo build --release --target aarch64-apple-darwin --features uniffi || exit 1
cargo build --release --target aarch64-apple-darwin --no-default-features --features "$UNIFFI_FEATURES" || exit 1
DYNAMIC_LIB_PATH="target/aarch64-apple-darwin/release/libldk_node.dylib"
RES_DIR="$BINDINGS_DIR/$PROJECT_DIR/lib/src/main/resources/darwin-aarch64/"
mkdir -p $RES_DIR || exit 1
Expand Down
Loading
Loading