Skip to content

Commit 6cdd0e6

Browse files
Copilotntheile
andauthored
Add Swift bindings using UniFFI similar to Kotlin bindings (#22)
* Initial plan * Add Swift bindings using UniFFI similar to Kotlin bindings Co-authored-by: ntheile <1273575+ntheile@users.noreply.github.com> * Fix XCFramework creation to include headers and update .gitignore Co-authored-by: ntheile <1273575+ntheile@users.noreply.github.com> * fix on ios * readme --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ntheile <1273575+ntheile@users.noreply.github.com> Co-authored-by: nicktee <ntheile@gmail.com>
1 parent 4ae942b commit 6cdd0e6

15 files changed

Lines changed: 9386 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ members = [
44
"crates/lni",
55
"bindings/lni_nodejs",
66
"bindings/kotlin",
7+
"bindings/swift",
78
]

bindings/swift/.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Generated Swift bindings
2+
Sources/LNI/lni.swift
3+
Sources/LNI/lniFFI.h
4+
Sources/LNI/lniFFI.modulemap
5+
6+
# Generated iOS libraries and headers
7+
libs/
8+
include/
9+
LNI.xcframework/
10+
11+
# Xcode
12+
*.xcuserdata
13+
*.xcworkspace
14+
!*.xcworkspace/contents.xcworkspacedata
15+
xcuserdata/
16+
DerivedData/
17+
*.pbxuser
18+
!default.pbxuser
19+
*.mode1v3
20+
!default.mode1v3
21+
*.mode2v3
22+
!default.mode2v3
23+
*.perspectivev3
24+
!default.perspectivev3
25+
*.hmap
26+
*.ipa
27+
*.dSYM.zip
28+
*.dSYM
29+
30+
# Swift Package Manager
31+
.build/
32+
.swiftpm/
33+
Package.resolved
34+
Packages/
35+
36+
# Build outputs
37+
target/
38+
out/
39+
40+
# Native libraries (generated)
41+
*.a
42+
*.dylib
43+
*.so
44+
45+
# macOS
46+
.DS_Store
47+
.AppleDouble
48+
.LSOverride
49+
._*
50+
51+
# IDE
52+
.idea/
53+
*.iml
54+
.vscode/
55+
56+
# Xcode schemes (these are usually user-specific)
57+
*.xcscheme
58+
59+
# Local configuration
60+
local.xcconfig

bindings/swift/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "lni-swift-bindgen"
3+
version = "0.1.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[[bin]]
8+
name = "uniffi-bindgen"
9+
path = "uniffi-bindgen.rs"
10+
11+
[dependencies]
12+
uniffi = { version = "0.29.0", features = ["cli"] }

bindings/swift/README.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# LNI Swift Bindings
2+
3+
Swift bindings for the Lightning Node Interface (LNI) library, generated using UniFFI.
4+
5+
## Overview
6+
7+
This package provides Swift bindings for LNI, allowing you to interact with various Lightning Network node implementations from Swift/iOS applications.
8+
9+
## Supported Nodes
10+
11+
- **BlinkNode** - Blink Lightning service
12+
- **StrikeNode** - Strike Lightning service
13+
- **PhoenixdNode** - Phoenixd daemon
14+
- **LndNode** - LND (Lightning Network Daemon)
15+
- **ClnNode** - Core Lightning (CLN)
16+
- **NwcNode** - Nostr Wallet Connect
17+
- **SpeedNode** - Speed Lightning service
18+
19+
## Building
20+
21+
### Prerequisites
22+
23+
- Rust toolchain (stable)
24+
- Cargo
25+
- Xcode (for iOS builds)
26+
- iOS SDK (comes with Xcode)
27+
28+
### Generate Swift bindings
29+
30+
```bash
31+
./build.sh --release
32+
```
33+
34+
This will:
35+
1. Build the LNI library with UniFFI support
36+
2. Generate Swift bindings in `Sources/LNI/`
37+
38+
### Build for iOS
39+
40+
```bash
41+
./build.sh --release --ios
42+
```
43+
44+
This will additionally:
45+
1. Build static libraries for iOS Simulator (arm64 + x86_64)
46+
2. Build static library for iOS devices (arm64)
47+
3. Create a universal XCFramework
48+
49+
## Usage
50+
51+
### Basic Example
52+
53+
```swift
54+
import LNI
55+
56+
// Create a Strike node
57+
let config = StrikeConfig(
58+
apiKey: "your-api-key",
59+
baseUrl: "https://api.strike.me/v1",
60+
socks5Proxy: nil,
61+
acceptInvalidCerts: false,
62+
httpTimeout: 60
63+
)
64+
65+
do {
66+
let node = StrikeNode(config: config)
67+
68+
// Get node info
69+
let info = try await node.getInfo()
70+
print("Node alias: \(info.alias)")
71+
72+
// Create an invoice
73+
let invoiceParams = CreateInvoiceParams(
74+
invoiceType: .bolt11,
75+
amountMsats: 21000, // 21 sats
76+
offer: nil,
77+
description: "Test invoice",
78+
descriptionHash: nil,
79+
expiry: 3600,
80+
rPreimage: nil,
81+
isBlinded: false,
82+
isKeysend: false,
83+
isAmp: false,
84+
isPrivate: false
85+
)
86+
let transaction = try await node.createInvoice(params: invoiceParams)
87+
print("Invoice: \(transaction.invoice)")
88+
89+
} catch {
90+
print("Error: \(error)")
91+
}
92+
```
93+
94+
### Using NWC (Nostr Wallet Connect)
95+
96+
```swift
97+
import LNI
98+
99+
let config = NwcConfig(
100+
nwcUri: "nostr+walletconnect://pubkey?relay=wss://relay.example.com&secret=..."
101+
)
102+
103+
do {
104+
let node = NwcNode(config: config)
105+
let info = try await node.getInfo()
106+
print("Connected to: \(info.alias)")
107+
} catch {
108+
print("Error: \(error)")
109+
}
110+
```
111+
112+
### Polymorphic Usage
113+
114+
You can use the factory functions to create nodes as the `LightningNode` protocol:
115+
116+
```swift
117+
import LNI
118+
119+
// Create different node types using factory functions
120+
let strikeNode: LightningNode = createStrikeNode(config: strikeConfig)
121+
let blinkNode: LightningNode = createBlinkNode(config: blinkConfig)
122+
let nwcNode: LightningNode = createNwcNode(config: nwcConfig)
123+
124+
// All nodes share the same interface
125+
for node in [strikeNode, blinkNode, nwcNode] {
126+
let info = try await node.getInfo()
127+
print("Balance: \(info.sendBalanceMsat) msats")
128+
}
129+
```
130+
131+
## Integration with iOS
132+
133+
See the `example/` directory for a complete iOS example project that runs on the iOS Simulator.
134+
135+
### Adding to your iOS project
136+
137+
1. Copy the generated Swift files from `Sources/LNI/` to your project
138+
2. Add the static library or XCFramework to your project
139+
3. Link against the library in your build settings
140+
141+
### Using Swift Package Manager (future)
142+
143+
We plan to add SPM support in a future release.
144+
145+
## License
146+
147+
Same license as the main LNI project.

0 commit comments

Comments
 (0)