From 2ed790394b6e08ab354c0a228efc4b3f403b77d2 Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Thu, 14 Mar 2024 16:15:30 +0100 Subject: [PATCH 1/5] fix(BUX-644): handle new paymail pub key --- transports/authentication.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/transports/authentication.go b/transports/authentication.go index 110c76f..e11ee43 100644 --- a/transports/authentication.go +++ b/transports/authentication.go @@ -44,11 +44,12 @@ func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHe // Sign the inputs for index, input := range dt.Configuration.Inputs { + dst := input.Destination // Get the locking script var ls *bscript.Script if ls, err = bscript.NewFromHexString( - input.Destination.LockingScript, + dst.LockingScript, ); err != nil { resError = WrapError(err) return @@ -59,7 +60,7 @@ func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHe // Derive the child key (chain) var chainKey *bip32.ExtendedKey if chainKey, err = xPriv.Child( - input.Destination.Chain, + dst.Chain, ); err != nil { resError = WrapError(err) return @@ -68,12 +69,22 @@ func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHe // Derive the child key (num) var numKey *bip32.ExtendedKey if numKey, err = chainKey.Child( - input.Destination.Num, + dst.Num, ); err != nil { resError = WrapError(err) return } + // Derive key for paymail destination + if dst.PaymailExternalDerivationNum != nil { + if numKey, err = chainKey.Child( + *dst.PaymailExternalDerivationNum, + ); err != nil { + resError = WrapError(err) + return + } + } + // Get the private key var privateKey *bec.PrivateKey if privateKey, err = bitcoin.GetPrivateKeyFromHDKey( From 66a3440e06d66679677da03eed7361869e3b6506 Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Sat, 23 Mar 2024 16:33:14 +0100 Subject: [PATCH 2/5] fix(BUX-644): fix xpriv derivation --- transports/authentication.go | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/transports/authentication.go b/transports/authentication.go index e11ee43..1d7f847 100644 --- a/transports/authentication.go +++ b/transports/authentication.go @@ -57,27 +57,16 @@ func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHe txDraft.Inputs[index].PreviousTxScript = ls txDraft.Inputs[index].PreviousTxSatoshis = input.Satoshis - // Derive the child key (chain) - var chainKey *bip32.ExtendedKey - if chainKey, err = xPriv.Child( - dst.Chain, - ); err != nil { + // Derive the child key (m/chain/num) + var derivedKey *bip32.ExtendedKey + if derivedKey, err = bitcoin.GetHDKeyByPath(xPriv, dst.Chain, dst.Num); err != nil { resError = WrapError(err) return } - // Derive the child key (num) - var numKey *bip32.ExtendedKey - if numKey, err = chainKey.Child( - dst.Num, - ); err != nil { - resError = WrapError(err) - return - } - - // Derive key for paymail destination + // Derive key for paymail destination (m/chain/num/paymailNum) if dst.PaymailExternalDerivationNum != nil { - if numKey, err = chainKey.Child( + if derivedKey, err = derivedKey.Child( *dst.PaymailExternalDerivationNum, ); err != nil { resError = WrapError(err) @@ -87,9 +76,7 @@ func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHe // Get the private key var privateKey *bec.PrivateKey - if privateKey, err = bitcoin.GetPrivateKeyFromHDKey( - numKey, - ); err != nil { + if privateKey, err = bitcoin.GetPrivateKeyFromHDKey(derivedKey); err != nil { resError = WrapError(err) return } From cab3fe5c83116601c89bec80eb747d0a50bf1431 Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Sat, 23 Mar 2024 17:19:27 +0100 Subject: [PATCH 3/5] fix(BUX-644): clean code --- transactions.go | 7 ++- transports/authentication.go | 105 ++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/transactions.go b/transactions.go index 74ac2ce..a4e256f 100644 --- a/transactions.go +++ b/transactions.go @@ -56,7 +56,12 @@ func (b *WalletClient) UpdateTransactionMetadata(ctx context.Context, txID strin // FinalizeTransaction will finalize the transaction func (b *WalletClient) FinalizeTransaction(draft *models.DraftTransaction) (string, transports.ResponseError) { - return transports.SignInputs(draft, b.xPriv) + res, err := transports.GetSignedHex(draft, b.xPriv) + if err != nil { + return "", transports.WrapError(err) + } + + return res, nil } // SendToRecipients send to recipients diff --git a/transports/authentication.go b/transports/authentication.go index 1d7f847..bb3dd30 100644 --- a/transports/authentication.go +++ b/transports/authentication.go @@ -32,75 +32,78 @@ func setSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString stri return setSignatureHeaders(header, authData) } -// SignInputs will sign all the inputs using the given xPriv key -func SignInputs(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHex string, resError ResponseError) { - var err error - // Start a bt draft transaction - var txDraft *bt.Tx - if txDraft, err = bt.NewTxFromString(dt.Hex); err != nil { - resError = WrapError(err) +// GetSignedHex will sign all the inputs using the given xPriv key +func GetSignedHex(dt *models.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHex string, err error) { + var tx *bt.Tx + if tx, err = bt.NewTxFromString(dt.Hex); err != nil { return } - // Sign the inputs - for index, input := range dt.Configuration.Inputs { - dst := input.Destination + // Enrich inputs + for index, draftInput := range dt.Configuration.Inputs { + tx.Inputs[index].PreviousTxSatoshis = draftInput.Satoshis - // Get the locking script - var ls *bscript.Script - if ls, err = bscript.NewFromHexString( - dst.LockingScript, - ); err != nil { - resError = WrapError(err) + dst := draftInput.Destination + if err = setPreviousTxScript(tx, uint32(index), &dst); err != nil { return } - txDraft.Inputs[index].PreviousTxScript = ls - txDraft.Inputs[index].PreviousTxSatoshis = input.Satoshis - // Derive the child key (m/chain/num) - var derivedKey *bip32.ExtendedKey - if derivedKey, err = bitcoin.GetHDKeyByPath(xPriv, dst.Chain, dst.Num); err != nil { - resError = WrapError(err) + if err = setUnlockingScript(tx, uint32(index), xPriv, &dst); err != nil { return } + } - // Derive key for paymail destination (m/chain/num/paymailNum) - if dst.PaymailExternalDerivationNum != nil { - if derivedKey, err = derivedKey.Child( - *dst.PaymailExternalDerivationNum, - ); err != nil { - resError = WrapError(err) - return - } - } + // Return the signed hex + signedHex = tx.String() + return +} - // Get the private key - var privateKey *bec.PrivateKey - if privateKey, err = bitcoin.GetPrivateKeyFromHDKey(derivedKey); err != nil { - resError = WrapError(err) - return - } +func setPreviousTxScript(tx *bt.Tx, inputIndex uint32, dst *models.Destination) (err error) { + var ls *bscript.Script + if ls, err = bscript.NewFromHexString(dst.LockingScript); err != nil { + return + } - // Get the unlocking script - var s *bscript.Script - if s, err = getUnlockingScript( - txDraft, uint32(index), privateKey, - ); err != nil { - resError = WrapError(err) - return - } + tx.Inputs[inputIndex].PreviousTxScript = ls + return +} - // Insert the locking script - if err = txDraft.InsertInputUnlockingScript( - uint32(index), s, +func setUnlockingScript(tx *bt.Tx, inputIndex uint32, xPriv *bip32.ExtendedKey, dst *models.Destination) (err error) { + var key *bec.PrivateKey + if key, err = getDerivedKeyForDestination(xPriv, dst); err != nil { + return + } + + var s *bscript.Script + if s, err = getUnlockingScript(tx, inputIndex, key); err != nil { + return + } + + tx.Inputs[inputIndex].UnlockingScript = s + return +} + +func getDerivedKeyForDestination(xPriv *bip32.ExtendedKey, dst *models.Destination) (key *bec.PrivateKey, err error) { + // Derive the child key (m/chain/num) + var derivedKey *bip32.ExtendedKey + if derivedKey, err = bitcoin.GetHDKeyByPath(xPriv, dst.Chain, dst.Num); err != nil { + return + } + + // Derive key for paymail destination (m/chain/num/paymailNum) + if dst.PaymailExternalDerivationNum != nil { + if derivedKey, err = derivedKey.Child( + *dst.PaymailExternalDerivationNum, ); err != nil { - resError = WrapError(err) return } } - // Return the signed hex - signedHex = txDraft.String() + // Get the private key + if key, err = bitcoin.GetPrivateKeyFromHDKey(derivedKey); err != nil { + return + } + return } From 14c089aaa7b97915178d49c6c329b55a29b7576f Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Mon, 25 Mar 2024 14:05:33 +0100 Subject: [PATCH 4/5] fix(BUX-644): update spv models ref --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c03ad97..5b58a63 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/bitcoin-sv/spv-wallet-go-client go 1.21 require ( - github.com/bitcoin-sv/spv-wallet/models v0.20.0 + github.com/bitcoin-sv/spv-wallet/models v0.24.0 github.com/bitcoinschema/go-bitcoin/v2 v2.0.5 github.com/libsv/go-bk v0.1.6 github.com/libsv/go-bt/v2 v2.2.5 diff --git a/go.sum b/go.sum index e712f6a..c87e53f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bitcoin-sv/spv-wallet/models v0.20.0 h1:rBVsmtrE7bmP7ieaAXowRWhvptQVU/R/DMS5F70qRX4= -github.com/bitcoin-sv/spv-wallet/models v0.20.0/go.mod h1:P8vXF1mPg1Zh3xSvB9yqwuPJfOR8Tt/SAG2FYztwENI= +github.com/bitcoin-sv/spv-wallet/models v0.24.0 h1:cIfi2noDfRWaFt0VMOECwF8H9OsJFdP0T03XK4BULe0= +github.com/bitcoin-sv/spv-wallet/models v0.24.0/go.mod h1:P8vXF1mPg1Zh3xSvB9yqwuPJfOR8Tt/SAG2FYztwENI= github.com/bitcoinschema/go-bitcoin/v2 v2.0.5 h1:Sgh5Eb746Zck/46rFDrZZEXZWyO53fMuWYhNoZa1tck= github.com/bitcoinschema/go-bitcoin/v2 v2.0.5/go.mod h1:JjO1ivfZv6vhK0uAXzyH08AAHlzNMAfnyK1Fiv9r4ZA= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 h1:2yTIV9u7H0BhRDGXH5xrAwAz7XibWJtX2dNezMeNsUo= From b5d5dd302a0a92ae78663f391ba89fdcbedb3848 Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Mon, 25 Mar 2024 14:09:43 +0100 Subject: [PATCH 5/5] fix(BUX-644): remove redundant comment --- transports/authentication.go | 1 - 1 file changed, 1 deletion(-) diff --git a/transports/authentication.go b/transports/authentication.go index bb3dd30..3a51108 100644 --- a/transports/authentication.go +++ b/transports/authentication.go @@ -99,7 +99,6 @@ func getDerivedKeyForDestination(xPriv *bip32.ExtendedKey, dst *models.Destinati } } - // Get the private key if key, err = bitcoin.GetPrivateKeyFromHDKey(derivedKey); err != nil { return }