Skip to content

Commit 8dbb3ce

Browse files
committed
Kotlin channel manager event handling
Code cleanup
1 parent c130dc7 commit 8dbb3ce

File tree

8 files changed

+177
-23
lines changed

8 files changed

+177
-23
lines changed

android/src/main/java/com/reactnativeldk/Helpers.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.reactnativeldk
22
import com.facebook.react.bridge.Arguments
33
import com.facebook.react.bridge.Promise
4+
import com.facebook.react.bridge.WritableArray
45
import com.facebook.react.bridge.WritableMap
56
import org.ldk.structs.*
67

@@ -36,7 +37,7 @@ val Invoice.asJson: WritableMap
3637
val signedInv = into_signed_raw()
3738
val rawInvoice = signedInv.raw_invoice()
3839

39-
result.putDouble("amount_milli_satoshis", (amount_milli_satoshis() as Option_u64Z.Some).some.toDouble())
40+
result.putInt("amount_milli_satoshis", (amount_milli_satoshis() as Option_u64Z.Some).some.toInt())
4041
result.putString("description", rawInvoice.description()?.into_inner())
4142
result.putBoolean("check_signature", signedInv.check_signature())
4243
result.putBoolean("is_expired", is_expired)
@@ -85,3 +86,23 @@ val ChannelDetails.asJson: WritableMap
8586

