lightening_wallet 0.5.4 copy "lightening_wallet: ^0.5.4" to clipboard
lightening_wallet: ^0.5.4 copied to clipboard

High-performance Lightning wallet for Flutter using Rust FFI with LDK-node. Supports Bitcoin on-chain and Lightning Network payments.

Flutter Lightning Wallet (Rust FFI) #

A high-performance Lightning wallet library for Flutter, built with Rust and using dart:ffi for native bindings. This library provides Bitcoin and Lightning Network functionality through a unified Dart API.

Features #

  • High Performance: All wallet logic runs in native Rust code
  • Bitcoin Wallet: BIP39/BIP32 HD wallet with native address derivation
  • Lightning Network: LDK-node integration for Lightning payments
  • UTXO Management: Native UTXO tracking with caching
  • Transaction Building: Coin selection and transaction signing
  • Payment History: SQLite-based payment database
  • Event Streaming: Real-time wallet events
  • Cross-platform: Supports Android, iOS, macOS, Linux, and Windows

Architecture #

lightening_wallet/
├── rust/               # Rust core library
│   ├── src/
│   │   ├── lib.rs           # C FFI bindings
│   │   ├── coordinator.rs   # Main orchestrator
│   │   ├── wallet/          # Bitcoin wallet logic
│   │   ├── ldk/             # LDK-node integration
│   │   ├── storage/         # SQLite & caching
│   │   └── events.rs        # Event system
│   └── Cargo.toml
├── lib/                # Dart API
│   ├── lightening_wallet.dart  # Main export
│   └── src/
│       ├── bindings.dart     # FFI bindings
│       ├── lightning_wallet.dart  # High-level API
│       └── models.dart       # Data models
├── android/            # Android plugin config
├── ios/                # iOS plugin config & headers
├── macos/              # macOS plugin config & headers
├── linux/              # Linux plugin config (CMake)
├── windows/            # Windows plugin config (CMake)
└── scripts/            # Build scripts

Installation #

Prerequisites #

  • Flutter 3.10+
  • Rust 1.70+ with cargo
  • Android NDK (if building for Android)
  • Xcode (if building for iOS/macOS)
  • cargo-ndk for Android builds: cargo install cargo-ndk
  • zig and cargo-zigbuild for cross-compiling Linux/Windows from macOS:
    brew install zig
    cargo install cargo-zigbuild
    

Add to your project #

Add to your pubspec.yaml:

dependencies:
  lightening_wallet:
    path: /path/to/lightening_wallet

Or if published to pub.dev:

dependencies:
  lightening_wallet: ^0.1.42

Build the native library #

Before using the plugin, you need to build the Rust library for your target platforms.

Android

# Using the build script (recommended)
./scripts/build-android.sh

# Or manually with cargo-ndk
cd rust
cargo ndk -t arm64-v8a -t armeabi-v7a -t x86_64 -t x86 \
  -o ../android/src/main/jniLibs build --release

Requirements:

  • Android NDK installed (set ANDROID_NDK_HOME environment variable)
  • cargo-ndk installed: cargo install cargo-ndk
  • Rust Android targets:
    rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
    

iOS

# Using the build script (recommended)
./scripts/build-ios.sh

This will:

  1. Build for iOS device (aarch64-apple-ios)
  2. Build for iOS simulators (x86_64-apple-ios, aarch64-apple-ios-sim)
  3. Create a universal XCFramework

Requirements:

  • Xcode with command line tools
  • Rust iOS targets:
    rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
    

macOS

./scripts/build-macos.sh

This builds a universal static library (arm64 + x86_64) at macos/liblightening_wallet_macos.a.

Requirements:

  • Xcode with command line tools
  • Rust macOS targets:
    rustup target add aarch64-apple-darwin x86_64-apple-darwin
    

Linux

./scripts/build-linux.sh

This builds linux/liblightening_wallet.so. When cross-compiling from macOS, uses cargo-zigbuild.

