Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f6238c9
locize: make locize-pull
benma Oct 20, 2025
592ddbe
Merge branch 'locize' into release-v4.49.0
benma Oct 27, 2025
5812741
qt/windows: don't link libssp
benma Oct 20, 2025
d5cf59a
ci: temporarily skip locize format CI
benma Oct 27, 2025
c1e7ad9
Merge branch 'ssp-rel' into release-v4.49.0
benma Oct 27, 2025
2ddcbac
frontend: make locize-pull
benma Oct 28, 2025
dab0da7
Merge branch 'locize' into release-v4.49.0
benma Oct 28, 2025
6f01186
backend/bitbox02bootloader: remove var that is now unused
benma Oct 28, 2025
dc3f88a
ios: fix bottom nav underline artefact
shonsirsha Oct 28, 2025
824b348
regtest: make run_regtest.sh work again
benma Oct 29, 2025
9a9d8de
backend/btc: fix error when signing same PSBT twice
benma Oct 30, 2025
482cd12
Merge branch 'update-regtest'
benma Oct 30, 2025
ee8e801
frontend: cleanup and remove sidebar-header-size css variable
thisconnect Oct 31, 2025
ec121d9
frontend: cleanup and remove sidebar-header-line-heigh css variable
thisconnect Oct 31, 2025
df571b2
Merge branch 'ios-fix-underline-artefact-btm-nav' into release-v4.49.0
shonsirsha Nov 3, 2025
5a08835
ios: prevent body scroll when tx detail dialog is opened
shonsirsha Oct 28, 2025
efc3f97
Merge branch 'ios-fix-scrolling-in-txdetail-dialog'
shonsirsha Nov 3, 2025
43b29d9
Merge branch 'frontend-cleanup-css-II'
thisconnect Nov 3, 2025
9eb83a8
fix: ios scan qr dialog keeps reloading
shonsirsha Oct 29, 2025
0ef4dfc
Merge branch 'ios-fix-scan-qr-dialog-reload' into release-v4.49.0
shonsirsha Nov 3, 2025
44ee0ff
fronted: make locize-pull
benma Nov 3, 2025
2443b3e
Merge branch 'fixdup' into release-v4.49.0
benma Nov 3, 2025
78bc31a
Merge branch 'locize' into release-v4.49.0
benma Nov 3, 2025
22ff563
CHANGELOG: add BitBox02 Nova v9.24.0
benma Nov 4, 2025
c3889ec
Merge branch 'changelog' into release-v4.49.0
benma Nov 4, 2025
be443e6
tests: retry flaky Playwright tests.
bznein Nov 5, 2025
ca6f94f
chore: only upload video and trace on failure.
bznein Nov 5, 2025
8ed5e10
Merge branch 'retryFlaky'
bznein Nov 5, 2025
3496693
frontend: npm audit fix
thisconnect Nov 5, 2025
6a24acd
Merge branch 'frontend-audit-fix'
thisconnect Nov 5, 2025
8df9249
Merge branch 'plusprod'
benma Nov 10, 2025
eb7b572
Merge remote-tracking branch 'pull/master' into merge-v4.49.0
benma Nov 10, 2025
ac88bfa
Merge branch 'merge-v4.49.0'
benma Nov 10, 2025
ddde520
frontend: add feedback and support link to about settings
sutterseba Nov 10, 2025
9bae201
frontend: add feedback link to guide appendix
sutterseba Nov 10, 2025
00b6d56
Merge branch 'feedback-link'
sutterseba Nov 11, 2025
cf169f0
feat: implement PSBT handling in software keystore.
bznein Nov 10, 2025
4958c8e
Merge branch 'psbtSoftware'
bznein Nov 11, 2025
103b061
Merge remote-tracking branch 'upstream/master' into staging-send-to-s…
thisconnect Nov 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
run: make webe2etest

- name: Upload Playwright artifacts
if: always()
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-artifacts
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

## Unreleased
- Add a dropdown on the "Receiver address" input in the send screen to select an account
- Add feedback link to guide and about settings

