Skip to content

backend: add LDK Node#3784

Merged
kaloudis merged 81 commits intomasterfrom
ldk-node
Mar 27, 2026
Merged

backend: add LDK Node#3784
kaloudis merged 81 commits intomasterfrom
ldk-node

Conversation

@kaloudis
Copy link
Copy Markdown
Contributor

@kaloudis kaloudis commented Mar 4, 2026

Description

Summary

  • Adds LDK Node as a new on-device Lightning backend alongside Embedded LND
  • Full native module implementation for both iOS (Swift) and Android (Kotlin)
  • Supports BOLT11, BOLT12 (Offers), keysend, LSPS1, and LSPS7
  • VSS (Versioned Storage Service) with signature auth for cloud state backup
  • Configurable Esplora, RGS, and VSS servers with reset-to-default support
  • Real-time streaming log viewer, troubleshooting view with network graph reset
  • Channel management: open, cooperative close, force close, closed channel history
  • Wallet creation, seed backup, and seed recovery
  • Testnet support with network label display

Notable changes

  • Groups wallet implementations by On-device / Remote in the node config dropdown
  • Reuses LDK Node seed as swap rescue key instead of generating a separate one
  • Adds supportsMessageVerification, supportsListingOffers, supportsBolt12Address backend capability flags
  • Caps log buffer in both LND and LDK log viewers to prevent unbounded memory growth
  • Fixes MobX store mutation in SeedRecovery by cloning the settings.nodes array
  • Localizes all closure reason messages
  • Updates bug report and PR templates to include LDK Node

Test plan

  • Create new LDK Node mainnet wallet
  • Create new LDK Node testnet wallet
  • Restore LDK Node wallet from seed
  • Open channel via LSPS1
  • Send/receive BOLT11 payments
  • Send/receive BOLT12 payments (Offers)
  • Send keysend payment
  • Cooperative close channel
  • Force close channel
  • Verify VSS backup/restore across devices
  • Check log viewer streams in real time
  • Verify network graph reset in troubleshooting view
  • Confirm Verify tab is hidden in Sign/Verify Message

PR Type

  • New feature
  • Bug fix
  • Code refactor
  • Configuration change
  • Locales update
  • Quality assurance
  • Other

Checklist

  • I’ve run yarn run tsc and made sure my code compiles correctly
  • I’ve run yarn run lint and made sure my code didn’t contain any problematic patterns
  • I’ve run yarn run prettier and made sure my code is formatted correctly
  • I’ve run yarn run test and made sure all of the tests pass

Testing

If you modified or added a utility file, did you add new unit tests?

  • No, I’m a fool
  • Yes
  • N/A

I have tested this PR on the following platforms (please specify OS version and phone model/VM):

  • Android
  • iOS

I have tested this PR with the following types of nodes (please specify node version and API version where appropriate):

  • Embedded LND
  • LND (REST)
  • LND (Lightning Node Connect)
  • Core Lightning (CLNRest)
  • Nostr Wallet Connect
  • LndHub

Locales

  • I’ve added new locale text that requires translations
  • I’m aware that new translations should be made on the ZEUS Transfix page and not directly to this repo

Third Party Dependencies and Packages

  • Contributors will need to run yarn after this PR is merged in
  • 3rd party dependencies have been modified:
    • verify that package.json and yarn.lock have been properly updated
    • verify that dependencies are installed for both iOS and Android platforms

Other:

  • Changes were made that require an update to the README
  • Changes were made that require an update to onboarding

@kaloudis kaloudis added this to the v0.13.0 milestone Mar 4, 2026
@kaloudis kaloudis changed the title backend: add LDK Node support backend: add LDK Node Mar 4, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the application's capabilities by integrating LDK Node as a new on-device Lightning backend. This integration provides users with an alternative, robust Lightning implementation, supporting a wide array of modern Lightning features like BOLT12 offers and LSPS. The changes also introduce configurable external services for chain synchronization, gossip, and cloud backups, enhancing the wallet's resilience and user control. Furthermore, dedicated tools for monitoring and troubleshooting the LDK Node are now available, ensuring a smoother user experience.

