func ESig(w io.Writer, val interface{}, buf *[8]byte) error {
	if v, ok := val.(**btcec.Signature); ok {
		var s [64]byte
		if *v != nil {
			rawSig := (*v).Serialize()
			sig, err := lnwire.NewSigFromRawSignature(rawSig)
			if err != nil {
				return err
			}
			copy(s[:], sig[:])
		}
		return tlv.EBytes64(w, &s, buf)
	}
	return tlv.NewTypeForEncodingErr(val, "*btcec.Signature")
}
ESig is an Encoder for the btcec.Signature type. An error is returned if val
is not a **btcec.Signature.
package sidecar
import (
	"bytes"
	"fmt"
	"io"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcutil"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/lightningnetwork/lnd/tlv"
)
const (
	idType      tlv.Type = 1
	versionType tlv.Type = 2
	stateType   tlv.Type = 3
	offerType          tlv.Type = 10
	capacityType       tlv.Type = 11
	pushAmtType        tlv.Type = 12
	leaseDurationType  tlv.Type = 13
	signPubKeyType     tlv.Type = 14
	sigOfferDigestType tlv.Type = 15
	offerAutoType      tlv.Type = 16
	recipientType        tlv.Type = 20
	nodePubKeyType       tlv.Type = 21
	multiSigPubKeyType   tlv.Type = 22
	multiSigKeyIndexType tlv.Type = 23
	orderType          tlv.Type = 30
	bidNonceType       tlv.Type = 31
	sigOrderDigestType tlv.Type = 32
	executionType        tlv.Type = 40
	pendingChannelIDType tlv.Type = 41
)
var (
	ZeroSignature = [64]byte{}
)
func SerializeTicket(w io.Writer, ticket *Ticket) error {
	if ticket == nil {
		return fmt.Errorf("ticket cannot be nil")
	}
	var (
		version    = uint8(ticket.Version)
		state      = uint8(ticket.State)
		offerBytes []byte
		err        error
	)
	offerBytes, err = serializeOffer(ticket.Offer)
	if err != nil {
		return err
	}
	tlvRecords := []tlv.Record{
		tlv.MakeStaticRecord(idType, &ticket.ID, 8, EBytes8, DBytes8),
		tlv.MakePrimitiveRecord(versionType, &version),
		tlv.MakePrimitiveRecord(stateType, &state),
		tlv.MakePrimitiveRecord(offerType, &offerBytes),
	}
	if ticket.Recipient != nil {
		recipientBytes, err := serializeRecipient(*ticket.Recipient)
		if err != nil {
			return err
		}
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			recipientType, &recipientBytes,
		))
	}
	if ticket.Order != nil {
		orderBytes, err := serializeOrder(*ticket.Order)
		if err != nil {
			return err
		}
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			orderType, &orderBytes,
		))
	}
	if ticket.Execution != nil {
		executionBytes, err := serializeExecution(*ticket.Execution)
		if err != nil {
			return err
		}
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			executionType, &executionBytes,
		))
	}
	tlvStream, err := tlv.NewStream(tlvRecords...)
	if err != nil {
		return err
	}
	return tlvStream.Encode(w)
}
func DeserializeTicket(r io.Reader) (*Ticket, error) {
	var (
		ticket                     = &Ticket{}
		version, state             uint8
		offerBytes, recipientBytes []byte
		orderBytes, executionBytes []byte
	)
	tlvStream, err := tlv.NewStream(
		tlv.MakeStaticRecord(idType, &ticket.ID, 8, EBytes8, DBytes8),
		tlv.MakePrimitiveRecord(versionType, &version),
		tlv.MakePrimitiveRecord(stateType, &state),
		tlv.MakePrimitiveRecord(offerType, &offerBytes),
		tlv.MakePrimitiveRecord(recipientType, &recipientBytes),
		tlv.MakePrimitiveRecord(orderType, &orderBytes),
		tlv.MakePrimitiveRecord(executionType, &executionBytes),
	)
	if err != nil {
		return nil, err
	}
	parsedTypes, err := tlvStream.DecodeWithParsedTypes(r)
	if err != nil {
		return nil, err
	}
	ticket.Version = Version(version)
	ticket.State = State(state)
	if t, ok := parsedTypes[offerType]; ok && t == nil {
		ticket.Offer, err = deserializeOffer(offerBytes)
		if err != nil {
			return nil, err
		}
	}
	if t, ok := parsedTypes[recipientType]; ok && t == nil {
		recipient, err := deserializeRecipient(recipientBytes)
		if err != nil {
			return nil, err
		}
		ticket.Recipient = &recipient
	}
	if t, ok := parsedTypes[orderType]; ok && t == nil {
		order, err := deserializeOrder(orderBytes)
		if err != nil {
			return nil, err
		}
		ticket.Order = &order
	}
	if t, ok := parsedTypes[executionType]; ok && t == nil {
		execution, err := deserializeExecution(executionBytes)
		if err != nil {
			return nil, err
		}
		ticket.Execution = &execution
	}
	return ticket, nil
}
func serializeOffer(o Offer) ([]byte, error) {
	capacity := uint64(o.Capacity)
	pushAmt := uint64(o.PushAmt)
	var autoAsInt uint8
	if o.Auto {
		autoAsInt = 1
	}
	tlvRecords := []tlv.Record{
		tlv.MakePrimitiveRecord(capacityType, &capacity),
		tlv.MakePrimitiveRecord(pushAmtType, &pushAmt),
		tlv.MakePrimitiveRecord(
			leaseDurationType, &o.LeaseDurationBlocks,
		),
		tlv.MakePrimitiveRecord(offerAutoType, &autoAsInt),
	}
	if o.SignPubKey != nil {
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			signPubKeyType, &o.SignPubKey,
		))
	}
	if o.SigOfferDigest != nil {
		tlvRecords = append(tlvRecords, tlv.MakeStaticRecord(
			sigOfferDigestType, &o.SigOfferDigest, 64, ESig, DSig,
		))
	}
	return encodeBytes(tlvRecords...)
}
func deserializeOffer(offerBytes []byte) (Offer, error) {
	var (
		o                 = Offer{}
		capacity, pushAmt uint64
		autoAsInt         uint8
	)
	if err := decodeBytes(
		offerBytes,
		tlv.MakePrimitiveRecord(capacityType, &capacity),
		tlv.MakePrimitiveRecord(pushAmtType, &pushAmt),
		tlv.MakePrimitiveRecord(
			leaseDurationType, &o.LeaseDurationBlocks,
		),
		tlv.MakePrimitiveRecord(signPubKeyType, &o.SignPubKey),
		tlv.MakeStaticRecord(
			sigOfferDigestType, &o.SigOfferDigest, 64, ESig, DSig,
		),
		tlv.MakePrimitiveRecord(offerAutoType, &autoAsInt),
	); err != nil {
		return o, err
	}
	o.Auto = autoAsInt == 1
	o.Capacity = btcutil.Amount(capacity)
	o.PushAmt = btcutil.Amount(pushAmt)
	return o, nil
}
func serializeRecipient(r Recipient) ([]byte, error) {
	var tlvRecords []tlv.Record
	if r.NodePubKey != nil {
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			nodePubKeyType, &r.NodePubKey,
		))
	}
	if r.MultiSigPubKey != nil {
		tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
			multiSigPubKeyType, &r.MultiSigPubKey,
		))
	}
	tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
		multiSigKeyIndexType, &r.MultiSigKeyIndex,
	))
	return encodeBytes(tlvRecords...)
}
func deserializeRecipient(recipientBytes []byte) (Recipient, error) {
	r := Recipient{}
	return r, decodeBytes(
		recipientBytes,
		tlv.MakePrimitiveRecord(nodePubKeyType, &r.NodePubKey),
		tlv.MakePrimitiveRecord(multiSigPubKeyType, &r.MultiSigPubKey),
		tlv.MakePrimitiveRecord(
			multiSigKeyIndexType, &r.MultiSigKeyIndex,
		),
	)
}
func serializeOrder(o Order) ([]byte, error) {
	tlvRecords := []tlv.Record{
		tlv.MakePrimitiveRecord(bidNonceType, &o.BidNonce),
	}
	if o.SigOrderDigest != nil {
		tlvRecords = append(tlvRecords, tlv.MakeStaticRecord(
			sigOrderDigestType, &o.SigOrderDigest, 64, ESig, DSig,
		))
	}
	return encodeBytes(tlvRecords...)
}
func deserializeOrder(orderBytes []byte) (Order, error) {
	o := Order{}
	return o, decodeBytes(
		orderBytes,
		tlv.MakePrimitiveRecord(bidNonceType, &o.BidNonce),
		tlv.MakeStaticRecord(
			sigOrderDigestType, &o.SigOrderDigest, 64, ESig, DSig,
		),
	)
}
func serializeExecution(e Execution) ([]byte, error) {
	return encodeBytes(tlv.MakePrimitiveRecord(
		pendingChannelIDType, &e.PendingChannelID,
	))
}
func deserializeExecution(executionBytes []byte) (Execution, error) {
	e := Execution{}
	return e, decodeBytes(executionBytes, tlv.MakePrimitiveRecord(
		pendingChannelIDType, &e.PendingChannelID,
	))
}