mirror of
https://github.com/muun/recovery.git
synced 2025-11-10 22:10:14 -05:00
Release v0.1.0
This commit is contained in:
149
vendor/github.com/muun/libwallet/partiallysignedtransaction.go
generated
vendored
Normal file
149
vendor/github.com/muun/libwallet/partiallysignedtransaction.go
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
package libwallet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type MuunAddress interface {
|
||||
Version() int
|
||||
DerivationPath() string
|
||||
Address() string
|
||||
}
|
||||
|
||||
// TODO: Change name
|
||||
type RedeemableAddress interface {
|
||||
RedeemScript() []byte
|
||||
}
|
||||
|
||||
type Outpoint interface {
|
||||
TxId() []byte
|
||||
Index() int
|
||||
Amount() int64
|
||||
}
|
||||
|
||||
type InputSubmarineSwap interface {
|
||||
RefundAddress() string
|
||||
PaymentHash256() []byte
|
||||
ServerPublicKey() []byte
|
||||
LockTime() int64
|
||||
}
|
||||
|
||||
type Input interface {
|
||||
OutPoint() Outpoint
|
||||
Address() MuunAddress
|
||||
UserSignature() []byte
|
||||
MuunSignature() []byte
|
||||
SubmarineSwap() InputSubmarineSwap
|
||||
}
|
||||
|
||||
type PartiallySignedTransaction struct {
|
||||
tx *wire.MsgTx
|
||||
inputs []Input
|
||||
}
|
||||
|
||||
type Transaction struct {
|
||||
Hash string
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
func NewPartiallySignedTransaction(hexTx string) (*PartiallySignedTransaction, error) {
|
||||
|
||||
rawTx, err := hex.DecodeString(hexTx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode hex tx")
|
||||
}
|
||||
|
||||
tx := wire.NewMsgTx(0)
|
||||
err = tx.BtcDecode(bytes.NewBuffer(rawTx), 0, wire.WitnessEncoding)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode tx")
|
||||
}
|
||||
|
||||
return &PartiallySignedTransaction{tx: tx, inputs: []Input{}}, nil
|
||||
}
|
||||
|
||||
func (p *PartiallySignedTransaction) AddInput(input Input) {
|
||||
p.inputs = append(p.inputs, input)
|
||||
}
|
||||
|
||||
func (p *PartiallySignedTransaction) Sign(key *HDPrivateKey, muunKey *HDPublicKey) (*Transaction, error) {
|
||||
|
||||
for i, input := range p.inputs {
|
||||
|
||||
derivedKey, err := key.DeriveTo(input.Address().DerivationPath())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to derive user key")
|
||||
}
|
||||
|
||||
derivedMuunKey, err := muunKey.DeriveTo(input.Address().DerivationPath())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to derive muun key")
|
||||
}
|
||||
|
||||
var txIn *wire.TxIn
|
||||
|
||||
switch AddressVersion(input.Address().Version()) {
|
||||
case addressV1:
|
||||
txIn, err = addUserSignatureInputV1(input, i, p.tx, derivedKey)
|
||||
case addressV2:
|
||||
txIn, err = addUserSignatureInputV2(input, i, p.tx, derivedKey, derivedMuunKey)
|
||||
case addressV3:
|
||||
txIn, err = addUserSignatureInputV3(input, i, p.tx, derivedKey, derivedMuunKey)
|
||||
case addressSubmarineSwap:
|
||||
txIn, err = addUserSignatureInputSubmarineSwap(input, i, p.tx, derivedKey, derivedMuunKey)
|
||||
default:
|
||||
return nil, errors.Errorf("cant sign transaction of version %v", input.Address().Version())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to sign input using version %v", input.Address().Version())
|
||||
}
|
||||
|
||||
p.tx.TxIn[i] = txIn
|
||||
}
|
||||
|
||||
var writer bytes.Buffer
|
||||
err := p.tx.BtcEncode(&writer, 0, wire.WitnessEncoding)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to encode tx")
|
||||
}
|
||||
|
||||
return &Transaction{
|
||||
Hash: p.tx.TxHash().String(),
|
||||
Bytes: writer.Bytes(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (p *PartiallySignedTransaction) MuunSignatureForInput(index int, userKey *HDPublicKey,
|
||||
muunKey *HDPrivateKey) ([]byte, error) {
|
||||
|
||||
input := p.inputs[index]
|
||||
|
||||
derivedUserKey, err := userKey.DeriveTo(input.Address().DerivationPath())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to derive user key")
|
||||
}
|
||||
|
||||
derivedMuunKey, err := muunKey.DeriveTo(input.Address().DerivationPath())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to derive muun key")
|
||||
}
|
||||
|
||||
switch AddressVersion(input.Address().Version()) {
|
||||
case addressV1:
|
||||
return []byte{}, nil
|
||||
case addressV2:
|
||||
return signInputV2(input, index, p.tx, derivedUserKey, derivedMuunKey.PublicKey(), derivedMuunKey)
|
||||
case addressV3:
|
||||
return signInputV3(input, index, p.tx, derivedUserKey, derivedMuunKey.PublicKey(), derivedMuunKey)
|
||||
case addressSubmarineSwap:
|
||||
return nil, errors.New("cant sign arbitrary submarine swap inputs")
|
||||
}
|
||||
|
||||
return nil, errors.New("unknown address scheme")
|
||||
}
|
||||
Reference in New Issue
Block a user