Requirements:

  • Rust Linux target:
    rustup target add x86_64-unknown-linux-gnu
    
  • For cross-compilation from macOS: zig and cargo-zigbuild

Windows

./scripts/build-windows.sh

This builds windows/lightening_wallet.dll. When cross-compiling from macOS, uses cargo-zigbuild.

Requirements:

  • Rust Windows target:
    rustup target add x86_64-pc-windows-gnu
    
  • For cross-compilation from macOS: zig and cargo-zigbuild

Usage #

Initialize the library #

import 'package:lightening_wallet/lightening_wallet.dart';

void main() {
  // Initialize the native library (required before any other calls)
  LightningWallet.initialize();

  runApp(MyApp());
}

Generate a new wallet #

// Generate a new BIP39 mnemonic
final result = LightningWallet.generateMnemonic();
if (result.success) {
  final mnemonic = result.data!;
  print('Mnemonic: $mnemonic');
}

Initialize wallet #

final initResult = LightningWallet.initializeWallet(
  userId: 'user123',
  mnemonic: mnemonic,
  network: BitcoinNetwork.testnet,
  dbPath: '/path/to/wallet/data',
);

if (initResult.success) {
  print('Wallet initialized!');
} else {
  print('Error: ${initResult.error}');
}

Get balance #

final balanceResult = LightningWallet.getBalance('user123');
if (balanceResult.success) {
  final balance = balanceResult.data!;
  print('On-chain confirmed: ${balance.onchainConfirmed} sats');
  print('Lightning balance: ${balance.lightningBalance} sats');
  print('Total: ${balance.total} sats');
}

Sync wallet #

final syncResult = LightningWallet.sync('user123');
if (syncResult.success) {
  print('Wallet synced!');
}

Get receiving address #

final addressResult = LightningWallet.getReceivingAddress('user123');
if (addressResult.success) {
  print('Receive to: ${addressResult.data}');
}

List payment history #

final paymentsResult = LightningWallet.listPayments(
  'user123',
  limit: 10,
  offset: 0,
);

if (paymentsResult.success) {
  for (final payment in paymentsResult.data!) {
    print('${payment.paymentType}: ${payment.amountSats} sats');
  }
}

Poll for events #

final eventsResult = LightningWallet.getEvents('user123');
if (eventsResult.success) {
  for (final event in eventsResult.data!) {
    switch (event.eventType) {
      case 'BalanceUpdated':
        print('Balance updated!');
        break;
      case 'PaymentReceived':
        print('Payment received!');
        break;
      case 'SyncCompleted':
        print('Sync completed!');
        break;
    }
  }
}

Disconnect wallet #

LightningWallet.disconnect('user123');

API Reference #

Dart API (LightningWallet) #

All methods are static and return a WalletResponse<T> wrapper with success, data, and error fields.


Wallet Lifecycle

static void initialize()

Initialize the native library bindings. Must be called before any other methods.

LightningWallet.initialize();
static WalletResponse<String> generateMnemonic()

Generate a new 24-word BIP39 mnemonic phrase.

Returns: Space-separated string of 24 BIP39 words.

static WalletResponse<void> initializeWallet({...})

Initialize a wallet instance (blocking).

Parameters:

Parameter Type Required Description
userId String Yes Unique identifier for this wallet instance
mnemonic String Yes 24-word BIP39 mnemonic phrase
network BitcoinNetwork Yes bitcoin, testnet, or regtest
dbPath String Yes Path to store wallet data
esploraUrl String? No Custom Esplora server URL
static WalletResponse<void> initializeWalletAsync({...})

Initialize a wallet instance (non-blocking). Use getInitStatus() to poll for completion.

Parameters: Same as initializeWallet().

static WalletResponse<InitStatus> getInitStatus(String userId)

Get the current initialization status for async initialization.

Returns: InitStatus with status (not_started, pending, initializing, completed, failed), progress, and error.

static WalletResponse<void> clearInitStatus(String userId)

Clear the initialization status (for retry after failure).

static WalletResponse<void> disconnect(String userId)

