@@ -62,3 +62,82 @@ async fn invoice() {
6262 . await ;
6363 assert ! ( res. is_ok( ) ) ;
6464}
65+
66+ #[ serial_test:: serial]
67+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
68+ #[ traced_test]
69+ async fn zero_amount_invoice ( ) {
70+ initialize ( ) ;
71+
72+ let test_dir_base = format ! ( "{TEST_DIR_BASE}zero_amount/" ) ;
73+ let test_dir_node1 = format ! ( "{test_dir_base}node1" ) ;
74+ let test_dir_node2 = format ! ( "{test_dir_base}node2" ) ;
75+ let ( node1_addr, _) = start_node ( & test_dir_node1, NODE1_PEER_PORT , false ) . await ;
76+ let ( node2_addr, _) = start_node ( & test_dir_node2, NODE2_PEER_PORT , false ) . await ;
77+
78+ fund_and_create_utxos ( node1_addr, None ) . await ;
79+ fund_and_create_utxos ( node2_addr, None ) . await ;
80+
81+ let node2_pubkey = node_info ( node2_addr) . await . pubkey ;
82+
83+ // Open a channel between node1 and node2
84+ open_channel (
85+ node1_addr,
86+ & node2_pubkey,
87+ Some ( NODE2_PEER_PORT ) ,
88+ None ,
89+ None ,
90+ None ,
91+ None ,
92+ )
93+ . await ;
94+
95+ // Create a zero-amount invoice on node2
96+ println ! ( "Creating zero-amount invoice on node {node2_addr}" ) ;
97+ let payload = LNInvoiceRequest {
98+ amt_msat : None ,
99+ expiry_sec : 900 ,
100+ asset_id : None ,
101+ asset_amount : None ,
102+ } ;
103+ let res = reqwest:: Client :: new ( )
104+ . post ( format ! ( "http://{node2_addr}/lninvoice" ) )
105+ . json ( & payload)
106+ . send ( )
107+ . await
108+ . unwrap ( )
109+ . json :: < LNInvoiceResponse > ( )
110+ . await
111+ . unwrap ( ) ;
112+ let invoice = res. invoice ;
113+
114+ // Decode the invoice to verify it's zero-amount
115+ let decoded = decode_ln_invoice ( node1_addr, & invoice) . await ;
116+ assert_eq ! ( decoded. amt_msat, None , "Invoice should have no amount" ) ;
117+
118+ // Pay the zero-amount invoice with a specific amount (5000 msat)
119+ let payment_amount = 5000u64 ;
120+ println ! ( "Paying zero-amount invoice from node {node1_addr} with amount {payment_amount}" ) ;
121+ let payload = SendPaymentRequest {
122+ invoice : invoice. clone ( ) ,
123+ amt_msat : Some ( payment_amount) ,
124+ } ;
125+ let res = reqwest:: Client :: new ( )
126+ . post ( format ! ( "http://{node1_addr}/sendpayment" ) )
127+ . json ( & payload)
128+ . send ( )
129+ . await
130+ . unwrap ( ) ;
131+
132+ // Check that the payment succeeded
133+ let status_code = res. status ( ) ;
134+ let response_text = res. text ( ) . await . unwrap ( ) ;
135+ assert_eq ! (
136+ status_code,
137+ reqwest:: StatusCode :: OK ,
138+ "Payment should succeed. Response: {response_text}"
139+ ) ;
140+
141+ // Wait for payment to complete
142+ wait_for_ln_payment ( node1_addr, & decoded. payment_hash , HTLCStatus :: Succeeded ) . await ;
143+ }
0 commit comments