@@ -20,6 +20,7 @@ import (
2020 "github.com/lightninglabs/loop/looprpc"
2121 "github.com/lightninglabs/loop/staticaddr/address"
2222 "github.com/lightninglabs/loop/staticaddr/deposit"
23+ "github.com/lightninglabs/loop/staticaddr/loopin"
2324 "github.com/lightninglabs/loop/staticaddr/script"
2425 "github.com/lightninglabs/loop/swap"
2526 mock_lnd "github.com/lightninglabs/loop/test"
@@ -306,6 +307,72 @@ func TestSetLiquidityParamsRejectsStaticAutoloopWithoutExperimental(
306307 require .ErrorContains (t , err , "--experimental" )
307308}
308309
310+ // TestStaticAddressLoopInTimestamp verifies that zero timestamps are omitted
311+ // from static loop-in responses instead of passing a zero time to UnixNano.
312+ func TestStaticAddressLoopInTimestamp (t * testing.T ) {
313+ require .Zero (t , staticAddressLoopInTimestamp (time.Time {}))
314+
315+ timestamp := time .Unix (1_234 , 567 ).UTC ()
316+ require .Equal (
317+ t , timestamp .UnixNano (),
318+ staticAddressLoopInTimestamp (timestamp ),
319+ )
320+ }
321+
322+ // TestStaticAddressLoopInSwapServerCost verifies that static loop-in server
323+ // costs are only reported once the invoice payment was received. Timeout path
324+ // costs are not persisted today, so they are intentionally not estimated here.
325+ func TestStaticAddressLoopInSwapServerCost (t * testing.T ) {
326+ const quoteFee = btcutil .Amount (1_234 )
327+
328+ tests := []struct {
329+ name string
330+ state fsm.StateType
331+ wantServer int64
332+ }{
333+ {
334+ name : "pending before payment" ,
335+ state : loopin .SignHtlcTx ,
336+ },
337+ {
338+ name : "payment received" ,
339+ state : loopin .PaymentReceived ,
340+ wantServer : int64 (quoteFee ),
341+ },
342+ {
343+ name : "succeeded" ,
344+ state : loopin .Succeeded ,
345+ wantServer : int64 (quoteFee ),
346+ },
347+ {
348+ name : "succeeded transition failed" ,
349+ state : loopin .SucceededTransitioningFailed ,
350+ wantServer : int64 (quoteFee ),
351+ },
352+ {
353+ name : "timeout swept" ,
354+ state : loopin .HtlcTimeoutSwept ,
355+ },
356+ {
357+ name : "failed" ,
358+ state : loopin .Failed ,
359+ },
360+ }
361+
362+ for _ , test := range tests {
363+ t .Run (test .name , func (t * testing.T ) {
364+ swap := & loopin.StaticAddressLoopIn {
365+ QuotedSwapFee : quoteFee ,
366+ }
367+ swap .SetState (test .state )
368+
369+ costServer := staticAddressLoopInSwapServerCost (swap )
370+
371+ require .Equal (t , test .wantServer , costServer )
372+ })
373+ }
374+ }
375+
309376// TestRPCAutoloopReasonStaticLoopInNoCandidate verifies that the new planner
310377// reason is exposed over rpc.
311378func TestRPCAutoloopReasonStaticLoopInNoCandidate (t * testing.T ) {
0 commit comments