Disconnect and cleanup the wallet. Stops the Lightning node and releases resources.


Balance and Sync

static WalletResponse<WalletBalance> getBalance(String userId)

Get the current wallet balance.

Returns: WalletBalance with:

  • onchain - On-chain balance in satoshis
  • lightning - Lightning channel balance in satoshis
  • total - Sum of both balances
static WalletResponse<void> sync(String userId)

Sync the wallet with the blockchain (blocking).

static WalletResponse<String> syncAsync(String userId)

Sync the wallet (non-blocking). Returns operation ID.

static WalletResponse<void> restartNode(String userId)

Restart the Lightning node to reconnect peers. Useful after opening new channels.


Addresses

static WalletResponse<String> getReceivingAddress(String userId)

Generate a fresh on-chain receiving address (BIP84 native SegWit).

Returns: A bech32 Bitcoin address.

static WalletResponse<String> getNodeId(String userId)

Get the Lightning node's public key.

Returns: 33-byte hex-encoded public key.


Payment History

static WalletResponse<List<Payment>> listPayments(String userId, {int? limit, int? offset})

List payment history from database.

Parameters:

Parameter Type Required Description
limit int? No Maximum payments to return (0 = all)
offset int? No Number of payments to skip

Returns: List of Payment objects.

static WalletResponse<List<Payment>> getOnchainTransactions(String userId)

Get on-chain transaction history by querying Esplora directly.

static WalletResponse<String> getOnchainTransactionsAsync(String userId)

Get on-chain transactions (non-blocking). Returns operation ID.


Events

static WalletResponse<List<WalletEvent>> getEvents(String userId)

Drain pending wallet events from the event queue. Events are removed after being returned.

Returns: List of WalletEvent with eventType, data, and timestamp.

Event Types:

  • BalanceUpdated - Balance changed
  • PaymentReceived - Incoming payment completed
  • PaymentSent - Outgoing payment completed
  • PaymentFailed - Payment failed
  • ChannelOpened - New channel opened
  • ChannelClosed - Channel closed
  • SyncCompleted - Blockchain sync completed

Peer Management

static WalletResponse<void> connectPeer(String userId, {required String nodeId, required String address, required int port})

Connect to a Lightning Network peer (blocking).

Parameters:

Parameter Type Required Description
nodeId String Yes 33-byte hex-encoded public key
address String Yes IP address or hostname
port int Yes TCP port (typically 9735)
static WalletResponse<String> connectPeerAsync(String userId, {required String nodeId, required String address, required int port})

Connect to a peer (non-blocking). Returns operation ID.

static WalletResponse<void> disconnectPeer(String userId, String nodeId)

Disconnect from a Lightning Network peer.

static WalletResponse<List<Peer>> listPeers(String userId)

List all connected peers.

Returns: List of Peer with nodeId, address, port, and isConnected.


Channel Management

static WalletResponse<String> openChannel(String userId, {...})

Open a new Lightning channel (blocking).

Parameters:

Parameter Type Required Description
counterpartyNodeId String Yes Peer's 33-byte hex public key
channelValueSats int Yes Total channel capacity in sats
pushMsat int No Amount to push to peer (default: 0)
peerAddress String? No Peer address if not connected
peerPort int? No Peer port if not connected

Returns: Hex-encoded channel ID.

static WalletResponse<String> openChannelAsync(String userId, {...})

Open a channel (non-blocking). Returns operation ID. Same parameters as openChannel().

static WalletResponse<void> closeChannel(String userId, String channelId, {bool force = false})

Close a Lightning channel (blocking).

Parameters:

Parameter Type Required Description
channelId String Yes Hex-encoded channel ID
force bool No Force close unilaterally (default: false)
static WalletResponse<String> closeChannelAsync(String userId, String channelId, {bool force = false, String? peerAddress, int? peerPort})

Close a channel (non-blocking). Returns operation ID. Optionally provide peer address for cooperative close.

static WalletResponse<List<Channel>> listChannels(String userId)

List all Lightning channels.

