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

Commit 63e4325

Browse files
committed
Add pending incoming payments
1 parent 241e106 commit 63e4325

3 files changed

Lines changed: 63 additions & 21 deletions

File tree

lib/android/src/main/java/com/reactnativeldk/classes/LdkChannelManagerPersister.kt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
3232
(paymentClaimable.purpose as? PaymentPurpose.SpontaneousPayment)?.let {
3333
body.putHexString("spontaneous_payment_preimage", it.spontaneous_payment)
3434
}
35+
body.putInt("unix_timestamp", (System.currentTimeMillis() / 1000).toInt())
36+
body.putBoolean("confirmed", false)
37+
38+
persistPaymentClaimed(body)
3539
return LdkEventEmitter.send(EventTypes.channel_manager_payment_claimable, body)
3640
}
3741

@@ -135,6 +139,7 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
135139
body.putHexString("spontaneous_payment_preimage", it.spontaneous_payment)
136140
}
137141
body.putInt("unix_timestamp", (System.currentTimeMillis() / 1000).toInt())
142+
body.putBoolean("confirmed", true)
138143

139144
persistPaymentClaimed(body)
140145
return LdkEventEmitter.send(EventTypes.channel_manager_payment_claimed, body)
@@ -171,31 +176,44 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
171176
return
172177
}
173178

174-
var newContent: Array<HashMap<String, Any>> = arrayOf()
179+
var payments: Array<HashMap<String, Any>> = arrayOf()
180+
var paymentReplaced = false
175181

176182
try {
177183
if (File(LdkModule.accountStoragePath + "/" + LdkFileNames.paymentsClaimed.fileName).exists()) {
178184
val data = File(LdkModule.accountStoragePath + "/" + LdkFileNames.paymentsClaimed.fileName).readBytes()
179185
println(String(data))
180-
val existingContent = JSONArray(String(data))
181-
for (i in 0 until existingContent.length()) {
186+
val existingPayments = JSONArray(String(data))
187+
for (i in 0 until existingPayments.length()) {
188+
val existingPayment = existingPayments.getJSONObject(i)
189+
190+
//Replace entry if payment hash exists (Confirmed payment replacing pending)
191+
if (existingPayment.getString("payment_hash") == payment.getString("payment_hash")) {
192+
payments[i] = payment.toHashMap()
193+
paymentReplaced = true
194+
continue
195+
}
196+
182197
val map = HashMap<String, Any>()
183-
for (key in existingContent.getJSONObject(i).keys()) {
184-
map[key] = existingContent.getJSONObject(i).get(key)
198+
for (key in existingPayment.keys()) {
199+
map[key] = existingPayments.getJSONObject(i).get(key)
185200
}
186201

187-
newContent = newContent.plus(map)
202+
payments = payments.plus(map)
188203
}
189204
}
190205
} catch (e: Exception) {
191206
LdkEventEmitter.send(EventTypes.native_log, "Error could not read exisitng claimed payments")
192207
}
193208

194-
newContent = newContent.plus(payment.toHashMap())
209+
//No existing payment found, append as new payment
210+
if (!paymentReplaced) {
211+
payments = payments.plus(payment.toHashMap())
212+
}
195213

196214
println("New content")
197-
newContent.iterator().forEach { println(it) }
215+
payments.iterator().forEach { println(it) }
198216

199-
File(LdkModule.accountStoragePath + "/" + LdkFileNames.paymentsClaimed.fileName).writeText(JSONArray(newContent).toString())
217+
File(LdkModule.accountStoragePath + "/" + LdkFileNames.paymentsClaimed.fileName).writeText(JSONArray(payments).toString())
200218
}
201219
}

lib/ios/Classes/LdkChannelManagerPersister.swift

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,23 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
4545
let paymentSecret = paymentClaimable.getPurpose().getValueAsInvoicePayment()?.getPaymentSecret()
4646
let spontaneousPayment = paymentClaimable.getPurpose().getValueAsSpontaneousPayment()
4747

