mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-18 20:54:20 +01:00
* [domain] add reverse boarding inputs in Payment struct * [tx-builder] support reverse boarding script * [wallet] add GetTransaction * [api-spec][application] add reverse boarding support in covenantless * [config] add reverse boarding config * [api-spec] add ReverseBoardingAddress RPC * [domain][application] support empty forfeits txs in EndFinalization events * [tx-builder] optional connector output in round tx * [btc-embedded] fix getTx and taproot finalizer * whitelist ReverseBoardingAddress RPC * [test] add reverse boarding integration test * [client] support reverse boarding * [sdk] support reverse boarding * [e2e] add sleep time after faucet * [test] run using bitcoin-core RPC * [tx-builder] fix GetSweepInput * [application][tx-builder] support reverse onboarding in covenant * [cli] support reverse onboarding in covenant CLI * [test] rework integration tests * [sdk] remove onchain wallet, replace by onboarding address * remove old onboarding protocols * [sdk] Fix RegisterPayment * [e2e] add more funds to covenant ASP * [e2e] add sleeping time * several fixes * descriptor boarding * remove boarding delay from info * [sdk] implement descriptor boarding * go mod tidy * fixes and revert error msgs * move descriptor pkg to common * add replace in go.mod * [sdk] fix unit tests * rename DescriptorInput --> BoardingInput * genrest in SDK * remove boarding input from domain * remove all "reverse boarding" * rename "onboarding" ==> "boarding" * remove outdate payment unit test * use tmpfs docker volument for compose testing files * several fixes
134 lines
3.1 KiB
Go
134 lines
3.1 KiB
Go
package covenantless
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/ark-network/ark/client/utils"
|
|
"github.com/ark-network/ark/common/bitcointree"
|
|
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
|
"github.com/btcsuite/btcd/btcutil/psbt"
|
|
"github.com/btcsuite/btcd/txscript"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
func signPsbt(
|
|
_ *cli.Context, ptx *psbt.Packet, explorer utils.Explorer, prvKey *secp256k1.PrivateKey,
|
|
) error {
|
|
updater, err := psbt.NewUpdater(ptx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, input := range updater.Upsbt.UnsignedTx.TxIn {
|
|
if updater.Upsbt.Inputs[i].WitnessUtxo != nil {
|
|
continue
|
|
}
|
|
|
|
prevoutTxHex, err := explorer.GetTxHex(input.PreviousOutPoint.Hash.String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var prevoutTx wire.MsgTx
|
|
|
|
if err := prevoutTx.Deserialize(hex.NewDecoder(strings.NewReader(prevoutTxHex))); err != nil {
|
|
return err
|
|
}
|
|
|
|
utxo := prevoutTx.TxOut[input.PreviousOutPoint.Index]
|
|
if utxo == nil {
|
|
return fmt.Errorf("witness utxo not found")
|
|
}
|
|
|
|
if err := updater.AddInWitnessUtxo(utxo, i); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := updater.AddInSighashType(txscript.SigHashDefault, i); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
prevouts := make(map[wire.OutPoint]*wire.TxOut)
|
|
|
|
for i, input := range updater.Upsbt.Inputs {
|
|
outpoint := updater.Upsbt.UnsignedTx.TxIn[i].PreviousOutPoint
|
|
prevouts[outpoint] = input.WitnessUtxo
|
|
}
|
|
|
|
prevoutFetcher := txscript.NewMultiPrevOutFetcher(
|
|
prevouts,
|
|
)
|
|
|
|
txsighashes := txscript.NewTxSigHashes(updater.Upsbt.UnsignedTx, prevoutFetcher)
|
|
|
|
for i, input := range ptx.Inputs {
|
|
if len(input.TaprootLeafScript) > 0 {
|
|
pubkey := prvKey.PubKey()
|
|
for _, leaf := range input.TaprootLeafScript {
|
|
closure, err := bitcointree.DecodeClosure(leaf.Script)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sign := false
|
|
|
|
switch c := closure.(type) {
|
|
case *bitcointree.CSVSigClosure:
|
|
sign = bytes.Equal(c.Pubkey.SerializeCompressed()[1:], pubkey.SerializeCompressed()[1:])
|
|
case *bitcointree.MultisigClosure:
|
|
sign = bytes.Equal(c.Pubkey.SerializeCompressed()[1:], pubkey.SerializeCompressed()[1:])
|
|
}
|
|
|
|
if sign {
|
|
if err := updater.AddInSighashType(txscript.SigHashDefault, i); err != nil {
|
|
return err
|
|
}
|
|
|
|
hash := txscript.NewTapLeaf(leaf.LeafVersion, leaf.Script).TapHash()
|
|
|
|
preimage, err := txscript.CalcTapscriptSignaturehash(
|
|
txsighashes,
|
|
txscript.SigHashDefault,
|
|
ptx.UnsignedTx,
|
|
i,
|
|
prevoutFetcher,
|
|
txscript.NewBaseTapLeaf(leaf.Script),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sig, err := schnorr.Sign(
|
|
prvKey,
|
|
preimage,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !sig.Verify(preimage, prvKey.PubKey()) {
|
|
return fmt.Errorf("signature verification failed")
|
|
}
|
|
|
|
updater.Upsbt.Inputs[i].TaprootScriptSpendSig = []*psbt.TaprootScriptSpendSig{
|
|
{
|
|
XOnlyPubKey: schnorr.SerializePubKey(prvKey.PubKey()),
|
|
LeafHash: hash.CloneBytes(),
|
|
Signature: sig.Serialize(),
|
|
SigHash: txscript.SigHashDefault,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|