Highlights

  • LDK Node Integration: Introduced LDK Node as a new on-device Lightning backend, offering an alternative to Embedded LND with native module implementations for both iOS (Swift) and Android (Kotlin).
  • Comprehensive Lightning Features: Added support for BOLT11, BOLT12 (Offers), keysend payments, LSPS1 for liquidity, and LSPS7 for channel lease extensions.
  • Cloud State Backup: Implemented Versioned Storage Service (VSS) with signature authentication for secure cloud state backup and recovery.
  • Configurable Services: Enabled configurable Esplora, Rapid Gossip Sync (RGS), and VSS servers, including options to reset to default settings.
  • Enhanced Troubleshooting: Provided a real-time streaming log viewer for LDK Node, a troubleshooting view with network graph reset functionality, and wallet creation/recovery flows.
  • Channel Management: Supported full channel lifecycle management, including opening, cooperative closing, force closing, and viewing closed channel history.
  • UI/UX Improvements: Grouped wallet implementations by 'On-device' and 'Remote' in the node config dropdown, reused LDK Node seed as the swap rescue key, and localized all channel closure reason messages.
  • Backend Capability Flags: Added new backend capability flags: supportsMessageVerification, supportsListingOffers, and supportsBolt12Address to adapt UI features based on the active backend.
  • Log Buffer Management: Implemented log buffer capping in both LND and LDK log viewers to prevent unbounded memory growth.
  • Bug Report & PR Templates: Updated bug report and pull request templates to include LDK Node as a supported interface.
