@@ -4,13 +4,16 @@ import (
44 "bytes"
55 "context"
66 "fmt"
7+ "math"
78 "net/url"
9+ "slices"
810 "sync"
911 "sync/atomic"
1012
1113 "github.com/btcsuite/btcd/btcec/v2"
1214 "github.com/btcsuite/btcd/btcec/v2/schnorr"
1315 "github.com/btcsuite/btcd/btcutil"
16+ "github.com/btcsuite/btcd/txscript"
1417 "github.com/btcsuite/btcd/wire"
1518 "github.com/davecgh/go-spew/spew"
1619 "github.com/lightninglabs/taproot-assets/address"
@@ -26,6 +29,7 @@ import (
2629 lfn "github.com/lightningnetwork/lnd/fn"
2730 "github.com/lightningnetwork/lnd/input"
2831 "github.com/lightningnetwork/lnd/keychain"
32+ "github.com/lightningnetwork/lnd/lntypes"
2933 "github.com/lightningnetwork/lnd/lnwallet"
3034 "github.com/lightningnetwork/lnd/lnwire"
3135 "github.com/lightningnetwork/lnd/sweep"
@@ -322,12 +326,14 @@ func (a *AuxSweeper) createSweepVpackets(sweepInputs []*cmsg.AssetOutput,
322326// signSweepVpackets attempts to sign the vPackets specified using the passed
323327// sign desc and script tree.
324328func (a * AuxSweeper ) signSweepVpackets (vPackets []* tappsbt.VPacket ,
325- signDesc input.SignDescriptor , tapscriptDesc tapscriptSweepDesc ) error {
329+ signDesc input.SignDescriptor , tapTweak , ctrlBlock []byte ,
330+ auxSigDesc lfn.Option [lnwallet.AuxSigDesc ],
331+ secondLevelSigIndex lfn.Option [uint32 ]) error {
326332
327333 // Before we sign below, we also need to generate the tapscript With
328334 // the vPackets prepared, we can now sign the output asset we'll create
329335 // at a later step.
330- for _ , vPacket := range vPackets {
336+ for vPktIndex , vPacket := range vPackets {
331337 if len (vPacket .Inputs ) != 1 {
332338 return fmt .Errorf ("expected single input, got %v" ,
333339 len (vPacket .Inputs ))
@@ -343,12 +349,12 @@ func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
343349 // signature.
344350 signingKey , leafToSign := applySignDescToVIn (
345351 signDesc , vIn , & a .cfg .ChainParams ,
346- tapscriptDesc . scriptTree . TapTweak () ,
352+ tapTweak ,
347353 )
348354
349355 // In this case, the witness isn't special, so we'll set the
350356 // control block now for it.
351- ctrlBlock := tapscriptDesc . ctrlBlockBytes
357+ ctrlBlock := ctrlBlock
352358 vIn .TaprootLeafScript [0 ].ControlBlock = ctrlBlock
353359
354360 log .Debugf ("signing vPacket for input=%v" ,
@@ -373,6 +379,50 @@ func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
373379 return fmt .Errorf ("error signing virtual packet, " +
374380 "got no sig" )
375381 }
382+
383+ // At this point, the witness looks like: <sig> <witnessScript>
384+ // <ctrlBlock>. If, This is a second level transaction, so we
385+ // have another signature that we need to add to the witness
386+ // this additional signature for the multi-sig.
387+ err = lfn .MapOptionZ (
388+ auxSigDesc ,
389+ func (aux lnwallet.AuxSigDesc ) error {
390+ assetSigs , err := cmsg .DecodeAssetSigListRecord (
391+ aux .AuxSig ,
392+ )
393+ if err != nil {
394+ return fmt .Errorf ("error " +
395+ "decoding asset sig list " +
396+ "record: %w" , err )
397+ }
398+ auxSig := assetSigs .Sigs [vPktIndex ]
399+
400+ // With the sig obtained, we'll now insert the
401+ // signature are the specified index.
402+ sigIndex , err := secondLevelSigIndex .UnwrapOrErr (
403+ fmt .Errorf ("no sig index" ),
404+ )
405+ if err != nil {
406+ return err
407+ }
408+
409+ auxSigBytes := append (
410+ auxSig .Sig .Val .RawBytes (),
411+ byte (auxSig .SigHashType .Val ),
412+ )
413+
414+ prevWitness := vIn .Asset ().PrevWitnesses [0 ].TxWitness
415+ vIn .Asset ().PrevWitnesses [0 ].TxWitness = slices .Insert (
416+ prevWitness , int (sigIndex ),
417+ auxSigBytes ,
418+ )
419+
420+ return nil
421+ },
422+ )
423+ if err != nil {
424+ return err
425+ }
376426 }
377427
378428 return nil
0 commit comments