Returns: List of Channel with:

  • channelId - Unique channel identifier
  • counterpartyNodeId - Peer's public key
  • channelValueSats - Total channel capacity
  • balanceSats - Local balance
  • inboundCapacitySats - Available inbound liquidity
  • outboundCapacitySats - Available outbound liquidity
  • isUsable - Whether channel can route payments
  • isPublic - Whether channel is announced to network
  • shortChannelId - Short channel ID (if confirmed)

Invoice Management

static WalletResponse<InvoiceInfo> createInvoice(String userId, {int? amountSats, String? description, int expirySecs = 3600})

Create a BOLT11 Lightning invoice.

Parameters:

Parameter Type Required Description
amountSats int? No Invoice amount (null for "any amount")
description String? No Human-readable description
expirySecs int No Expiry time in seconds (default: 3600)

Returns: InvoiceInfo with bolt11, paymentHash, amountSats, description, createdAt, expiresAt.


Payment Operations

static WalletResponse<PaymentResult> payInvoice(String userId, String bolt11, {int? amountSats})

Pay a BOLT11 Lightning invoice (blocking).

Parameters:

Parameter Type Required Description
bolt11 String Yes BOLT11-encoded invoice
amountSats int? No Amount for "any amount" invoices

Returns: PaymentResult with payment details.

static WalletResponse<String> payInvoiceAsync(String userId, String bolt11, {int? amountSats})

Pay an invoice (non-blocking). Returns operation ID.

static WalletResponse<PaymentResult> sendKeysend(String userId, {required String destinationPubkey, required int amountSats, Map<int, List<int>>? customRecords})

Send a spontaneous keysend payment (blocking).

Parameters:

Parameter Type Required Description
destinationPubkey String Yes Destination node's 33-byte hex public key
amountSats int Yes Amount to send in satoshis
customRecords Map<int, List<int>>? No TLV custom records (Podcasting 2.0)

Podcasting 2.0 TLV Types:

const podcastTlv = 7629169;    // Podcast name
const episodeTlv = 7629171;    // Episode GUID
const actionTlv = 7629173;     // Action (stream/boost)
const timestampTlv = 7629175;  // Timestamp in episode
const appNameTlv = 7629177;    // App name
static WalletResponse<String> sendKeysendAsync(String userId, {...})

Send keysend (non-blocking). Returns operation ID. Same parameters as sendKeysend().

static WalletResponse<PaymentResult> payLightningAddress(String userId, {required String lightningAddress, required int amountSats, String? comment})

Pay a Lightning Address (LNURL-pay) (blocking).

Parameters:

Parameter Type Required Description
lightningAddress String Yes Lightning Address (e.g., user@domain.com)
amountSats int Yes Amount to send in satoshis
comment String? No Optional payment comment
static WalletResponse<String> payLightningAddressAsync(String userId, {...})

Pay Lightning Address (non-blocking). Returns operation ID.

static WalletResponse<String> sendOnchain(String userId, {required String address, required int amountSats, int feeRateSatPerVbyte = 0})

Send an on-chain Bitcoin transaction (blocking).

Parameters:

Parameter Type Required Description
address String Yes Destination Bitcoin address
amountSats int Yes Amount to send in satoshis
feeRateSatPerVbyte int No Fee rate (0 = use default)

Returns: Transaction ID (txid) as hex string.

static WalletResponse<String> sendOnchainAsync(String userId, {...})

Send on-chain (non-blocking). Returns operation ID.


Fee Estimation

static WalletResponse<FeeEstimate> estimateOnchainFee(String userId, {required int amountSats, required int feeRateSatPerVbyte})

Estimate the fee for an on-chain transaction.

Returns: FeeEstimate with:

  • feeSats - Estimated fee in satoshis
  • feeRateSatPerVbyte - Fee rate used
  • estimatedVbytes - Estimated transaction size
  • totalSats - Total amount including fee
static WalletResponse<RecommendedFeeRates> getRecommendedFeeRates(String userId)

Get recommended fee rates for different confirmation speeds (blocking).