Changelog
  • .github/ISSUE_TEMPLATE/bug_report.yml
    • Added LDK Node as an option for node interfaces affected by bugs.
  • .github/PULL_REQUEST_TEMPLATE.md
    • Grouped node types into 'On-device' and 'Remote' categories.
    • Added LDK Node as a testing option under 'On-device' nodes.
  • .gitignore
    • Added __MACOSX/ to ignore macOS resource forks.
    • Added LDK Node binaries (LDKNodeFFI.xcframework, LdkNodeLibZipFile) to ignore list.
  • App.tsx
    • Imported new views for Rapid Gossip Sync, Esplora Server, VSS Server, and LDK Logs.
    • Added new Stack.Screen components for RapidGossipSync, EsploraServer, VssServer, and LDKLogs to the navigation stack.
  • android/app/build.gradle
    • Updated comment for CDK dependencies to include LDK Node.
  • android/app/src/main/assets/custom/Gazelle.svg
    • Added a new SVG asset for 'Gazelle'.
  • android/app/src/main/assets/custom/Olympus.svg
    • Added a new SVG asset for 'Olympus'.
  • android/app/src/main/assets/custom/OnChain.svg
    • Added a new SVG asset for 'OnChain'.
  • android/app/src/main/assets/custom/Rabbit.svg
    • Added a new SVG asset for 'Rabbit'.
  • android/app/src/main/assets/custom/RebalanceIcon.svg
    • Added a new SVG asset for 'RebalanceIcon'.
  • android/app/src/main/assets/custom/Turtle.svg
    • Added a new SVG asset for 'Turtle'.
  • android/app/src/main/assets/custom/Upgrade.svg
    • Added a new SVG asset for 'Upgrade'.
  • android/app/src/main/assets/custom/Watchtower.svg
    • Added a new SVG asset for 'Watchtower'.
  • android/app/src/main/assets/custom/gift.svg
    • Added a new SVG asset for 'gift'.
  • android/app/src/main/assets/custom/nwc-logo.svg
    • Added a new SVG asset for 'nwc-logo'.
  • android/app/src/main/java/app/zeusln/zeus/LdkNodeModule.kt
    • Added a new Kotlin module LdkNodeModule for LDK Node functionality.
    • Implemented builder methods for LDK Node configuration (network, storage path, Esplora, RGS, listening addresses, LSPS1/LSPS2/LSPS7, trusted peers, VSS).
    • Implemented mnemonic generation and node build methods.
    • Implemented node lifecycle methods (start, stop, syncWallets).
    • Implemented node info methods (nodeId, status, listBalances, networkGraphInfo, resetNetworkGraph, updateRgsSnapshot).
    • Implemented channel methods (listChannels, listClosedChannels, openChannel, closeChannel, forceCloseChannel).
    • Implemented on-chain methods (newOnchainAddress, sendToOnchainAddress, sendAllToOnchainAddress).
    • Implemented BOLT11 payment methods (receiveBolt11, receiveVariableAmountBolt11, sendBolt11, sendBolt11UsingAmount).
    • Implemented spontaneous payment methods (sendSpontaneousPayment).
    • Implemented BOLT12 payment methods (bolt12Receive, bolt12ReceiveVariableAmount, bolt12Send, bolt12SendUsingAmount, bolt12InitiateRefund, bolt12RequestRefundPayment).
    • Implemented general payment listing (listPayments).
    • Implemented peer methods (connect, disconnect, listPeers).
    • Implemented event methods (nextEvent, waitNextEvent, eventHandled).
    • Implemented LSPS1 methods (lsps1RequestChannel, lsps1CheckOrderStatus).
    • Implemented LSPS7 methods (lsps7GetExtendableChannels, lsps7CreateOrder, lsps7CheckOrderStatus).
    • Implemented message signing and verification methods (signMessage, verifySignature).
    • Implemented log file methods (tailLdkNodeLog, observeLdkNodeLogFile).
  • android/app/src/main/java/app/zeusln/zeus/LdkNodePackage.kt
    • Added a new Kotlin package LdkNodePackage to register LdkNodeModule with React Native.
  • android/app/src/main/java/com/zeus/MainApplication.kt
    • Registered LdkNodePackage in the list of React Native packages.
  • android/app/src/main/java/org/lightningdevkit/ldknode/LogFileObserver.kt
    • Added a new Kotlin class LogFileObserver for observing changes in log files and tailing them.
  • android/link-assets-manifest.json
    • Updated the asset manifest to include new SVG images and ldk.png.
  • backends/CLNRest.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • backends/EmbeddedLND.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • backends/EmbeddedLdkNode.ts
    • Added a new TypeScript backend EmbeddedLdkNode for integrating with the LDK Node native module.
    • Implemented node initialization, start, stop, and event subscription logic.
    • Provided methods for node info, balances, channel management, on-chain operations, BOLT11/BOLT12/spontaneous payments, and peer management.
    • Included helper methods for formatting data to Zeus compatibility standards.
    • Defined capability flags specific to LDK Node features.
  • backends/LND.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • backends/LightningNodeConnect.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • backends/LndHub.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • backends/NostrWalletConnect.ts
    • Added supportsMessageVerification capability.
    • Added supportsListingOffers capability.
    • Added supportsBolt12Address capability.
    • Added supportsCustomFeeLimit capability.
  • components/Amount.tsx
    • Added forceMsats prop to AmountDisplay and Amount components to force showing millisatoshi decimals.
    • Updated processSatsAmount to use the new forceMsats parameter.
  • components/DropdownSetting.tsx
    • Added support for isHeader property in dropdown values to display non-selectable headers.
    • Adjusted iOS ActionSheetIOS to disable header buttons and correctly map selected values.
  • components/FeeLimit.tsx
    • Updated conditional rendering for fee limit options to use BackendUtils.supportsCustomFeeLimit() instead of BackendUtils.isLNDBased().
  • components/LayerBalances/LightningSwipeableRow.tsx
    • Modified navigation for 'PayCodes' to direct to 'CreatePayCode' if the backend does not support listing offers.
  • components/Modals/AlertModal.tsx
    • Wrapped alert content in a ScrollView and set maxHeight for better display of multiple errors.
    • Added swipeToClose={false} to ModalBox.
    • Introduced new alert types for VSS, Esplora, and RGS errors with corresponding locale strings and explanations.
  • components/Modals/NewChannelModal.tsx
    • Added BackendUtils.supportsLSPS1native() check to determine LSPS1 support.
  • components/Modals/RatingModal.tsx
    • Updated the image path for the ZEUS icon.
  • components/NodeIdenticon.tsx
    • Added logic to include ldkNodeDir in the identicon generation key for embedded-ldk-node implementations.
  • fetch-libraries.sh
    • Added variables for LDK Node version, iOS file, SHA256 checksum, and download link.
    • Implemented download and checksum verification for LDK Node iOS library (LDKNodeFFI.xcframework).
    • Added logic to unzip the LDK Node iOS library.
  • index.js
    • Added LogBox.ignoreLogs to suppress specific LDK Node async errors (FeerateEstimationUpdateTimeout, NodeException) that are handled by AlertStore.
  • ios/LdkNodeMobile/LdkNodeModule.m
    • Added Objective-C bridging header for the LdkNodeModule Swift class, exposing its methods to React Native.
  • ios/LdkNodeMobile/LdkNodeModule.swift
    • Added a new Swift class LdkNodeModule implementing the LDK Node functionality for iOS.
    • Implemented builder methods for LDK Node configuration (network, storage path, Esplora, RGS, listening addresses, LSPS1/LSPS2/LSPS7, trusted peers, VSS).
    • Implemented mnemonic generation and node build methods.
    • Implemented node lifecycle methods (start, stop, syncWallets).
    • Implemented node info methods (nodeId, status, listBalances, networkGraphInfo, resetNetworkGraph, updateRgsSnapshot).
    • Implemented channel methods (listChannels, listClosedChannels, openChannel, closeChannel, forceCloseChannel).
    • Implemented on-chain methods (newOnchainAddress, sendToOnchainAddress, sendAllToOnchainAddress).
    • Implemented BOLT11 payment methods (receiveBolt11, receiveVariableAmountBolt11, sendBolt11, sendBolt11UsingAmount).
    • Implemented spontaneous payment methods (sendSpontaneousPayment).
    • Implemented BOLT12 payment methods (bolt12Receive, bolt12ReceiveVariableAmount, bolt12Send, bolt12SendUsingAmount, bolt12InitiateRefund, bolt12RequestRefundPayment).
    • Implemented general payment listing (listPayments).
    • Implemented peer methods (connect, disconnect, listPeers).
    • Implemented event methods (nextEvent, waitNextEvent, eventHandled).
    • Implemented LSPS1 methods (lsps1RequestChannel, lsps1CheckOrderStatus).
    • Implemented LSPS7 methods (lsps7GetExtendableChannels, lsps7CreateOrder, lsps7CheckOrderStatus).
    • Implemented message signing and verification methods (signMessage, verifySignature).
    • Implemented log file methods (tailLdkNodeLog, observeLdkNodeLogFile).
    • Added helper functions for serializing LDK Node data types and error messages.
  • ios/LdkNodeMobile/LogFileObserver.swift
    • Added a new Swift class LogFileObserver for observing changes in log files and tailing them on iOS.
  • ios/link-assets-manifest.json
    • Updated the asset manifest to include new SVG images and ldk.png.
  • ios/zeus.xcodeproj/project.pbxproj
    • Added LDKNodeFFI.xcframework to the project's frameworks.
    • Added LdkNodeMobile group and its Swift/Objective-C source files (LDKNode.swift, LogFileObserver.swift, LdkNodeModule.swift, LdkNodeModule.m) to the Xcode project.
  • ldknode/LdkNode.d.ts
    • Added TypeScript type definitions for LDK Node enums, data types (NodeStatus, BalanceDetails, ChannelDetails, ClosedChannelDetails, PaymentDetails, PeerDetails), event types, LSPS1 types, and LSPS7 types.
    • Defined the ILdkNodeModule interface for the native module.
  • ldknode/LdkNodeInjection.ts
    • Added a new TypeScript wrapper LdkNodeInjection for the LDK Node native module.
    • Provided a structured interface for accessing LDK Node builder, mnemonic, node lifecycle, info, channel, on-chain, payment, peer, event, LSPS1, LSPS7, and signing functionalities.
    • Implemented initializeNode utility function for common LDK Node setup, including VSS authentication header generation.
  • ldknode/index.ts
    • Exported all types from LdkNode.d.ts.
    • Exported ILdkNodeInjections type.
    • Exported LdkNodeModule directly from react-native.
    • Exported LdkNodeInjection as the recommended wrapper and default export.
  • locales/en.json
    • Added new locale strings for LDK Node channel closure reasons (e.g., counterpartyForceClosed, fundingTimedOut).
    • Added new locale strings for LDK Node settings: Esplora Server, Rapid Gossip Sync, VSS Server, LDK Node Logs, Sync Wallets, Reset Network Graph.
    • Added new locale strings for LSPS1 native integration (e.g., nativeLsps1Enabled, restartRequired).
    • Added new error messages: paymentFailed, paymentTimedOut, vssError, esploraError, rgsError, rgsEmptyGraph.
  • models/Channel.ts
    • Updated the shortChannelId getter to prioritize short_channel_id and gracefully handle chan_id conversion, including error handling for chanFormat.
  • stores/AlertStore.ts
    • Added observable properties vssError, esploraError, and rgsError.
    • Implemented actions setVssError, setEsploraError, and setRgsError to manage LDK Node related errors.
  • stores/CashuStore.ts
    • Modified deriveCashuSeedFromWalletSeed to use ldkMnemonic if the LDK Node backend is active, ensuring proper seed derivation for LDK Node wallets.
    • Added error handling to initializeCDK and checkAndSweepMints to prevent issues if the CDK wallet is not initialized.
  • stores/ChannelsStore.ts
    • Added logic to fetch pending HTLCs from LDK Node payments if the embedded-ldk-node implementation is active.
    • Adjusted channel host deletion logic to be conditional on the backend type, allowing LDK Node to retain its host for openChannel.
  • stores/LSPStore.ts
    • Updated getExtendableChannels to use native LSPS7 methods if BackendUtils.supportsLSPS7native() is true, otherwise falls back to custom messages.
    • Added lsps1GetInfoNative, lsps1CreateOrderNative, and lsps1GetOrderNative actions for native LSPS1 integration with LDK Node.
    • Updated lsps7CreateOrderCustomMessage and lsps7GetOrderCustomMessage to use native LSPS7 methods if BackendUtils.supportsLSPS7native() is true.
  • stores/NodeInfoStore.ts
    • Added supportsListingOffers observable property.
    • Updated getNodeInfo to set supportsListingOffers based on BackendUtils.supportsListingOffers().
    • Adjusted flowLspNotConfigured check to use BackendUtils.isLocalWallet().
  • stores/OffersStore.ts
    • Added error logging to the createOffer method.
  • stores/SettingsStore.ts
    • Extended the Node interface with LDK Node specific properties (embeddedLdkNetwork, ldkNodeDir, ldkMnemonic, ldkPassphrase, ldkEsploraServer, ldkRgsServer, ldkVssServer).
    • Updated INTERFACE_KEYS to include 'LDK Node' and group node types under 'On-device' and 'Remote' headers.
    • Added embedded-ldk-node to Implementations type.
    • Changed default showMillisatoshiAmounts to false.
  • stores/SwapStore.ts
    • Modified generateRescueKey to reuse the LDK Node mnemonic if the embedded-ldk-node implementation is active and ldkMnemonic is available.
  • utils/AmountUtils.ts
    • Added forceMsats parameter to processSatsAmount to allow forcing millisatoshi display for specific cases like fees.
  • utils/BackendUtils.ts
    • Added an instance of EmbeddedLdkNode.
    • Updated getBackend() to return this.embeddedLdkNode for the embedded-ldk-node implementation.
    • Added new capability flags: supportsLSPS1native, supportsLSPS7native, supportsMessageVerification, supportsListingOffers, supportsBolt12Address, supportsCustomFeeLimit.
    • Introduced isLocalWallet() to check if the current implementation is either embedded-lnd or embedded-ldk-node.
  • utils/EmbeddedLdkNodeUtils.ts
    • Added a new utility file EmbeddedLdkNodeUtils.ts for LDK Node specific operations.
    • Implemented functions for getting LDK Node storage path, creating directories, converting network types, and getting default Esplora/RGS/VSS servers.
    • Provided functions for generating mnemonics, creating new LDK Node wallets, starting existing LDK Node wallets, stopping LDK Node, deleting LDK Node wallet data, and checking wallet existence.
    • Included a validateMnemonic function for BIP39 mnemonics.
  • utils/EventListenerUtils.ts
    • Added LdkNodeEventEmitter to listen for events from the LDK Node native module.
  • utils/PhotoUtils.ts
    • Added LDK image asset.
    • Updated getPhoto to return the LDK image for the 'ldk' filename.
  • utils/RestartUtils.ts
    • Modified stopNode to conditionally stop LDK Node if the embedded-ldk-node implementation is active.
  • utils/VssAuthUtils.ts
    • Added a new utility file VssAuthUtils.ts for generating VSS (Versioned Storage Service) authentication headers.
    • Implemented deriveVssSigningKey to derive a secp256k1 keypair from a BIP39 mnemonic.
    • Implemented generateVssAuthHeaders to create the VSS Authorization header using the derived key and a timestamp.
  • views/Cashu/CashuPayment.tsx
    • Added forceMsats prop to the Amount component for fee display.
  • views/Channels/Channel.tsx
    • Updated renewalInfo to use LSPStore.getExtendableChannelsData.
  • views/Channels/ChannelsPane.tsx
    • Updated renewalInfo to use LSPStore.getExtendableChannelsData.
    • Adjusted conditional rendering for channel tabs to explicitly check for supportsClosedChannels() in addition to supportsPendingChannels().
  • views/LSPS1/Order.tsx
    • Modified order fetching logic to use LSPStore.lsps1GetOrderNative if the order is marked as native, otherwise falls back to REST.
  • views/LSPS1/Settings.tsx
    • Added state variables (originalPubkey, originalHost, originalToken, nativeSettingsChanged) to track changes in native LSPS1 settings.
    • Implemented checkNativeSettingsChanged and showRestartPrompt for native LSPS1 configuration.
    • Added UI elements for configuring native LSPS1 (pubkey, host, token) and a restart prompt if settings are changed.
    • Adjusted reset button visibility based on native LSPS1 support.
  • views/LSPS1/index.tsx
    • Modified componentDidMount to call LSPStore.lsps1GetInfoNative() if native LSPS1 is supported.
    • Updated lspDisplay logic to show 'Native LSPS1 Enabled' if BackendUtils.supportsLSPS1native() is true.
    • Adjusted createOrder button handler to call LSPStore.lsps1CreateOrderNative() if native LSPS1 is supported.
  • views/LightningAddress/ZaplockerGetChan.tsx
    • Added BackendUtils.supportsLSPS1native() check to determine LSPS1 support.
  • views/LightningAddress/index.tsx
    • Updated notEmbedded check to use !BackendUtils.isLocalWallet().
    • Conditional rendering for Zaplocker section based on BackendUtils.supportsCustomPreimages().
  • views/Menu.tsx
    • Updated implementationDisplayValue filtering to exclude header items.
    • Added LDK Node network display to the node subtitle.
    • Adjusted conditional rendering for Seed and EmbeddedNodeSettings based on BackendUtils.isLocalWallet().
    • Modified conditional rendering for Offers to use BackendUtils.supportsBolt12Address() and NodeInfoStore.supportsListingOffers.
  • views/NetworkInfo.tsx
    • Added conditional rendering for network information fields (zombie channels, graph diameter, out degree) based on whether the current implementation is embedded-ldk-node.
  • views/PayCodeCreate.tsx
    • Added a check for the result of OffersStore.createOffer before navigating back.
  • views/Payment.tsx
    • Added forceMsats prop to the Amount component for fee display.
  • views/PaymentRequest.tsx
    • Updated fee_limit_sat logic to remove isLnd check, relying on BackendUtils.supportsCustomFeeLimit().
    • Adjusted conditional rendering for fee limit options to use BackendUtils.supportsCustomFeeLimit().
  • views/PendingHTLCs.tsx
    • Made expiration_height display optional, showing it only if a value exists.
  • views/Receive.tsx
    • Added ldkUnsubscribe state variable and logic to subscribe to LDK Node events (paymentReceived) for tracking invoices.
    • Implemented event handling for LDK Node paymentReceived events to update watched invoices and balances.
  • views/Routing/RoutingEvent.tsx
    • Added forceMsats prop to Amount components for fee and amount display.
  • views/Routing/RoutingHeader.tsx
    • Added forceMsats prop to Amount component for total fee display.
  • views/Routing/RoutingListItem.tsx
    • Added forceMsats prop to Amount component for fee display.
  • views/Send.tsx
    • Added LDK Node specific handling for BOLT12 payments, checking if the payment is already completed directly after fetchInvoiceFromOffer.
  • views/SendingLightning.tsx
    • Added forceMsats prop to Amount components for fee and amount display.
    • Updated troubleshooting button visibility to include embedded-ldk-node.
  • views/Settings/CustodialWalletWarning.tsx
    • Updated the filter for embedded wallets to include embedded-ldk-node.
  • views/Settings/EmbeddedNode/EsploraServer.tsx
    • Added a new view EsploraServer.tsx for configuring the LDK Node Esplora server URL, including default server display and reset functionality.
  • views/Settings/EmbeddedNode/LDKLogs.tsx
    • Added a new view LDKLogs.tsx for displaying real-time LDK Node logs with log buffer capping and copy functionality.
  • views/Settings/EmbeddedNode/LNDLogs.tsx
    • Implemented log buffer capping (MAX_LOG_LENGTH) to prevent unbounded memory growth in LND logs.
  • views/Settings/EmbeddedNode/RapidGossipSync.tsx
    • Added a new view RapidGossipSync.tsx for configuring the LDK Node Rapid Gossip Sync server URL, including default server display and reset functionality.
  • views/Settings/EmbeddedNode/Troubleshooting.tsx
    • Added new state properties for LDK Node troubleshooting (syncWalletsLoading, syncWalletsSuccess, syncWalletsError, resetGraphLoading, resetGraphSuccess, resetGraphError, resetGraphResult).
    • Adjusted loading indicator visibility to include LDK Node operations.
    • Added conditional rendering for LND-specific troubleshooting options (resetExpressGraphSyncOnStartup, compactDb, resetMissionControl, stopLndDeleteNeutrino).
    • Added new troubleshooting options for LDK Node: 'Sync wallets' and 'Reset and resync network graph', with corresponding logic and status displays.
  • views/Settings/EmbeddedNode/VssServer.tsx
    • Added a new view VssServer.tsx for configuring the LDK Node Versioned Storage Service (VSS) server URL, including default server display and reset functionality.
  • views/Settings/EmbeddedNode/index.tsx
    • Added conditional rendering for LDK Node specific settings (Esplora Server, Rapid Gossip Sync, VSS Server) and LND specific settings (Disaster Recovery, Express Graph Sync, Peers, LND Logs, Advanced) based on the implementation type.
    • Grouped Troubleshooting under a common condition for both embedded LND and LDK Node.
  • views/Settings/Seed.tsx
    • Modified seed phrase retrieval to handle LDK Node mnemonics (stored as a single string) and convert them to an array.
    • Introduced isTwelveWords state to dynamically adjust text based on 12-word or 24-word seed phrase length.
    • Updated locale string replacements to correctly reflect 12-word or 24-word seeds.
    • Ensured copyValue for the seed phrase handles potential undefined values.
  • views/Settings/SeedRecovery.tsx
    • Extended SeedRecoveryProps and SeedRecoveryState to include implementation for LDK Node.
    • Implemented saveLdkNodeWalletConfiguration to save LDK Node specific wallet settings.
    • Modified the restore function to conditionally handle LDK Node wallet restoration, including LSPS1, VSS, Esplora, and RGS configuration.
    • Adjusted seed phrase length validation for 12-word mnemonics when restoring LDK Node wallets.
  • views/Settings/SetWalletPicture.tsx
    • Added ldk.png to the implementationImagesMap for embedded-ldk-node.
  • views/Settings/Settings.tsx
    • Added conditional rendering for 'Embedded Node Settings' based on BackendUtils.isLocalWallet().
    • Updated LSPS1 settings navigation to check for BackendUtils.supportsLSPS1native().
  • views/Settings/WalletConfiguration.tsx
    • Extended WalletConfigurationState with LDK Node specific properties.
    • Updated initFromProps and initFromNode to populate LDK Node state.
    • Modified saveNodeConfig to include LDK Node properties.
    • Updated deleteNodeConfig to stop and delete LDK Node wallet data if applicable.
    • Implemented saveLdkNodeWalletConfiguration and createLdkNodeNewWallet for LDK Node specific wallet management.
    • Added UI elements for LDK Node wallet creation/restoration, including network selection and passphrase input.
    • Adjusted conditional rendering for 'Back Up Wallet' and 'Duplicate Wallet' buttons to account for LDK Node.
  • views/Settings/Wallets.tsx
    • Updated implementationDisplayValue filtering to exclude header items.
    • Added LDK Node network display to the node subtitle in the wallet list.
  • views/Swaps/index.tsx
    • Modified checkAndShowModal and unsubFocus to auto-populate the swap rescue key from the LDK Node mnemonic if available.
  • views/Tools/CashuTools.tsx
    • Added SettingsStore injection and isLdk state.
    • Conditional rendering for 'Derive Cashu Seed' and 'Legacy Seed Recovery' based on whether the current implementation is LDK Node.
  • views/Tools/NodeConfigExportImport.tsx
    • Updated getImplementationDisplayName to filter out header items from INTERFACE_KEYS.
    • Modified node filtering for export to include embedded-ldk-node as an embedded type.
  • views/Tools/SignVerifyMessage.tsx
    • Added supportsMessageVerification state and initialized it based on BackendUtils.supportsMessageVerification().
    • Conditional rendering for the ButtonGroup based on supportsMessageVerification.
  • views/Transaction.tsx
    • Added forceMsats prop to the Amount component for amount display.
  • views/Wallet/Wallet.tsx
    • Added startLdkNodeWallet, stopLdkNode, DEFAULT_VSS_SERVER imports.
    • Added DEFAULT_LSPS1_PUBKEY_MAINNET, DEFAULT_LSPS1_PUBKEY_TESTNET imports.
    • Extended state with LDK Node specific settings (ldkNodeDir, ldkMnemonic, ldkPassphrase, embeddedLdkNetwork, ldkEsploraServer, ldkRgsServer, ldkVssServer).
    • Implemented LDK Node initialization and start logic within componentDidMount, including LSPS1, VSS, Esplora, and RGS configuration.
    • Added error handling for LDK Node start and sync operations, populating AlertStore with relevant errors.
    • Updated implementationDisplayValue filtering to exclude header items.
    • Adjusted conditional rendering for 'Express Graph Sync' status to use BackendUtils.isLocalWallet().
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is a large and impressive pull request that adds LDK Node as a new on-device backend. The implementation covers both Android and iOS, with extensive changes across the native and React Native layers to support the new backend's features, including BOLT12, LSPS, and VSS for cloud backups. The code is generally well-structured. I've found a few issues, including an incorrect implementation of lnurl-auth and a capability flag that was incorrectly disabled. I've also noted a minor issue with exception handling in the Android log observer. Overall, this is a significant and well-executed feature addition.