48+
let body: [String: Encodable] = [
49+
"payment_hash": Data(paymentClaimable.getPaymentHash()).hexEncodedString(),
50+
"amount_sat": paymentClaimable.getAmountMsat() / 1000,
51+
"payment_preimage": Data(paymentPreimage ?? []).hexEncodedString(),
52+
"payment_secret": Data(paymentSecret ?? []).hexEncodedString(),
53+
"spontaneous_payment_preimage": Data(spontaneousPayment ?? []).hexEncodedString(),
54+
"unix_timestamp": Int(Date().timeIntervalSince1970),
55+
"confirmed": false
56+
]
57+
4858
LdkEventEmitter.shared.send(
4959
withEvent: .channel_manager_payment_claimable,
50-
body: [
51-
"payment_hash": Data(paymentClaimable.getPaymentHash()).hexEncodedString(),
52-
"amount_sat": paymentClaimable.getAmountMsat() / 1000,
53-
"payment_preimage": Data(paymentPreimage ?? []).hexEncodedString(),
54-
"payment_secret": Data(paymentSecret ?? []).hexEncodedString(),
55-
"spontaneous_payment_preimage": Data(spontaneousPayment ?? []).hexEncodedString(),
56-
]
60+
body: body
5761
)
62+
63+
//Save to disk for TX history
64+
persistPaymentClaimed(body)
5865
return
5966
case .PaymentSent:
6067
guard let paymentSent = event.getValueAsPaymentSent() else {
@@ -200,7 +207,8 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
200207
"payment_preimage": Data(paymentPreimage ?? []).hexEncodedString(),
201208
"payment_secret": Data(paymentSecret ?? []).hexEncodedString(),
202209
"spontaneous_payment_preimage": Data(spontaneousPayment ?? []).hexEncodedString(),
203-
"unix_timestamp": Int(Date().timeIntervalSince1970)
210+
"unix_timestamp": Int(Date().timeIntervalSince1970),
211+
"confirmed": true
204212
]
205213

206214
LdkEventEmitter.shared.send(
@@ -270,21 +278,36 @@ class LdkChannelManagerPersister: Persister, ExtendedChannelManagerPersister {
270278
return
271279
}
272280

273-
var newContent: [[String: Any]] = []
281+
var payments: [[String: Any]] = []
274282

275283
do {
276284
if FileManager.default.fileExists(atPath: claimedPaymentsStorage.path) {
277285
let data = try Data(contentsOf: URL(fileURLWithPath: claimedPaymentsStorage.path), options: .mappedIfSafe)
278286

279287
if let existingContent = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
280-
newContent = existingContent
288+
payments = existingContent
281289
} else {
282290
LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error could not read existing claimed payments")
283291
}
284292
}
285293

286-
newContent.append(payment)
287-
guard let jsonData = try? JSONSerialization.data(withJSONObject: newContent, options: []) else {
294+
//Replace entry if payment hash exists (Confirmed payment replacing pending)
295+
var paymentReplaced = false
296+
for (index, existingPayment) in payments.enumerated() {
297+
if let existingPaymentHash = existingPayment["payment_hash"] as? String, let newPaymentHash = payment["payment_hash"] as? String {
298+
if existingPaymentHash == newPaymentHash {
299+
payments[index] = payment
300+
paymentReplaced = true
301+
}
302+
}
303+
}
304+
305+
//No existing payment found, append as new payment
306+
if !paymentReplaced {
307+
payments.append(payment)
308+
}
309+
310+
guard let jsonData = try? JSONSerialization.data(withJSONObject: payments, options: []) else {
288311
LdkEventEmitter.shared.send(withEvent: .native_log, body: "Error could not serialize claimed payments")
289312
return
290313
}

lib/src/utils/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export type TChannelManagerClaim = {
5555
payment_secret: string;
5656
spontaneous_payment_preimage: string;
5757
unix_timestamp: number;
58+
confirmed: boolean;
5859
};
5960

6061
export type TChannelManagerPaymentSent = {

0 commit comments

Comments
 (0)