Skip to content

Commit 8c53d4f

Browse files
committed
Add python integration test for spontaneous keysend payments
this commit adds the test_spontaneous_payment method which : - sets up two nodes in regtest environment, funds them, and opens channel - Arbitrary sends a 2.5M msat keysend with a custom TLV record - Asserts PAYMENT_SUCCESSFUL / PAYMENT_RECEIVED events - verify payment details Shared helpers (_setup_two_nodes, _fund_nodes, _open_channel_and_wait_ready, _stop_and_cleanup) reduce duplication for future integration
1 parent 47dad6d commit 8c53d4f

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

bindings/python/src/ldk_node/test_ldk_node.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,95 @@ def setUp(self):
130130
esplora_endpoint = get_esplora_endpoint()
131131
mine_and_wait(esplora_endpoint, 1)
132132

133+
def _setup_two_nodes(self, esplora_endpoint):
134+
tmp_dir_1 = tempfile.TemporaryDirectory("_ldk_node_1")
135+
listening_addresses_1 = ["127.0.0.1:2323"]
136+
node_1 = setup_node(tmp_dir_1.name, esplora_endpoint, listening_addresses_1)
137+
node_1.start()
138+
node_id_1 = node_1.node_id()
139+
140+
tmp_dir_2 = tempfile.TemporaryDirectory("_ldk_node_2")
141+
listening_addresses_2 = ["127.0.0.1:2324"]
142+
node_2 = setup_node(tmp_dir_2.name, esplora_endpoint, listening_addresses_2)
143+
node_2.start()
144+
node_id_2 = node_2.node_id()
145+
146+
return node_1, node_2, tmp_dir_1, tmp_dir_2, node_id_1, node_id_2, listening_addresses_2
147+
148+
def _fund_nodes(self, node_1, node_2, esplora_endpoint, amount_sats=100000):
149+
address_1 = node_1.onchain_payment().new_address()
150+
txid_1 = send_to_address(address_1, amount_sats)
151+
address_2 = node_2.onchain_payment().new_address()
152+
txid_2 = send_to_address(address_2, amount_sats)
153+
154+
wait_for_tx(esplora_endpoint, txid_1)
155+
wait_for_tx(esplora_endpoint, txid_2)
156+
mine_and_wait(esplora_endpoint, 6)
157+
158+
node_1.sync_wallets()
159+
node_2.sync_wallets()
160+
161+
def _open_channel_and_wait_ready(self, node_1, node_2, node_id_2, listening_address_2, esplora_endpoint, channel_amount_sats=50000):
162+
node_1.open_channel(node_id_2, listening_address_2, channel_amount_sats, None, None)
163+
164+
channel_pending_event_1 = expect_event(node_1, Event.CHANNEL_PENDING)
165+
expect_event(node_2, Event.CHANNEL_PENDING)
166+
167+
funding_txid = channel_pending_event_1.funding_txo.txid
168+
wait_for_tx(esplora_endpoint, funding_txid)
169+
mine_and_wait(esplora_endpoint, 6)
170+
171+
node_1.sync_wallets()
172+
node_2.sync_wallets()
173+
174+
channel_ready_event_1 = expect_event(node_1, Event.CHANNEL_READY)
175+
channel_ready_event_2 = expect_event(node_2, Event.CHANNEL_READY)
176+
return channel_ready_event_1, channel_ready_event_2, funding_txid
177+
178+
def _stop_and_cleanup(self, node_1, node_2, tmp_dir_1, tmp_dir_2):
179+
node_1.stop()
180+
node_2.stop()
181+
time.sleep(1)
182+
tmp_dir_1.cleanup()
183+
tmp_dir_2.cleanup()
184+
185+
def test_spontaneous_payment(self):
186+
"""Spontaneous payment test in python: keysend after channel ready."""
187+
esplora_endpoint = get_esplora_endpoint()
188+
189+
node_1, node_2, tmp_dir_1, tmp_dir_2, node_id_1, node_id_2, listening_addresses_2 = self._setup_two_nodes(esplora_endpoint)
190+
self._fund_nodes(node_1, node_2, esplora_endpoint)
191+
self._open_channel_and_wait_ready(node_1, node_2, node_id_2, listening_addresses_2[0], esplora_endpoint)
192+
193+
keysend_amount_msat = 2_500_000
194+
custom_tlvs = [CustomTlvRecord(type_num=13377331, value=bytes([1, 2, 3]))]
195+
keysend_payment_id = node_1.spontaneous_payment().send_with_custom_tlvs(
196+
keysend_amount_msat, node_id_2, None, custom_tlvs
197+
)
198+
199+
expect_event(node_1, Event.PAYMENT_SUCCESSFUL)
200+
received_event = expect_event(node_2, Event.PAYMENT_RECEIVED)
201+
202+
self.assertEqual(received_event.amount_msat, keysend_amount_msat)
203+
self.assertEqual(received_event.custom_records, custom_tlvs)
204+
205+
sender_payment = node_1.payment(keysend_payment_id)
206+
receiver_payment = node_2.payment(keysend_payment_id)
207+
208+
self.assertIsNotNone(sender_payment)
209+
self.assertIsNotNone(receiver_payment)
210+
self.assertEqual(sender_payment.status, PaymentStatus.SUCCEEDED)
211+
self.assertEqual(sender_payment.direction, PaymentDirection.OUTBOUND)
212+
self.assertEqual(sender_payment.amount_msat, keysend_amount_msat)
213+
self.assertTrue(sender_payment.kind.is_spontaneous())
214+
215+
self.assertEqual(receiver_payment.status, PaymentStatus.SUCCEEDED)
216+
self.assertEqual(receiver_payment.direction, PaymentDirection.INBOUND)
217+
self.assertEqual(receiver_payment.amount_msat, keysend_amount_msat)
218+
self.assertTrue(receiver_payment.kind.is_spontaneous())
219+
220+
self._stop_and_cleanup(node_1, node_2, tmp_dir_1, tmp_dir_2)
221+
133222
def test_channel_full_cycle(self):
134223
esplora_endpoint = get_esplora_endpoint()
135224

0 commit comments

Comments
 (0)