@@ -18,6 +18,7 @@ import (
1818 "github.com/btcsuite/btcd/btcec/v2/schnorr"
1919 "github.com/btcsuite/btcd/btcutil/psbt"
2020 "github.com/btcsuite/btcd/chaincfg/chainhash"
21+ "github.com/btcsuite/btcd/txscript"
2122 "github.com/btcsuite/btcd/wire"
2223 "github.com/davecgh/go-spew/spew"
2324 proxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
@@ -515,12 +516,44 @@ func (r *rpcServer) FinalizeBatch(_ context.Context,
515516 req * mintrpc.FinalizeBatchRequest ) (* mintrpc.FinalizeBatchResponse ,
516517 error ) {
517518
519+ var batchSibling * asset.TapscriptTreeNodes
520+
518521 feeRate , err := checkFeeRateSanity (req .FeeRate )
519522 if err != nil {
520523 return nil , err
521524 }
525+ feeRateOpt := fn .MaybeSome (feeRate )
526+
527+ batchTapscriptTree := req .GetFullTree ()
528+ batchTapBranch := req .GetBranch ()
529+
530+ switch {
531+ case batchTapscriptTree != nil && batchTapBranch != nil :
532+ return nil , fmt .Errorf ("cannot specify both tapscript tree " +
533+ "and tapscript tree branches" )
534+
535+ case batchTapscriptTree != nil :
536+ batchSibling , err = marshalTapscriptFullTree (batchTapscriptTree )
537+ if err != nil {
538+ return nil , fmt .Errorf ("invalid tapscript tree: %w" ,
539+ err )
540+ }
541+
542+ case batchTapBranch != nil :
543+ batchSibling , err = marshalTapscriptBranch (batchTapBranch )
544+ if err != nil {
545+ return nil , fmt .Errorf ("invalid tapscript branch: %w" ,
546+ err )
547+ }
548+ }
549+ tapTreeOpt := fn .MaybeSome (batchSibling )
522550
523- batch , err := r .cfg .AssetMinter .FinalizeBatch (feeRate )
551+ batch , err := r .cfg .AssetMinter .FinalizeBatch (
552+ tapgarden.FinalizeParams {
553+ FeeRate : feeRateOpt ,
554+ SiblingTapTree : tapTreeOpt ,
555+ },
556+ )
524557 if err != nil {
525558 return nil , fmt .Errorf ("unable to finalize batch: %w" , err )
526559 }
@@ -2917,6 +2950,29 @@ func marshalBatchState(batch *tapgarden.MintingBatch) (mintrpc.BatchState,
29172950 }
29182951}
29192952
2953+ func marshalTapscriptFullTree (tree * taprpc.TapscriptFullTree ) (
2954+ * asset.TapscriptTreeNodes , error ) {
2955+
2956+ rpcLeaves := tree .GetAllLeaves ()
2957+ leaves := fn .Map (rpcLeaves , func (l * taprpc.TapLeaf ) txscript.TapLeaf {
2958+ return txscript .NewBaseTapLeaf (l .Script )
2959+ })
2960+
2961+ return asset .TapTreeNodesFromLeaves (leaves )
2962+ }
2963+
2964+ func marshalTapscriptBranch (branch * taprpc.TapBranch ) (* asset.TapscriptTreeNodes ,
2965+ error ) {
2966+
2967+ branchData := [][]byte {branch .LeftTaphash , branch .RightTaphash }
2968+ tapBranch , err := asset .DecodeTapBranchNodes (branchData )
2969+ if err != nil {
2970+ return nil , err
2971+ }
2972+
2973+ return fn .Ptr (asset .FromBranch (* tapBranch )), nil
2974+ }
2975+
29202976// UnmarshalScriptKey parses the RPC script key into the native counterpart.
29212977func UnmarshalScriptKey (rpcKey * taprpc.ScriptKey ) (* asset.ScriptKey , error ) {
29222978 var (
0 commit comments