@@ -7,8 +7,10 @@ import com.lightspark.sdk.crypto.PasswordRecoverySigningKeyLoader
77import com.lightspark.sdk.model.Account
88import com.lightspark.sdk.model.BitcoinNetwork
99import com.lightspark.sdk.model.IncomingPayment
10+ import com.lightspark.sdk.model.Invoice
1011import com.lightspark.sdk.model.LightsparkNode
1112import com.lightspark.sdk.model.OutgoingPayment
13+ import com.lightspark.sdk.model.PaymentRequestStatus
1214import com.lightspark.sdk.model.Transaction
1315import com.lightspark.sdk.model.TransactionStatus
1416import com.lightspark.sdk.model.WithdrawalMode
@@ -28,6 +30,7 @@ import kotlinx.datetime.TimeZone
2830import kotlinx.datetime.minus
2931import org.mockito.Mockito.spy
3032import org.mockito.Mockito.`when`
33+ import java.security.MessageDigest
3134import kotlin.random.Random
3235
3336@OptIn(ExperimentalCoroutinesApi ::class )
@@ -363,6 +366,31 @@ class ClientIntegrationTests {
363366 println (hashedUmaNewMonth)
364367 }
365368
369+ @Test
370+ fun `create and settle a hold invoice` () = runTest {
371+ val nodeA = getFirstOskNode()
372+ val nodeB = getSecondOskNode()
373+ val preimage = generateRandomHexString()
374+ val paymentHash = sha256Hash(preimage)
375+ var invoice = client.createInvoice(nodeA.id, 1000 , paymentHash = paymentHash)
376+
377+ println (" encoded invoice: $invoice .data.encodedPaymentRequest}" )
378+
379+ client.loadNodeSigningKey(nodeB.id, PasswordRecoverySigningKeyLoader (nodeB.id, NODE_PASSWORD ))
380+ val outgoingPayment = client.payInvoice(nodeB.id, invoice.data.encodedPaymentRequest, maxFeesMsats = 100_000 )
381+ outgoingPayment.shouldNotBeNull()
382+
383+ println (" outgoing payment: $outgoingPayment " )
384+
385+ // client.releasePaymentPreimage(invoice.id, preimage)
386+ while (invoice.status == PaymentRequestStatus .OPEN ) {
387+ delay(500 )
388+ invoice = Invoice .getInvoiceQuery(invoice.id).execute(client)!!
389+ invoice.shouldNotBeNull()
390+ println (" Invoice status: ${invoice.status} " )
391+ }
392+ }
393+
366394 // TODO: Add tests for withdrawals and deposits.
367395
368396 private suspend fun getFirstOskNode (): LightsparkNode {
@@ -373,6 +401,14 @@ class ClientIntegrationTests {
373401 return nodes.entities.first { it.id.contains(" OSK" ) }
374402 }
375403
404+ private suspend fun getSecondOskNode (): LightsparkNode {
405+ val account = getCurrentAccount()
406+ val nodes = account.getNodesQuery().execute(client)
407+ nodes.shouldNotBeNull()
408+ nodes.entities.shouldNotBeEmpty()
409+ return nodes.entities.get(1 )
410+ }
411+
376412 private suspend fun getNodeId (): String {
377413 return getFirstOskNode().id
378414 }
@@ -382,4 +418,17 @@ class ClientIntegrationTests {
382418 account.shouldNotBeNull()
383419 return account
384420 }
421+
422+ private fun sha256Hash (input : String ): String {
423+ val bytes = input.toByteArray()
424+ val digest = MessageDigest .getInstance(" SHA-256" ).digest(bytes)
425+ return digest.joinToString(" " ) { " %02x" .format(it) }
426+ }
427+
428+ private fun generateRandomHexString (): String {
429+ val allowedChars = (' a' .. ' f' ) + (' 0' .. ' 9' )
430+ return (1 .. 64 )
431+ .map { allowedChars.random(Random .Default ) }
432+ .joinToString(" " )
433+ }
385434}
0 commit comments