@@ -380,7 +380,39 @@ func (m *Manager) createFinalizedWithdrawalTx(ctx context.Context,
380380 ).FeePerKWeight ()
381381 }
382382
383+ // We'll now check the selected fee rate leaves a withdrawal output that
384+ // is above the dust limit. If not we cancel the withdrawal instead of
385+ // requesting a signature from the server.
386+ addressParams , err := m .cfg .AddressManager .GetStaticAddressParameters (
387+ ctx ,
388+ )
389+ if err != nil {
390+ return nil , fmt .Errorf ("couldn't get confirmation height for " +
391+ "deposit, %w" , err )
392+ }
393+
394+ // Calculate the fee value in satoshis.
383395 outpoints := toOutpoints (deposits )
396+ weight , err := withdrawalFee (len (outpoints ), withdrawalAddress )
397+ if err != nil {
398+ return nil , err
399+ }
400+ feeValue := withdrawalSweepFeeRate .FeeForWeight (weight )
401+
402+ var (
403+ prevOuts = m .toPrevOuts (deposits , addressParams .PkScript )
404+ totalValue = withdrawalValue (prevOuts )
405+ outputValue = int64 (totalValue ) - int64 (feeValue )
406+ // P2TRSize calculates a dust limit based on a 40 byte maximum
407+ // size witness output.
408+ dustLimit = lnwallet .DustLimitForSize (input .P2TRSize )
409+ )
410+
411+ if outputValue < int64 (dustLimit ) {
412+ return nil , fmt .Errorf ("withdrawal output value %d sats " +
413+ "below dust limit %d sats" , outputValue , dustLimit )
414+ }
415+
384416 resp , err := m .cfg .StaticAddressServerClient .ServerWithdrawDeposits (
385417 ctx , & staticaddressrpc.ServerWithdrawRequest {
386418 Outpoints : toPrevoutInfo (outpoints ),
@@ -393,19 +425,9 @@ func (m *Manager) createFinalizedWithdrawalTx(ctx context.Context,
393425 return nil , err
394426 }
395427
396- addressParams , err := m .cfg .AddressManager .GetStaticAddressParameters (
397- ctx ,
398- )
399- if err != nil {
400- return nil , fmt .Errorf ("couldn't get confirmation height for " +
401- "deposit, %w" , err )
402- }
403-
404- prevOuts := m .toPrevOuts (deposits , addressParams .PkScript )
405- totalValue := withdrawalValue (prevOuts )
428+ withdrawalOutputValue := int64 (totalValue - feeValue )
406429 withdrawalTx , err := m .createWithdrawalTx (
407- outpoints , totalValue , withdrawalAddress ,
408- withdrawalSweepFeeRate ,
430+ outpoints , withdrawalOutputValue , withdrawalAddress ,
409431 )
410432 if err != nil {
411433 return nil , err
@@ -613,9 +635,8 @@ func byteSliceTo66ByteSlice(b []byte) ([musig2.PubNonceSize]byte, error) {
613635}
614636
615637func (m * Manager ) createWithdrawalTx (outpoints []wire.OutPoint ,
616- withdrawlAmount btcutil.Amount , clientSweepAddress btcutil.Address ,
617- feeRate chainfee.SatPerKWeight ) (* wire.MsgTx ,
618- error ) {
638+ withdrawlOutputValue int64 , clientSweepAddress btcutil.Address ) (
639+ * wire.MsgTx , error ) {
619640
620641 // First Create the tx.
621642 msgTx := wire .NewMsgTx (2 )
@@ -628,22 +649,14 @@ func (m *Manager) createWithdrawalTx(outpoints []wire.OutPoint,
628649 })
629650 }
630651
631- // Estimate the fee.
632- weight , err := withdrawalFee (len (outpoints ), clientSweepAddress )
633- if err != nil {
634- return nil , err
635- }
636-
637652 pkscript , err := txscript .PayToAddrScript (clientSweepAddress )
638653 if err != nil {
639654 return nil , err
640655 }
641656
642- fee := feeRate .FeeForWeight (weight )
643-
644657 // Create the sweep output
645658 sweepOutput := & wire.TxOut {
646- Value : int64 ( withdrawlAmount ) - int64 ( fee ) ,
659+ Value : withdrawlOutputValue ,
647660 PkScript : pkscript ,
648661 }
649662
0 commit comments