8687
return result
8788
}
89+
90+
val RouteHop.asJson: WritableMap
91+
get() {
92+
val hop = Arguments.createMap()
93+
hop.putHexString("pubkey", _pubkey)
94+
hop.putInt("fee_msat", _fee_msat.toInt())
95+
return hop
96+
}
97+
98+
fun WritableMap.putHexString(key: String, bytes: ByteArray?) {
99+
if (bytes != null) {
100+
putString(key, bytes.hexEncodedString())
101+
} else {
102+
putString(key, null)
103+
}
104+
}
105+
106+
fun WritableArray.pushHexString(bytes: ByteArray) {
107+
pushString(bytes.hexEncodedString())
108+
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import org.ldk.structs.Result_InvoiceParseOrSemanticErrorZ.Result_InvoiceParseOr
1515
import org.ldk.structs.Result_InvoiceSignOrCreationErrorZ.Result_InvoiceSignOrCreationErrorZ_OK
1616
import java.net.InetSocketAddress
1717

18-
1918
//MARK: ************Replicate in typescript and swift************
2019
enum class EventTypes {
2120
ldk_log,
@@ -34,6 +33,7 @@ enum class EventTypes {
3433
channel_manager_payment_path_successful,
3534
channel_manager_payment_path_failed,
3635
channel_manager_payment_failed,
36+
channel_manager_pending_htlcs_forwardable,
3737
channel_manager_spendable_outputs,
3838
channel_manager_channel_closed,
3939
channel_manager_discard_funding
@@ -77,7 +77,6 @@ enum class LdkCallbackResponses {
7777
channel_manager_init_success,
7878
load_channel_monitors_success,
7979
config_init_success,
80-
net_graph_msg_handler_init_success,
8180
chain_monitor_updated,
8281
network_graph_init_success,
8382
add_peer_success,
Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,142 @@
11
package com.reactnativeldk.classes
22

3+
import com.facebook.react.bridge.Arguments
4+
import com.reactnativeldk.*
35
import org.ldk.batteries.ChannelManagerConstructor
46
import org.ldk.structs.Event
7+
import org.ldk.structs.Option_u64Z
8+
import org.ldk.structs.PaymentPurpose
59

610
class LdkChannelManagerPersister {
711
var channelManagerPersister = object : ChannelManagerConstructor.EventHandler {
812
override fun handle_event(event: Event) {
9-
//TODO
13+
(event as? Event.FundingGenerationReady)?.let { fundingGenerationReady ->
14+
val body = Arguments.createMap()
15+
body.putHexString("temp_channel_id", fundingGenerationReady.temporary_channel_id)
16+
body.putHexString("output_script", fundingGenerationReady.output_script)
17+
body.putInt("user_channel_id", fundingGenerationReady.user_channel_id.toInt())
18+
body.putInt("value_satoshis", fundingGenerationReady.channel_value_satoshis.toInt())
19+
return LdkEventEmitter.send(EventTypes.channel_manager_funding_generation_ready, body)
20+
}
21+
22+
(event as? Event.PaymentReceived)?.let { paymentReceived ->
23+
val body = Arguments.createMap()
24+
body.putHexString("payment_hash", paymentReceived.payment_hash)
25+
body.putInt("amount", paymentReceived.amt.toInt())
26+
(paymentReceived.purpose as? PaymentPurpose.InvoicePayment)?.let {
27+
body.putHexString("payment_preimage", it.payment_preimage)
28+
body.putHexString("payment_secret", it.payment_secret)
29+
}
30+
(paymentReceived.purpose as? PaymentPurpose.SpontaneousPayment)?.let {
31+
body.putHexString("spontaneous_payment_preimage", it.spontaneous_payment)
32+
}
33+
return LdkEventEmitter.send(EventTypes.channel_manager_payment_received, body)
34+
}
35+
36+
(event as? Event.PaymentSent)?.let { paymentSent ->
37+
val body = Arguments.createMap()
38+
body.putHexString("payment_id", paymentSent.payment_id)
39+
body.putHexString("payment_preimage", paymentSent.payment_preimage)
40+
body.putHexString("payment_hash", paymentSent.payment_hash)
41+
body.putInt("fee_paid_msat", (paymentSent.fee_paid_msat as Option_u64Z.Some).some.toInt())
42+
return LdkEventEmitter.send(EventTypes.channel_manager_payment_sent, body)
43+
}
44+
45+
(event as? Event.OpenChannelRequest)?.let { openChannelRequest ->
46+
//Use if we ever manually accept inbound channels. Setting in initConfig.
47+
val body = Arguments.createMap()
48+
body.putHexString("temp_channel_id", openChannelRequest.temporary_channel_id)
49+
body.putHexString("counterparty_node_id", openChannelRequest.counterparty_node_id)
50+
body.putInt("push_msat", openChannelRequest.push_msat.toInt())
51+
body.putInt("funding_satoshis", openChannelRequest.funding_satoshis.toInt())
52+
body.putHexString("channel_type", openChannelRequest.channel_type.write())
53+
return LdkEventEmitter.send(EventTypes.channel_manager_open_channel_request, body)
54+
}
55+
56+
(event as? Event.PaymentPathSuccessful)?.let { paymentPathSuccessful ->
57+
val body = Arguments.createMap()
58+
59+
body.putHexString("payment_id", paymentPathSuccessful.payment_id)
60+
body.putHexString("payment_hash", paymentPathSuccessful.payment_hash)
61+
62+
val path = Arguments.createArray()
63+
paymentPathSuccessful.path.iterator().forEach { path.pushMap(it.asJson) }
64+
body.putArray("path", path)
65+
66+
return LdkEventEmitter.send(EventTypes.channel_manager_payment_path_successful, body)
67+
}
68+
69+
(event as? Event.PaymentPathFailed)?.let { paymentPathFailed ->
70+
val body = Arguments.createMap()
71+
body.putHexString("payment_id", paymentPathFailed.payment_id)
72+
body.putHexString("payment_hash", paymentPathFailed.payment_hash)
73+
body.putBoolean("rejected_by_dest", paymentPathFailed.rejected_by_dest)
74+
body.putInt("short_channel_id", (paymentPathFailed.short_channel_id as Option_u64Z.Some).some.toInt())
75+
val path = Arguments.createArray()
76+
paymentPathFailed.path.iterator().forEach { path.pushMap(it.asJson) }
77+
body.putArray("path", path)
78+
body.putString("network_update", paymentPathFailed.network_update.toString()) //TODO could be more detailed
79+
80+
return LdkEventEmitter.send(EventTypes.channel_manager_payment_path_failed, body)
81+
}
82+
83+
(event as? Event.PaymentFailed)?.let { paymentFailed ->
84+
val body = Arguments.createMap()
85+
body.putHexString("payment_id", paymentFailed.payment_id)
86+
body.putHexString("payment_hash", paymentFailed.payment_hash)
87+
return LdkEventEmitter.send(EventTypes.channel_manager_payment_failed, body)
88+
}
89+
90+
(event as? Event.PaymentForwarded)?.let { paymentForwarded ->
91+
//Unused on mobile
92+
}
93+
94+
(event as? Event.PendingHTLCsForwardable)?.let { pendingHTLCsForwardable ->
95+
val body = Arguments.createMap()
96+
body.putInt("time_forwardable", pendingHTLCsForwardable.time_forwardable.toInt())
97+
return LdkEventEmitter.send(EventTypes.channel_manager_pending_htlcs_forwardable, body)
98+
}
99+
100+
(event as? Event.SpendableOutputs)?.let { spendableOutputs ->
101+
val body = Arguments.createMap()
102+
val outputs = Arguments.createArray()
103+
spendableOutputs.outputs.iterator().forEach {
104+
outputs.pushHexString(it.write())
105+
}
106+
body.putArray("outputs", outputs)
107+
return LdkEventEmitter.send(EventTypes.channel_manager_spendable_outputs, body)
108+
}
109+
110+
(event as? Event.ChannelClosed)?.let { channelClosed ->
111+
val body = Arguments.createMap()
112+
body.putInt("user_channel_id", channelClosed.user_channel_id.toInt())
113+
body.putHexString("channel_id", channelClosed.channel_id)
114+
body.putHexString("reason", channelClosed.reason.write())
115+
return LdkEventEmitter.send(EventTypes.channel_manager_channel_closed, body)
116+
}
117+
118+
(event as? Event.DiscardFunding)?.let { discardFunding ->
119+
val body = Arguments.createMap()
120+
body.putHexString("channel_id", discardFunding.channel_id)
121+
body.putHexString("tx", discardFunding.transaction)
122+
return LdkEventEmitter.send(EventTypes.channel_manager_discard_funding, body)
123+
}
10124
}
11125

12126
override fun persist_manager(channel_manager_bytes: ByteArray?) {
13-
//TODO
127+
if (channel_manager_bytes != null) {
128+
val body = Arguments.createMap()
129+
body.putHexString("channel_manager", channel_manager_bytes)
130+
LdkEventEmitter.send(EventTypes.persist_manager, body)
131+
}
14132
}
15133

16134
override fun persist_network_graph(network_graph: ByteArray?) {
17-
//TODO
135+
if (network_graph != null) {
136+
val body = Arguments.createMap()
137+
body.putHexString("network_graph", network_graph)
138+
LdkEventEmitter.send(EventTypes.persist_graph, body)
139+
}
18140
}
19141
}
20142
}

android/src/main/java/com/reactnativeldk/classes/LdkFilter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class LdkFilter {
2525
}
2626
body.putInt("index", output._outpoint._index.toInt())
2727
body.putString("script_pubkey", output._script_pubkey.hexEncodedString())
28-
LdkEventEmitter.send(EventTypes.register_tx, body)
28+
LdkEventEmitter.send(EventTypes.register_output, body)
2929
return Option_C2Tuple_usizeTransactionZZ.none();
3030
}
3131
})

ios/Classes/LdkChannelManagerPersister.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
7676
)
7777
return
7878
case .OpenChannelRequest:
79+
//Use if we ever manually accept inbound channels. Setting in initConfig.
7980
guard let openChannelRequest = event.getValueAsOpenChannelRequest() else {
8081
return handleEventError(event)
8182
}
@@ -89,7 +90,6 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
8990
"channel_type": Data(openChannelRequest.getChannel_type().write()).hexEncodedString()
9091
]
9192
)
92-
//Use if we ever manually accept inbound channels. Setting in initConfig.
9393
return
9494
case .PaymentPathSuccessful:
9595
guard let paymentPathSuccessful = event.getValueAsPaymentPathSuccessful() else {
@@ -101,7 +101,7 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
101101
body: [
102102
"payment_id": Data(paymentPathSuccessful.getPayment_id()).hexEncodedString(),
103103
"payment_hash": Data(paymentPathSuccessful.getPayment_hash()).hexEncodedString(),
104-
"path": paymentPathSuccessful.getPath().map { [ "pubkey": $0.get_pubkey(), "fee_msat": $0.get_fee_msat() ] },
104+
"path": paymentPathSuccessful.getPath().map { $0.asJson },
105105
]
106106
)
107107
return
@@ -116,9 +116,9 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
116116
"payment_id": Data(paymentPathFailed.getPayment_id()).hexEncodedString(),
117117
"payment_hash": Data(paymentPathFailed.getPayment_hash()).hexEncodedString(),
118118
"rejected_by_dest": paymentPathFailed.getRejected_by_dest(),
119-
"channel_id": paymentPathFailed.getShort_channel_id(),
120-
"path": paymentPathFailed.getPath().map { [ "pubkey": $0.get_pubkey(), "fee_msat": $0.get_fee_msat() ] },
121-
"network_update": paymentPathFailed.getNetwork_update().getValue().debugDescription
119+
"short_channel_id": paymentPathFailed.getShort_channel_id(),
120+
"path": paymentPathFailed.getPath().map { $0.asJson },
121+
"network_update": paymentPathFailed.getNetwork_update().getValue().debugDescription //TODO could be more detailed
122122
]
123123
)
124124
return

