Skip to content

Commit f1bfea5

Browse files
committed
Merge branch 'test-paymentrequest'
2 parents 9a79804 + 6a70b4f commit f1bfea5

File tree

4 files changed

+134
-4
lines changed

4 files changed

+134
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Ethereum bugfix: show all internal transactions that share the same transaction ID
1212
- Allow up to 6 unused BTC/LTC accounts (previously 5)
1313
- Add support for New Zealand Dollar (NZD)
14+
- Fix empty suggested name for BTC account when only BTC is supported by the BitBox.
1415

1516
## v4.48.4
1617
- macOS: fix potential USB communication issue with BitBox02 bootloaders <v1.1.2 and firmwares <v9.23.1

backend/devices/bitbox02/keystore_simulator_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import (
2121
"bufio"
2222
"bytes"
2323
"crypto/sha256"
24+
"encoding/binary"
2425
"encoding/hex"
2526
"encoding/json"
2627
"fmt"
28+
"hash"
2729
"io"
2830
"net"
2931
"net/http"
@@ -39,11 +41,13 @@ import (
3941
"testing"
4042
"time"
4143

44+
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts"
4245
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc"
4346
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/addresses"
4447
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain"
4548
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/maketx"
4649
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/types"
50+
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/util"
4751
coinpkg "github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
4852
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/eth"
4953
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/ltc"
@@ -59,11 +63,13 @@ import (
5963
"github.com/BitBoxSwiss/bitbox02-api-go/api/firmware/mocks"
6064
"github.com/BitBoxSwiss/bitbox02-api-go/communication/u2fhid"
6165
"github.com/BitBoxSwiss/bitbox02-api-go/util/semver"
66+
"github.com/btcsuite/btcd/btcec/v2"
6267
"github.com/btcsuite/btcd/btcutil"
6368
"github.com/btcsuite/btcd/btcutil/hdkeychain"
6469
"github.com/btcsuite/btcd/chaincfg"
6570
"github.com/btcsuite/btcd/chaincfg/chainhash"
6671
"github.com/btcsuite/btcd/wire"
72+
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
6773
"github.com/ethereum/go-ethereum/params"
6874
"github.com/stretchr/testify/require"
6975
)
@@ -698,3 +704,122 @@ func TestSimulatorVerifyAddressETH(t *testing.T) {
698704
}
699705
})
700706
}
707+
708+
func computePaymentRequestSighash(paymentRequest *accounts.PaymentRequest, slip44 uint32, outputValue uint64, outputAddress string) ([]byte, error) {
709+
710+
hashDataLenPrefixed := func(hasher hash.Hash, data []byte) {
711+
_ = wire.WriteVarInt(hasher, 0, uint64(len(data)))
712+
hasher.Write(data)
713+
}
714+
715+
sighash := sha256.New()
716+
717+
// versionMagic
718+
sighash.Write([]byte("SL\x00\x24"))
719+
720+
// nonce
721+
hashDataLenPrefixed(sighash, paymentRequest.Nonce)
722+
723+
// recipientName
724+
hashDataLenPrefixed(sighash, []byte(paymentRequest.RecipientName))
725+
726+
// memos
727+
_ = wire.WriteVarInt(sighash, 0, uint64(len(paymentRequest.Memos)))
728+
for _, textMemo := range paymentRequest.Memos {
729+
_ = binary.Write(sighash, binary.LittleEndian, uint32(1))
730+
hashDataLenPrefixed(sighash, []byte(textMemo.Note))
731+
}
732+
733+
// coinType
734+
_ = binary.Write(sighash, binary.LittleEndian, slip44)
735+
736+
// outputsHash (only one output for now)
737+
outputHasher := sha256.New()
738+
_ = binary.Write(outputHasher, binary.LittleEndian, outputValue)
739+
hashDataLenPrefixed(outputHasher, []byte(outputAddress))
740+
sighash.Write(outputHasher.Sum(nil))
741+
742+
return sighash.Sum(nil), nil
743+
}
744+
745+
func TestSimulatorSignBTCPaymentRequest(t *testing.T) {
746+
testInitializedSimulators(t, func(t *testing.T, device *Device, stdOut *bytes.Buffer) {
747+
t.Helper()
748+
749+
if !device.Version().AtLeast(semver.NewSemVer(9, 24, 0)) {
750+
// While payment requests were added in v9.19.0, the simulator only enabled the
751+
// test merchant in v9.24.0.
752+
t.Skip()
753+
}
754+
755+
address, err := btcutil.DecodeAddress(
756+
"bc1q2q0j6gmfxynj40p0kxsr9jkagcvgpuqv2zgq8j",
757+
&chaincfg.MainNetParams)
758+
require.NoError(t, err)
759+
pkScript, err := util.PkScriptFromAddress(address)
760+
require.NoError(t, err)
761+
proposedTransaction := makeTx(t, device, maketx.NewOutputInfo(pkScript))
762+
763+
txProposal := proposedTransaction.TXProposal
764+
recipientOutput := txProposal.Transaction.TxOut[txProposal.OutIndex]
765+
value := uint64(recipientOutput.Value)
766+
767+
paymentRequest := &accounts.PaymentRequest{
768+
RecipientName: "Test Merchant", // Hard-coded test merchant in simulator
769+
Nonce: nil,
770+
TotalAmount: value,
771+
Memos: []accounts.TextMemo{
772+
{
773+
Note: "TextMemo line1\nTextMemo line2",
774+
},
775+
},
776+
}
777+
778+
// Sign the payment request.
779+
sighash, err := computePaymentRequestSighash(paymentRequest, 0, value, address.String())
780+
require.NoError(t, err)
781+
privKey, _ := btcec.PrivKeyFromBytes([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
782+
require.NoError(t, err)
783+
signature := ecdsa.SignCompact(privKey, sighash, true)
784+
paymentRequest.Signature = signature[1:]
785+
786+
proposedTransaction.TXProposal.PaymentRequest = paymentRequest
787+
788+
require.NoError(t, device.Keystore().SignTransaction(proposedTransaction))
789+
require.NoError(t, proposedTransaction.Finalize())
790+
require.NoError(
791+
t,
792+
btc.TxValidityCheck(
793+
proposedTransaction.TXProposal.Transaction,
794+
proposedTransaction.TXProposal.PreviousOutputs,
795+
proposedTransaction.TXProposal.SigHashes()))
796+
797+
const expected1 = `CONFIRM TRANSACTION ADDRESS SCREEN START
798+
AMOUNT: 2.50000000 BTC
799+
ADDRESS: Test Merchant
800+
CONFIRM TRANSACTION ADDRESS SCREEN END`
801+
802+
const expected2 = `BODY: Memo from
803+
804+
Test Merchant
805+
CONFIRM SCREEN END
806+
CONFIRM SCREEN START
807+
TITLE: Memo 1/2
808+
BODY: TextMemo line1
809+
CONFIRM SCREEN END
810+
CONFIRM SCREEN START
811+
TITLE: Memo 2/2
812+
BODY: TextMemo line2
813+
CONFIRM SCREEN END`
814+
815+
require.Eventually(t,
816+
func() bool {
817+
return strings.Contains(
818+
stdOut.String(), expected1) &&
819+
strings.Contains(
820+
stdOut.String(), expected2) &&
821+
!strings.Contains(stdOut.String(), address.String())
822+
},
823+
time.Second, 10*time.Millisecond)
824+
})
825+
}

frontends/web/src/routes/account/add/add.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const AddAccount = ({ accounts }: TAddAccountGuide) => {
6868
setStep(onlyOneCoinIsSupported ? 'choose-name' : 'select-coin');
6969
setSupportedCoins(coins);
7070
if (onlyOneCoinIsSupported) {
71-
setAccountCode(coins[0].suggestedAccountName);
71+
setAccountName(coins[0].suggestedAccountName);
7272
}
7373
inputRef.current?.focus();
7474
} catch (err) {
@@ -91,8 +91,12 @@ export const AddAccount = ({ accounts }: TAddAccountGuide) => {
9191
navigate(-1);
9292
break;
9393
case 'choose-name':
94-
setStep('select-coin');
95-
setErrorMessage(undefined);
94+
if (onlyOneSupportedCoin()) {
95+
navigate(-1);
96+
} else {
97+
setStep('select-coin');
98+
setErrorMessage(undefined);
99+
}
96100
break;
97101
case 'success':
98102
setStep('choose-name');

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/btcsuite/btcd/btcec/v2 v2.3.4
1010
github.com/btcsuite/btcd/btcutil v1.1.6
1111
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
12+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
1213
github.com/ethereum/go-ethereum v1.14.13
1314
github.com/flynn/noise v1.1.0
1415
github.com/gorilla/mux v1.8.1
@@ -39,7 +40,6 @@ require (
3940
github.com/davecgh/go-spew v1.1.1 // indirect
4041
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
4142
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
42-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
4343
github.com/ethereum/c-kzg-4844 v1.0.3 // indirect
4444
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect
4545
github.com/fsnotify/fsnotify v1.7.0 // indirect

0 commit comments

Comments
 (0)