Note: Security Review did not run due to the size of the PR.

Comment thread backends/EmbeddedLdkNode.ts
Comment thread android/app/src/main/java/org/lightningdevkit/ldknode/LogFileObserver.kt Outdated
Comment thread backends/EmbeddedLdkNode.ts Outdated
Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

@kaloudis, the UI looks disturbed here.

Image

Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

@kaloudis, when switching from embedded LND to LDK, the app takes a long time after these logs:

LOADING CONTACTS.....
Loading notes...

Then the following logs appear:
LDK Node: Initializing...
LDK Node: Network set to Bitcoin
LDK Node: Esplora server set to https://electrs.getalbypro.com
LDK Node: RGS server set to https://rapidsync.lightningdevkit.org/snapshot
LDK Node: LSPS1 liquidity source configured
LDK Node: LSPS2 liquidity source configured
LDK Node: LSPS7 liquidity source configured

After these logs, the app crashes.

Screen.Recording.2026-03-09.at.2.28.04.PM.mov

Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

I noticed that when we create an invoice, we receive a payment_request. However, in the activity view, the payment_request is undefined. Because of this, the QR button in the header of the Lightning invoice is not visible. Is this expected?

Image

Comment thread locales/en.json
Comment thread locales/en.json Outdated
Comment thread locales/en.json
Comment thread utils/EmbeddedLdkNodeUtils.ts Outdated
Comment thread android/app/src/main/java/app/zeusln/zeus/LdkNodeModule.kt
Comment thread android/app/src/main/java/app/zeusln/zeus/LdkNodeModule.kt Outdated
Comment thread ios/LdkNodeMobile/LdkNodeModule.swift
Comment thread ios/LdkNodeMobile/LdkNodeModule.swift
Comment thread ios/LdkNodeMobile/LdkNodeModule.swift
@kaloudis
Copy link
Copy Markdown
Contributor Author

