Skip to content
This repository was archived by the owner on Feb 9, 2026. It is now read-only.

Commit d43d4ed

Browse files
authored
Merge branch 'master' into ldk-115
2 parents f402b5a + 2caec98 commit d43d4ed

11 files changed

Lines changed: 134 additions & 52 deletions

File tree

example/App.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,18 @@ const App = (): ReactElement => {
611611
);
612612
}}
613613
/>
614+
<Button
615+
title={'Restart node'}
616+
onPress={async (): Promise<void> => {
617+
setMessage('Restarting...');
618+
const res = await ldk.restart();
619+
if (res.isErr()) {
620+
setMessage(res.error.message);
621+
return;
622+
}
623+
setMessage('Node Restarted');
624+
}}
625+
/>
614626
</View>
615627
</ScrollView>
616628

example/electrum/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export const subscribeToHeader = async ({
107107
network: selectedNetwork,
108108
onReceive: async (data) => {
109109
const hex = data[0].hex;
110-
const hash = getBlockHashFromHex({ blockHex: hex });
110+
const hash = await getBlockHashFromHex({ blockHex: hex });
111111
const header = { ...data[0], hash };
112112
await updateHeader({
113113
header,

example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ PODS:
302302
- React-jsinspector (0.70.6)
303303
- React-logger (0.70.6):
304304
- glog
305-
- react-native-ldk (0.0.95):
305+
- react-native-ldk (0.0.97):
306306
- React
307307
- react-native-randombytes (3.6.1):
308308
- React-Core
@@ -593,7 +593,7 @@ SPEC CHECKSUMS:
593593
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
594594
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
595595
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
596-
react-native-ldk: 3608ec98dc228dc8ea4ca15e68a8b4562be7cfb5
596+
react-native-ldk: 38eb5291779f3ef181fd6472e7cd5ebf15797f8d
597597
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
598598
react-native-tcp-socket: c1b7297619616b4c9caae6889bcb0aba78086989
599599
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
@@ -618,4 +618,4 @@ SPEC CHECKSUMS:
618618

619619
PODFILE CHECKSUM: 686e912f33d09c328c075738266ee797003d369e
620620

621-
COCOAPODS: 1.11.3
621+
COCOAPODS: 1.12.0

example/ldk/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export const syncLdk = async (): Promise<Result<string>> => {
9797
*/
9898
export const setupLdk = async (): Promise<Result<string>> => {
9999
try {
100-
await ldk.reset();
100+
await ldk.stop();
101101
const account = await getAccount();
102102
const storageRes = await lm.setBaseStoragePath(
103103
`${RNFS.DocumentDirectoryPath}/ldk/`,

lib/android/src/main/java/com/reactnativeldk/LdkModule.kt

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ enum class EventTypes {
4242
channel_manager_payment_claimed,
4343
emergency_force_close_channel,
4444
new_channel,
45-
network_graph_updated
45+
network_graph_updated,
46+
channel_manager_restarted
4647
}
4748
//*****************************************************************
4849

@@ -101,7 +102,8 @@ enum class LdkCallbackResponses {
101102
tx_set_unconfirmed,
102103
process_pending_htlc_forwards_success,
103104
claim_funds_success,
104-
ldk_reset,
105+
ldk_stop,
106+
ldk_restart,
105107
close_channel_success,
106108
file_write_success
107109
}
@@ -142,6 +144,11 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
142144
private var ldkNetwork: Network? = null
143145
private var ldkCurrency: Currency? = null
144146

147+
//Keep these in memory for restarting the channel manager constructor
148+
private var currentNetwork: String? = null
149+
private var currentBlockchainTipHash: String? = null
150+
private var currentBlockchainHeight: Double? = null
151+
145152
//Static to be accessed from other classes
146153
companion object {
147154
lateinit var accountStoragePath: String
@@ -157,10 +164,6 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
157164

158165
@ReactMethod
159166
fun setAccountStoragePath(storagePath: String, promise: Promise) {
160-
if (accountStoragePath != "") {
161-
return handleReject(promise, LdkErrors.already_init)
162-
}
163-
164167
val accountStoragePath = File(storagePath)
165168
val channelStoragePath = File("$storagePath/channels/")
166169

@@ -397,8 +400,6 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
397400
channelMonitors.add(it.toFile().readBytes())
398401
}
399402

400-
println("***1***")
401-
402403
LdkEventEmitter.send(EventTypes.native_log, "Restoring node from disk2")
403404

404405
channelManagerConstructor = ChannelManagerConstructor(
@@ -419,7 +420,6 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
419420
logger.logger
420421
)
421422

422-
println("***2***")
423423
} else {
424424
//New node
425425
LdkEventEmitter.send(EventTypes.native_log, "Creating new channel manager")
@@ -451,11 +451,56 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
451451

452452
peerHandler = channelManagerConstructor!!.nio_peer_handler
453453

454+
//Cached for restarts
455+
currentNetwork = network
456+
currentBlockchainTipHash = blockHash
457+
currentBlockchainHeight = blockHeight
458+
454459
handleResolve(promise, LdkCallbackResponses.channel_manager_init_success)
455460
}
461+
@ReactMethod
462+
fun restart(promise: Promise) {
463+
if (channelManagerConstructor == null) {
464+
return handleReject(promise, LdkErrors.init_channel_manager)
465+
}
466+
467+
//Node was never started
468+
val currentNetwork = currentNetwork ?: return handleReject(promise, LdkErrors.init_channel_manager)
469+
val currentBlockchainTipHash = currentBlockchainTipHash ?: return handleReject(promise, LdkErrors.init_channel_manager)
470+
val currentBlockchainHeight = currentBlockchainHeight ?: return handleReject(promise, LdkErrors.init_channel_manager)
471+
472+
LdkEventEmitter.send(EventTypes.native_log, "Stopping LDK background tasks")
473+
474+
//Reset only objects created by initChannelManager
475+
channelManagerConstructor?.interrupt()
476+
channelManagerConstructor = null
477+
channelManager = null
478+
peerManager = null
479+
peerHandler = null
480+
481+
LdkEventEmitter.send(EventTypes.native_log, "Starting LDK background tasks again")
482+
483+
val initPromise = PromiseImpl(
484+
{ resolve ->
485+
LdkEventEmitter.send(EventTypes.channel_manager_restarted, "")
486+
LdkEventEmitter.send(EventTypes.native_log, "LDK restarted successfully")
487+
handleResolve(promise, LdkCallbackResponses.ldk_restart)
488+
},
489+
{ reject ->
490+
LdkEventEmitter.send(EventTypes.native_log, "Error restarting LDK. Error: $reject")
491+
handleReject(promise, LdkErrors.unknown_error)
492+
})
493+
494+
initChannelManager(
495+
currentNetwork,
496+
currentBlockchainTipHash,
497+
currentBlockchainHeight,
498+
initPromise
499+
)
500+
}
456501

457502
@ReactMethod
458-
fun reset(promise: Promise) {
503+
fun stop(promise: Promise) {
459504
channelManagerConstructor?.interrupt()
460505
channelManagerConstructor = null
461506
chainMonitor = null
@@ -467,10 +512,8 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
467512
peerHandler = null
468513
ldkNetwork = null
469514
ldkCurrency = null
470-
accountStoragePath = ""
471-
channelStoragePath = ""
472515

473-
handleResolve(promise, LdkCallbackResponses.ldk_reset)
516+
handleResolve(promise, LdkCallbackResponses.ldk_stop)
474517
}
475518

476519
//MARK: Update methods
@@ -488,7 +531,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
488531
}
489532

490533
@ReactMethod
491-
fun syncToTip(header: String, height: Double, promise: Promise) {
534+
fun syncToTip(header: String, blockHash: String, height: Double, promise: Promise) {
492535
channelManager ?: return handleReject(promise, LdkErrors.init_channel_manager)
493536
chainMonitor ?: return handleReject(promise, LdkErrors.init_chain_monitor)
494537

@@ -499,6 +542,10 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
499542
return handleReject(promise, LdkErrors.unknown_error, Error(e))
500543
}
501544

545+
//Used for quick restarts
546+
currentBlockchainTipHash = blockHash
547+
currentBlockchainHeight = height
548+
502549
handleResolve(promise, LdkCallbackResponses.chain_sync_success)
503550
}
504551

lib/ios/Ldk.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ @interface RCT_EXTERN_MODULE(Ldk, NSObject)
3030
blockHeight:(NSInteger *)blockHeight
3131
resolve:(RCTPromiseResolveBlock)resolve
3232
reject:(RCTPromiseRejectBlock)reject)
33-
RCT_EXTERN_METHOD(reset:(RCTPromiseResolveBlock)resolve
33+
RCT_EXTERN_METHOD(restart:(RCTPromiseResolveBlock)resolve
34+
reject:(RCTPromiseRejectBlock)reject)
35+
RCT_EXTERN_METHOD(stop:(RCTPromiseResolveBlock)resolve
3436
reject:(RCTPromiseRejectBlock)reject)
3537

3638
//MARK: Update methods
@@ -44,6 +46,7 @@ @interface RCT_EXTERN_MODULE(Ldk, NSObject)
4446
resolve:(RCTPromiseResolveBlock)resolve
4547
reject:(RCTPromiseRejectBlock)reject)
4648
RCT_EXTERN_METHOD(syncToTip:(NSString *)header
49+
blockHash:(NSString *)blockHash
4750
height:(NSInteger *)height
4851
resolve:(RCTPromiseResolveBlock)resolve
4952
reject:(RCTPromiseRejectBlock)reject)

lib/ios/Ldk.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ enum LdkCallbackResponses: String {
8484
case tx_set_unconfirmed = "tx_set_unconfirmed"
8585
case process_pending_htlc_forwards_success = "process_pending_htlc_forwards_success"
8686
case claim_funds_success = "claim_funds_success"
87-
case ldk_reset = "ldk_reset"
87+
case ldk_stop = "ldk_stop"
88+
case ldk_restart = "ldk_restart"
8889
case close_channel_success = "close_channel_success"
8990
case file_write_success = "file_write_success"
9091
case abandon_payment_success = "abandon_payment_success"
@@ -444,26 +445,32 @@ class Ldk: NSObject {
444445

445446
func addForegroundObserver() {
446447
removeForegroundObserver()
447-
NotificationCenter.default.addObserver(self, selector: #selector(restartChannelManagerConstructor), name: UIApplication.didBecomeActiveNotification, object: nil)
448+
NotificationCenter.default.addObserver(self, selector: #selector(restartOnForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
448449
}
449450

450451
func removeForegroundObserver() {
451452
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
452453
}
453454

455+
/// Used by event listener so responses are not handled
456+
@objc
457+
func restartOnForeground() {
458+
restart { res in } reject: { code, message, error in }
459+
}
460+
454461
/// Restarts channel manager constructor to get a new TCP peer handler
455462
@objc
456-
func restartChannelManagerConstructor() {
463+
func restart(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
457464
guard channelManagerConstructor != nil else {
458465
//Wasn't yet started
459-
return
466+
return handleReject(reject, .init_channel_manager)
460467
}
461468

462469
guard let currentNetwork = self.currentNetwork,
463470
let currentBlockchainTipHash = self.currentBlockchainTipHash,
464471
let currentBlockchainHeight = self.currentBlockchainHeight else {
465472
//Node was never started
466-
return
473+
return handleReject(reject, .init_channel_manager)
467474
}
468475

469476
LdkEventEmitter.shared.send(withEvent: .native_log, body: "Stopping LDK background tasks")
@@ -480,16 +487,19 @@ class Ldk: NSObject {
480487
//Notify JS that a sync is required
481488
LdkEventEmitter.shared.send(withEvent: .channel_manager_restarted, body: "")
482489
LdkEventEmitter.shared.send(withEvent: .native_log, body: "LDK restarted successfully")
490+
491+
return handleResolve(resolve, .ldk_restart)
483492
} reject: { errorCode, errorMessage, error in
484-
LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error restarting LDK. \(errorCode) \(errorMessage)")
493+
LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error restarting LDK. \(String(describing: errorCode)) \(String(describing: errorMessage))")
494+
handleReject(reject, .unknown_error)
485495
}
486496
}
487497

488498
@objc
489-
func reset(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
499+
func stop(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
490500
guard let cm = channelManagerConstructor else {
491501
//Wasn't yet started
492-
return handleResolve(resolve, .ldk_reset)
502+
return handleResolve(resolve, .ldk_stop)
493503
}
494504

495505
removeForegroundObserver() //LDK was intentionally stopped and we shouldn't attempt a restart
@@ -504,10 +514,8 @@ class Ldk: NSObject {
504514
peerHandler = nil
505515
ldkNetwork = nil
506516
ldkCurrency = nil
507-
Ldk.accountStoragePath = nil
508-
Ldk.channelStoragePath = nil
509517

510-
return handleResolve(resolve, .ldk_reset)
518+
return handleResolve(resolve, .ldk_stop)
511519
}
512520

513521
//MARK: Update methods
@@ -525,7 +533,7 @@ class Ldk: NSObject {
525533
}
526534

527535
@objc
528-
func syncToTip(_ header: NSString, height: NSInteger, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
536+
func syncToTip(_ header: NSString, blockHash: NSString, height: NSInteger, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
529537
//Sync ChannelMonitors and ChannelManager to chain tip
530538
guard let channelManager = channelManager else {
531539
return handleReject(reject, .init_channel_manager)
@@ -538,6 +546,10 @@ class Ldk: NSObject {
538546
channelManager.asConfirm().bestBlockUpdated(header: String(header).hexaBytes, height: UInt32(height))
539547
chainMonitor.asConfirm().bestBlockUpdated(header: String(header).hexaBytes, height: UInt32(height))
540548

549+
//Used for quick restarts
550+
currentBlockchainTipHash = blockHash
551+
currentBlockchainHeight = height
552+
541553
return handleResolve(resolve, .chain_sync_success)
542554
}
543555

lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@synonymdev/react-native-ldk",
33
"title": "React Native LDK",
4-
"version": "0.0.95",
4+
"version": "0.0.97",
55
"description": "React Native wrapper for LDK",
66
"main": "./dist/index.js",
77
"types": "./dist/index.d.ts",

0 commit comments

Comments
 (0)