fix(LNC): route register callbacks through events to avoid new-arch crash
This commit is contained in:
@@ -2,15 +2,38 @@
|
||||
#import "Callback.h"
|
||||
#import <React/RCTEventEmitter.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <atomic>
|
||||
|
||||
@implementation Callback
|
||||
@implementation Callback {
|
||||
std::atomic<bool> _consumed;
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
if ((self = [super init])) {
|
||||
_consumed.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setCallback:(RCTResponseSenderBlock)callback {
|
||||
self.rnCallback = callback;
|
||||
}
|
||||
|
||||
-(void)sendResult:(NSString *)data {
|
||||
self.rnCallback(@[data]);
|
||||
// Under React Native's new architecture, RCTResponseSenderBlock can only be
|
||||
// invoked once. The Go LNC bridge may legitimately fire callbacks more than
|
||||
// once for some routes (potentially from different threads); the atomic
|
||||
// compare-exchange drops subsequent invocations safely to avoid a fatal abort.
|
||||
bool expected = false;
|
||||
if (!_consumed.compare_exchange_strong(expected, true)) {
|
||||
return;
|
||||
}
|
||||
RCTResponseSenderBlock cb = self.rnCallback;
|
||||
if (cb == nil) {
|
||||
return;
|
||||
}
|
||||
// Defend against a nil data argument — @[nil] would throw NSInvalidArgumentException.
|
||||
cb(@[data ?: @""]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,10 +21,11 @@ RCT_EXPORT_METHOD(initLNC:(NSString *)nameSpace)
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(registerLocalPrivCreateCallback:(NSString *)nameSpace
|
||||
resolver:(RCTResponseSenderBlock)onLocalPrivCreate)
|
||||
eventName:(NSString *)eventName)
|
||||
{
|
||||
Callback *lpccb = [[Callback alloc] init];
|
||||
[lpccb setCallback:onLocalPrivCreate];
|
||||
StreamingCallback *lpccb = [[StreamingCallback alloc] init];
|
||||
lpccb.delegate = self;
|
||||
[lpccb setEventName:eventName];
|
||||
NSError *error;
|
||||
LndmobileRegisterLocalPrivCreateCallback(nameSpace, lpccb, &error);
|
||||
if (error) {
|
||||
@@ -33,10 +34,11 @@ RCT_EXPORT_METHOD(registerLocalPrivCreateCallback:(NSString *)nameSpace
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(registerRemoteKeyReceiveCallback:(NSString *)nameSpace
|
||||
resolver:(RCTResponseSenderBlock)onRemoteKeyReceive)
|
||||
eventName:(NSString *)eventName)
|
||||
{
|
||||
Callback * rkrcb = [[Callback alloc] init];
|
||||
[rkrcb setCallback:onRemoteKeyReceive];
|
||||
StreamingCallback *rkrcb = [[StreamingCallback alloc] init];
|
||||
rkrcb.delegate = self;
|
||||
[rkrcb setEventName:eventName];
|
||||
NSError *error;
|
||||
LndmobileRegisterRemoteKeyReceiveCallback(nameSpace, rkrcb, &error);
|
||||
if (error) {
|
||||
@@ -45,10 +47,11 @@ RCT_EXPORT_METHOD(registerRemoteKeyReceiveCallback:(NSString *)nameSpace
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(registerAuthDataCallback:(NSString *)nameSpace
|
||||
resolver:(RCTResponseSenderBlock)onAuthData)
|
||||
eventName:(NSString *)eventName)
|
||||
{
|
||||
Callback * oacb = [[Callback alloc] init];
|
||||
[oacb setCallback:onAuthData];
|
||||
StreamingCallback *oacb = [[StreamingCallback alloc] init];
|
||||
oacb.delegate = self;
|
||||
[oacb setEventName:eventName];
|
||||
NSError *error;
|
||||
LndmobileRegisterAuthDataCallback(nameSpace, oacb, &error);
|
||||
if (error) {
|
||||
@@ -187,6 +190,9 @@ RCT_EXPORT_METHOD(initListener:(NSString *)nameSpace
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[
|
||||
@"lnc.localPrivCreate",
|
||||
@"lnc.remoteKeyReceive",
|
||||
@"lnc.authData",
|
||||
@"chainrpc.ChainNotifier.RegisterBlockEpochNtfn",
|
||||
@"chainrpc.ChainNotifier.RegisterConfirmationsNtfn",
|
||||
@"chainrpc.ChainNotifier.RegisterSpendNtfn",
|
||||
|
||||
Reference in New Issue
Block a user