## v4.49.0
- Bundle BitBox02 Nova firmware version v9.24.0
- macOS: fix potential USB communication issue with BitBox02 bootloaders <v1.1.2 and firmwares <v9.23.1
- Added BTC Direct sell option
- Added a banner to remind user to backup their seed phrase when an account reaches a certain threshold.
Expand Down
1 change: 1 addition & 0 deletions backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var fixedURLWhitelist = []string{
"https://bitbox.swiss/",
"https://shop.bitbox.swiss/",
"https://shiftcrypto.support/",
"https://support.bitbox.swiss",
// Exchange rates.
"https://www.coingecko.com/",
// Block explorers.
Expand Down
14 changes: 7 additions & 7 deletions backend/coins/btc/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/addresses"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/maketx"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/types"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
coinpkg "github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/signing"
Expand All @@ -38,9 +37,7 @@ type ProposedTransaction struct {
// List of signing configurations that might be used in the tx inputs.
AccountSigningConfigurations signing.Configurations
GetPrevTx func(chainhash.Hash) (*wire.MsgTx, error)
// Signatures collects the signatures, one per transaction input.
Signatures []*types.Signature
FormatUnit coin.BtcUnit
FormatUnit coin.BtcUnit
// GetKeystoreAddress returns the address from the same keystore given the script hash,
// or nil if not found.
GetKeystoreAddress func(coinpkg.Code, blockchain.ScriptHashHex) (*addresses.AccountAddress, error)
Expand Down Expand Up @@ -87,7 +84,9 @@ func (p *ProposedTransaction) Update() error {
rootFingerprintUint32,
inputAddress.AbsoluteKeypath().ToUInt32(),
inputAddress.PublicKey.SerializeCompressed(),
index); err != nil {
index); err != nil && err != psbt.ErrDuplicateKey {
// If we update the same PSBT multiple times, the key info is already present,
// so we can ignore the duplicate key error.
return err
}
case signing.ScriptTypeP2TR:
Expand Down Expand Up @@ -123,7 +122,9 @@ func (p *ProposedTransaction) Update() error {
rootFingerprintUint32,
outputAddress.AbsoluteKeypath().ToUInt32(),
outputAddress.PublicKey.SerializeCompressed(),
index); err != nil {
index); err != nil && err != psbt.ErrDuplicateKey {
// If we update the same PSBT multiple times, the key info is already present,
// so we can ignore the duplicate key error.
return err
}
case signing.ScriptTypeP2TR:
Expand Down Expand Up @@ -181,7 +182,6 @@ func (account *Account) signTransaction(
AccountSigningConfigurations: signingConfigs,
GetKeystoreAddress: account.getAddressFromSameKeystore,
GetPrevTx: getPrevTx,
Signatures: make([]*types.Signature, len(txProposal.Psbt.UnsignedTx.TxIn)),
FormatUnit: account.coin.formatUnit,
}
if err := proposedTransaction.Update(); err != nil {
Expand Down
1 change: 0 additions & 1 deletion backend/devices/bitbox02/keystore_simulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ func makeTx(t *testing.T, device *Device, recipient *maketx.OutputInfo) *btc.Pro
}
return nil, nil
},
Signatures: make([]*types.Signature, len(txProposal.Psbt.UnsignedTx.TxIn)),
FormatUnit: coinpkg.BtcUnitDefault,
}
require.NoError(t, proposedTransaction.Update())
Expand Down
5 changes: 0 additions & 5 deletions backend/devices/bitbox02bootloader/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable"
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable/action"
"github.com/BitBoxSwiss/bitbox02-api-go/api/bootloader"
"github.com/BitBoxSwiss/bitbox02-api-go/api/common"
bitbox02common "github.com/BitBoxSwiss/bitbox02-api-go/api/common"
"github.com/BitBoxSwiss/bitbox02-api-go/util/semver"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -203,10 +202,6 @@ func (device *Device) UpgradeFirmware() error {
return err
}
if err := device.Device.UpgradeFirmware(signedBinary); err != nil {
// Ignore sig errors for the Plus firmware while we are testing with unsigned firmwares.
if plusIsPlaceholder && product == common.ProductBitBox02PlusMulti {
return device.Reboot()
}
return err
}
return nil
Expand Down
3 changes: 0 additions & 3 deletions backend/devices/bitbox02bootloader/firmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ var firmwareBB02PlusBinaryBTCOnly []byte
var firmwareBB02PlusVersionBTCOnly = semver.NewSemVer(9, 24, 0)
var firmwareBB02PlusMonotonicVersionBtcOnly uint32 = 47

// TODO: set to false / remove before production. This is only to allow upgrading unsigned firmware.
const plusIsPlaceholder = false

//go:embed assets/firmware-bitbox02nova-multi.v9.24.0.signed.bin.gz
var firmwareBB02PlusBinaryMulti []byte
var firmwareBB02PlusVersionMulti = semver.NewSemVer(9, 24, 0)
Expand Down
21 changes: 8 additions & 13 deletions backend/keystore/software/software.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
"math/big"

"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc"
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/types"
Expand All @@ -33,6 +32,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
ethTypes "github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -211,7 +211,6 @@ func (keystore *Keystore) Features() *keystorePkg.Features {
func (keystore *Keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransaction) error {
keystore.log.Info("Sign transaction.")
transaction := btcProposedTx.TXProposal.Psbt.UnsignedTx
signatures := make([]*types.Signature, len(transaction.TxIn))
sigHashes := btcProposedTx.TXProposal.SigHashes()
for index, txIn := range transaction.TxIn {
spentOutput, ok := btcProposedTx.TXProposal.PreviousOutputs[txIn.PreviousOutPoint]
Expand Down Expand Up @@ -249,11 +248,7 @@ func (keystore *Keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
if err != nil {
return err
}
signatureSer := signature.Serialize()
signatures[index] = &types.Signature{
R: new(big.Int).SetBytes(signatureSer[:32]),
S: new(big.Int).SetBytes(signatureSer[32:]),
}
btcProposedTx.TXProposal.Psbt.Inputs[index].TaprootKeySpendSig = signature.Serialize()
} else {
var signatureHash []byte
isSegwit, subScript := address.ScriptForHashToSign()
Expand All @@ -274,16 +269,16 @@ func (keystore *Keystore) signBTCTransaction(btcProposedTx *btc.ProposedTransact
}
keystore.log.Debug("Calculated legacy signature hash")
}
signature := ecdsa.SignCompact(prv, signatureHash, true)

signatures[index] = &types.Signature{
R: new(big.Int).SetBytes(signature[1:33]),
S: new(big.Int).SetBytes(signature[33:]),
signature := ecdsa.Sign(prv, signatureHash).Serialize()
btcProposedTx.TXProposal.Psbt.Inputs[index].PartialSigs = []*psbt.PartialSig{
{
PubKey: prv.PubKey().SerializeCompressed(),
Signature: append(signature, byte(txscript.SigHashAll)),
},
}
}
}

btcProposedTx.Signatures = signatures
return nil
}

Expand Down
Loading