func getKey(r io.Reader) (int, []byte, error) {
	count, err := wire.ReadVarInt(r, 0)
	if err != nil {
		return -1, nil, psbt.ErrInvalidPsbtFormat
	}
	if count == 0 {
		return -1, nil, nil
	}
	if count > psbt.MaxPsbtKeyLength {
		return -1, nil, psbt.ErrInvalidKeydata
	}
	keyTypeAndData := make([]byte, count)
	if _, err := io.ReadFull(r, keyTypeAndData[:]); err != nil {
		return -1, nil, err
	}
	keyType := int(string(keyTypeAndData)[0])
	if len(keyTypeAndData) == 1 {
		return keyType, nil, nil
	}
	return keyType, keyTypeAndData[1:], nil
}
getKey retrieves a single key - both the key type and the keydata (if
present) from the stream and returns the key type as an integer, or -1 if
the key was of zero length. This integer is is used to indicate the presence
of a separator byte which indicates the end of a given key-value pair list,
and the keydata as a byte slice or nil if none is present.
package pset
import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
	"sort"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil/psbt"
	"github.com/vulpemventures/go-elements/internal/bufferutil"
	"github.com/vulpemventures/go-elements/transaction"
)
func writeTxWitness(wit [][]byte) ([]byte, error) {
	s, err := bufferutil.NewSerializer(nil)
	if err != nil {
		return nil, err
	}
	if err := s.WriteVarInt(uint64(len(wit))); err != nil {
		return nil, err
	}
	for _, item := range wit {
		err := s.WriteVarSlice(item)
		if err != nil {
			return nil, err
		}
	}
	return s.Bytes(), nil
}
func writePKHWitness(sig []byte, pub []byte) ([]byte, error) {
	witnessItems := [][]byte{sig, pub}
	return writeTxWitness(witnessItems)
}
func checkIsMultiSigScript(pubKeys [][]byte, sigs [][]byte,
	script []byte) bool {
	if txscript.GetScriptClass(script) != txscript.MultiSigTy {
		return false
	}
	_, numSigs, err := txscript.CalcMultiSigStats(script)
	if err != nil {
		return false
	}
	if numSigs != len(pubKeys) || numSigs != len(sigs) {
		return false
	}
	return true
}
func extractKeyOrderFromScript(script []byte, expectedPubkeys [][]byte,
	sigs [][]byte) ([][]byte, error) {
	if !checkIsMultiSigScript(expectedPubkeys, sigs, script) {
		return nil, psbt.ErrUnsupportedScriptType
	}
	type sigWithPub struct {
		pubKey []byte
		sig    []byte
	}
	var pubsSigs []sigWithPub
	for i, pub := range expectedPubkeys {
		pubsSigs = append(pubsSigs, sigWithPub{
			pubKey: pub,
			sig:    sigs[i],
		})
	}
	type positionEntry struct {
		index int
		value sigWithPub
	}
	var positionMap []positionEntry
	for _, p := range pubsSigs {
		pos := bytes.Index(script, p.pubKey)
		if pos < 0 {
			return nil, errors.New("script does not contain pubkeys")
		}
		positionMap = append(positionMap, positionEntry{
			index: pos,
			value: p,
		})
	}
	sort.Slice(positionMap, func(i, j int) bool {
		return positionMap[i].index < positionMap[j].index
	})
	sortedSigs := make([][]byte, 0, len(positionMap))
	for _, x := range positionMap {
		sortedSigs = append(sortedSigs, x.value.sig)
	}
	return sortedSigs, nil
}
func getMultisigScriptWitness(witnessScript []byte, pubKeys [][]byte,
	sigs [][]byte) ([]byte, error) {
	orderedSigs, err := extractKeyOrderFromScript(
		witnessScript, pubKeys, sigs,
	)
	if err != nil {
		return nil, err
	}
	witnessElements := make(transaction.TxWitness, 0, len(sigs)+2)
	witnessElements = append(witnessElements, nil)
	for _, os := range orderedSigs {
		witnessElements = append(witnessElements, os)
	}
	witnessElements = append(witnessElements, witnessScript)
	return writeTxWitness(witnessElements)
}
func checkSigHashFlags(sig []byte, input *PInput) bool {
	expectedSighashType := txscript.SigHashAll
	if input.SighashType != 0 {
		expectedSighashType = input.SighashType
	}
	return expectedSighashType == txscript.SigHashType(sig[len(sig)-1])
}
func serializeKVpair(w io.Writer, key []byte, value []byte) error {
	if err := wire.WriteVarBytes(w, 0, key); err != nil {
		return err
	}
	return wire.WriteVarBytes(w, 0, value)
}
func serializeKVPairWithType(w io.Writer, kt uint8, keydata []byte,
	value []byte) error {
	if keydata == nil {
		keydata = []byte{}
	}
	serializedKey := append([]byte{byte(kt)}, keydata...)
	return serializeKVpair(w, serializedKey, value)
}