11package com.reactnativeldk.classes
22
33import com.facebook.react.bridge.Arguments
4+ import com.facebook.react.bridge.WritableMap
45import com.reactnativeldk.*
6+ import org.json.JSONArray
57import org.ldk.batteries.ChannelManagerConstructor
68import org.ldk.structs.Event
79import org.ldk.structs.Option_u64Z
@@ -30,6 +32,10 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
3032 (paymentClaimable.purpose as ? PaymentPurpose .SpontaneousPayment )?.let {
3133 body.putHexString(" spontaneous_payment_preimage" , it.spontaneous_payment)
3234 }
35+ body.putInt(" unix_timestamp" , (System .currentTimeMillis() / 1000 ).toInt())
36+ body.putString(" state" , " pending" )
37+
38+ persistPaymentClaimed(body)
3339 return LdkEventEmitter .send(EventTypes .channel_manager_payment_claimable, body)
3440 }
3541
@@ -39,6 +45,11 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
3945 body.putHexString(" payment_preimage" , paymentSent.payment_preimage)
4046 body.putHexString(" payment_hash" , paymentSent.payment_hash)
4147 body.putInt(" fee_paid_sat" , (paymentSent.fee_paid_msat as Option_u64Z .Some ).some.toInt() / 1000 )
48+ body.putInt(" unix_timestamp" , (System .currentTimeMillis() / 1000 ).toInt())
49+ body.putString(" state" , " successful" )
50+
51+ persistPaymentSent(body.toHashMap())
52+
4253 return LdkEventEmitter .send(EventTypes .channel_manager_payment_sent, body)
4354 }
4455
@@ -76,13 +87,30 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
7687// paymentPathFailed.path.iterator().forEach { path.pushMap(it.asJson) }
7788// body.putArray("path_hops", path)
7889
90+ if (paymentPathFailed.payment_id != null ) {
91+ persistPaymentSent(hashMapOf(
92+ " payment_id" to paymentPathFailed.payment_id!! .hexEncodedString(),
93+ " payment_hash" to paymentPathFailed.payment_hash.hexEncodedString(),
94+ " unix_timestamp" to (System .currentTimeMillis() / 1000 ).toInt(),
95+ " state" to if (paymentPathFailed.payment_failed_permanently) " failed" else " pending"
96+ ))
97+ }
98+
7999 return LdkEventEmitter .send(EventTypes .channel_manager_payment_path_failed, body)
80100 }
81101
82102 (event as ? Event .PaymentFailed )?.let { paymentFailed ->
83103 val body = Arguments .createMap()
84104 body.putHexString(" payment_id" , paymentFailed.payment_id)
85105 body.putHexString(" payment_hash" , paymentFailed.payment_hash)
106+
107+ persistPaymentSent(hashMapOf(
108+ " payment_id" to paymentFailed.payment_id!! .hexEncodedString(),
109+ " payment_hash" to paymentFailed.payment_hash.hexEncodedString(),
110+ " unix_timestamp" to (System .currentTimeMillis() / 1000 ).toInt(),
111+ " state" to " failed"
112+ ))
113+
86114 return LdkEventEmitter .send(EventTypes .channel_manager_payment_failed, body)
87115 }
88116
@@ -132,6 +160,10 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
132160 (paymentClaimed.purpose as ? PaymentPurpose .SpontaneousPayment )?.let {
133161 body.putHexString(" spontaneous_payment_preimage" , it.spontaneous_payment)
134162 }
163+ body.putInt(" unix_timestamp" , (System .currentTimeMillis() / 1000 ).toInt())
164+ body.putString(" state" , " successful" )
165+
166+ persistPaymentClaimed(body)
135167 return LdkEventEmitter .send(EventTypes .channel_manager_payment_claimed, body)
136168 }
137169 }
@@ -159,4 +191,89 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
159191 LdkEventEmitter .send(EventTypes .native_log, " Persisted scorer to disk" )
160192 }
161193 }
194+
195+ private fun persistPaymentClaimed (payment : WritableMap ) {
196+ if (LdkModule .accountStoragePath == " " ) {
197+ LdkEventEmitter .send(EventTypes .native_log, " Error. Failed to persist claimed payment to disk (No set storage)" )
198+ return
199+ }
200+
201+ var payments: Array <HashMap <String , Any >> = arrayOf()
202+ var paymentReplaced = false
203+
204+ try {
205+ if (File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsClaimed.fileName).exists()) {
206+ val data = File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsClaimed.fileName).readBytes()
207+ val existingPayments = JSONArray (String (data))
208+ for (i in 0 until existingPayments.length()) {
209+ val existingPayment = existingPayments.getJSONObject(i)
210+ // Replace entry if payment hash exists (Confirmed payment replacing pending)
211+ if (existingPayment.getString(" payment_hash" ) == payment.getString(" payment_hash" )) {
212+ payments[i] = mergeObj(existingPayment, payment.toHashMap())
213+ paymentReplaced = true
214+ continue
215+ }
216+
217+ val map = HashMap <String , Any >()
218+ for (key in existingPayment.keys()) {
219+ map[key] = existingPayments.getJSONObject(i).get(key)
220+ }
221+
222+ payments = payments.plus(map)
223+ }
224+ }
225+ } catch (e: Exception ) {
226+ LdkEventEmitter .send(EventTypes .native_log, " Error could not read existing claimed payments" )
227+ }
228+
229+ // No existing payment found, append as new payment
230+ if (! paymentReplaced) {
231+ payments = payments.plus(payment.toHashMap())
232+ }
233+
234+ File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsClaimed.fileName).writeText(JSONArray (payments).toString())
235+ }
236+
237+ fun persistPaymentSent (payment : HashMap <String , Any >) {
238+ if (LdkModule .accountStoragePath == " " ) {
239+ LdkEventEmitter .send(EventTypes .native_log, " Error. Failed to persist sent payment to disk (No set storage)" )
240+ return
241+ }
242+
243+ var payments: Array <HashMap <String , Any >> = arrayOf()
244+ var paymentReplaced = false
245+
246+ try {
247+ if (File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsSent.fileName).exists()) {
248+ val data = File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsSent.fileName).readBytes()
249+ val existingPayments = JSONArray (String (data))
250+ for (i in 0 until existingPayments.length()) {
251+ val existingPayment = existingPayments.getJSONObject(i)
252+ // Replace entry if payment ID exists (Confirmed payment replacing pending)
253+ if (existingPayment.getString(" payment_id" ) == payment[" payment_id" ]) {
254+ var merged = mergeObj(existingPayment, payment)
255+ payments = payments.plus(merged)
256+ paymentReplaced = true
257+ continue
258+ }
259+
260+ val map = HashMap <String , Any >()
261+ for (key in existingPayment.keys()) {
262+ map[key] = existingPayment.get(key)
263+ }
264+
265+ payments = payments.plus(map)
266+ }
267+ }
268+ } catch (e: Exception ) {
269+ LdkEventEmitter .send(EventTypes .native_log, " Error could not read existing sent payments" )
270+ }
271+
272+ // No existing payment found, append as new payment
273+ if (! paymentReplaced) {
274+ payments = payments.plus(payment)
275+ }
276+
277+ File (LdkModule .accountStoragePath + " /" + LdkFileNames .paymentsSent.fileName).writeText(JSONArray (payments).toString())
278+ }
162279}
0 commit comments