Returns: RecommendedFeeRates with:

  • fastSatPerVbyte - Fast (1-2 blocks)
  • mediumSatPerVbyte - Medium (3-6 blocks)
  • slowSatPerVbyte - Slow (7+ blocks)
static WalletResponse<String> getRecommendedFeeRatesAsync(String userId)

Get fee rates (non-blocking). Returns operation ID.


Async Operation Management

All *Async methods return an operation ID. Use these methods to poll for results:

static WalletResponse<OperationStatus> getOperationStatus(String operationId)

Get the status of an async operation.

Returns: OperationStatus with:

  • operationId - The operation ID
  • operationType - Type of operation
  • status - pending, running, completed, failed, not_found
  • progress - Progress message (if available)
  • result - Result data (if completed)
  • error - Error message (if failed)

Helper properties:

  • isPending, isRunning, isCompleted, isFailed, isNotFound
  • isInProgress - true if pending or running
  • isDone - true if completed or failed
static WalletResponse<void> clearOperationStatus(String operationId)

Clear the status of an operation to free memory. Call after you're done polling.

Types #

WalletResponse #

Generic response wrapper for all API calls.

class WalletResponse<T> {
  final bool success;   // Whether the operation succeeded
  final T? data;        // Result data (if success)
  final String? error;  // Error message (if failed)
}

WalletBalance #

Balance information for the wallet.

class WalletBalance {
  final int onchain;     // On-chain balance in satoshis
  final int lightning;   // Lightning channel balance in satoshis
  int get total;         // Sum of both balances
}

InitStatus #

Initialization status for async wallet initialization.

class InitStatus {
  final String status;    // "not_started", "pending", "initializing", "completed", "failed"
  final String? progress; // Progress message
  final String? error;    // Error message (if failed)

  // Helper getters
  bool get isNotStarted;
  bool get isPending;
  bool get isInitializing;
  bool get isCompleted;
  bool get isFailed;
  bool get isInProgress;  // true if pending or initializing
}

Payment #

Payment record for both Lightning and on-chain transactions.

class Payment {
  final String paymentHash;    // Unique payment identifier
  final String paymentType;    // 'sent', 'received', 'onchain_sent', 'onchain_received'
  final String status;         // 'pending', 'completed', 'failed'
  final int amountSats;        // Payment amount in satoshis
  final int? feeSats;          // Fee paid (if applicable)
  final String? bolt11;        // Original BOLT11 invoice
  final String? preimage;      // Lightning payment preimage
  final int timestamp;         // Unix timestamp
  final String? description;   // Payment description/memo
  final String? destination;   // Destination node ID or address
  final String? txid;          // On-chain transaction ID
}

Channel #

Lightning channel information.

class Channel {
  final String channelId;           // Unique channel identifier
  final String counterpartyNodeId;  // Peer's public key
  final int channelValueSats;       // Total channel capacity
  final int balanceSats;            // Local balance
  final int inboundCapacitySats;    // Available for receiving
  final int outboundCapacitySats;   // Available for sending
  final bool isUsable;              // Can route payments
  final bool isPublic;              // Announced to network
  final String? shortChannelId;     // Short channel ID (if confirmed)
}

Peer #

Connected Lightning peer information.

class Peer {
  final String nodeId;      // Peer's public key
  final String? address;    // IP address or hostname
  final int? port;          // TCP port
  final bool isConnected;   // Connection status
}

InvoiceInfo #

BOLT11 invoice creation result.

class InvoiceInfo {
  final String bolt11;         // BOLT11-encoded invoice
  final String paymentHash;    // Unique payment identifier
  final int? amountSats;       // Invoice amount (null for "any amount")
  final String? description;   // Invoice description
  final int createdAt;         // Unix timestamp of creation
  final int expiresAt;         // Unix timestamp of expiry
}

PaymentResult #

Payment result from paying an invoice or sending keysend.

