Skip to content
Merged
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
14 changes: 0 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions libs/gl-sdk-napi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1226,17 +1226,19 @@ pub fn parse_input(input: String) -> Result<ParsedInput> {
Ok(napi_parsed_input_from_gl(parsed))
}

/// Asynchronously classify and resolve the input.
/// Classify and resolve the input.
///
/// Internally calls `parseInput`. For LNURL bech32 strings and
/// Lightning Addresses performs the HTTP GET to the endpoint and
/// returns typed pay or withdraw request data. For BOLT11 invoices
/// and node IDs returns immediately without I/O.
#[napi]
pub async fn resolve_input(input: String) -> Result<ResolvedInput> {
let resolved = glsdk::resolve_input(input)
.await
.map_err(|e| Error::from_reason(e.to_string()))?;
let resolved = tokio::task::spawn_blocking(move || {
glsdk::resolve_input(input).map_err(|e| Error::from_reason(e.to_string()))
})
.await
.map_err(|e| Error::from_reason(e.to_string()))??;
Ok(napi_resolved_input_from_gl(resolved))
}

Expand Down
3 changes: 1 addition & 2 deletions libs/gl-sdk/.tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ tasks:
desc: "Generate C++ bindings (requires uniffi-bindgen-cpp)"
dir: "{{.TASKFILE_DIR}}/../.."
deps:
- task: build
vars: { CARGO_FLAGS: '{{if eq .PROFILE "release"}}--release{{else}}{{end}} --features cpp-bindings' }
- build
cmds:
- |
cp ${CARGO_TARGET_DIR:-target}/{{.PROFILE_DIR}}/libglsdk.{{.LIB_EXT}} ./libs/gl-sdk/glsdk/libglsdk.{{.LIB_EXT}};
Expand Down
5 changes: 5 additions & 0 deletions libs/gl-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## Unreleased

### Changed

- `resolve_input()` is now **synchronous**, matching every other public SDK function. Async work (LNURL HTTP fetches) is executed internally on a shared Tokio runtime. Callers no longer need an async runtime or coroutine support; use native threading primitives to call off the main thread if needed.
- Removed the `cpp-bindings` Cargo feature flag. A single build of the shared library now works for all language bindings (Python, Kotlin, Swift, Ruby, C++) without conditional compilation.

## [0.2.1] - 2026-04-30

### Added
Expand Down
5 changes: 1 addition & 4 deletions libs/gl-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ thiserror = "2.0.17"
tokio = { version = "1", features = ["sync"] }
tonic.workspace = true
tracing = { version = "0.1.43", features = ["async-await", "log"] }
uniffi = { version = "0.29.4", features = ["tokio"] }
uniffi = { version = "0.29.4" }
url = "2"

[build-dependencies]
uniffi = { version = "0.29.4", features = [ "build" ] }

[features]
cpp-bindings = []
28 changes: 26 additions & 2 deletions libs/gl-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ C++ bindings use [uniffi-bindgen-cpp](https://github.com/NordSecurity/uniffi-bin
cargo install uniffi-bindgen-cpp --git https://github.com/NordSecurity/uniffi-bindgen-cpp --tag v0.8.1+v0.29.4
```

Then build with the `cpp-bindings` feature and generate bindings:
Then build and generate bindings:

```bash
cargo build --release -p gl-sdk --features cpp-bindings
cargo build --release -p gl-sdk
uniffi-bindgen-cpp --library target/release/libglsdk.dylib --out-dir libs/gl-sdk/bindings
```

Expand All @@ -105,6 +105,30 @@ perl -pi -e 's/NodeBuilder::register\(/NodeBuilder::register_node\(/g; s/Schedul

The `task sdk:bindings-cpp` command handles all of the above automatically, including platform detection.

## Synchronous API Design

The entire public API exposed by the SDK through UniFFI is
**synchronous**. Functions that need to perform async work (network
I/O, gRPC calls) block the calling thread while an internal Tokio
runtime executes the underlying async operations.

This is a deliberate design choice:

- **Uniform bindings** -- every target language (Python, Kotlin,
Swift, Ruby, C++) gets the same blocking API. No language needs
an async runtime, coroutine support, or special feature flags on
the caller side.
- **Simpler integration** -- callers that need concurrency can use
their language's native threading primitives (e.g. `threading` in
Python, `std::thread` in C++, coroutines in Kotlin) to call SDK
methods off the main thread.
- **No conditional compilation** -- a single build of the shared
library works for all bindings, avoiding feature-flag divergence
between languages.

The internal Tokio runtime is created lazily on the first call and
lives for the lifetime of the process (see `src/util.rs`).

## Files

- `src/sdk.udl` - UniFFI interface definition
Expand Down
20 changes: 10 additions & 10 deletions libs/gl-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub fn parse_input(input: String) -> Result<input::ParsedInput, Error> {
input::parse_input(input)
}

/// Asynchronously classify and resolve the input.
/// Classify and resolve the input.
///
/// Internally calls `parse_input` for offline classification, then
/// for LNURL bech32 strings and Lightning Addresses performs the
Expand All @@ -259,15 +259,15 @@ pub fn parse_input(input: String) -> Result<input::ParsedInput, Error> {
/// immediately without I/O.
///
/// Strips `lightning:` / `LIGHTNING:` prefixes automatically.
#[cfg(not(feature = "cpp-bindings"))]
#[uniffi::export(async_runtime = "tokio")]
pub async fn resolve_input(input: String) -> Result<input::ResolvedInput, Error> {
input::resolve_input(input).await
}

/// Synchronously classify and resolve the input (C++ bindings).
/// Note: This blocks the current thread. Use in a background thread if needed.
#[cfg(feature = "cpp-bindings")]
///
/// # Blocking
///
/// This function blocks the calling thread while any network I/O
/// completes. The SDK exposes a **synchronous-only** public API so
/// that every language binding (Python, Kotlin, Swift, Ruby, C++)
/// works without requiring an async runtime on the caller side.
/// Async work is executed internally on a shared Tokio runtime
/// managed by the SDK.
#[uniffi::export]
pub fn resolve_input(input: String) -> Result<input::ResolvedInput, Error> {
util::exec(async { input::resolve_input(input).await })
Expand Down
Loading