Skip to content

Commit

Permalink
psbt: add output silent payment info
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Dec 28, 2024
1 parent ce1d461 commit edef016
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
23 changes: 23 additions & 0 deletions btcutil/psbt/partial_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type POutput struct {
TaprootInternalKey []byte
TaprootTapTree []byte
TaprootBip32Derivation []*TaprootBip32Derivation
SilentPaymentInfo *SilentPaymentInfo
Unknowns []*Unknown
}

Expand Down Expand Up @@ -144,6 +145,18 @@ func (po *POutput) deserialize(r io.Reader) error {
po.TaprootBip32Derivation, taprootDerivation,
)

case SilentPaymentV0InfoOutputType:
if po.SilentPaymentInfo != nil {
return ErrDuplicateKey
}

info, err := ReadSilentPaymentInfo(value)
if err != nil {
return err
}

po.SilentPaymentInfo = info

default:
// A fall through case for any proprietary types.
keyCodeAndData := append(
Expand Down Expand Up @@ -246,6 +259,16 @@ func (po *POutput) serialize(w io.Writer) error {
}
}

if po.SilentPaymentInfo != nil {
err := serializeKVPairWithType(
w, uint8(SilentPaymentV0InfoOutputType), nil,
SerializeSilentPaymentInfo(po.SilentPaymentInfo),
)
if err != nil {
return err
}
}

// Unknown is a special case; we don't have a key type, only a key and
// a value field
for _, kv := range po.Unknowns {
Expand Down
32 changes: 32 additions & 0 deletions btcutil/psbt/silentpayments.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,35 @@ func SerializeSilentPaymentDLEQ(dleq *SilentPaymentDLEQ) ([]byte, []byte) {

return keyData, dleq.Proof
}

// SilentPaymentInfo is the information needed to create a silent payment
// recipient output.
type SilentPaymentInfo struct {
// ScanKey is the silent payment recipient's scan key.
ScanKey []byte

// SpendKey is the silent payment recipient's spend key.
SpendKey []byte
}

// ReadSilentPaymentInfo deserializes a silent payment info from the given
// value.
func ReadSilentPaymentInfo(value []byte) (*SilentPaymentInfo, error) {
if len(value) != secp.PubKeyBytesLenCompressed*2 {
return nil, ErrInvalidPsbtFormat
}

return &SilentPaymentInfo{
ScanKey: value[:secp.PubKeyBytesLenCompressed],
SpendKey: value[secp.PubKeyBytesLenCompressed:],
}, nil
}

// SerializeSilentPaymentInfo serializes a silent payment info to value.
func SerializeSilentPaymentInfo(info *SilentPaymentInfo) []byte {
value := make([]byte, 0, secp.PubKeyBytesLenCompressed*2)
value = append(value, info.ScanKey...)
value = append(value, info.SpendKey...)

return value
}
4 changes: 4 additions & 0 deletions btcutil/psbt/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,8 @@ const (
// followed by said number of 32-byte leaf hashes. The rest of the value
// is then identical to the Bip32DerivationInputType value.
TaprootBip32DerivationOutputType OutputType = 7

// SilentPaymentV0InfoOutputType is used to house the silent payment
// recipient information for a version 0 silent payment output.
SilentPaymentV0InfoOutputType OutputType = 0x09
)

0 comments on commit edef016

Please sign in to comment.