class PaymentResult {
  final String paymentHash;    // Unique payment identifier
  final String paymentType;    // 'sent', 'received', etc.
  final int amountSats;        // Payment amount
  final int? feeSats;          // Fee paid
  final String status;         // 'pending', 'completed', 'failed'
  final int timestamp;         // Unix timestamp
  final String? description;   // Payment description
  final String? destination;   // Destination node/address
  final String? preimage;      // Payment preimage (proof of payment)
  final String? bolt11;        // Original invoice
}

FeeEstimate #

On-chain fee estimate.

class FeeEstimate {
  final int feeSats;              // Estimated fee in satoshis
  final int feeRateSatPerVbyte;   // Fee rate used (sat/vbyte)
  final int estimatedVbytes;      // Estimated transaction size
  final int totalSats;            // Total amount including fee
}

RecommendedFeeRates #

Recommended fee rates for different confirmation speeds.

class RecommendedFeeRates {
  final int fastSatPerVbyte;    // Fast (1-2 blocks)
  final int mediumSatPerVbyte;  // Medium (3-6 blocks)
  final int slowSatPerVbyte;    // Slow (7+ blocks)
}

WalletEvent #

Real-time wallet event.

class WalletEvent {
  final String eventType;           // Event type string
  final Map<String, dynamic> data;  // Event-specific data
  final int timestamp;              // Unix timestamp
}

OperationStatus #

Status of an async operation.

class OperationStatus {
  final String operationId;     // The operation ID
  final String operationType;   // Type of operation
  final String status;          // "pending", "running", "completed", "failed", "not_found"
  final String? progress;       // Progress message
  final dynamic result;         // Result data (if completed)
  final String? error;          // Error message (if failed)

  // Helper getters
  bool get isPending;
  bool get isRunning;
  bool get isCompleted;
  bool get isFailed;
  bool get isNotFound;
  bool get isInProgress;  // true if pending or running
  bool get isDone;        // true if completed or failed
}

BitcoinNetwork #

Supported Bitcoin networks.

enum BitcoinNetwork {
  bitcoin,   // Mainnet (real funds)
  testnet,   // Testnet (test funds)
  regtest,   // Regtest (local testing)
}

Rust FFI Reference #

The native Rust library exposes C-compatible FFI functions. All functions return JSON strings with the format:

{"success": true, "data": {...}}
// or
{"success": false, "error": "error message"}

Core Functions #

C Function Parameters Description
wallet_initialize user_id, mnemonic, network, db_path Initialize wallet instance
wallet_generate_mnemonic None Generate 24-word BIP39 mnemonic
wallet_get_balance user_id Get wallet balance
wallet_sync user_id Sync with blockchain
wallet_get_receiving_address user_id Get new receiving address
wallet_list_payments user_id, limit, offset List payment history
wallet_get_events user_id Drain pending events
wallet_disconnect user_id Disconnect and cleanup
wallet_free_string ptr Free allocated string memory

Peer Functions #

C Function Parameters Description
wallet_connect_peer user_id, node_id, address, port Connect to peer
wallet_disconnect_peer user_id, node_id Disconnect from peer
wallet_list_peers user_id List connected peers

Channel Functions #

C Function Parameters Description
wallet_open_channel user_id, counterparty_node_id, channel_value_sats, push_msat, peer_address, peer_port Open channel
wallet_close_channel user_id, channel_id, force Close channel
wallet_list_channels user_id List all channels

Invoice Functions #

C Function Parameters Description
wallet_create_invoice user_id, amount_sats, description, expiry_secs Create BOLT11 invoice

Payment Functions #

C Function Parameters Description
wallet_pay_invoice user_id, bolt11, amount_sats Pay BOLT11 invoice
wallet_send_keysend user_id, destination_pubkey, amount_sats, custom_records_json Send keysend payment
wallet_send_onchain user_id, address, amount_sats Send on-chain transaction
wallet_get_node_id user_id Get node public key

Android JNI Functions #

For Android, the library also exports JNI-compatible functions:

JNI Function Equivalent C Function
Java_..._nativeInitialize wallet_initialize
Java_..._nativeGenerateMnemonic wallet_generate_mnemonic
Java_..._nativeGetBalance wallet_get_balance
Java_..._nativeSyncWallet wallet_sync
Java_..._nativeGetReceivingAddress wallet_get_receiving_address
Java_..._nativeListPayments wallet_list_payments
Java_..._nativeGetEvents wallet_get_events
Java_..._nativeDisconnect wallet_disconnect

Rust Module Reference #

WalletCoordinator (coordinator.rs) #

Main orchestrator that manages wallet components.

impl WalletCoordinator {
    pub fn new(db_path: &str) -> Result<Self, CoordinatorError>;
    pub fn initialize(&self, mnemonic: &str, network: BitcoinNetwork) -> Result<(), CoordinatorError>;
    pub fn sync(&self) -> Result<(), CoordinatorError>;
    pub fn get_lightning_node(&self) -> Arc<LightningNode>;
    pub fn get_database(&self) -> Arc<Database>;
    pub fn get_event_emitter(&self) -> Arc<EventEmitter>;
    pub fn disconnect(&self) -> Result<(), CoordinatorError>;
}

KeyManager (wallet/keys.rs) #

BIP39/BIP32 HD wallet key management.

impl KeyManager {
    pub fn from_mnemonic(mnemonic: &str, network: Network) -> Result<Self, KeyError>;
    pub fn generate_mnemonic() -> String;
    pub fn get_lightning_seed(&self) -> Result<[u8; 32], KeyError>;  // Derives at m/535'/0'
}

LightningNode (ldk/node.rs) #

LDK-node wrapper for Lightning Network operations.

impl LightningNode {
    // Lifecycle
    pub fn new() -> Self;
    pub fn initialize(&self, entropy: [u8; 32], network: Network, storage_path: &str, esplora_server: Option<&str>) -> Result<(), LightningError>;
    pub fn start(&self) -> Result<(), LightningError>;
    pub fn stop(&self) -> Result<(), LightningError>;
    pub fn sync_wallets(&self) -> Result<(), LightningError>;

    // Peer Management
    pub fn connect_peer(&self, params: ConnectPeerParams) -> Result<(), LightningError>;
    pub fn disconnect_peer(&self, node_id: &str) -> Result<(), LightningError>;
    pub fn list_peers(&self) -> Result<Vec<PeerInfo>, LightningError>;
    pub fn get_node_id(&self) -> Result<String, LightningError>;

    // Channel Management
    pub fn open_channel(&self, params: OpenChannelParams) -> Result<String, LightningError>;
    pub fn close_channel(&self, params: CloseChannelParams) -> Result<(), LightningError>;
    pub fn list_channels(&self) -> Result<Vec<ChannelInfo>, LightningError>;

    // Invoices
    pub fn create_invoice(&self, params: CreateInvoiceParams) -> Result<InvoiceInfo, LightningError>;

    // Payments
    pub fn pay_invoice(&self, params: PayInvoiceParams) -> Result<PaymentInfo, LightningError>;
    pub fn send_keysend(&self, params: KeysendParams) -> Result<PaymentInfo, LightningError>;
    pub fn send_onchain(&self, params: SendOnChainParams) -> Result<String, LightningError>;
    pub fn list_payments(&self) -> Result<Vec<PaymentInfo>, LightningError>;

    // Balance
    pub fn get_onchain_address(&self) -> Result<String, LightningError>;
    pub fn get_spendable_onchain_balance(&self) -> Result<u64, LightningError>;
    pub fn get_total_onchain_balance(&self) -> Result<u64, LightningError>;
}

Database (storage/db.rs) #

SQLite storage for payment history.

impl Database {
    pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, DatabaseError>;
    pub fn list_payments(&self, limit: Option<usize>, offset: Option<usize>) -> Result<Vec<Payment>, DatabaseError>;
}

EventEmitter (events.rs) #

Bounded event queue for real-time notifications.

impl EventEmitter {
    pub fn new(capacity: usize) -> Self;
    pub fn emit(&self, event: WalletEvent);
    pub fn drain_events(&self) -> Vec<WalletEvent>;
}