kaloudis commented Mar 9, 2026

I noticed that when we create an invoice, we receive a payment_request. However, in the activity view, the payment_request is undefined. Because of this, the QR button in the header of the Lightning invoice is not visible. Is this expected?

This one is a limitation of LDK Node. We can modify our fork and potentially submit a PR upstream. Will take a look at that this week.

Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

Screen.Recording.2026-03-10.at.10.48.47.AM.mov

@kaloudis, We are getting an error when creating pay codes. Also, we should make sure to clean up any errors when the pay codes UI unmounts.

@kaloudis
Copy link
Copy Markdown
Contributor Author

Screen.Recording.2026-03-10.at.10.48.47.AM.mov

@kaloudis, We are getting an error when creating pay codes. Also, we should make sure to clean up any errors when the pay codes UI unmounts.

Do you have channels set up?

@ajaysehwal
Copy link
Copy Markdown
Contributor

Screen.Recording.2026-03-10.at.10.48.47.AM.mov
@kaloudis, We are getting an error when creating pay codes. Also, we should make sure to clean up any errors when the pay codes UI unmounts.

Do you have channels set up?

nope

Comment thread ldknode/LdkNodeInjection.ts Outdated
Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

Screen.Recording.2026-03-10.at.4.19.18.PM.mov

Error initializing seed TypeError: Cannot read property 'map' of undefined
at ?anon_0_ (SeedQRExport.tsx:119:21)
at next (native)
at asyncGeneratorStep (asyncToGenerator.js:3:17)
at _next (asyncToGenerator.js:17:27)
at tryCallOne (address at InternalBytecode.js:1:1274)
at anonymous (address at InternalBytecode.js:1:4865)

Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