ios/Helpers.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ extension ChannelDetails {
7272
}
7373
}
7474

75+
extension LDKFramework.RouteHop {
76+
var asJson: Any {
77+
return [
78+
"pubkey": get_pubkey(),
79+
"fee_msat": get_fee_msat(),
80+
"short_channel_id": get_short_channel_id(),
81+
"cltv_expiry_delta": get_cltv_expiry_delta()
82+
]
83+
}
84+
}
85+
7586
extension Data {
7687
struct HexEncodingOptions: OptionSet {
7788
let rawValue: Int

ios/Ldk.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ enum LdkCallbackResponses: String {
6565
case channel_manager_init_success = "channel_manager_init_success"
6666
case load_channel_monitors_success = "load_channel_monitors_success"
6767
case config_init_success = "config_init_success"
68-
case net_graph_msg_handler_init_success = "net_graph_msg_handler_init_success"
6968
case chain_monitor_updated = "chain_monitor_updated"
7069
case network_graph_init_success = "network_graph_init_success"
7170
case add_peer_success = "add_peer_success"

src/utils/types.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,25 @@ export type TChannelManagerOpenChannelRequest = {
6767
funding_satoshis: number;
6868
channel_type: string;
6969
};
70+
71+
type TPath = {
72+
pubkey: string;
73+
fee_msat: number;
74+
short_channel_id: number;
75+
cltv_expiry_delta: number;
76+
};
77+
7078
export type TChannelManagerPaymentPathSuccessful = {
7179
payment_id: string;
7280
payment_hash: string;
73-
path: {
74-
pubkey: string;
75-
fee_msat: number;
76-
}[];
81+
path: TPath[];
7782
};
7883
export type TChannelManagerPaymentPathFailed = {
7984
payment_id: string;
8085
payment_hash: string;
8186
rejected_by_dest: boolean;
82-
channel_id: string;
83-
path: {
84-
pubkey: string;
85-
fee_msat: number;
86-
}[];
87+
short_channel_id: string;
88+
path: TPath[];
8789
network_update: string;
8890
};
8991
export type TChannelManagerPaymentFailed = {
@@ -130,7 +132,7 @@ export type TChannel = {
130132

131133
export type TInvoice = {
132134
amount_milli_satoshis?: number;
133-
description?: string,
135+
description?: string;
134136
check_signature: boolean;
135137
is_expired: boolean;
136138
duration_since_epoch: number;

0 commit comments

Comments
 (0)