Podcasting20Builder (ldk/podcasting.rs) #

Fluent builder for Podcasting 2.0 value-for-value TLV records.

impl Podcasting20Builder {
    pub fn new() -> Self;
    pub fn podcast(self, name: &str) -> Self;        // TLV 7629169
    pub fn episode(self, guid: &str) -> Self;        // TLV 7629171
    pub fn action(self, action: &str) -> Self;       // TLV 7629173
    pub fn timestamp(self, timestamp: u64) -> Self;  // TLV 7629175
    pub fn app_name(self, name: &str) -> Self;       // TLV 7629177
    pub fn custom(self, key: u64, value: &str) -> Self;
    pub fn custom_bytes(self, key: u64, value: Vec<u8>) -> Self;
    pub fn build(self) -> HashMap<u64, Vec<u8>>;
}

// Usage example:
let custom_records = Podcasting20Builder::new()
    .podcast("My Podcast")
    .episode("episode-guid-123")
    .action("stream")
    .app_name("MyApp")
    .build();

Error Types #

CoordinatorError #

pub enum CoordinatorError {
    AlreadyInitialized,           // Wallet already initialized
    KeyError(String),             // Key derivation/management error
    StorageError(String),         // Database/storage error
    LightningError(String),       // Lightning node error
}

KeyError #

pub enum KeyError {
    InvalidMnemonic(String),      // Invalid BIP39 mnemonic
    Derivation(String),           // BIP32 derivation failed
    InvalidNetwork(String),       // Network mismatch
}

LightningError #

pub enum LightningError {
    NotInitialized,               // Node not initialized
    AlreadyInitialized,           // Node already initialized
    LdkError(String),             // LDK-node error
    NetworkError(String),         // Network communication error
    PeerError(String),            // Peer connection error
    ChannelError(String),         // Channel operation error
    PaymentError(String),         // Payment failed
    InvoiceError(String),         // Invoice creation/parsing error
    StorageError(String),         // Storage error
}

DatabaseError #

pub enum DatabaseError {
    Connection(String),           // Database connection failed
    Query(String),                // Query execution error
    NotFound(String),             // Record not found
}

Development #

Run Rust tests #

cd rust
cargo test

Build Rust library (debug) #

cd rust
cargo build

Format Rust code #

cd rust
cargo fmt

Lint Rust code #

cd rust
cargo clippy

Regenerate FFI bindings #

If you modify the C header file, regenerate bindings:

dart run ffigen

Troubleshooting #

Android: Library not found #

Make sure you've built the native library and the .so files are in android/src/main/jniLibs/:

android/src/main/jniLibs/
├── arm64-v8a/liblightening_wallet.so
├── armeabi-v7a/liblightening_wallet.so
├── x86_64/liblightening_wallet.so
└── x86/liblightening_wallet.so

iOS: Framework not found #

Ensure the XCFramework was built correctly:

./scripts/build-ios.sh

Check that ios/LighteningWallet.xcframework exists.

macOS: Library not found #

Ensure the static library was built:

./scripts/build-macos.sh

Check that macos/liblightening_wallet_macos.a exists.

Linux: Library not found #

Ensure the shared library was built:

./scripts/build-linux.sh

Check that linux/liblightening_wallet.so exists.

Windows: DLL not found #

Ensure the DLL was built:

./scripts/build-windows.sh

Check that windows/lightening_wallet.dll exists.

License #

MIT

Credits #

This library integrates and builds upon:

0
likes
140
points
589
downloads

Publisher

unverified uploader

Weekly Downloads

High-performance Lightning wallet for Flutter using Rust FFI with LDK-node. Supports Bitcoin on-chain and Lightning Network payments.

Repository (GitHub)
View/report issues

Topics

#bitcoin #lightning #wallet #payments #ffi

License

MIT (license)

Dependencies

ffi, flutter, path

More

Packages that depend on lightening_wallet

Packages that implement lightening_wallet