Screen.Recording.2026-03-10.at.4.30.47.PM.mov

@kaloudis kaloudis force-pushed the ldk-node branch 2 times, most recently from f19c5d7 to 87b23a0 Compare March 10, 2026 18:24
@kaloudis
Copy link
Copy Markdown
Contributor Author

@kaloudis, when switching from embedded LND to LDK, the app takes a long time after these logs:

LOADING CONTACTS..... Loading notes...

Then the following logs appear: LDK Node: Initializing... LDK Node: Network set to Bitcoin LDK Node: Esplora server set to https://electrs.getalbypro.com LDK Node: RGS server set to https://rapidsync.lightningdevkit.org/snapshot LDK Node: LSPS1 liquidity source configured LDK Node: LSPS2 liquidity source configured LDK Node: LSPS7 liquidity source configured

After these logs, the app crashes.
Screen.Recording.2026-03-09.at.2.28.04.PM.mov

This one should be resolved now. lmk

kaloudis added 20 commits March 26, 2026 20:01
…rtup

The VSS key was derived twice during LDK Node startup — once for the
storeId and again for auth header generation — each costing ~3.4s of
PBKDF2 in JavaScript. Derive once in initNode and pass the precomputed
keypair through to generateVssAuthHeaders.
Add a native mnemonicToSeed method (CommonCrypto on iOS, javax.crypto on
Android) that performs BIP39 PBKDF2-SHA512 in ~5ms vs ~3.4s in pure JS.
The fast BIP32 key derivation and secp256k1 signing remain in JS.

Combined with the prior dedup fix, LDK Node startup drops from ~8.6s to
~2.8s (67% faster).
Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

Screen.Recording.2026-03-27.at.10.03.13.AM.mov

Copy link
Copy Markdown
Contributor

@shubhamkmr04 shubhamkmr04 left a comment

Choose a reason for hiding this comment

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

tACK

Copy link
Copy Markdown
Contributor

@ajaysehwal ajaysehwal left a comment

Choose a reason for hiding this comment

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

tACK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LDK: add message verification support LDK Node: add coin control Support for mutiny net for testing purposes

4 participants